From aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Mon, 5 Oct 2020 22:27:18 +0200 Subject: New upstream version 1.27.90 --- src/settings/nm-agent-manager.c | 2445 +-- src/settings/nm-agent-manager.h | 104 +- src/settings/nm-secret-agent.c | 1129 +- src/settings/nm-secret-agent.h | 115 +- src/settings/nm-settings-connection.c | 4092 ++-- src/settings/nm-settings-connection.h | 473 +- src/settings/nm-settings-plugin.c | 360 +- src/settings/nm-settings-plugin.h | 250 +- src/settings/nm-settings-storage.c | 223 +- src/settings/nm-settings-storage.h | 104 +- src/settings/nm-settings-utils.c | 206 +- src/settings/nm-settings-utils.h | 81 +- src/settings/nm-settings.c | 6808 ++++--- src/settings/nm-settings.h | 149 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-common.h | 27 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c | 2062 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h | 22 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 11783 ++++++------ .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.h | 22 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-storage.c | 199 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-storage.h | 71 +- src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c | 1860 +- src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h | 181 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 6510 ++++--- .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.h | 28 +- src/settings/plugins/ifcfg-rh/shvar.c | 2409 +-- src/settings/plugins/ifcfg-rh/shvar.h | 112 +- .../ifcfg-Test_Write_WiFi_AP_Mode.cexpected | 19 + .../network-scripts/ifcfg-test-write-unknown-1 | 4 +- .../ifcfg-test-write-unknown-1.expected | 6 +- .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 19226 ++++++++++--------- .../ifupdown/nms-ifupdown-interface-parser.c | 579 +- .../ifupdown/nms-ifupdown-interface-parser.h | 36 +- .../plugins/ifupdown/nms-ifupdown-parser.c | 1192 +- .../plugins/ifupdown/nms-ifupdown-parser.h | 7 +- .../plugins/ifupdown/nms-ifupdown-plugin.c | 586 +- .../plugins/ifupdown/nms-ifupdown-plugin.h | 22 +- .../plugins/ifupdown/tests/test-ifupdown.c | 820 +- src/settings/plugins/keyfile/nms-keyfile-plugin.c | 2240 +-- src/settings/plugins/keyfile/nms-keyfile-plugin.h | 94 +- src/settings/plugins/keyfile/nms-keyfile-reader.c | 394 +- src/settings/plugins/keyfile/nms-keyfile-reader.h | 32 +- src/settings/plugins/keyfile/nms-keyfile-storage.c | 361 +- src/settings/plugins/keyfile/nms-keyfile-storage.h | 335 +- src/settings/plugins/keyfile/nms-keyfile-utils.c | 641 +- src/settings/plugins/keyfile/nms-keyfile-utils.h | 89 +- src/settings/plugins/keyfile/nms-keyfile-writer.c | 849 +- src/settings/plugins/keyfile/nms-keyfile-writer.h | 56 +- .../plugins/keyfile/tests/test-keyfile-settings.c | 4521 ++--- 49 files changed, 37850 insertions(+), 36084 deletions(-) create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_AP_Mode.cexpected (limited to 'src/settings') diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 363b1175..07a3dafe 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2013 Red Hat, Inc. */ @@ -25,1135 +25,1179 @@ /*****************************************************************************/ enum { - AGENT_REGISTERED, - LAST_SIGNAL, + AGENT_REGISTERED, + LAST_SIGNAL, }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = {0}; typedef struct { - NMAuthManager *auth_mgr; - NMSessionMonitor *session_monitor; + NMAuthManager * auth_mgr; + NMSessionMonitor *session_monitor; - CList agent_lst_head; + CList agent_lst_head; - CList request_lst_head; + CList request_lst_head; - guint64 agent_version_id; + guint64 agent_version_id; } NMAgentManagerPrivate; struct _NMAgentManager { - NMDBusObject parent; - NMAgentManagerPrivate _priv; + NMDBusObject parent; + NMAgentManagerPrivate _priv; }; struct _NMAgentManagerClass { - NMDBusObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, NM_TYPE_DBUS_OBJECT) +G_DEFINE_TYPE(NMAgentManager, nm_agent_manager, NM_TYPE_DBUS_OBJECT) -#define NM_AGENT_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMAgentManager, NM_IS_AGENT_MANAGER) +#define NM_AGENT_MANAGER_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMAgentManager, NM_IS_AGENT_MANAGER) /*****************************************************************************/ -NM_DEFINE_SINGLETON_GETTER (NMAgentManager, nm_agent_manager_get, NM_TYPE_AGENT_MANAGER); +NM_DEFINE_SINGLETON_GETTER(NMAgentManager, nm_agent_manager_get, NM_TYPE_AGENT_MANAGER); /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "agent-manager" -#define _NMLOG_DOMAIN LOGD_AGENTS -#define _NMLOG(level, agent, ...) \ - G_STMT_START { \ - if (nm_logging_enabled ((level), (_NMLOG_DOMAIN))) { \ - char __prefix1[32]; \ - char __prefix2[128]; \ - NMSecretAgent *__agent = (agent); \ - \ - if (!(self)) \ - g_snprintf (__prefix1, sizeof (__prefix1), "%s%s", ""_NMLOG_PREFIX_NAME"", "[]"); \ - else if ((self) != singleton_instance) \ - g_snprintf (__prefix1, sizeof (__prefix1), "%s["NM_HASH_OBFUSCATE_PTR_FMT"]", ""_NMLOG_PREFIX_NAME"", NM_HASH_OBFUSCATE_PTR (self)); \ - else \ - g_strlcpy (__prefix1, _NMLOG_PREFIX_NAME, sizeof (__prefix1)); \ - if (__agent) { \ - g_snprintf (__prefix2, sizeof (__prefix2), \ - ": agent["NM_HASH_OBFUSCATE_PTR_FMT",%s]", \ - NM_HASH_OBFUSCATE_PTR (__agent), \ - nm_secret_agent_get_description (__agent)); \ - } else \ - __prefix2[0] = '\0'; \ - _nm_log ((level), (_NMLOG_DOMAIN), 0, NULL, NULL, \ - "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - __prefix1, __prefix2 _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - } G_STMT_END - -#define LOG_REQ_FMT "["NM_HASH_OBFUSCATE_PTR_FMT"/%s%s%s%s%s%s]" -#define LOG_REQ_ARG(req) \ - NM_HASH_OBFUSCATE_PTR (req), \ - NM_PRINT_FMT_QUOTE_STRING ((req)->detail), \ - NM_PRINT_FMT_QUOTED (((req)->request_type == REQUEST_TYPE_CON_GET) && (req)->con.get.setting_name, \ - "/\"", (req)->con.get.setting_name, "\"", \ - ((req)->request_type == REQUEST_TYPE_CON_GET ? "/(none)" : _request_type_to_string ((req)->request_type, FALSE))) +#define _NMLOG_PREFIX_NAME "agent-manager" +#define _NMLOG_DOMAIN LOGD_AGENTS +#define _NMLOG(level, agent, ...) \ + G_STMT_START \ + { \ + if (nm_logging_enabled((level), (_NMLOG_DOMAIN))) { \ + char __prefix1[32]; \ + char __prefix2[128]; \ + NMSecretAgent *__agent = (agent); \ + \ + if (!(self)) \ + g_snprintf(__prefix1, \ + sizeof(__prefix1), \ + "%s%s", \ + ""_NMLOG_PREFIX_NAME \ + "", \ + "[]"); \ + else if ((self) != singleton_instance) \ + g_snprintf(__prefix1, \ + sizeof(__prefix1), \ + "%s[" NM_HASH_OBFUSCATE_PTR_FMT "]", \ + ""_NMLOG_PREFIX_NAME \ + "", \ + NM_HASH_OBFUSCATE_PTR(self)); \ + else \ + g_strlcpy(__prefix1, _NMLOG_PREFIX_NAME, sizeof(__prefix1)); \ + if (__agent) { \ + g_snprintf(__prefix2, \ + sizeof(__prefix2), \ + ": agent[" NM_HASH_OBFUSCATE_PTR_FMT ",%s]", \ + NM_HASH_OBFUSCATE_PTR(__agent), \ + nm_secret_agent_get_description(__agent)); \ + } else \ + __prefix2[0] = '\0'; \ + _nm_log((level), \ + (_NMLOG_DOMAIN), \ + 0, \ + NULL, \ + NULL, \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __prefix1, \ + __prefix2 _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END + +#define LOG_REQ_FMT "[" NM_HASH_OBFUSCATE_PTR_FMT "/%s%s%s%s%s%s]" +#define LOG_REQ_ARG(req) \ + NM_HASH_OBFUSCATE_PTR(req), NM_PRINT_FMT_QUOTE_STRING((req)->detail), \ + NM_PRINT_FMT_QUOTED(((req)->request_type == REQUEST_TYPE_CON_GET) \ + && (req)->con.get.setting_name, \ + "/\"", \ + (req)->con.get.setting_name, \ + "\"", \ + ((req)->request_type == REQUEST_TYPE_CON_GET \ + ? "/(none)" \ + : _request_type_to_string((req)->request_type, FALSE))) /*****************************************************************************/ typedef struct _NMAgentManagerCallId Request; -static void request_add_agent (Request *req, NMSecretAgent *agent); +static void request_add_agent(Request *req, NMSecretAgent *agent); -static void request_remove_agent (Request *req, NMSecretAgent *agent); +static void request_remove_agent(Request *req, NMSecretAgent *agent); -static void request_next_agent (Request *req); +static void request_next_agent(Request *req); -static void _con_get_request_start (Request *req); -static void _con_save_request_start (Request *req); -static void _con_del_request_start (Request *req); +static void _con_get_request_start(Request *req); +static void _con_save_request_start(Request *req); +static void _con_del_request_start(Request *req); -static gboolean _con_get_try_complete_early (Request *req); +static gboolean _con_get_try_complete_early(Request *req); -static void agent_disconnected_cb (NMSecretAgent *agent, gpointer user_data); +static void agent_disconnected_cb(NMSecretAgent *agent, gpointer user_data); /*****************************************************************************/ guint64 -nm_agent_manager_get_agent_version_id (NMAgentManager *self) +nm_agent_manager_get_agent_version_id(NMAgentManager *self) { - g_return_val_if_fail (NM_IS_AGENT_MANAGER (self), 0); + g_return_val_if_fail(NM_IS_AGENT_MANAGER(self), 0); - return NM_AGENT_MANAGER_GET_PRIVATE (self)->agent_version_id; + return NM_AGENT_MANAGER_GET_PRIVATE(self)->agent_version_id; } /*****************************************************************************/ typedef enum { - REQUEST_TYPE_INVALID, - REQUEST_TYPE_CON_GET, - REQUEST_TYPE_CON_SAVE, - REQUEST_TYPE_CON_DEL, + REQUEST_TYPE_INVALID, + REQUEST_TYPE_CON_GET, + REQUEST_TYPE_CON_SAVE, + REQUEST_TYPE_CON_DEL, } RequestType; static const char * -_request_type_to_string (RequestType request_type, gboolean verbose) +_request_type_to_string(RequestType request_type, gboolean verbose) { - switch (request_type) { - case REQUEST_TYPE_CON_GET: return verbose ? "getting" : "get"; - case REQUEST_TYPE_CON_SAVE: return verbose ? "saving" : "sav"; - case REQUEST_TYPE_CON_DEL: return verbose ? "deleting" : "del"; - default: return "??"; - } + switch (request_type) { + case REQUEST_TYPE_CON_GET: + return verbose ? "getting" : "get"; + case REQUEST_TYPE_CON_SAVE: + return verbose ? "saving" : "sav"; + case REQUEST_TYPE_CON_DEL: + return verbose ? "deleting" : "del"; + default: + return "??"; + } } /*****************************************************************************/ struct _NMAgentManagerCallId { - CList request_lst; + CList request_lst; - NMAgentManager *self; + NMAgentManager *self; - RequestType request_type; + RequestType request_type; - char *detail; + char *detail; - NMAuthSubject *subject; + NMAuthSubject *subject; - /* Current agent being asked for secrets */ - NMSecretAgent *current; - NMSecretAgentCallId *current_call_id; + /* Current agent being asked for secrets */ + NMSecretAgent * current; + NMSecretAgentCallId *current_call_id; - /* Stores the sorted list of NMSecretAgents which will be asked for secrets */ - GSList *pending; + /* Stores the sorted list of NMSecretAgents which will be asked for secrets */ + GSList *pending; - guint idle_id; + guint idle_id; - union { - struct { - char *path; - NMConnection *connection; + union { + struct { + char * path; + NMConnection *connection; - NMAuthChain *chain; + NMAuthChain *chain; - /* Whether the agent currently being asked for secrets - * has the system.modify privilege. - */ - gboolean current_has_modify; + /* Whether the agent currently being asked for secrets + * has the system.modify privilege. + */ + gboolean current_has_modify; - union { - struct { - NMSecretAgentGetSecretsFlags flags; - char *setting_name; - char **hints; + union { + struct { + NMSecretAgentGetSecretsFlags flags; + char * setting_name; + char ** hints; - GVariant *existing_secrets; + GVariant *existing_secrets; - NMAgentSecretsResultFunc callback; - gpointer callback_data; - } get; - }; - } con; - }; + NMAgentSecretsResultFunc callback; + gpointer callback_data; + } get; + }; + } con; + }; }; /*****************************************************************************/ static NMSecretAgent * -_agent_find_by_owner (NMAgentManagerPrivate *priv, - const char *owner) +_agent_find_by_owner(NMAgentManagerPrivate *priv, const char *owner) { - NMSecretAgent *agent; + NMSecretAgent *agent; - c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) { - if (nm_streq (nm_secret_agent_get_dbus_owner (agent), owner)) - return agent; - } - return NULL; + c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) { + if (nm_streq(nm_secret_agent_get_dbus_owner(agent), owner)) + return agent; + } + return NULL; } static NMSecretAgent * -_agent_find_by_identifier_and_uid (NMAgentManagerPrivate *priv, - const char *identifier, - gulong sender_uid) +_agent_find_by_identifier_and_uid(NMAgentManagerPrivate *priv, + const char * identifier, + gulong sender_uid) { - NMSecretAgent *agent; - - c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) { - if ( nm_streq0 (nm_secret_agent_get_identifier (agent), identifier) - && sender_uid == nm_secret_agent_get_owner_uid (agent)) - return agent; - } - return NULL; + NMSecretAgent *agent; + + c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) { + if (nm_streq0(nm_secret_agent_get_identifier(agent), identifier) + && sender_uid == nm_secret_agent_get_owner_uid(agent)) + return agent; + } + return NULL; } /*****************************************************************************/ static void -_agent_remove (NMAgentManager *self, NMSecretAgent *agent) +_agent_remove(NMAgentManager *self, NMSecretAgent *agent) { - NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); - CList *iter, *safe; + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self); + CList * iter, *safe; - nm_assert (NM_IS_SECRET_AGENT (agent)); - nm_assert (c_list_contains (&priv->agent_lst_head, &agent->agent_lst)); + nm_assert(NM_IS_SECRET_AGENT(agent)); + nm_assert(c_list_contains(&priv->agent_lst_head, &agent->agent_lst)); - _LOGD (agent, "agent unregistered or disappeared"); + _LOGD(agent, "agent unregistered or disappeared"); - nm_clear_pointer (&agent->auth_chain, nm_auth_chain_destroy); + nm_clear_pointer(&agent->auth_chain, nm_auth_chain_destroy); - c_list_unlink (&agent->agent_lst); + c_list_unlink(&agent->agent_lst); - g_signal_handlers_disconnect_by_func (agent, G_CALLBACK (agent_disconnected_cb), self); + g_signal_handlers_disconnect_by_func(agent, G_CALLBACK(agent_disconnected_cb), self); - /* Remove this agent from any in-progress secrets requests */ - c_list_for_each_safe (iter, safe, &priv->request_lst_head) - request_remove_agent (c_list_entry (iter, Request, request_lst), agent); + /* Remove this agent from any in-progress secrets requests */ + c_list_for_each_safe (iter, safe, &priv->request_lst_head) + request_remove_agent(c_list_entry(iter, Request, request_lst), agent); - g_object_unref (agent); + g_object_unref(agent); } /* Call this *after* calling request_next_agent() */ static void -maybe_remove_agent_on_error (NMAgentManager *self, - NMSecretAgent *agent, - GError *error) +maybe_remove_agent_on_error(NMAgentManager *self, NMSecretAgent *agent, GError *error) { - if ( !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_DISCONNECTED) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER)) - return; + if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CLOSED) + && !g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_DISCONNECTED) + && !g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER)) + return; - if (!c_list_is_empty (&agent->agent_lst)) - _agent_remove (self, agent); + if (!c_list_is_empty(&agent->agent_lst)) + _agent_remove(self, agent); } /*****************************************************************************/ static gboolean -validate_identifier (const char *identifier, GError **error) +validate_identifier(const char *identifier, GError **error) { - const char *p = identifier; - size_t id_len; - - if (!identifier) { - g_set_error_literal (error, - NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, - "No identifier was given"); - return FALSE; - } - - /* Length between 3 and 255 characters inclusive */ - id_len = strlen (identifier); - if (id_len < 3 || id_len > 255) { - g_set_error_literal (error, - NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, - "Identifier length not between 3 and 255 characters (inclusive)"); - return FALSE; - } - - if ((identifier[0] == '.') || (identifier[id_len - 1] == '.')) { - g_set_error_literal (error, - NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, - "Identifier must not start or end with '.'"); - return FALSE; - } - - /* FIXME: do complete validation here */ - while (p && *p) { - if (!g_ascii_isalnum (*p) && (*p != '_') && (*p != '-') && (*p != '.')) { - g_set_error (error, - NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, - "Identifier contains invalid character '%c'", *p); - return FALSE; - } - - if ((*p == '.') && (*(p + 1) == '.')) { - g_set_error_literal (error, - NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, - "Identifier contains two '.' characters in sequence"); - return FALSE; - } - p++; - } - - return TRUE; + const char *p = identifier; + size_t id_len; + + if (!identifier) { + g_set_error_literal(error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "No identifier was given"); + return FALSE; + } + + /* Length between 3 and 255 characters inclusive */ + id_len = strlen(identifier); + if (id_len < 3 || id_len > 255) { + g_set_error_literal(error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier length not between 3 and 255 characters (inclusive)"); + return FALSE; + } + + if ((identifier[0] == '.') || (identifier[id_len - 1] == '.')) { + g_set_error_literal(error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier must not start or end with '.'"); + return FALSE; + } + + /* FIXME: do complete validation here */ + while (p && *p) { + if (!g_ascii_isalnum(*p) && (*p != '_') && (*p != '-') && (*p != '.')) { + g_set_error(error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier contains invalid character '%c'", + *p); + return FALSE; + } + + if ((*p == '.') && (*(p + 1) == '.')) { + g_set_error_literal(error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier contains two '.' characters in sequence"); + return FALSE; + } + p++; + } + + return TRUE; } static void -_agent_permissions_check_done (NMAuthChain *chain, - GDBusMethodInvocation *context, - gpointer user_data) +_agent_permissions_check_done(NMAuthChain * chain, + GDBusMethodInvocation *context, + gpointer user_data) { - NMAgentManager *self = NM_AGENT_MANAGER (user_data); - NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); - NMSecretAgent *agent; - Request *request; + NMAgentManager * self = NM_AGENT_MANAGER(user_data); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self); + NMSecretAgent * agent; + Request * request; - nm_assert (!context || G_IS_DBUS_METHOD_INVOCATION (context)); + nm_assert(!context || G_IS_DBUS_METHOD_INVOCATION(context)); - agent = nm_auth_chain_steal_data (chain, "agent"); + agent = nm_auth_chain_steal_data(chain, "agent"); - nm_assert (NM_IS_SECRET_AGENT (agent)); - nm_assert (agent->auth_chain == chain); - nm_assert (agent->fully_registered == (!context)); - nm_assert (c_list_contains (&priv->agent_lst_head, &agent->agent_lst)); + nm_assert(NM_IS_SECRET_AGENT(agent)); + nm_assert(agent->auth_chain == chain); + nm_assert(agent->fully_registered == (!context)); + nm_assert(c_list_contains(&priv->agent_lst_head, &agent->agent_lst)); - agent->auth_chain = NULL; + agent->auth_chain = NULL; - nm_secret_agent_add_permission (agent, - NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, - (nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED) == NM_AUTH_CALL_RESULT_YES)); - nm_secret_agent_add_permission (agent, - NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, - (nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN) == NM_AUTH_CALL_RESULT_YES)); + nm_secret_agent_add_permission( + agent, + NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, + (nm_auth_chain_get_result(chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED) + == NM_AUTH_CALL_RESULT_YES)); + nm_secret_agent_add_permission( + agent, + NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, + (nm_auth_chain_get_result(chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN) + == NM_AUTH_CALL_RESULT_YES)); - if (agent->fully_registered) { - _LOGD (agent, "updated agent permissions"); - return; - } + if (agent->fully_registered) { + _LOGD(agent, "updated agent permissions"); + return; + } - _LOGI (agent, "agent registered"); + _LOGI(agent, "agent registered"); - agent->fully_registered = TRUE; + agent->fully_registered = TRUE; - priv->agent_version_id += 1; + priv->agent_version_id += 1; - g_dbus_method_invocation_return_value (context, NULL); + g_dbus_method_invocation_return_value(context, NULL); - c_list_for_each_entry (request, &priv->request_lst_head, request_lst) - request_add_agent (request, agent); + c_list_for_each_entry (request, &priv->request_lst_head, request_lst) + request_add_agent(request, agent); - g_signal_emit (self, signals[AGENT_REGISTERED], 0, agent); + g_signal_emit(self, signals[AGENT_REGISTERED], 0, agent); } static NMAuthChain * -_agent_create_auth_chain (NMAgentManager *self, - NMSecretAgent *agent, - GDBusMethodInvocation *context) +_agent_create_auth_chain(NMAgentManager *self, NMSecretAgent *agent, GDBusMethodInvocation *context) { - NMAuthChain *chain; - - _LOGD (agent, "requesting permissions"); - - nm_assert ( !agent->auth_chain - || (agent->fully_registered == (!nm_auth_chain_get_context (agent->auth_chain)))); - - if ( agent->auth_chain - && !context - && !agent->fully_registered) { - /* we restart the authorization check (without a @context), but the currently - * pending auth-chain carries a context. We need to pass it on as we replace - * the auth-chain. */ - context = nm_auth_chain_get_context (agent->auth_chain); - nm_assert (context); - } - - chain = nm_auth_chain_new_subject (nm_secret_agent_get_subject (agent), - context, - _agent_permissions_check_done, - self); - - nm_auth_chain_set_data (chain, "agent", agent, NULL); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE); - - nm_clear_pointer (&agent->auth_chain, nm_auth_chain_destroy); - agent->auth_chain = chain; - return chain; + NMAuthChain *chain; + + _LOGD(agent, "requesting permissions"); + + nm_assert(!agent->auth_chain + || (agent->fully_registered == (!nm_auth_chain_get_context(agent->auth_chain)))); + + if (agent->auth_chain && !context && !agent->fully_registered) { + /* we restart the authorization check (without a @context), but the currently + * pending auth-chain carries a context. We need to pass it on as we replace + * the auth-chain. */ + context = nm_auth_chain_get_context(agent->auth_chain); + nm_assert(context); + } + + chain = nm_auth_chain_new_subject(nm_secret_agent_get_subject(agent), + context, + _agent_permissions_check_done, + self); + + nm_auth_chain_set_data(chain, "agent", agent, NULL); + nm_auth_chain_add_call(chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE); + nm_auth_chain_add_call(chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE); + + nm_clear_pointer(&agent->auth_chain, nm_auth_chain_destroy); + agent->auth_chain = chain; + return chain; } static void -agent_disconnected_cb (NMSecretAgent *agent, gpointer user_data) +agent_disconnected_cb(NMSecretAgent *agent, gpointer user_data) { - _agent_remove (NM_AGENT_MANAGER (user_data), agent); + _agent_remove(NM_AGENT_MANAGER(user_data), agent); } static void -agent_manager_register_with_capabilities (NMAgentManager *self, - GDBusMethodInvocation *context, - const char *identifier, - guint32 capabilities) +agent_manager_register_with_capabilities(NMAgentManager * self, + GDBusMethodInvocation *context, + const char * identifier, + guint32 capabilities) { - NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); - gs_unref_object NMAuthSubject *subject = NULL; - gulong sender_uid = G_MAXULONG; - GError *error = NULL; - NMSecretAgent *agent; - - subject = nm_dbus_manager_new_auth_subject_from_context (context); - if (!subject) { - error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, - NM_UTILS_ERROR_MSG_REQ_UID_UKNOWN); - g_dbus_method_invocation_take_error (context, error); - return; - } - sender_uid = nm_auth_subject_get_unix_process_uid (subject); - - /* Validate the identifier */ - if (!validate_identifier (identifier, &error)) { - g_dbus_method_invocation_take_error (context, error); - return; - } - - /* Only one agent for each identifier is allowed per user */ - if (_agent_find_by_identifier_and_uid (priv, identifier, sender_uid)) { - error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, - "An agent with this ID is already registered for this user."); - g_dbus_method_invocation_take_error (context, error); - return; - } - - agent = nm_secret_agent_new (context, subject, identifier, capabilities); - - g_signal_connect (agent, NM_SECRET_AGENT_DISCONNECTED, - G_CALLBACK (agent_disconnected_cb), self); - - c_list_link_tail (&priv->agent_lst_head, &agent->agent_lst); - - _agent_create_auth_chain (self, agent, context); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self); + gs_unref_object NMAuthSubject *subject = NULL; + gulong sender_uid = G_MAXULONG; + GError * error = NULL; + NMSecretAgent * agent; + + subject = nm_dbus_manager_new_auth_subject_from_context(context); + if (!subject) { + error = g_error_new_literal(NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, + NM_UTILS_ERROR_MSG_REQ_UID_UKNOWN); + g_dbus_method_invocation_take_error(context, error); + return; + } + sender_uid = nm_auth_subject_get_unix_process_uid(subject); + + /* Validate the identifier */ + if (!validate_identifier(identifier, &error)) { + g_dbus_method_invocation_take_error(context, error); + return; + } + + /* Only one agent for each identifier is allowed per user */ + if (_agent_find_by_identifier_and_uid(priv, identifier, sender_uid)) { + error = g_error_new_literal(NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, + "An agent with this ID is already registered for this user."); + g_dbus_method_invocation_take_error(context, error); + return; + } + + agent = nm_secret_agent_new(context, subject, identifier, capabilities); + + g_signal_connect(agent, NM_SECRET_AGENT_DISCONNECTED, G_CALLBACK(agent_disconnected_cb), self); + + c_list_link_tail(&priv->agent_lst_head, &agent->agent_lst); + + _agent_create_auth_chain(self, agent, context); } static void -impl_agent_manager_register (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_agent_manager_register(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - const char *identifier; + const char *identifier; - g_variant_get (parameters, "(&s)", &identifier); - agent_manager_register_with_capabilities (NM_AGENT_MANAGER (obj), invocation, identifier, 0); + g_variant_get(parameters, "(&s)", &identifier); + agent_manager_register_with_capabilities(NM_AGENT_MANAGER(obj), invocation, identifier, 0); } static void -impl_agent_manager_register_with_capabilities (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_agent_manager_register_with_capabilities(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - const char *identifier; - guint32 capabilities; - - g_variant_get (parameters, "(&su)", &identifier, &capabilities); - agent_manager_register_with_capabilities (NM_AGENT_MANAGER (obj), invocation, identifier, capabilities); + const char *identifier; + guint32 capabilities; + + g_variant_get(parameters, "(&su)", &identifier, &capabilities); + agent_manager_register_with_capabilities(NM_AGENT_MANAGER(obj), + invocation, + identifier, + capabilities); } static void -impl_agent_manager_unregister (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_agent_manager_unregister(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMAgentManager *self = NM_AGENT_MANAGER (obj); - NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); - NMSecretAgent *agent; - - agent = _agent_find_by_owner (priv, sender); - if (!agent) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, - "Caller is not registered as an Agent"); - return; - } - - _agent_remove (self, agent); - - g_dbus_method_invocation_return_value (invocation, NULL); + NMAgentManager * self = NM_AGENT_MANAGER(obj); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self); + NMSecretAgent * agent; + + agent = _agent_find_by_owner(priv, sender); + if (!agent) { + g_dbus_method_invocation_return_error_literal(invocation, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, + "Caller is not registered as an Agent"); + return; + } + + _agent_remove(self, agent); + + g_dbus_method_invocation_return_value(invocation, NULL); } /*****************************************************************************/ static Request * -request_new (NMAgentManager *self, - RequestType request_type, - const char *detail, - NMAuthSubject *subject) +request_new(NMAgentManager *self, + RequestType request_type, + const char * detail, + NMAuthSubject * subject) { - Request *req; - - req = g_slice_new0 (Request); - req->self = g_object_ref (self); - req->request_type = request_type; - req->detail = g_strdup (detail); - req->subject = g_object_ref (subject); - c_list_link_tail (&NM_AGENT_MANAGER_GET_PRIVATE (self)->request_lst_head, &req->request_lst); - return req; + Request *req; + + req = g_slice_new0(Request); + req->self = g_object_ref(self); + req->request_type = request_type; + req->detail = g_strdup(detail); + req->subject = g_object_ref(subject); + c_list_link_tail(&NM_AGENT_MANAGER_GET_PRIVATE(self)->request_lst_head, &req->request_lst); + return req; } static void -request_free (Request *req) +request_free(Request *req) { - switch (req->request_type) { - case REQUEST_TYPE_CON_GET: - case REQUEST_TYPE_CON_SAVE: - case REQUEST_TYPE_CON_DEL: - g_object_unref (req->con.connection); - g_free (req->con.path); - nm_clear_pointer (&req->con.chain, nm_auth_chain_destroy); - if (req->request_type == REQUEST_TYPE_CON_GET) { - g_free (req->con.get.setting_name); - g_strfreev (req->con.get.hints); - if (req->con.get.existing_secrets) - g_variant_unref (req->con.get.existing_secrets); - } - break; - default: - g_assert_not_reached (); - } - - if (req->idle_id) - g_source_remove (req->idle_id); - - /* cancel-secrets invokes the done-callback synchronously -- in which case - * the handler just return. - * Hence, we can proceed to free @req... */ - nm_secret_agent_cancel_call (req->current, req->current_call_id); - - g_object_unref (req->subject); - - g_free (req->detail); - g_slist_free_full (req->pending, g_object_unref); - - g_object_unref (req->self); - - if (req->current) - g_object_unref (req->current); - - memset (req, 0, sizeof (Request)); - g_slice_free (Request, req); + switch (req->request_type) { + case REQUEST_TYPE_CON_GET: + case REQUEST_TYPE_CON_SAVE: + case REQUEST_TYPE_CON_DEL: + g_object_unref(req->con.connection); + g_free(req->con.path); + nm_clear_pointer(&req->con.chain, nm_auth_chain_destroy); + if (req->request_type == REQUEST_TYPE_CON_GET) { + g_free(req->con.get.setting_name); + g_strfreev(req->con.get.hints); + if (req->con.get.existing_secrets) + g_variant_unref(req->con.get.existing_secrets); + } + break; + default: + g_assert_not_reached(); + } + + if (req->idle_id) + g_source_remove(req->idle_id); + + /* cancel-secrets invokes the done-callback synchronously -- in which case + * the handler just return. + * Hence, we can proceed to free @req... */ + nm_secret_agent_cancel_call(req->current, req->current_call_id); + + g_object_unref(req->subject); + + g_free(req->detail); + g_slist_free_full(req->pending, g_object_unref); + + g_object_unref(req->self); + + if (req->current) + g_object_unref(req->current); + + memset(req, 0, sizeof(Request)); + g_slice_free(Request, req); } static void -req_complete_release (Request *req, - GVariant *secrets, - const char *agent_dbus_owner, - const char *agent_username, - GError *error) +req_complete_release(Request * req, + GVariant * secrets, + const char *agent_dbus_owner, + const char *agent_username, + GError * error) { - NMAgentManager *self = req->self; - - switch (req->request_type) { - case REQUEST_TYPE_CON_GET: - req->con.get.callback (self, - req, - agent_dbus_owner, - agent_username, - req->con.current_has_modify, - req->con.get.setting_name, - req->con.get.flags, - error ? NULL : secrets, - error, - req->con.get.callback_data); - - break; - case REQUEST_TYPE_CON_SAVE: - case REQUEST_TYPE_CON_DEL: - break; - default: - g_return_if_reached (); - } - - request_free (req); + NMAgentManager *self = req->self; + + switch (req->request_type) { + case REQUEST_TYPE_CON_GET: + req->con.get.callback(self, + req, + agent_dbus_owner, + agent_username, + req->con.current_has_modify, + req->con.get.setting_name, + req->con.get.flags, + error ? NULL : secrets, + error, + req->con.get.callback_data); + + break; + case REQUEST_TYPE_CON_SAVE: + case REQUEST_TYPE_CON_DEL: + break; + default: + g_return_if_reached(); + } + + request_free(req); } static void -req_complete_cancel (Request *req, gboolean is_disposing) +req_complete_cancel(Request *req, gboolean is_disposing) { - gs_free_error GError *error = NULL; + gs_free_error GError *error = NULL; - nm_assert (req && req->self); - nm_assert (!c_list_contains (&NM_AGENT_MANAGER_GET_PRIVATE (req->self)->request_lst_head, &req->request_lst)); + nm_assert(req && req->self); + nm_assert(!c_list_contains(&NM_AGENT_MANAGER_GET_PRIVATE(req->self)->request_lst_head, + &req->request_lst)); - nm_utils_error_set_cancelled (&error, is_disposing, "NMAgentManager"); - req_complete_release (req, NULL, NULL, NULL, error); + nm_utils_error_set_cancelled(&error, is_disposing, "NMAgentManager"); + req_complete_release(req, NULL, NULL, NULL, error); } static void -req_complete (Request *req, - GVariant *secrets, - const char *agent_dbus_owner, - const char *agent_username, - GError *error) +req_complete(Request * req, + GVariant * secrets, + const char *agent_dbus_owner, + const char *agent_username, + GError * error) { - NMAgentManager *self = req->self; + NMAgentManager *self = req->self; - nm_assert (c_list_contains (&NM_AGENT_MANAGER_GET_PRIVATE (self)->request_lst_head, &req->request_lst)); + nm_assert( + c_list_contains(&NM_AGENT_MANAGER_GET_PRIVATE(self)->request_lst_head, &req->request_lst)); - c_list_unlink (&req->request_lst); + c_list_unlink(&req->request_lst); - req_complete_release (req, secrets, agent_dbus_owner, agent_username, error); + req_complete_release(req, secrets, agent_dbus_owner, agent_username, error); } static void -req_complete_error (Request *req, GError *error) +req_complete_error(Request *req, GError *error) { - req_complete (req, NULL, NULL, NULL, error); + req_complete(req, NULL, NULL, NULL, error); } static int -agent_compare_func (gconstpointer aa, gconstpointer bb, gpointer user_data) +agent_compare_func(gconstpointer aa, gconstpointer bb, gpointer user_data) { - NMSecretAgent *a = (NMSecretAgent *)aa; - NMSecretAgent *b = (NMSecretAgent *)bb; - Request *req = user_data; - NMSessionMonitor *sm; - gboolean a_active, b_active; - gulong a_pid, b_pid, requester; - guint64 a_start, b_start; - - a_pid = nm_secret_agent_get_pid (a); - b_pid = nm_secret_agent_get_pid (b); - - /* Prefer agents in the process the request came from */ - if (nm_auth_subject_get_subject_type (req->subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) { - requester = nm_auth_subject_get_unix_process_pid (req->subject); - - if (a_pid != b_pid) { - if (a_pid == requester) - return -1; - else if (b_pid == requester) - return 1; - } - } - - /* Prefer agents in active sessions */ - sm = NM_AGENT_MANAGER_GET_PRIVATE (req->self)->session_monitor; - a_active = nm_session_monitor_session_exists (sm, nm_secret_agent_get_owner_uid (a), TRUE); - b_active = nm_session_monitor_session_exists (sm, nm_secret_agent_get_owner_uid (b), TRUE); - if (a_active && !b_active) - return -1; - else if (!a_active && b_active) - return 1; - - /* Prefer agents launched later (this is essentially to ease agent debugging) */ - a_start = nm_utils_get_start_time_for_pid (a_pid, NULL, NULL); - b_start = nm_utils_get_start_time_for_pid (b_pid, NULL, NULL); - if (a_start > b_start) - return -1; - else if (a_start < b_start) - return 1; - - return 0; + NMSecretAgent * a = (NMSecretAgent *) aa; + NMSecretAgent * b = (NMSecretAgent *) bb; + Request * req = user_data; + NMSessionMonitor *sm; + gboolean a_active, b_active; + gulong a_pid, b_pid, requester; + guint64 a_start, b_start; + + a_pid = nm_secret_agent_get_pid(a); + b_pid = nm_secret_agent_get_pid(b); + + /* Prefer agents in the process the request came from */ + if (nm_auth_subject_get_subject_type(req->subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) { + requester = nm_auth_subject_get_unix_process_pid(req->subject); + + if (a_pid != b_pid) { + if (a_pid == requester) + return -1; + else if (b_pid == requester) + return 1; + } + } + + /* Prefer agents in active sessions */ + sm = NM_AGENT_MANAGER_GET_PRIVATE(req->self)->session_monitor; + a_active = nm_session_monitor_session_exists(sm, nm_secret_agent_get_owner_uid(a), TRUE); + b_active = nm_session_monitor_session_exists(sm, nm_secret_agent_get_owner_uid(b), TRUE); + if (a_active && !b_active) + return -1; + else if (!a_active && b_active) + return 1; + + /* Prefer agents launched later (this is essentially to ease agent debugging) */ + a_start = nm_utils_get_start_time_for_pid(a_pid, NULL, NULL); + b_start = nm_utils_get_start_time_for_pid(b_pid, NULL, NULL); + if (a_start > b_start) + return -1; + else if (a_start < b_start) + return 1; + + return 0; } static void -request_add_agent (Request *req, NMSecretAgent *agent) +request_add_agent(Request *req, NMSecretAgent *agent) { - NMAgentManager *self; - - g_return_if_fail (req != NULL); - g_return_if_fail (agent != NULL); - - self = req->self; - - if (req->request_type == REQUEST_TYPE_CON_GET) { - NMAuthSubject *subject = nm_secret_agent_get_subject (agent); - - /* Ensure the caller's username exists in the connection's permissions, - * or that the permissions is empty (ie, visible by everyone). - */ - if (!nm_auth_is_subject_in_acl (req->con.connection, subject, NULL)) { - _LOGD (agent, "agent ignored for secrets request "LOG_REQ_FMT" (not in ACL)", - LOG_REQ_ARG (req)); - /* Connection not visible to this agent's user */ - return; - } - } - - /* If the request should filter agents by UID, do that now */ - if (nm_auth_subject_get_subject_type (req->subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) { - uid_t agent_uid, subject_uid; - - agent_uid = nm_secret_agent_get_owner_uid (agent); - subject_uid = nm_auth_subject_get_unix_process_uid (req->subject); - if (agent_uid != subject_uid) { - _LOGD (agent, "agent ignored for secrets request "LOG_REQ_FMT" " - "(uid %ld not required %ld)", - LOG_REQ_ARG (req), - (long) agent_uid, (long) subject_uid); - return; - } - } - - _LOGD (agent, "agent allowed for secrets request "LOG_REQ_FMT, - LOG_REQ_ARG (req)); - - /* Add this agent to the list, sorted appropriately */ - req->pending = g_slist_insert_sorted_with_data (req->pending, - g_object_ref (agent), - agent_compare_func, - req); + NMAgentManager *self; + + g_return_if_fail(req != NULL); + g_return_if_fail(agent != NULL); + + self = req->self; + + if (req->request_type == REQUEST_TYPE_CON_GET) { + NMAuthSubject *subject = nm_secret_agent_get_subject(agent); + + /* Ensure the caller's username exists in the connection's permissions, + * or that the permissions is empty (ie, visible by everyone). + */ + if (!nm_auth_is_subject_in_acl(req->con.connection, subject, NULL)) { + _LOGD(agent, + "agent ignored for secrets request " LOG_REQ_FMT " (not in ACL)", + LOG_REQ_ARG(req)); + /* Connection not visible to this agent's user */ + return; + } + } + + /* If the request should filter agents by UID, do that now */ + if (nm_auth_subject_get_subject_type(req->subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) { + uid_t agent_uid, subject_uid; + + agent_uid = nm_secret_agent_get_owner_uid(agent); + subject_uid = nm_auth_subject_get_unix_process_uid(req->subject); + if (agent_uid != subject_uid) { + _LOGD(agent, + "agent ignored for secrets request " LOG_REQ_FMT " " + "(uid %ld not required %ld)", + LOG_REQ_ARG(req), + (long) agent_uid, + (long) subject_uid); + return; + } + } + + _LOGD(agent, "agent allowed for secrets request " LOG_REQ_FMT, LOG_REQ_ARG(req)); + + /* Add this agent to the list, sorted appropriately */ + req->pending = + g_slist_insert_sorted_with_data(req->pending, g_object_ref(agent), agent_compare_func, req); } static void -request_add_agents (NMAgentManager *self, Request *req) +request_add_agents(NMAgentManager *self, Request *req) { - NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); - NMSecretAgent *agent; + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self); + NMSecretAgent * agent; - c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) { - if (agent->fully_registered) - request_add_agent (req, agent); - } + c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) { + if (agent->fully_registered) + request_add_agent(req, agent); + } } static void -request_next_agent (Request *req) +request_next_agent(Request *req) { - NMAgentManager *self; - GError *error = NULL; - - self = req->self; - - nm_secret_agent_cancel_call (req->current, req->current_call_id); - nm_assert (!req->current_call_id); - g_clear_object (&req->current); - - if (req->pending) { - /* Send the request to the next agent */ - req->current = req->pending->data; - req->pending = g_slist_remove (req->pending, req->current); - - _LOGD (req->current, "agent %s secrets for request "LOG_REQ_FMT, - _request_type_to_string (req->request_type, TRUE), - LOG_REQ_ARG (req)); - - switch (req->request_type) { - case REQUEST_TYPE_CON_GET: - _con_get_request_start (req); - break; - case REQUEST_TYPE_CON_SAVE: - _con_save_request_start (req); - break; - case REQUEST_TYPE_CON_DEL: - _con_del_request_start (req); - break; - default: - g_assert_not_reached (); - } - } else { - /* No more secret agents are available to fulfill this secrets request */ - error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_NO_SECRETS, - "No agents were available for this request."); - req_complete_error (req, error); - g_error_free (error); - } + NMAgentManager *self; + GError * error = NULL; + + self = req->self; + + nm_secret_agent_cancel_call(req->current, req->current_call_id); + nm_assert(!req->current_call_id); + g_clear_object(&req->current); + + if (req->pending) { + /* Send the request to the next agent */ + req->current = req->pending->data; + req->pending = g_slist_remove(req->pending, req->current); + + _LOGD(req->current, + "agent %s secrets for request " LOG_REQ_FMT, + _request_type_to_string(req->request_type, TRUE), + LOG_REQ_ARG(req)); + + switch (req->request_type) { + case REQUEST_TYPE_CON_GET: + _con_get_request_start(req); + break; + case REQUEST_TYPE_CON_SAVE: + _con_save_request_start(req); + break; + case REQUEST_TYPE_CON_DEL: + _con_del_request_start(req); + break; + default: + g_assert_not_reached(); + } + } else { + /* No more secret agents are available to fulfill this secrets request */ + error = g_error_new_literal(NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_NO_SECRETS, + "No agents were available for this request."); + req_complete_error(req, error); + g_error_free(error); + } } static void -request_remove_agent (Request *req, NMSecretAgent *agent) +request_remove_agent(Request *req, NMSecretAgent *agent) { - NMAgentManager *self; + NMAgentManager *self; - g_return_if_fail (req != NULL); - g_return_if_fail (agent != NULL); + g_return_if_fail(req != NULL); + g_return_if_fail(agent != NULL); - self = req->self; + self = req->self; - if (agent == req->current) { - nm_assert (!g_slist_find (req->pending, agent)); + if (agent == req->current) { + nm_assert(!g_slist_find(req->pending, agent)); - _LOGD (agent, "current agent removed from secrets request "LOG_REQ_FMT, - LOG_REQ_ARG (req)); + _LOGD(agent, "current agent removed from secrets request " LOG_REQ_FMT, LOG_REQ_ARG(req)); - switch (req->request_type) { - case REQUEST_TYPE_CON_GET: - case REQUEST_TYPE_CON_SAVE: - case REQUEST_TYPE_CON_DEL: - /* This cancels the pending authorization requests. */ - nm_clear_pointer (&req->con.chain, nm_auth_chain_destroy); - break; - default: - g_assert_not_reached (); - } + switch (req->request_type) { + case REQUEST_TYPE_CON_GET: + case REQUEST_TYPE_CON_SAVE: + case REQUEST_TYPE_CON_DEL: + /* This cancels the pending authorization requests. */ + nm_clear_pointer(&req->con.chain, nm_auth_chain_destroy); + break; + default: + g_assert_not_reached(); + } - request_next_agent (req); - } else if (g_slist_find (req->pending, agent)) { - req->pending = g_slist_remove (req->pending, agent); + request_next_agent(req); + } else if (g_slist_find(req->pending, agent)) { + req->pending = g_slist_remove(req->pending, agent); - _LOGD (agent, "agent removed from secrets request "LOG_REQ_FMT, - LOG_REQ_ARG (req)); + _LOGD(agent, "agent removed from secrets request " LOG_REQ_FMT, LOG_REQ_ARG(req)); - g_object_unref (agent); - } + g_object_unref(agent); + } } static gboolean -request_start (gpointer user_data) +request_start(gpointer user_data) { - Request *req = user_data; + Request *req = user_data; - req->idle_id = 0; + req->idle_id = 0; - switch (req->request_type) { - case REQUEST_TYPE_CON_GET: - if (_con_get_try_complete_early (req)) - goto out; - break; - default: - break; - } - request_next_agent (req); + switch (req->request_type) { + case REQUEST_TYPE_CON_GET: + if (_con_get_try_complete_early(req)) + goto out; + break; + default: + break; + } + request_next_agent(req); out: - return FALSE; + return FALSE; } /*****************************************************************************/ static void -_con_get_request_done (NMSecretAgent *agent, - NMSecretAgentCallId *call_id, - GVariant *secrets, - GError *error, - gpointer user_data) +_con_get_request_done(NMSecretAgent * agent, + NMSecretAgentCallId *call_id, + GVariant * secrets, + GError * error, + gpointer user_data) { - NMAgentManager *self; - Request *req = user_data; - GVariant *setting_secrets; - const char *agent_dbus_owner; - struct passwd *pw; - char *agent_uname = NULL; - - g_return_if_fail (call_id == req->current_call_id); - g_return_if_fail (agent == req->current); - g_return_if_fail (req->request_type == REQUEST_TYPE_CON_GET); - - self = req->self; - - req->current_call_id = NULL; - - if (error) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - _LOGD (agent, "get secrets request cancelled: "LOG_REQ_FMT, - LOG_REQ_ARG (req)); - return; - } - - _LOGD (agent, "agent failed secrets request "LOG_REQ_FMT": %s", - LOG_REQ_ARG (req), - error->message); - - if (g_error_matches (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_USER_CANCELED)) { - error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_USER_CANCELED, - "User canceled the secrets request."); - req_complete_error (req, error); - g_error_free (error); - } else { - /* Tell the failed agent we're no longer interested. */ - nm_secret_agent_cancel_call (req->current, req->current_call_id); - - /* Try the next agent */ - request_next_agent (req); - maybe_remove_agent_on_error (self, agent, error); - } - return; - } - - /* Ensure the setting we wanted secrets for got returned and has something in it */ - setting_secrets = g_variant_lookup_value (secrets, req->con.get.setting_name, NM_VARIANT_TYPE_SETTING); - if (!setting_secrets || !g_variant_n_children (setting_secrets)) { - _LOGD (agent, "agent returned no secrets for request "LOG_REQ_FMT, - LOG_REQ_ARG (req)); - /* Try the next agent */ - request_next_agent (req); - return; - } - - _LOGD (agent, "agent returned secrets for request "LOG_REQ_FMT, - LOG_REQ_ARG (req)); - - /* Get the agent's username */ - pw = getpwuid (nm_secret_agent_get_owner_uid (agent)); - if (pw && strlen (pw->pw_name)) { - /* Needs to be UTF-8 valid since it may be pushed through D-Bus */ - if (g_utf8_validate (pw->pw_name, -1, NULL)) - agent_uname = g_strdup (pw->pw_name); - } - - agent_dbus_owner = nm_secret_agent_get_dbus_owner (agent); - req_complete (req, secrets, agent_dbus_owner, agent_uname, NULL); - g_free (agent_uname); + NMAgentManager *self; + Request * req = user_data; + GVariant * setting_secrets; + const char * agent_dbus_owner; + gs_free char * agent_name = NULL; + + g_return_if_fail(call_id == req->current_call_id); + g_return_if_fail(agent == req->current); + g_return_if_fail(req->request_type == REQUEST_TYPE_CON_GET); + + self = req->self; + + req->current_call_id = NULL; + + if (error) { + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + _LOGD(agent, "get secrets request cancelled: " LOG_REQ_FMT, LOG_REQ_ARG(req)); + return; + } + + _LOGD(agent, + "agent failed secrets request " LOG_REQ_FMT ": %s", + LOG_REQ_ARG(req), + error->message); + + if (g_error_matches(error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_USER_CANCELED)) { + error = g_error_new_literal(NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_USER_CANCELED, + "User canceled the secrets request."); + req_complete_error(req, error); + g_error_free(error); + } else { + /* Tell the failed agent we're no longer interested. */ + nm_secret_agent_cancel_call(req->current, req->current_call_id); + + /* Try the next agent */ + request_next_agent(req); + maybe_remove_agent_on_error(self, agent, error); + } + return; + } + + /* Ensure the setting we wanted secrets for got returned and has something in it */ + setting_secrets = + g_variant_lookup_value(secrets, req->con.get.setting_name, NM_VARIANT_TYPE_SETTING); + if (!setting_secrets || !g_variant_n_children(setting_secrets)) { + _LOGD(agent, "agent returned no secrets for request " LOG_REQ_FMT, LOG_REQ_ARG(req)); + /* Try the next agent */ + request_next_agent(req); + return; + } + + _LOGD(agent, "agent returned secrets for request " LOG_REQ_FMT, LOG_REQ_ARG(req)); + + agent_name = nm_utils_uid_to_name(nm_secret_agent_get_owner_uid(agent)); + if (agent_name && !g_utf8_validate(agent_name, -1, NULL)) { + /* Needs to be UTF-8 valid since it may be pushed through D-Bus */ + nm_clear_g_free(&agent_name); + } + + agent_dbus_owner = nm_secret_agent_get_dbus_owner(agent); + + req_complete(req, secrets, agent_dbus_owner, agent_name, NULL); } static void -set_secrets_not_required (NMConnection *connection, GVariant *dict) +set_secrets_not_required(NMConnection *connection, GVariant *dict) { - GVariantIter iter, setting_iter; - const char *setting_name = NULL; - GVariant *setting_dict = NULL; - - /* Iterate through the settings dicts */ - g_variant_iter_init (&iter, dict); - while (g_variant_iter_next (&iter, "{&s@a{sv}}", &setting_name, &setting_dict)) { - const char *key_name = NULL; - NMSetting *setting; - GVariant *val; - - setting = nm_connection_get_setting_by_name (connection, setting_name); - if (setting) { - /* Now through each secret in the setting and mark it as not required */ - g_variant_iter_init (&setting_iter, setting_dict); - while (g_variant_iter_next (&setting_iter, "{&sv}", &key_name, &val)) { - /* For each secret, set the flag that it's not required; VPN - * secrets need slightly different treatment here since the - * "secrets" property is actually a dictionary of secrets. - */ - if ( strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME) == 0 - && strcmp (key_name, NM_SETTING_VPN_SECRETS) == 0 - && g_variant_is_of_type (val, G_VARIANT_TYPE ("a{ss}"))) { - GVariantIter vpn_secret_iter; - const char *secret_name, *secret; - - g_variant_iter_init (&vpn_secret_iter, val); - while (g_variant_iter_next (&vpn_secret_iter, "{&s&s}", &secret_name, &secret)) - nm_setting_set_secret_flags (setting, secret_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL); - } else - nm_setting_set_secret_flags (setting, key_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL); - g_variant_unref (val); - } - } - g_variant_unref (setting_dict); - } + GVariantIter iter, setting_iter; + const char * setting_name = NULL; + GVariant * setting_dict = NULL; + + /* Iterate through the settings dicts */ + g_variant_iter_init(&iter, dict); + while (g_variant_iter_next(&iter, "{&s@a{sv}}", &setting_name, &setting_dict)) { + const char *key_name = NULL; + NMSetting * setting; + GVariant * val; + + setting = nm_connection_get_setting_by_name(connection, setting_name); + if (setting) { + /* Now through each secret in the setting and mark it as not required */ + g_variant_iter_init(&setting_iter, setting_dict); + while (g_variant_iter_next(&setting_iter, "{&sv}", &key_name, &val)) { + /* For each secret, set the flag that it's not required; VPN + * secrets need slightly different treatment here since the + * "secrets" property is actually a dictionary of secrets. + */ + if (strcmp(setting_name, NM_SETTING_VPN_SETTING_NAME) == 0 + && strcmp(key_name, NM_SETTING_VPN_SECRETS) == 0 + && g_variant_is_of_type(val, G_VARIANT_TYPE("a{ss}"))) { + GVariantIter vpn_secret_iter; + const char * secret_name, *secret; + + g_variant_iter_init(&vpn_secret_iter, val); + while (g_variant_iter_next(&vpn_secret_iter, "{&s&s}", &secret_name, &secret)) + nm_setting_set_secret_flags(setting, + secret_name, + NM_SETTING_SECRET_FLAG_NOT_REQUIRED, + NULL); + } else + nm_setting_set_secret_flags(setting, + key_name, + NM_SETTING_SECRET_FLAG_NOT_REQUIRED, + NULL); + g_variant_unref(val); + } + } + g_variant_unref(setting_dict); + } } static void -_con_get_request_start_proceed (Request *req, gboolean include_system_secrets) +_con_get_request_start_proceed(Request *req, gboolean include_system_secrets) { - NMConnection *tmp; - - g_return_if_fail (req->request_type == REQUEST_TYPE_CON_GET); - - tmp = nm_simple_connection_new_clone (req->con.connection); - nm_connection_clear_secrets (tmp); - if (include_system_secrets) { - if (req->con.get.existing_secrets) - (void) nm_connection_update_secrets (tmp, req->con.get.setting_name, req->con.get.existing_secrets, NULL); - } else { - /* Update secret flags in the temporary connection to indicate that - * the system secrets we're not sending to the agent aren't required, - * so the agent can properly validate UI controls and such. - */ - if (req->con.get.existing_secrets) - set_secrets_not_required (tmp, req->con.get.existing_secrets); - } - - req->current_call_id = nm_secret_agent_get_secrets (req->current, - req->con.path, - tmp, - req->con.get.setting_name, - (const char **) req->con.get.hints, - req->con.get.flags, - _con_get_request_done, - req); - if (!req->current_call_id) { - g_warn_if_reached (); - request_next_agent (req); - } - - g_object_unref (tmp); + NMConnection *tmp; + + g_return_if_fail(req->request_type == REQUEST_TYPE_CON_GET); + + tmp = nm_simple_connection_new_clone(req->con.connection); + nm_connection_clear_secrets(tmp); + if (include_system_secrets) { + if (req->con.get.existing_secrets) + (void) nm_connection_update_secrets(tmp, + req->con.get.setting_name, + req->con.get.existing_secrets, + NULL); + } else { + /* Update secret flags in the temporary connection to indicate that + * the system secrets we're not sending to the agent aren't required, + * so the agent can properly validate UI controls and such. + */ + if (req->con.get.existing_secrets) + set_secrets_not_required(tmp, req->con.get.existing_secrets); + } + + req->current_call_id = nm_secret_agent_get_secrets(req->current, + req->con.path, + tmp, + req->con.get.setting_name, + (const char **) req->con.get.hints, + req->con.get.flags, + _con_get_request_done, + req); + if (!req->current_call_id) { + g_warn_if_reached(); + request_next_agent(req); + } + + g_object_unref(tmp); } static void -_con_get_request_start_validated (NMAuthChain *chain, +_con_get_request_start_validated(NMAuthChain * chain, GDBusMethodInvocation *context, - gpointer user_data) + gpointer user_data) { - NMAgentManager *self; - Request *req = user_data; - const char *perm; + NMAgentManager *self; + Request * req = user_data; + const char * perm; - g_return_if_fail (req->request_type == REQUEST_TYPE_CON_GET); + g_return_if_fail(req->request_type == REQUEST_TYPE_CON_GET); - self = req->self; + self = req->self; - req->con.chain = NULL; + req->con.chain = NULL; - /* If the agent obtained the 'modify' permission, we send all system secrets - * to it. If it didn't, we still ask it for secrets, but we don't send - * any system secrets. - */ - perm = nm_auth_chain_get_data (chain, "perm"); - g_assert (perm); - if (nm_auth_chain_get_result (chain, perm) == NM_AUTH_CALL_RESULT_YES) - req->con.current_has_modify = TRUE; + /* If the agent obtained the 'modify' permission, we send all system secrets + * to it. If it didn't, we still ask it for secrets, but we don't send + * any system secrets. + */ + perm = nm_auth_chain_get_data(chain, "perm"); + g_assert(perm); + if (nm_auth_chain_get_result(chain, perm) == NM_AUTH_CALL_RESULT_YES) + req->con.current_has_modify = TRUE; - _LOGD (req->current, "agent "LOG_REQ_FMT" MODIFY check result %s", - LOG_REQ_ARG (req), - req->con.current_has_modify ? "YES" : "NO"); + _LOGD(req->current, + "agent " LOG_REQ_FMT " MODIFY check result %s", + LOG_REQ_ARG(req), + req->con.current_has_modify ? "YES" : "NO"); - _con_get_request_start_proceed (req, req->con.current_has_modify); + _con_get_request_start_proceed(req, req->con.current_has_modify); } static void -_con_get_request_start (Request *req) +_con_get_request_start(Request *req) { - NMAgentManager *self; - NMSettingConnection *s_con; - const char *agent_dbus_owner, *perm; - - self = req->self; - - req->con.current_has_modify = FALSE; - - agent_dbus_owner = nm_secret_agent_get_dbus_owner (req->current); - - /* If the request flags allow user interaction, and there are existing - * system secrets (or blank secrets that are supposed to be system-owned), - * check whether the agent has the 'modify' permission before sending those - * secrets to the agent. We shouldn't leak system-owned secrets to - * unprivileged users. - */ - if ( (req->con.get.flags != NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) - && ( req->con.get.existing_secrets - || _nm_connection_aggregate (req->con.connection, NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, NULL))) { - _LOGD (NULL, "("LOG_REQ_FMT") request has system secrets; checking agent %s for MODIFY", - LOG_REQ_ARG (req), agent_dbus_owner); - - req->con.chain = nm_auth_chain_new_subject (nm_secret_agent_get_subject (req->current), - NULL, - _con_get_request_start_validated, - req); - nm_assert (req->con.chain); - - /* If the caller is the only user in the connection's permissions, then - * we use the 'modify.own' permission instead of 'modify.system'. If the - * request affects more than just the caller, require 'modify.system'. - */ - s_con = nm_connection_get_setting_connection (req->con.connection); - g_assert (s_con); - if (nm_setting_connection_get_num_permissions (s_con) == 1) - perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; - else - perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; - nm_auth_chain_set_data (req->con.chain, "perm", (gpointer) perm, NULL); - - nm_auth_chain_add_call_unsafe (req->con.chain, perm, TRUE); - } else { - _LOGD (NULL, "("LOG_REQ_FMT") requesting user-owned secrets from agent %s", - LOG_REQ_ARG (req), agent_dbus_owner); - - _con_get_request_start_proceed (req, FALSE); - } + NMAgentManager * self; + NMSettingConnection *s_con; + const char * agent_dbus_owner, *perm; + + self = req->self; + + req->con.current_has_modify = FALSE; + + agent_dbus_owner = nm_secret_agent_get_dbus_owner(req->current); + + /* If the request flags allow user interaction, and there are existing + * system secrets (or blank secrets that are supposed to be system-owned), + * check whether the agent has the 'modify' permission before sending those + * secrets to the agent. We shouldn't leak system-owned secrets to + * unprivileged users. + */ + if ((req->con.get.flags != NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) + && (req->con.get.existing_secrets + || _nm_connection_aggregate(req->con.connection, + NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS, + NULL))) { + _LOGD(NULL, + "(" LOG_REQ_FMT ") request has system secrets; checking agent %s for MODIFY", + LOG_REQ_ARG(req), + agent_dbus_owner); + + req->con.chain = nm_auth_chain_new_subject(nm_secret_agent_get_subject(req->current), + NULL, + _con_get_request_start_validated, + req); + nm_assert(req->con.chain); + + /* If the caller is the only user in the connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. If the + * request affects more than just the caller, require 'modify.system'. + */ + s_con = nm_connection_get_setting_connection(req->con.connection); + g_assert(s_con); + if (nm_setting_connection_get_num_permissions(s_con) == 1) + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + else + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; + nm_auth_chain_set_data(req->con.chain, "perm", (gpointer) perm, NULL); + + nm_auth_chain_add_call_unsafe(req->con.chain, perm, TRUE); + } else { + _LOGD(NULL, + "(" LOG_REQ_FMT ") requesting user-owned secrets from agent %s", + LOG_REQ_ARG(req), + agent_dbus_owner); + + _con_get_request_start_proceed(req, FALSE); + } } static gboolean -_con_get_try_complete_early (Request *req) +_con_get_try_complete_early(Request *req) { - NMAgentManager *self; - gs_unref_variant GVariant *setting_secrets = NULL; - gs_unref_object NMConnection *tmp = NULL; - GError *error = NULL; - - self = req->self; - - /* Check if there are any existing secrets */ - if (req->con.get.existing_secrets) - setting_secrets = g_variant_lookup_value (req->con.get.existing_secrets, req->con.get.setting_name, NM_VARIANT_TYPE_SETTING); - - if (!setting_secrets || !g_variant_n_children (setting_secrets)) - return FALSE; - - /* The connection already had secrets; check if any more are required. - * If no more are required, we're done. If secrets are still needed, - * ask a secret agent for more. This allows admins to provide generic - * secrets but allow additional user-specific ones as well. - */ - tmp = nm_simple_connection_new_clone (req->con.connection); - g_assert (tmp); - - if (!nm_connection_update_secrets (tmp, req->con.get.setting_name, req->con.get.existing_secrets, &error)) { - req_complete_error (req, error); - g_clear_error (&error); - return TRUE; - } - /* Do we have everything we need? */ - if ( NM_FLAGS_HAS (req->con.get.flags, NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM) - || ( (nm_connection_need_secrets (tmp, NULL) == NULL) - && !NM_FLAGS_HAS(req->con.get.flags, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW))) { - _LOGD (NULL, "("LOG_REQ_FMT") system settings secrets sufficient", - LOG_REQ_ARG (req)); - - /* Got everything, we're done */ - req_complete (req, req->con.get.existing_secrets, NULL, NULL, NULL); - return TRUE; - } - - _LOGD (NULL, "("LOG_REQ_FMT") system settings secrets insufficient, asking agents", - LOG_REQ_ARG (req)); - - /* We don't, so ask some agents for additional secrets */ - if ( req->con.get.flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS - && !req->pending) { - /* The request initiated from GetSecrets() via DBus, - * don't error out if any secrets are missing. */ - req_complete (req, req->con.get.existing_secrets, NULL, NULL, NULL); - return TRUE; - } - - /* Couldn't get secrets from system settings, so now we ask the - * agents for secrets. Let the Agent Manager handle which agents - * we'll ask and in which order. - */ - return FALSE; + NMAgentManager * self; + gs_unref_variant GVariant *setting_secrets = NULL; + gs_unref_object NMConnection *tmp = NULL; + GError * error = NULL; + + self = req->self; + + /* Check if there are any existing secrets */ + if (req->con.get.existing_secrets) + setting_secrets = g_variant_lookup_value(req->con.get.existing_secrets, + req->con.get.setting_name, + NM_VARIANT_TYPE_SETTING); + + if (!setting_secrets || !g_variant_n_children(setting_secrets)) + return FALSE; + + /* The connection already had secrets; check if any more are required. + * If no more are required, we're done. If secrets are still needed, + * ask a secret agent for more. This allows admins to provide generic + * secrets but allow additional user-specific ones as well. + */ + tmp = nm_simple_connection_new_clone(req->con.connection); + g_assert(tmp); + + if (!nm_connection_update_secrets(tmp, + req->con.get.setting_name, + req->con.get.existing_secrets, + &error)) { + req_complete_error(req, error); + g_clear_error(&error); + return TRUE; + } + /* Do we have everything we need? */ + if (NM_FLAGS_HAS(req->con.get.flags, NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM) + || ((nm_connection_need_secrets(tmp, NULL) == NULL) + && !NM_FLAGS_HAS(req->con.get.flags, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW))) { + _LOGD(NULL, "(" LOG_REQ_FMT ") system settings secrets sufficient", LOG_REQ_ARG(req)); + + /* Got everything, we're done */ + req_complete(req, req->con.get.existing_secrets, NULL, NULL, NULL); + return TRUE; + } + + _LOGD(NULL, + "(" LOG_REQ_FMT ") system settings secrets insufficient, asking agents", + LOG_REQ_ARG(req)); + + /* We don't, so ask some agents for additional secrets */ + if (req->con.get.flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS && !req->pending) { + /* The request initiated from GetSecrets() via DBus, + * don't error out if any secrets are missing. */ + req_complete(req, req->con.get.existing_secrets, NULL, NULL, NULL); + return TRUE; + } + + /* Couldn't get secrets from system settings, so now we ask the + * agents for secrets. Let the Agent Manager handle which agents + * we'll ask and in which order. + */ + return FALSE; } /** @@ -1171,425 +1215,404 @@ _con_get_try_complete_early (Request *req) * Requests secrets for a connection. * * This function cannot fail. The callback will be invoked - * asynchrnously, but it will always be invoked exactly once. + * asynchronously, but it will always be invoked exactly once. * Even for cancellation and disposing of @self. In those latter - * cases, the callback is invoked synchrnously during the cancellation/ + * cases, the callback is invoked synchronously during the cancellation/ * disposal. * * Returns: a call-id to cancel the call. */ NMAgentManagerCallId -nm_agent_manager_get_secrets (NMAgentManager *self, - const char *path, - NMConnection *connection, - NMAuthSubject *subject, - GVariant *existing_secrets, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags, - const char *const*hints, - NMAgentSecretsResultFunc callback, - gpointer callback_data) +nm_agent_manager_get_secrets(NMAgentManager * self, + const char * path, + NMConnection * connection, + NMAuthSubject * subject, + GVariant * existing_secrets, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags, + const char *const * hints, + NMAgentSecretsResultFunc callback, + gpointer callback_data) { - Request *req; - - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (path && *path, NULL); - g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (callback != NULL, NULL); - - nm_log_dbg (LOGD_SETTINGS, - "Secrets requested for connection %s (%s/%s)", - path, - nm_connection_get_id (connection), - setting_name); - - /* NOTE: a few things in the Request handling depend on existing_secrets - * being NULL if there aren't any system-owned secrets for this connection. - * This in turn depends on nm_connection_to_dbus() and nm_setting_to_hash() - * both returning NULL if they didn't hash anything. - */ - req = request_new (self, - REQUEST_TYPE_CON_GET, - nm_connection_get_id (connection), - subject); - - req->con.path = g_strdup (path); - req->con.connection = g_object_ref (connection); - if (existing_secrets) - req->con.get.existing_secrets = g_variant_ref (existing_secrets); - req->con.get.setting_name = g_strdup (setting_name); - req->con.get.hints = g_strdupv ((char **) hints); - req->con.get.flags = flags; - req->con.get.callback = callback; - req->con.get.callback_data = callback_data; - - if (!(req->con.get.flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM)) - request_add_agents (self, req); - req->idle_id = g_idle_add (request_start, req); - return req; + Request *req; + + g_return_val_if_fail(self != NULL, NULL); + g_return_val_if_fail(path && *path, NULL); + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + g_return_val_if_fail(callback != NULL, NULL); + + nm_log_dbg(LOGD_SETTINGS, + "Secrets requested for connection %s (%s/%s)", + path, + nm_connection_get_id(connection), + setting_name); + + /* NOTE: a few things in the Request handling depend on existing_secrets + * being NULL if there aren't any system-owned secrets for this connection. + * This in turn depends on nm_connection_to_dbus() and nm_setting_to_hash() + * both returning NULL if they didn't hash anything. + */ + req = request_new(self, REQUEST_TYPE_CON_GET, nm_connection_get_id(connection), subject); + + req->con.path = g_strdup(path); + req->con.connection = g_object_ref(connection); + if (existing_secrets) + req->con.get.existing_secrets = g_variant_ref(existing_secrets); + req->con.get.setting_name = g_strdup(setting_name); + req->con.get.hints = g_strdupv((char **) hints); + req->con.get.flags = flags; + req->con.get.callback = callback; + req->con.get.callback_data = callback_data; + + if (!(req->con.get.flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM)) + request_add_agents(self, req); + req->idle_id = g_idle_add(request_start, req); + return req; } void -nm_agent_manager_cancel_secrets (NMAgentManager *self, - NMAgentManagerCallId request_id) +nm_agent_manager_cancel_secrets(NMAgentManager *self, NMAgentManagerCallId request_id) { - g_return_if_fail (self != NULL); - g_return_if_fail (request_id); - g_return_if_fail (request_id->request_type == REQUEST_TYPE_CON_GET); + g_return_if_fail(self != NULL); + g_return_if_fail(request_id); + g_return_if_fail(request_id->request_type == REQUEST_TYPE_CON_GET); - nm_assert (c_list_contains (&NM_AGENT_MANAGER_GET_PRIVATE (self)->request_lst_head, &request_id->request_lst)); + nm_assert(c_list_contains(&NM_AGENT_MANAGER_GET_PRIVATE(self)->request_lst_head, + &request_id->request_lst)); - c_list_unlink (&request_id->request_lst); + c_list_unlink(&request_id->request_lst); - req_complete_cancel (request_id, FALSE); + req_complete_cancel(request_id, FALSE); } /*****************************************************************************/ static void -_con_save_request_done (NMSecretAgent *agent, - NMSecretAgentCallId *call_id, - GVariant *secrets, - GError *error, - gpointer user_data) +_con_save_request_done(NMSecretAgent * agent, + NMSecretAgentCallId *call_id, + GVariant * secrets, + GError * error, + gpointer user_data) { - NMAgentManager *self; - Request *req = user_data; - const char *agent_dbus_owner; - - g_return_if_fail (call_id == req->current_call_id); - g_return_if_fail (agent == req->current); - g_return_if_fail (req->request_type == REQUEST_TYPE_CON_SAVE); - - self = req->self; - - req->current_call_id = NULL; - - if (error) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - _LOGD (agent, "save secrets request cancelled: "LOG_REQ_FMT, - LOG_REQ_ARG (req)); - return; - } - - _LOGD (agent, "agent failed save secrets request "LOG_REQ_FMT": %s", - LOG_REQ_ARG (req), error->message); - /* Try the next agent */ - request_next_agent (req); - maybe_remove_agent_on_error (self, agent, error); - return; - } - - _LOGD (agent, "agent saved secrets for request "LOG_REQ_FMT, - LOG_REQ_ARG (req)); - - agent_dbus_owner = nm_secret_agent_get_dbus_owner (agent); - req_complete (req, NULL, NULL, agent_dbus_owner, NULL); + NMAgentManager *self; + Request * req = user_data; + const char * agent_dbus_owner; + + g_return_if_fail(call_id == req->current_call_id); + g_return_if_fail(agent == req->current); + g_return_if_fail(req->request_type == REQUEST_TYPE_CON_SAVE); + + self = req->self; + + req->current_call_id = NULL; + + if (error) { + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + _LOGD(agent, "save secrets request cancelled: " LOG_REQ_FMT, LOG_REQ_ARG(req)); + return; + } + + _LOGD(agent, + "agent failed save secrets request " LOG_REQ_FMT ": %s", + LOG_REQ_ARG(req), + error->message); + /* Try the next agent */ + request_next_agent(req); + maybe_remove_agent_on_error(self, agent, error); + return; + } + + _LOGD(agent, "agent saved secrets for request " LOG_REQ_FMT, LOG_REQ_ARG(req)); + + agent_dbus_owner = nm_secret_agent_get_dbus_owner(agent); + req_complete(req, NULL, NULL, agent_dbus_owner, NULL); } static void -_con_save_request_start (Request *req) +_con_save_request_start(Request *req) { - req->current_call_id = nm_secret_agent_save_secrets (req->current, - req->con.path, - req->con.connection, - _con_save_request_done, - req); - if (!req->current_call_id) { - g_warn_if_reached (); - request_next_agent (req); - } + req->current_call_id = nm_secret_agent_save_secrets(req->current, + req->con.path, + req->con.connection, + _con_save_request_done, + req); + if (!req->current_call_id) { + g_warn_if_reached(); + request_next_agent(req); + } } void -nm_agent_manager_save_secrets (NMAgentManager *self, - const char *path, - NMConnection *connection, - NMAuthSubject *subject) +nm_agent_manager_save_secrets(NMAgentManager *self, + const char * path, + NMConnection * connection, + NMAuthSubject * subject) { - Request *req; - - g_return_if_fail (self); - g_return_if_fail (path && *path); - g_return_if_fail (NM_IS_CONNECTION (connection)); - - nm_log_dbg (LOGD_SETTINGS, - "Saving secrets for connection %s (%s)", - path, - nm_connection_get_id (connection)); - - req = request_new (self, - REQUEST_TYPE_CON_SAVE, - nm_connection_get_id (connection), - subject); - req->con.path = g_strdup (path); - req->con.connection = g_object_ref (connection); - - request_add_agents (self, req); - req->idle_id = g_idle_add (request_start, req); + Request *req; + + g_return_if_fail(self); + g_return_if_fail(path && *path); + g_return_if_fail(NM_IS_CONNECTION(connection)); + + nm_log_dbg(LOGD_SETTINGS, + "Saving secrets for connection %s (%s)", + path, + nm_connection_get_id(connection)); + + req = request_new(self, REQUEST_TYPE_CON_SAVE, nm_connection_get_id(connection), subject); + req->con.path = g_strdup(path); + req->con.connection = g_object_ref(connection); + + request_add_agents(self, req); + req->idle_id = g_idle_add(request_start, req); } /*****************************************************************************/ static void -_con_del_request_done (NMSecretAgent *agent, - NMSecretAgentCallId *call_id, - GVariant *secrets, - GError *error, - gpointer user_data) +_con_del_request_done(NMSecretAgent * agent, + NMSecretAgentCallId *call_id, + GVariant * secrets, + GError * error, + gpointer user_data) { - NMAgentManager *self; - Request *req = user_data; - - g_return_if_fail (call_id == req->current_call_id); - g_return_if_fail (agent == req->current); - g_return_if_fail (req->request_type == REQUEST_TYPE_CON_DEL); - - self = req->self; - - req->current_call_id = NULL; - - if (error) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - _LOGD (agent, "delete secrets request cancelled: "LOG_REQ_FMT, - LOG_REQ_ARG (req)); - return; - } - - _LOGD (agent, "agent failed delete secrets request "LOG_REQ_FMT": %s", - LOG_REQ_ARG (req), error->message); - } else { - _LOGD (agent, "agent deleted secrets for request "LOG_REQ_FMT, - LOG_REQ_ARG (req)); - } - - /* Tell the next agent to delete secrets */ - request_next_agent (req); - if (error) - maybe_remove_agent_on_error (self, agent, error); + NMAgentManager *self; + Request * req = user_data; + + g_return_if_fail(call_id == req->current_call_id); + g_return_if_fail(agent == req->current); + g_return_if_fail(req->request_type == REQUEST_TYPE_CON_DEL); + + self = req->self; + + req->current_call_id = NULL; + + if (error) { + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + _LOGD(agent, "delete secrets request cancelled: " LOG_REQ_FMT, LOG_REQ_ARG(req)); + return; + } + + _LOGD(agent, + "agent failed delete secrets request " LOG_REQ_FMT ": %s", + LOG_REQ_ARG(req), + error->message); + } else { + _LOGD(agent, "agent deleted secrets for request " LOG_REQ_FMT, LOG_REQ_ARG(req)); + } + + /* Tell the next agent to delete secrets */ + request_next_agent(req); + if (error) + maybe_remove_agent_on_error(self, agent, error); } static void -_con_del_request_start (Request *req) +_con_del_request_start(Request *req) { - req->current_call_id = nm_secret_agent_delete_secrets (req->current, - req->con.path, - req->con.connection, - _con_del_request_done, - req); - if (!req->current_call_id) { - g_warn_if_reached (); - request_next_agent (req); - } + req->current_call_id = nm_secret_agent_delete_secrets(req->current, + req->con.path, + req->con.connection, + _con_del_request_done, + req); + if (!req->current_call_id) { + g_warn_if_reached(); + request_next_agent(req); + } } void -nm_agent_manager_delete_secrets (NMAgentManager *self, - const char *path, - NMConnection *connection) +nm_agent_manager_delete_secrets(NMAgentManager *self, const char *path, NMConnection *connection) { - NMAuthSubject *subject; - Request *req; - - g_return_if_fail (self != NULL); - g_return_if_fail (path && *path); - g_return_if_fail (NM_IS_CONNECTION (connection)); - - nm_log_dbg (LOGD_SETTINGS, - "Deleting secrets for connection %s (%s)", - path, - nm_connection_get_id (connection)); - - subject = nm_auth_subject_new_internal (); - req = request_new (self, - REQUEST_TYPE_CON_DEL, - nm_connection_get_id (connection), - subject); - req->con.path = g_strdup (path); - req->con.connection = g_object_ref (connection); - g_object_unref (subject); - - request_add_agents (self, req); - req->idle_id = g_idle_add (request_start, req); + NMAuthSubject *subject; + Request * req; + + g_return_if_fail(self != NULL); + g_return_if_fail(path && *path); + g_return_if_fail(NM_IS_CONNECTION(connection)); + + nm_log_dbg(LOGD_SETTINGS, + "Deleting secrets for connection %s (%s)", + path, + nm_connection_get_id(connection)); + + subject = nm_auth_subject_new_internal(); + req = request_new(self, REQUEST_TYPE_CON_DEL, nm_connection_get_id(connection), subject); + req->con.path = g_strdup(path); + req->con.connection = g_object_ref(connection); + g_object_unref(subject); + + request_add_agents(self, req); + req->idle_id = g_idle_add(request_start, req); } /*****************************************************************************/ gboolean -nm_agent_manager_has_agent_with_permission (NMAgentManager *self, - const char *username, - const char *permission) +nm_agent_manager_has_agent_with_permission(NMAgentManager *self, + const char * username, + const char * permission) { - NMAgentManagerPrivate *priv; - NMSecretAgent *agent; + NMAgentManagerPrivate *priv; + NMSecretAgent * agent; - g_return_val_if_fail (NM_IS_AGENT_MANAGER (self), FALSE); - g_return_val_if_fail (username, FALSE); - g_return_val_if_fail (permission, FALSE); + g_return_val_if_fail(NM_IS_AGENT_MANAGER(self), FALSE); + g_return_val_if_fail(username, FALSE); + g_return_val_if_fail(permission, FALSE); - priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + priv = NM_AGENT_MANAGER_GET_PRIVATE(self); - c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) { - if (!agent->fully_registered) - continue; - if (!nm_streq0 (nm_secret_agent_get_owner_username (agent), username)) - continue; - if (nm_secret_agent_has_permission (agent, permission)) - return TRUE; - } + c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) { + if (!agent->fully_registered) + continue; + if (!nm_streq0(nm_secret_agent_get_owner_username(agent), username)) + continue; + if (nm_secret_agent_has_permission(agent, permission)) + return TRUE; + } - return FALSE; + return FALSE; } /*****************************************************************************/ gboolean -nm_agent_manager_all_agents_have_capability (NMAgentManager *manager, - NMAuthSubject *subject, - NMSecretAgentCapabilities capability) +nm_agent_manager_all_agents_have_capability(NMAgentManager * manager, + NMAuthSubject * subject, + NMSecretAgentCapabilities capability) { - NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (manager); - NMSecretAgent *agent; - gboolean subject_is_unix_process = (nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); - gulong subject_uid = subject_is_unix_process ? nm_auth_subject_get_unix_process_uid (subject) : 0u; - - c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) { - if (!agent->fully_registered) - continue; - if ( subject_is_unix_process - && nm_secret_agent_get_owner_uid (agent) != subject_uid) - continue; - if (!(nm_secret_agent_get_capabilities (agent) & capability)) - return FALSE; - } - - return TRUE; + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(manager); + NMSecretAgent * agent; + gboolean subject_is_unix_process = + (nm_auth_subject_get_subject_type(subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); + gulong subject_uid = + subject_is_unix_process ? nm_auth_subject_get_unix_process_uid(subject) : 0u; + + c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) { + if (!agent->fully_registered) + continue; + if (subject_is_unix_process && nm_secret_agent_get_owner_uid(agent) != subject_uid) + continue; + if (!(nm_secret_agent_get_capabilities(agent) & capability)) + return FALSE; + } + + return TRUE; } /*****************************************************************************/ static void -authority_changed_cb (NMAuthManager *auth_manager, NMAgentManager *self) +authority_changed_cb(NMAuthManager *auth_manager, NMAgentManager *self) { - NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); - NMSecretAgent *agent; + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self); + NMSecretAgent * agent; - c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) - _agent_create_auth_chain (self, agent, NULL); + c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) + _agent_create_auth_chain(self, agent, NULL); } /*****************************************************************************/ static void -nm_agent_manager_init (NMAgentManager *self) +nm_agent_manager_init(NMAgentManager *self) { - NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self); - priv->agent_version_id = 1; - c_list_init (&priv->agent_lst_head); - c_list_init (&priv->request_lst_head); + priv->agent_version_id = 1; + c_list_init(&priv->agent_lst_head); + c_list_init(&priv->request_lst_head); } static void -constructed (GObject *object) +constructed(GObject *object) { - NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (object); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(object); - G_OBJECT_CLASS (nm_agent_manager_parent_class)->constructed (object); + G_OBJECT_CLASS(nm_agent_manager_parent_class)->constructed(object); - priv->auth_mgr = g_object_ref (nm_auth_manager_get ()); - priv->session_monitor = g_object_ref (nm_session_monitor_get ()); + priv->auth_mgr = g_object_ref(nm_auth_manager_get()); + priv->session_monitor = g_object_ref(nm_session_monitor_get()); - nm_dbus_object_export (NM_DBUS_OBJECT (object)); + nm_dbus_object_export(NM_DBUS_OBJECT(object)); - g_signal_connect (priv->auth_mgr, - NM_AUTH_MANAGER_SIGNAL_CHANGED, - G_CALLBACK (authority_changed_cb), - object); + g_signal_connect(priv->auth_mgr, + NM_AUTH_MANAGER_SIGNAL_CHANGED, + G_CALLBACK(authority_changed_cb), + object); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMAgentManager *self = NM_AGENT_MANAGER (object); - NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); - Request *request; - NMSecretAgent *agent; + NMAgentManager * self = NM_AGENT_MANAGER(object); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self); + Request * request; + NMSecretAgent * agent; - while ((request = c_list_first_entry (&priv->request_lst_head, Request, request_lst))) { - c_list_unlink (&request->request_lst); - req_complete_cancel (request, TRUE); - } + while ((request = c_list_first_entry(&priv->request_lst_head, Request, request_lst))) { + c_list_unlink(&request->request_lst); + req_complete_cancel(request, TRUE); + } - while ((agent = c_list_first_entry (&priv->agent_lst_head, NMSecretAgent, agent_lst))) - _agent_remove (self, agent); + while ((agent = c_list_first_entry(&priv->agent_lst_head, NMSecretAgent, agent_lst))) + _agent_remove(self, agent); - if (priv->auth_mgr) { - g_signal_handlers_disconnect_by_func (priv->auth_mgr, - G_CALLBACK (authority_changed_cb), - object); - g_clear_object (&priv->auth_mgr); - } + if (priv->auth_mgr) { + g_signal_handlers_disconnect_by_func(priv->auth_mgr, + G_CALLBACK(authority_changed_cb), + object); + g_clear_object(&priv->auth_mgr); + } - nm_dbus_object_unexport (NM_DBUS_OBJECT (object)); + nm_dbus_object_unexport(NM_DBUS_OBJECT(object)); - g_clear_object (&priv->session_monitor); + g_clear_object(&priv->session_monitor); - G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_agent_manager_parent_class)->dispose(object); } static const NMDBusInterfaceInfoExtended interface_info_agent_manager = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_AGENT_MANAGER, - .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "Register", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("identifier", "s"), - ), - ), - .handle = impl_agent_manager_register, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "RegisterWithCapabilities", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("identifier", "s"), - NM_DEFINE_GDBUS_ARG_INFO ("capabilities", "u"), - ), - ), - .handle = impl_agent_manager_register_with_capabilities, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "Unregister", - ), - .handle = impl_agent_manager_unregister, - ), - ), - ), + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_AGENT_MANAGER, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "Register", + .in_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("identifier", "s"), ), ), + .handle = impl_agent_manager_register, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "RegisterWithCapabilities", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("identifier", "s"), + NM_DEFINE_GDBUS_ARG_INFO("capabilities", "u"), ), ), + .handle = impl_agent_manager_register_with_capabilities, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(NM_DEFINE_GDBUS_METHOD_INFO_INIT("Unregister", ), + .handle = impl_agent_manager_unregister, ), ), ), }; static void -nm_agent_manager_class_init (NMAgentManagerClass *agent_manager_class) +nm_agent_manager_class_init(NMAgentManagerClass *agent_manager_class) { - GObjectClass *object_class = G_OBJECT_CLASS (agent_manager_class); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (agent_manager_class); - - dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_STATIC (NM_DBUS_PATH_AGENT_MANAGER); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_agent_manager); - - object_class->constructed = constructed; - object_class->dispose = dispose; - - signals[AGENT_REGISTERED] = - g_signal_new (NM_AGENT_MANAGER_AGENT_REGISTERED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - G_TYPE_OBJECT); + GObjectClass * object_class = G_OBJECT_CLASS(agent_manager_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(agent_manager_class); + + dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_STATIC(NM_DBUS_PATH_AGENT_MANAGER); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_agent_manager); + + object_class->constructed = constructed; + object_class->dispose = dispose; + + signals[AGENT_REGISTERED] = g_signal_new(NM_AGENT_MANAGER_AGENT_REGISTERED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + G_TYPE_OBJECT); } diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h index bf2dcb6c..f4e3d139 100644 --- a/src/settings/nm-agent-manager.h +++ b/src/settings/nm-agent-manager.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2011 Red Hat, Inc. */ @@ -11,12 +11,15 @@ #include "nm-dbus-object.h" #include "nm-secret-agent.h" -#define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ()) -#define NM_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManager)) -#define NM_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) -#define NM_IS_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_AGENT_MANAGER)) -#define NM_IS_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_AGENT_MANAGER)) -#define NM_AGENT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) +#define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type()) +#define NM_AGENT_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_AGENT_MANAGER, NMAgentManager)) +#define NM_AGENT_MANAGER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) +#define NM_IS_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_AGENT_MANAGER)) +#define NM_IS_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_AGENT_MANAGER)) +#define NM_AGENT_MANAGER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) #define NM_AGENT_MANAGER_AGENT_REGISTERED "agent-registered" @@ -24,53 +27,52 @@ typedef struct _NMAgentManagerCallId *NMAgentManagerCallId; typedef struct _NMAgentManagerClass NMAgentManagerClass; -GType nm_agent_manager_get_type (void); +GType nm_agent_manager_get_type(void); -NMAgentManager *nm_agent_manager_get (void); +NMAgentManager *nm_agent_manager_get(void); -guint64 nm_agent_manager_get_agent_version_id (NMAgentManager *self); +guint64 nm_agent_manager_get_agent_version_id(NMAgentManager *self); /* If no agent fulfilled the secrets request, agent_dbus_owner will be NULL */ -typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, - NMAgentManagerCallId call_id, - const char *agent_dbus_owner, - const char *agent_uname, - gboolean agent_has_modify, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags, - GVariant *secrets, - GError *error, - gpointer user_data); - -NMAgentManagerCallId nm_agent_manager_get_secrets (NMAgentManager *manager, - const char *path, - NMConnection *connection, - NMAuthSubject *subject, - GVariant *existing_secrets, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags, - const char *const*hints, - NMAgentSecretsResultFunc callback, - gpointer callback_data); - -void nm_agent_manager_cancel_secrets (NMAgentManager *manager, - NMAgentManagerCallId request_id); - -void nm_agent_manager_save_secrets (NMAgentManager *manager, - const char *path, - NMConnection *connection, - NMAuthSubject *subject); - -void nm_agent_manager_delete_secrets (NMAgentManager *manager, - const char *path, - NMConnection *connection); - -gboolean nm_agent_manager_has_agent_with_permission (NMAgentManager *self, - const char *username, - const char *permission); - -gboolean nm_agent_manager_all_agents_have_capability (NMAgentManager *manager, - NMAuthSubject *subject, - NMSecretAgentCapabilities capability); +typedef void (*NMAgentSecretsResultFunc)(NMAgentManager * manager, + NMAgentManagerCallId call_id, + const char * agent_dbus_owner, + const char * agent_uname, + gboolean agent_has_modify, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags, + GVariant * secrets, + GError * error, + gpointer user_data); + +NMAgentManagerCallId nm_agent_manager_get_secrets(NMAgentManager * manager, + const char * path, + NMConnection * connection, + NMAuthSubject * subject, + GVariant * existing_secrets, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags, + const char *const * hints, + NMAgentSecretsResultFunc callback, + gpointer callback_data); + +void nm_agent_manager_cancel_secrets(NMAgentManager *manager, NMAgentManagerCallId request_id); + +void nm_agent_manager_save_secrets(NMAgentManager *manager, + const char * path, + NMConnection * connection, + NMAuthSubject * subject); + +void nm_agent_manager_delete_secrets(NMAgentManager *manager, + const char * path, + NMConnection * connection); + +gboolean nm_agent_manager_has_agent_with_permission(NMAgentManager *self, + const char * username, + const char * permission); + +gboolean nm_agent_manager_all_agents_have_capability(NMAgentManager * manager, + NMAuthSubject * subject, + NMSecretAgentCapabilities capability); #endif /* __NETWORKMANAGER_AGENT_MANAGER_H__ */ diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index d7172c63..743a3467 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2011 Red Hat, Inc. */ @@ -27,276 +27,278 @@ #define METHOD_DELETE_SECRETS "DeleteSecrets" enum { - DISCONNECTED, + DISCONNECTED, - LAST_SIGNAL + LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = {0}; typedef struct _NMSecretAgentPrivate { - CList permissions; - CList requests; - GDBusConnection *dbus_connection; - char *description; - NMAuthSubject *subject; - char *identifier; - char *owner_username; - char *dbus_owner; - GCancellable *name_owner_cancellable; - guint name_owner_changed_id; - NMSecretAgentCapabilities capabilities; - bool shutdown_wait_obj_registered:1; + CList permissions; + CList requests; + GDBusConnection * dbus_connection; + char * description; + NMAuthSubject * subject; + char * identifier; + char * owner_username; + char * dbus_owner; + GCancellable * name_owner_cancellable; + guint name_owner_changed_id; + NMSecretAgentCapabilities capabilities; + bool shutdown_wait_obj_registered : 1; } NMSecretAgentPrivate; struct _NMSecretAgentClass { - GObjectClass parent; + GObjectClass parent; }; -G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) +G_DEFINE_TYPE(NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) -#define NM_SECRET_AGENT_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR (self, NMSecretAgent, NM_IS_SECRET_AGENT) +#define NM_SECRET_AGENT_GET_PRIVATE(self) \ + _NM_GET_PRIVATE_PTR(self, NMSecretAgent, NM_IS_SECRET_AGENT) /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "secret-agent" -#define _NMLOG_DOMAIN LOGD_AGENTS -#define _NMLOG(level, ...) \ - G_STMT_START { \ - if (nm_logging_enabled ((level), (_NMLOG_DOMAIN))) { \ - char _prefix[64]; \ - \ - if ((self)) { \ - g_snprintf (_prefix, \ - sizeof (_prefix), \ - _NMLOG_PREFIX_NAME"["NM_HASH_OBFUSCATE_PTR_FMT"]", \ - NM_HASH_OBFUSCATE_PTR (self)); \ - } else \ - g_strlcpy (_prefix, _NMLOG_PREFIX_NAME, sizeof (_prefix)); \ - \ - _nm_log ((level), \ - (_NMLOG_DOMAIN), \ - 0, \ - NULL, \ - NULL, \ - "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _prefix \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - } G_STMT_END - -#define _NMLOG2(level, call_id, ...) \ - G_STMT_START { \ - NMSecretAgentCallId *const _call_id = (call_id); \ - \ - nm_assert (_call_id); \ - \ - nm_log ((level), \ - (_NMLOG_DOMAIN), \ - NULL, \ - NULL, \ - "%s["NM_HASH_OBFUSCATE_PTR_FMT"] request ["NM_HASH_OBFUSCATE_PTR_FMT",%s,%s%s%s%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME, \ - NM_HASH_OBFUSCATE_PTR (_call_id->self), \ - NM_HASH_OBFUSCATE_PTR (_call_id), \ - _call_id->method_name, \ - NM_PRINT_FMT_QUOTE_STRING (_call_id->path), \ - (_call_id->cancellable ? "" : " (cancelled)") \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } G_STMT_END +#define _NMLOG_PREFIX_NAME "secret-agent" +#define _NMLOG_DOMAIN LOGD_AGENTS +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + if (nm_logging_enabled((level), (_NMLOG_DOMAIN))) { \ + char _prefix[64]; \ + \ + if ((self)) { \ + g_snprintf(_prefix, \ + sizeof(_prefix), \ + _NMLOG_PREFIX_NAME "[" NM_HASH_OBFUSCATE_PTR_FMT "]", \ + NM_HASH_OBFUSCATE_PTR(self)); \ + } else \ + g_strlcpy(_prefix, _NMLOG_PREFIX_NAME, sizeof(_prefix)); \ + \ + _nm_log((level), \ + (_NMLOG_DOMAIN), \ + 0, \ + NULL, \ + NULL, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END + +#define _NMLOG2(level, call_id, ...) \ + G_STMT_START \ + { \ + NMSecretAgentCallId *const _call_id = (call_id); \ + \ + nm_assert(_call_id); \ + \ + nm_log((level), \ + (_NMLOG_DOMAIN), \ + NULL, \ + NULL, \ + "%s[" NM_HASH_OBFUSCATE_PTR_FMT "] request [" NM_HASH_OBFUSCATE_PTR_FMT \ + ",%s,%s%s%s%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + NM_HASH_OBFUSCATE_PTR(_call_id->self), \ + NM_HASH_OBFUSCATE_PTR(_call_id), \ + _call_id->method_name, \ + NM_PRINT_FMT_QUOTE_STRING(_call_id->path), \ + (_call_id->cancellable ? "" : " (cancelled)") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END /*****************************************************************************/ -static -NM_UTILS_FLAGS2STR_DEFINE (_capabilities_to_string, NMSecretAgentCapabilities, - NM_UTILS_FLAGS2STR (NM_SECRET_AGENT_CAPABILITY_NONE, "none"), - NM_UTILS_FLAGS2STR (NM_SECRET_AGENT_CAPABILITY_VPN_HINTS, "vpn-hints"), -); +static NM_UTILS_FLAGS2STR_DEFINE(_capabilities_to_string, + NMSecretAgentCapabilities, + NM_UTILS_FLAGS2STR(NM_SECRET_AGENT_CAPABILITY_NONE, "none"), + NM_UTILS_FLAGS2STR(NM_SECRET_AGENT_CAPABILITY_VPN_HINTS, + "vpn-hints"), ); /*****************************************************************************/ struct _NMSecretAgentCallId { - CList lst; - NMSecretAgent *self; - GCancellable *cancellable; - char *path; - const char *method_name; - char *setting_name; - NMSecretAgentCallback callback; - gpointer callback_data; + CList lst; + NMSecretAgent * self; + GCancellable * cancellable; + char * path; + const char * method_name; + char * setting_name; + NMSecretAgentCallback callback; + gpointer callback_data; }; static NMSecretAgentCallId * -_call_id_new (NMSecretAgent *self, - const char *method_name, /* this must be a static string. */ - const char *path, - const char *setting_name, - NMSecretAgentCallback callback, - gpointer callback_data) +_call_id_new(NMSecretAgent * self, + const char * method_name, /* this must be a static string. */ + const char * path, + const char * setting_name, + NMSecretAgentCallback callback, + gpointer callback_data) { - NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); - NMSecretAgentCallId *call_id; - - call_id = g_slice_new (NMSecretAgentCallId); - *call_id = (NMSecretAgentCallId) { - .self = g_object_ref (self), - .path = g_strdup (path), - .setting_name = g_strdup (setting_name), - .method_name = method_name, - .callback = callback, - .callback_data = callback_data, - .cancellable = g_cancellable_new (), - }; - c_list_link_tail (&priv->requests, &call_id->lst); - - _LOG2T (call_id, "new request..."); - - if (!priv->shutdown_wait_obj_registered) { - /* self has async requests (that keep self alive). As long as - * we have pending requests, shutdown is blocked. */ - priv->shutdown_wait_obj_registered = TRUE; - nm_shutdown_wait_obj_register_object (G_OBJECT (self), "secret-agent"); - } - - return call_id; + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE(self); + NMSecretAgentCallId * call_id; + + call_id = g_slice_new(NMSecretAgentCallId); + *call_id = (NMSecretAgentCallId){ + .self = g_object_ref(self), + .path = g_strdup(path), + .setting_name = g_strdup(setting_name), + .method_name = method_name, + .callback = callback, + .callback_data = callback_data, + .cancellable = g_cancellable_new(), + }; + c_list_link_tail(&priv->requests, &call_id->lst); + + _LOG2T(call_id, "new request..."); + + if (!priv->shutdown_wait_obj_registered) { + /* self has async requests (that keep self alive). As long as + * we have pending requests, shutdown is blocked. */ + priv->shutdown_wait_obj_registered = TRUE; + nm_shutdown_wait_obj_register_object(G_OBJECT(self), "secret-agent"); + } + + return call_id; } -#define _call_id_new(self, method_name, path, setting_name, callback, callback_data) _call_id_new(self, ""method_name"", path, setting_name, callback, callback_data) +#define _call_id_new(self, method_name, path, setting_name, callback, callback_data) \ + _call_id_new(self, "" method_name "", path, setting_name, callback, callback_data) static void -_call_id_free (NMSecretAgentCallId *call_id) +_call_id_free(NMSecretAgentCallId *call_id) { - c_list_unlink_stale (&call_id->lst); - g_free (call_id->path); - g_free (call_id->setting_name); - nm_g_object_unref (call_id->cancellable); - g_object_unref (call_id->self); - nm_g_slice_free (call_id); + c_list_unlink_stale(&call_id->lst); + g_free(call_id->path); + g_free(call_id->setting_name); + nm_g_object_unref(call_id->cancellable); + g_object_unref(call_id->self); + nm_g_slice_free(call_id); } static void -_call_id_invoke_callback (NMSecretAgentCallId *call_id, - GVariant *secrets, - GError *error, - gboolean cancelled, - gboolean free_call_id) +_call_id_invoke_callback(NMSecretAgentCallId *call_id, + GVariant * secrets, + GError * error, + gboolean cancelled, + gboolean free_call_id) { - gs_free_error GError *error_cancelled = NULL; - - nm_assert (call_id); - nm_assert (!c_list_is_empty (&call_id->lst)); - - c_list_unlink (&call_id->lst); - - if (cancelled) { - nm_assert (!secrets); - nm_assert (!error); - if (call_id->callback) { - nm_utils_error_set_cancelled (&error_cancelled, FALSE, "NMSecretAgent"); - error = error_cancelled; - } - _LOG2T (call_id, "cancelled"); - } else if (error) { - nm_assert (!secrets); - _LOG2T (call_id, "completed with failure: %s", error->message); - } else { - nm_assert ( !secrets - || g_variant_is_of_type (secrets, G_VARIANT_TYPE ("a{sa{sv}}"))); - nm_assert ((!!secrets) == nm_streq0 (call_id->method_name, METHOD_GET_SECRETS)); - _LOG2T (call_id, "completed successfully"); - } - - if (call_id->callback) - call_id->callback (call_id->self, call_id, secrets, error, call_id->callback_data); - - if (free_call_id) - _call_id_free (call_id); + gs_free_error GError *error_cancelled = NULL; + + nm_assert(call_id); + nm_assert(!c_list_is_empty(&call_id->lst)); + + c_list_unlink(&call_id->lst); + + if (cancelled) { + nm_assert(!secrets); + nm_assert(!error); + if (call_id->callback) { + nm_utils_error_set_cancelled(&error_cancelled, FALSE, "NMSecretAgent"); + error = error_cancelled; + } + _LOG2T(call_id, "cancelled"); + } else if (error) { + nm_assert(!secrets); + _LOG2T(call_id, "completed with failure: %s", error->message); + } else { + nm_assert(!secrets || g_variant_is_of_type(secrets, G_VARIANT_TYPE("a{sa{sv}}"))); + nm_assert((!!secrets) == nm_streq0(call_id->method_name, METHOD_GET_SECRETS)); + _LOG2T(call_id, "completed successfully"); + } + + if (call_id->callback) + call_id->callback(call_id->self, call_id, secrets, error, call_id->callback_data); + + if (free_call_id) + _call_id_free(call_id); } /*****************************************************************************/ static char * -_create_description (const char *dbus_owner, const char *identifier, gulong uid) +_create_description(const char *dbus_owner, const char *identifier, gulong uid) { - return g_strdup_printf ("%s/%s/%lu", - dbus_owner, - identifier, - uid); + return g_strdup_printf("%s/%s/%lu", dbus_owner, identifier, uid); } const char * -nm_secret_agent_get_description (NMSecretAgent *agent) +nm_secret_agent_get_description(NMSecretAgent *agent) { - NMSecretAgentPrivate *priv; + NMSecretAgentPrivate *priv; - g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); + g_return_val_if_fail(NM_IS_SECRET_AGENT(agent), NULL); - priv = NM_SECRET_AGENT_GET_PRIVATE (agent); - if (!priv->description) { - priv->description = _create_description (priv->dbus_owner, - priv->identifier, - nm_auth_subject_get_unix_process_uid (priv->subject)); - } + priv = NM_SECRET_AGENT_GET_PRIVATE(agent); + if (!priv->description) { + priv->description = + _create_description(priv->dbus_owner, + priv->identifier, + nm_auth_subject_get_unix_process_uid(priv->subject)); + } - return priv->description; + return priv->description; } /*****************************************************************************/ const char * -nm_secret_agent_get_dbus_owner (NMSecretAgent *agent) +nm_secret_agent_get_dbus_owner(NMSecretAgent *agent) { - g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); + g_return_val_if_fail(NM_IS_SECRET_AGENT(agent), NULL); - return NM_SECRET_AGENT_GET_PRIVATE (agent)->dbus_owner; + return NM_SECRET_AGENT_GET_PRIVATE(agent)->dbus_owner; } const char * -nm_secret_agent_get_identifier (NMSecretAgent *agent) +nm_secret_agent_get_identifier(NMSecretAgent *agent) { - g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); + g_return_val_if_fail(NM_IS_SECRET_AGENT(agent), NULL); - return NM_SECRET_AGENT_GET_PRIVATE (agent)->identifier; + return NM_SECRET_AGENT_GET_PRIVATE(agent)->identifier; } gulong -nm_secret_agent_get_owner_uid (NMSecretAgent *agent) +nm_secret_agent_get_owner_uid(NMSecretAgent *agent) { - g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), G_MAXULONG); + g_return_val_if_fail(NM_IS_SECRET_AGENT(agent), G_MAXULONG); - return nm_auth_subject_get_unix_process_uid (NM_SECRET_AGENT_GET_PRIVATE (agent)->subject); + return nm_auth_subject_get_unix_process_uid(NM_SECRET_AGENT_GET_PRIVATE(agent)->subject); } const char * -nm_secret_agent_get_owner_username (NMSecretAgent *agent) +nm_secret_agent_get_owner_username(NMSecretAgent *agent) { - g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); + g_return_val_if_fail(NM_IS_SECRET_AGENT(agent), NULL); - return NM_SECRET_AGENT_GET_PRIVATE (agent)->owner_username; + return NM_SECRET_AGENT_GET_PRIVATE(agent)->owner_username; } gulong -nm_secret_agent_get_pid (NMSecretAgent *agent) +nm_secret_agent_get_pid(NMSecretAgent *agent) { - g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), G_MAXULONG); + g_return_val_if_fail(NM_IS_SECRET_AGENT(agent), G_MAXULONG); - return nm_auth_subject_get_unix_process_pid (NM_SECRET_AGENT_GET_PRIVATE (agent)->subject); + return nm_auth_subject_get_unix_process_pid(NM_SECRET_AGENT_GET_PRIVATE(agent)->subject); } NMSecretAgentCapabilities -nm_secret_agent_get_capabilities (NMSecretAgent *agent) +nm_secret_agent_get_capabilities(NMSecretAgent *agent) { - g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NM_SECRET_AGENT_CAPABILITY_NONE); + g_return_val_if_fail(NM_IS_SECRET_AGENT(agent), NM_SECRET_AGENT_CAPABILITY_NONE); - return NM_SECRET_AGENT_GET_PRIVATE (agent)->capabilities; + return NM_SECRET_AGENT_GET_PRIVATE(agent)->capabilities; } NMAuthSubject * -nm_secret_agent_get_subject (NMSecretAgent *agent) +nm_secret_agent_get_subject(NMSecretAgent *agent) { - g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); + g_return_val_if_fail(NM_IS_SECRET_AGENT(agent), NULL); - return NM_SECRET_AGENT_GET_PRIVATE (agent)->subject; + return NM_SECRET_AGENT_GET_PRIVATE(agent)->subject; } /*****************************************************************************/ @@ -309,30 +311,27 @@ nm_secret_agent_get_subject (NMSecretAgent *agent) * Records whether or not the agent has a given permission. */ void -nm_secret_agent_add_permission (NMSecretAgent *agent, - const char *permission, - gboolean allowed) +nm_secret_agent_add_permission(NMSecretAgent *agent, const char *permission, gboolean allowed) { - NMSecretAgentPrivate *priv; - NMCListElem *elem; + NMSecretAgentPrivate *priv; + NMCListElem * elem; - g_return_if_fail (agent != NULL); - g_return_if_fail (permission != NULL); + g_return_if_fail(agent != NULL); + g_return_if_fail(permission != NULL); - priv = NM_SECRET_AGENT_GET_PRIVATE (agent); + priv = NM_SECRET_AGENT_GET_PRIVATE(agent); - elem = nm_c_list_elem_find_first (&priv->permissions, p, nm_streq (p, permission)); + elem = nm_c_list_elem_find_first(&priv->permissions, p, nm_streq(p, permission)); - if (elem) { - if (!allowed) - nm_c_list_elem_free_full (elem, g_free); - return; - } + if (elem) { + if (!allowed) + nm_c_list_elem_free_full(elem, g_free); + return; + } - if (allowed) { - c_list_link_tail (&priv->permissions, - &nm_c_list_elem_new_stale (g_strdup (permission))->lst); - } + if (allowed) { + c_list_link_tail(&priv->permissions, &nm_c_list_elem_new_stale(g_strdup(permission))->lst); + } } /** @@ -347,124 +346,117 @@ nm_secret_agent_add_permission (NMSecretAgent *agent, * nm_secret_agent_add_permission(). */ gboolean -nm_secret_agent_has_permission (NMSecretAgent *agent, const char *permission) +nm_secret_agent_has_permission(NMSecretAgent *agent, const char *permission) { - g_return_val_if_fail (agent != NULL, FALSE); - g_return_val_if_fail (permission != NULL, FALSE); + g_return_val_if_fail(agent != NULL, FALSE); + g_return_val_if_fail(permission != NULL, FALSE); - return !!nm_c_list_elem_find_first (&NM_SECRET_AGENT_GET_PRIVATE (agent)->permissions, - p, nm_streq (p, permission)); + return !!nm_c_list_elem_find_first(&NM_SECRET_AGENT_GET_PRIVATE(agent)->permissions, + p, + nm_streq(p, permission)); } /*****************************************************************************/ static void -_dbus_call_cb (GObject *source, - GAsyncResult *result, - gpointer user_data) +_dbus_call_cb(GObject *source, GAsyncResult *result, gpointer user_data) { - NMSecretAgentCallId *call_id; - gs_unref_variant GVariant *ret = NULL; - gs_unref_variant GVariant *secrets = NULL; - gs_free_error GError *error = NULL; - - ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); - - if ( !ret - && nm_utils_error_is_cancelled (error)) - return; - - call_id = user_data; - - if (!ret) - g_dbus_error_strip_remote_error (error); - else { - if (nm_streq (call_id->method_name, METHOD_GET_SECRETS)) { - g_variant_get (ret, - "(@a{sa{sv}})", - &secrets); - } - } - - _call_id_invoke_callback (call_id, secrets, error, FALSE, TRUE); + NMSecretAgentCallId *call_id; + gs_unref_variant GVariant *ret = NULL; + gs_unref_variant GVariant *secrets = NULL; + gs_free_error GError *error = NULL; + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error); + + if (!ret && nm_utils_error_is_cancelled(error)) + return; + + call_id = user_data; + + if (!ret) + g_dbus_error_strip_remote_error(error); + else { + if (nm_streq(call_id->method_name, METHOD_GET_SECRETS)) { + g_variant_get(ret, "(@a{sa{sv}})", &secrets); + } + } + + _call_id_invoke_callback(call_id, secrets, error, FALSE, TRUE); } /*****************************************************************************/ NMSecretAgentCallId * -nm_secret_agent_get_secrets (NMSecretAgent *self, - const char *path, - NMConnection *connection, - const char *setting_name, - const char **hints, - NMSecretAgentGetSecretsFlags flags, - NMSecretAgentCallback callback, - gpointer callback_data) +nm_secret_agent_get_secrets(NMSecretAgent * self, + const char * path, + NMConnection * connection, + const char * setting_name, + const char ** hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentCallback callback, + gpointer callback_data) { - NMSecretAgentPrivate *priv; - GVariant *dict; - NMSecretAgentCallId *call_id; - - g_return_val_if_fail (NM_IS_SECRET_AGENT (self), NULL); - g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (path && *path, NULL); - g_return_val_if_fail (setting_name, NULL); - g_return_val_if_fail (callback, NULL); - - priv = NM_SECRET_AGENT_GET_PRIVATE (self); - - dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); - - /* Mask off the private flags if present */ - flags &= ~( NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM - | NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS); - - call_id = _call_id_new (self, METHOD_GET_SECRETS, path, setting_name, callback, callback_data); - - g_dbus_connection_call (priv->dbus_connection, - priv->dbus_owner, - NM_DBUS_PATH_SECRET_AGENT, - NM_DBUS_INTERFACE_SECRET_AGENT, - call_id->method_name, - g_variant_new ("(@a{sa{sv}}os^asu)", - dict, - path, - setting_name, - hints ?: NM_PTRARRAY_EMPTY (const char *), - (guint32) flags), - G_VARIANT_TYPE ("(a{sa{sv}})"), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - 120000, - call_id->cancellable, - _dbus_call_cb, - call_id); - - return call_id; + NMSecretAgentPrivate *priv; + GVariant * dict; + NMSecretAgentCallId * call_id; + + g_return_val_if_fail(NM_IS_SECRET_AGENT(self), NULL); + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + g_return_val_if_fail(path && *path, NULL); + g_return_val_if_fail(setting_name, NULL); + g_return_val_if_fail(callback, NULL); + + priv = NM_SECRET_AGENT_GET_PRIVATE(self); + + dict = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL); + + /* Mask off the private flags if present */ + flags &= ~(NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM + | NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS); + + call_id = _call_id_new(self, METHOD_GET_SECRETS, path, setting_name, callback, callback_data); + + g_dbus_connection_call(priv->dbus_connection, + priv->dbus_owner, + NM_DBUS_PATH_SECRET_AGENT, + NM_DBUS_INTERFACE_SECRET_AGENT, + call_id->method_name, + g_variant_new("(@a{sa{sv}}os^asu)", + dict, + path, + setting_name, + hints ?: NM_PTRARRAY_EMPTY(const char *), + (guint32) flags), + G_VARIANT_TYPE("(a{sa{sv}})"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 120000, + call_id->cancellable, + _dbus_call_cb, + call_id); + + return call_id; } /*****************************************************************************/ static void -_call_cancel_cb (GObject *source, - GAsyncResult *result, - gpointer user_data) +_call_cancel_cb(GObject *source, GAsyncResult *result, gpointer user_data) { - NMSecretAgentCallId *call_id = user_data; - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *ret = NULL; - - ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); - - if (ret) - _LOG2T (call_id, "success cancelling GetSecrets"); - else if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) - _LOG2T (call_id, "cancelling GetSecrets no longer works as service disconnected"); - else { - _LOG2T (call_id, "failed to cancel GetSecrets: %s", - error->message); - } - - _call_id_free (call_id); + NMSecretAgentCallId *call_id = user_data; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *ret = NULL; + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error); + + if (ret) + _LOG2T(call_id, "success cancelling GetSecrets"); + else if (g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) + _LOG2T(call_id, "cancelling GetSecrets no longer works as service disconnected"); + else { + _LOG2T(call_id, "failed to cancel GetSecrets: %s", error->message); + } + + _call_id_free(call_id); } /** @@ -481,353 +473,336 @@ _call_cancel_cb (GObject *source, * callback before nm_secret_agent_cancel_call() returns. */ void -nm_secret_agent_cancel_call (NMSecretAgent *self, - NMSecretAgentCallId *call_id) +nm_secret_agent_cancel_call(NMSecretAgent *self, NMSecretAgentCallId *call_id) { - NMSecretAgentPrivate *priv; - gboolean free_call_id = TRUE; - - if (!call_id) { - /* for convenience, %NULL is accepted fine. */ - nm_assert (!self || NM_IS_SECRET_AGENT (self)); - return; - } - - g_return_if_fail (NM_IS_SECRET_AGENT (call_id->self)); - g_return_if_fail (!c_list_is_empty (&call_id->lst)); - - /* Theoretically, call-id already has a self pointer. But nm_secret_agent_cancel_call() has only - * one user: NMAgentManager. And that one has the self-pointer at hand, so the only purpose of - * the @self argument is to assert that we are cancelling the expected call. - * - * We could drop the @self argument, but that just remove an additional assert-check from - * our code, without making a simplification for the only caller of this function. */ - g_return_if_fail (self == call_id->self); - - priv = NM_SECRET_AGENT_GET_PRIVATE (self); - - nm_assert (c_list_contains (&priv->requests, - &call_id->lst)); - - nm_clear_g_cancellable (&call_id->cancellable); - - if (nm_streq (call_id->method_name, METHOD_GET_SECRETS)) { - g_dbus_connection_call (priv->dbus_connection, - priv->dbus_owner, - NM_DBUS_PATH_SECRET_AGENT, - NM_DBUS_INTERFACE_SECRET_AGENT, - METHOD_CANCEL_GET_SECRETS, - g_variant_new ("(os)", - call_id->path, - call_id->setting_name), - G_VARIANT_TYPE ("()"), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - NM_SHUTDOWN_TIMEOUT_MS, - NULL, /* this operation is not cancellable. We rely on the timeout. */ - _call_cancel_cb, - call_id); - /* we keep call-id alive, but it will be unlinked from priv->requests. - * _call_cancel_cb() will finally free it later. */ - free_call_id = FALSE; - } - - _call_id_invoke_callback (call_id, NULL, NULL, TRUE, free_call_id); + NMSecretAgentPrivate *priv; + gboolean free_call_id = TRUE; + + if (!call_id) { + /* for convenience, %NULL is accepted fine. */ + nm_assert(!self || NM_IS_SECRET_AGENT(self)); + return; + } + + g_return_if_fail(NM_IS_SECRET_AGENT(call_id->self)); + g_return_if_fail(!c_list_is_empty(&call_id->lst)); + + /* Theoretically, call-id already has a self pointer. But nm_secret_agent_cancel_call() has only + * one user: NMAgentManager. And that one has the self-pointer at hand, so the only purpose of + * the @self argument is to assert that we are cancelling the expected call. + * + * We could drop the @self argument, but that just remove an additional assert-check from + * our code, without making a simplification for the only caller of this function. */ + g_return_if_fail(self == call_id->self); + + priv = NM_SECRET_AGENT_GET_PRIVATE(self); + + nm_assert(c_list_contains(&priv->requests, &call_id->lst)); + + nm_clear_g_cancellable(&call_id->cancellable); + + if (nm_streq(call_id->method_name, METHOD_GET_SECRETS)) { + g_dbus_connection_call( + priv->dbus_connection, + priv->dbus_owner, + NM_DBUS_PATH_SECRET_AGENT, + NM_DBUS_INTERFACE_SECRET_AGENT, + METHOD_CANCEL_GET_SECRETS, + g_variant_new("(os)", call_id->path, call_id->setting_name), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + NM_SHUTDOWN_TIMEOUT_MS, + NULL, /* this operation is not cancellable. We rely on the timeout. */ + _call_cancel_cb, + call_id); + /* we keep call-id alive, but it will be unlinked from priv->requests. + * _call_cancel_cb() will finally free it later. */ + free_call_id = FALSE; + } + + _call_id_invoke_callback(call_id, NULL, NULL, TRUE, free_call_id); } /*****************************************************************************/ NMSecretAgentCallId * -nm_secret_agent_save_secrets (NMSecretAgent *self, - const char *path, - NMConnection *connection, - NMSecretAgentCallback callback, - gpointer callback_data) +nm_secret_agent_save_secrets(NMSecretAgent * self, + const char * path, + NMConnection * connection, + NMSecretAgentCallback callback, + gpointer callback_data) { - NMSecretAgentPrivate *priv; - GVariant *dict; - NMSecretAgentCallId *call_id; - - g_return_val_if_fail (NM_IS_SECRET_AGENT (self), NULL); - g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (path && *path, NULL); - - priv = NM_SECRET_AGENT_GET_PRIVATE (self); - - /* Caller should have ensured that only agent-owned secrets exist in 'connection' */ - dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); - - call_id = _call_id_new (self, METHOD_SAVE_SECRETS, path, NULL, callback, callback_data); - - g_dbus_connection_call (priv->dbus_connection, - priv->dbus_owner, - NM_DBUS_PATH_SECRET_AGENT, - NM_DBUS_INTERFACE_SECRET_AGENT, - call_id->method_name, - g_variant_new ("(@a{sa{sv}}o)", - dict, - path), - G_VARIANT_TYPE ("()"), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - 60000, - call_id->cancellable, - _dbus_call_cb, - call_id); - - return call_id; + NMSecretAgentPrivate *priv; + GVariant * dict; + NMSecretAgentCallId * call_id; + + g_return_val_if_fail(NM_IS_SECRET_AGENT(self), NULL); + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + g_return_val_if_fail(path && *path, NULL); + + priv = NM_SECRET_AGENT_GET_PRIVATE(self); + + /* Caller should have ensured that only agent-owned secrets exist in 'connection' */ + dict = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL); + + call_id = _call_id_new(self, METHOD_SAVE_SECRETS, path, NULL, callback, callback_data); + + g_dbus_connection_call(priv->dbus_connection, + priv->dbus_owner, + NM_DBUS_PATH_SECRET_AGENT, + NM_DBUS_INTERFACE_SECRET_AGENT, + call_id->method_name, + g_variant_new("(@a{sa{sv}}o)", dict, path), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 60000, + call_id->cancellable, + _dbus_call_cb, + call_id); + + return call_id; } /*****************************************************************************/ NMSecretAgentCallId * -nm_secret_agent_delete_secrets (NMSecretAgent *self, - const char *path, - NMConnection *connection, - NMSecretAgentCallback callback, - gpointer callback_data) +nm_secret_agent_delete_secrets(NMSecretAgent * self, + const char * path, + NMConnection * connection, + NMSecretAgentCallback callback, + gpointer callback_data) { - NMSecretAgentPrivate *priv; - GVariant *dict; - NMSecretAgentCallId *call_id; - - g_return_val_if_fail (NM_IS_SECRET_AGENT (self), NULL); - g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (path && *path, NULL); - - priv = NM_SECRET_AGENT_GET_PRIVATE (self); - - /* No secrets sent; agents must be smart enough to track secrets using the UUID or something */ - dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); - - call_id = _call_id_new (self, METHOD_DELETE_SECRETS, path, NULL, callback, callback_data); - - g_dbus_connection_call (priv->dbus_connection, - priv->dbus_owner, - NM_DBUS_PATH_SECRET_AGENT, - NM_DBUS_INTERFACE_SECRET_AGENT, - call_id->method_name, - g_variant_new ("(@a{sa{sv}}o)", - dict, - path), - G_VARIANT_TYPE ("()"), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - 60000, - call_id->cancellable, - _dbus_call_cb, - call_id); - return call_id; + NMSecretAgentPrivate *priv; + GVariant * dict; + NMSecretAgentCallId * call_id; + + g_return_val_if_fail(NM_IS_SECRET_AGENT(self), NULL); + g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); + g_return_val_if_fail(path && *path, NULL); + + priv = NM_SECRET_AGENT_GET_PRIVATE(self); + + /* No secrets sent; agents must be smart enough to track secrets using the UUID or something */ + dict = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); + + call_id = _call_id_new(self, METHOD_DELETE_SECRETS, path, NULL, callback, callback_data); + + g_dbus_connection_call(priv->dbus_connection, + priv->dbus_owner, + NM_DBUS_PATH_SECRET_AGENT, + NM_DBUS_INTERFACE_SECRET_AGENT, + call_id->method_name, + g_variant_new("(@a{sa{sv}}o)", dict, path), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 60000, + call_id->cancellable, + _dbus_call_cb, + call_id); + return call_id; } /*****************************************************************************/ static void -name_owner_changed (NMSecretAgent *self, - const char *owner) +name_owner_changed(NMSecretAgent *self, const char *owner) { - NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE(self); - nm_assert (!priv->name_owner_cancellable); + nm_assert(!priv->name_owner_cancellable); - owner = nm_str_not_empty (owner); + owner = nm_str_not_empty(owner); - _LOGT ("name-owner-changed: %s%s%s", - NM_PRINT_FMT_QUOTED (owner, "has ", owner, "", "disconnected")); + _LOGT("name-owner-changed: %s%s%s", + NM_PRINT_FMT_QUOTED(owner, "has ", owner, "", "disconnected")); - if (owner) - return; + if (owner) + return; - nm_clear_g_dbus_connection_signal (priv->dbus_connection, - &priv->name_owner_changed_id); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->name_owner_changed_id); - g_signal_emit (self, signals[DISCONNECTED], 0); + g_signal_emit(self, signals[DISCONNECTED], 0); } static void -name_owner_changed_cb (GDBusConnection *dbus_connection, - const char *sender_name, - const char *object_path, - const char *interface_name, - const char *signal_name, - GVariant *parameters, - gpointer user_data) +name_owner_changed_cb(GDBusConnection *dbus_connection, + const char * sender_name, + const char * object_path, + const char * interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) { - NMSecretAgent *self = NM_SECRET_AGENT (user_data); - const char *new_owner = NULL; + NMSecretAgent *self = NM_SECRET_AGENT(user_data); + const char * new_owner = NULL; - if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sss)"))) { - g_variant_get (parameters, - "(&s&s&s)", - NULL, - NULL, - &new_owner); - } + if (g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) { + g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_owner); + } - nm_clear_g_cancellable (&NM_SECRET_AGENT_GET_PRIVATE (self)->name_owner_cancellable); + nm_clear_g_cancellable(&NM_SECRET_AGENT_GET_PRIVATE(self)->name_owner_cancellable); - name_owner_changed (self, new_owner); + name_owner_changed(self, new_owner); } static void -get_name_owner_cb (const char *name_owner, - GError *error, - gpointer user_data) +get_name_owner_cb(const char *name_owner, GError *error, gpointer user_data) { - NMSecretAgent *self; + NMSecretAgent *self; - if ( !name_owner - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + if (!name_owner && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - self = user_data; + self = user_data; - g_clear_object (&NM_SECRET_AGENT_GET_PRIVATE (self)->name_owner_cancellable); + g_clear_object(&NM_SECRET_AGENT_GET_PRIVATE(self)->name_owner_cancellable); - name_owner_changed (self, name_owner); + name_owner_changed(self, name_owner); } /*****************************************************************************/ NMSecretAgent * -nm_secret_agent_new (GDBusMethodInvocation *context, - NMAuthSubject *subject, - const char *identifier, - NMSecretAgentCapabilities capabilities) +nm_secret_agent_new(GDBusMethodInvocation * context, + NMAuthSubject * subject, + const char * identifier, + NMSecretAgentCapabilities capabilities) { - NMSecretAgent *self; - NMSecretAgentPrivate *priv; - const char *dbus_owner; - struct passwd *pw; - char *owner_username = NULL; - char *description = NULL; - char buf_subject[64]; - char buf_caps[150]; - gulong uid; - GDBusConnection *dbus_connection; - - g_return_val_if_fail (context != NULL, NULL); - g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); - g_return_val_if_fail (nm_auth_subject_get_subject_type (subject) - == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, NULL); - g_return_val_if_fail (identifier != NULL, NULL); - - dbus_connection = g_dbus_method_invocation_get_connection (context); - - g_return_val_if_fail (G_IS_DBUS_CONNECTION (dbus_connection), NULL); - - uid = nm_auth_subject_get_unix_process_uid (subject); - - pw = getpwuid (uid); - if (pw && pw->pw_name && pw->pw_name[0]) - owner_username = g_strdup (pw->pw_name); - - dbus_owner = nm_auth_subject_get_unix_process_dbus_sender (subject); - - self = (NMSecretAgent *) g_object_new (NM_TYPE_SECRET_AGENT, NULL); - - priv = NM_SECRET_AGENT_GET_PRIVATE (self); - - priv->dbus_connection = g_object_ref (dbus_connection); - - _LOGT ("constructed: %s, owner=%s%s%s (%s), unique-name=%s%s%s, capabilities=%s", - (description = _create_description (dbus_owner, identifier, uid)), - NM_PRINT_FMT_QUOTE_STRING (owner_username), - nm_auth_subject_to_string (subject, buf_subject, sizeof (buf_subject)), - NM_PRINT_FMT_QUOTE_STRING (g_dbus_connection_get_unique_name (priv->dbus_connection)), - _capabilities_to_string (capabilities, buf_caps, sizeof (buf_caps))); - - priv->identifier = g_strdup (identifier); - priv->owner_username = owner_username; - priv->dbus_owner = g_strdup (dbus_owner); - priv->description = description; - priv->capabilities = capabilities; - priv->subject = g_object_ref (subject); - - priv->name_owner_changed_id = nm_dbus_connection_signal_subscribe_name_owner_changed (priv->dbus_connection, - priv->dbus_owner, - name_owner_changed_cb, - self, - NULL); - - priv->name_owner_cancellable = g_cancellable_new (); - nm_dbus_connection_call_get_name_owner (priv->dbus_connection, - priv->dbus_owner, - -1, - priv->name_owner_cancellable, - get_name_owner_cb, - self); - - return self; + NMSecretAgent * self; + NMSecretAgentPrivate *priv; + const char * dbus_owner; + gs_free char * owner_username = NULL; + char * description = NULL; + char buf_subject[64]; + char buf_caps[150]; + gulong uid; + GDBusConnection * dbus_connection; + + g_return_val_if_fail(context != NULL, NULL); + g_return_val_if_fail(NM_IS_AUTH_SUBJECT(subject), NULL); + g_return_val_if_fail(nm_auth_subject_get_subject_type(subject) + == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, + NULL); + g_return_val_if_fail(identifier != NULL, NULL); + + dbus_connection = g_dbus_method_invocation_get_connection(context); + + g_return_val_if_fail(G_IS_DBUS_CONNECTION(dbus_connection), NULL); + + uid = nm_auth_subject_get_unix_process_uid(subject); + + owner_username = nm_utils_uid_to_name(uid); + + dbus_owner = nm_auth_subject_get_unix_process_dbus_sender(subject); + + self = (NMSecretAgent *) g_object_new(NM_TYPE_SECRET_AGENT, NULL); + + priv = NM_SECRET_AGENT_GET_PRIVATE(self); + + priv->dbus_connection = g_object_ref(dbus_connection); + + _LOGT("constructed: %s, owner=%s%s%s (%s), unique-name=%s%s%s, capabilities=%s", + (description = _create_description(dbus_owner, identifier, uid)), + NM_PRINT_FMT_QUOTE_STRING(owner_username), + nm_auth_subject_to_string(subject, buf_subject, sizeof(buf_subject)), + NM_PRINT_FMT_QUOTE_STRING(g_dbus_connection_get_unique_name(priv->dbus_connection)), + _capabilities_to_string(capabilities, buf_caps, sizeof(buf_caps))); + + priv->identifier = g_strdup(identifier); + priv->owner_username = g_steal_pointer(&owner_username); + priv->dbus_owner = g_strdup(dbus_owner); + priv->description = description; + priv->capabilities = capabilities; + priv->subject = g_object_ref(subject); + + priv->name_owner_changed_id = + nm_dbus_connection_signal_subscribe_name_owner_changed(priv->dbus_connection, + priv->dbus_owner, + name_owner_changed_cb, + self, + NULL); + + priv->name_owner_cancellable = g_cancellable_new(); + nm_dbus_connection_call_get_name_owner(priv->dbus_connection, + priv->dbus_owner, + -1, + priv->name_owner_cancellable, + get_name_owner_cb, + self); + + return self; } static void -nm_secret_agent_init (NMSecretAgent *self) +nm_secret_agent_init(NMSecretAgent *self) { - NMSecretAgentPrivate *priv; + NMSecretAgentPrivate *priv; - priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_SECRET_AGENT, NMSecretAgentPrivate); + priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_SECRET_AGENT, NMSecretAgentPrivate); - self->_priv = priv; + self->_priv = priv; - c_list_init (&self->agent_lst); - c_list_init (&priv->permissions); - c_list_init (&priv->requests); + c_list_init(&self->agent_lst); + c_list_init(&priv->permissions); + c_list_init(&priv->requests); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMSecretAgent *self = NM_SECRET_AGENT (object); - NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + NMSecretAgent * self = NM_SECRET_AGENT(object); + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE(self); - nm_assert (c_list_is_empty (&self->agent_lst)); - nm_assert (!self->auth_chain); - nm_assert (c_list_is_empty (&priv->requests)); + nm_assert(c_list_is_empty(&self->agent_lst)); + nm_assert(!self->auth_chain); + nm_assert(c_list_is_empty(&priv->requests)); - nm_clear_g_dbus_connection_signal (priv->dbus_connection, - &priv->name_owner_changed_id); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->name_owner_changed_id); - nm_clear_g_cancellable (&priv->name_owner_cancellable); + nm_clear_g_cancellable(&priv->name_owner_cancellable); - G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_secret_agent_parent_class)->dispose(object); } static void -finalize (GObject *object) +finalize(GObject *object) { - NMSecretAgent *self = NM_SECRET_AGENT (object); - NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + NMSecretAgent * self = NM_SECRET_AGENT(object); + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE(self); - g_free (priv->description); - g_free (priv->identifier); - g_free (priv->owner_username); - g_free (priv->dbus_owner); + g_free(priv->description); + g_free(priv->identifier); + g_free(priv->owner_username); + g_free(priv->dbus_owner); - nm_c_list_elem_free_all (&priv->permissions, g_free); + nm_c_list_elem_free_all(&priv->permissions, g_free); - g_clear_object (&priv->subject); + g_clear_object(&priv->subject); - g_clear_object (&priv->dbus_connection); + g_clear_object(&priv->dbus_connection); - G_OBJECT_CLASS (nm_secret_agent_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_secret_agent_parent_class)->finalize(object); - _LOGT ("finalized"); + _LOGT("finalized"); } static void -nm_secret_agent_class_init (NMSecretAgentClass *config_class) +nm_secret_agent_class_init(NMSecretAgentClass *config_class) { - GObjectClass *object_class = G_OBJECT_CLASS (config_class); - - g_type_class_add_private (object_class, sizeof (NMSecretAgentPrivate)); - - object_class->dispose = dispose; - object_class->finalize = finalize; - - signals[DISCONNECTED] = - g_signal_new (NM_SECRET_AGENT_DISCONNECTED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + GObjectClass *object_class = G_OBJECT_CLASS(config_class); + + g_type_class_add_private(object_class, sizeof(NMSecretAgentPrivate)); + + object_class->dispose = dispose; + object_class->finalize = finalize; + + signals[DISCONNECTED] = g_signal_new(NM_SECRET_AGENT_DISCONNECTED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); } diff --git a/src/settings/nm-secret-agent.h b/src/settings/nm-secret-agent.h index 37a93d17..09f60bf4 100644 --- a/src/settings/nm-secret-agent.h +++ b/src/settings/nm-secret-agent.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2011 Red Hat, Inc. */ @@ -10,87 +10,86 @@ #include "c-list/src/c-list.h" -#define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ()) -#define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) -#define NM_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) -#define NM_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRET_AGENT)) -#define NM_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SECRET_AGENT)) -#define NM_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) +#define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type()) +#define NM_SECRET_AGENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) +#define NM_SECRET_AGENT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) +#define NM_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SECRET_AGENT)) +#define NM_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SECRET_AGENT)) +#define NM_SECRET_AGENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) #define NM_SECRET_AGENT_DISCONNECTED "disconnected" -typedef struct _NMSecretAgentClass NMSecretAgentClass; +typedef struct _NMSecretAgentClass NMSecretAgentClass; typedef struct _NMSecretAgentCallId NMSecretAgentCallId; struct _NMAuthChain; struct _NMSecretAgentPrivate; struct _NMSecretAgent { - GObject parent; - CList agent_lst; - struct _NMAuthChain *auth_chain; - struct _NMSecretAgentPrivate *_priv; - bool fully_registered:1; + GObject parent; + CList agent_lst; + struct _NMAuthChain * auth_chain; + struct _NMSecretAgentPrivate *_priv; + bool fully_registered : 1; }; -GType nm_secret_agent_get_type (void); +GType nm_secret_agent_get_type(void); -NMSecretAgent *nm_secret_agent_new (GDBusMethodInvocation *context, - NMAuthSubject *subject, - const char *identifier, - NMSecretAgentCapabilities capabilities); +NMSecretAgent *nm_secret_agent_new(GDBusMethodInvocation * context, + NMAuthSubject * subject, + const char * identifier, + NMSecretAgentCapabilities capabilities); -const char *nm_secret_agent_get_description (NMSecretAgent *agent); +const char *nm_secret_agent_get_description(NMSecretAgent *agent); -const char *nm_secret_agent_get_dbus_owner (NMSecretAgent *agent); +const char *nm_secret_agent_get_dbus_owner(NMSecretAgent *agent); -const char *nm_secret_agent_get_identifier (NMSecretAgent *agent); +const char *nm_secret_agent_get_identifier(NMSecretAgent *agent); -gulong nm_secret_agent_get_owner_uid (NMSecretAgent *agent); +gulong nm_secret_agent_get_owner_uid(NMSecretAgent *agent); -const char *nm_secret_agent_get_owner_username (NMSecretAgent *agent); +const char *nm_secret_agent_get_owner_username(NMSecretAgent *agent); -gulong nm_secret_agent_get_pid (NMSecretAgent *agent); +gulong nm_secret_agent_get_pid(NMSecretAgent *agent); -NMSecretAgentCapabilities nm_secret_agent_get_capabilities (NMSecretAgent *agent); +NMSecretAgentCapabilities nm_secret_agent_get_capabilities(NMSecretAgent *agent); -NMAuthSubject *nm_secret_agent_get_subject (NMSecretAgent *agent); +NMAuthSubject *nm_secret_agent_get_subject(NMSecretAgent *agent); -void nm_secret_agent_add_permission (NMSecretAgent *agent, - const char *permission, - gboolean allowed); +void nm_secret_agent_add_permission(NMSecretAgent *agent, const char *permission, gboolean allowed); -gboolean nm_secret_agent_has_permission (NMSecretAgent *agent, - const char *permission); +gboolean nm_secret_agent_has_permission(NMSecretAgent *agent, const char *permission); -typedef void (*NMSecretAgentCallback) (NMSecretAgent *agent, - NMSecretAgentCallId *call_id, - GVariant *new_secrets, /* NULL for save & delete */ - GError *error, - gpointer user_data); +typedef void (*NMSecretAgentCallback)(NMSecretAgent * agent, + NMSecretAgentCallId *call_id, + GVariant * new_secrets, /* NULL for save & delete */ + GError * error, + gpointer user_data); -NMSecretAgentCallId *nm_secret_agent_get_secrets (NMSecretAgent *agent, - const char *path, - NMConnection *connection, - const char *setting_name, - const char **hints, - NMSecretAgentGetSecretsFlags flags, +NMSecretAgentCallId *nm_secret_agent_get_secrets(NMSecretAgent * agent, + const char * path, + NMConnection * connection, + const char * setting_name, + const char ** hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentCallback callback, + gpointer callback_data); + +NMSecretAgentCallId *nm_secret_agent_save_secrets(NMSecretAgent * agent, + const char * path, + NMConnection * connection, NMSecretAgentCallback callback, - gpointer callback_data); - -NMSecretAgentCallId *nm_secret_agent_save_secrets (NMSecretAgent *agent, - const char *path, - NMConnection *connection, - NMSecretAgentCallback callback, - gpointer callback_data); - -NMSecretAgentCallId *nm_secret_agent_delete_secrets (NMSecretAgent *agent, - const char *path, - NMConnection *connection, - NMSecretAgentCallback callback, - gpointer callback_data); - -void nm_secret_agent_cancel_call (NMSecretAgent *self, - NMSecretAgentCallId *call_id); + gpointer callback_data); + +NMSecretAgentCallId *nm_secret_agent_delete_secrets(NMSecretAgent * agent, + const char * path, + NMConnection * connection, + NMSecretAgentCallback callback, + gpointer callback_data); + +void nm_secret_agent_cancel_call(NMSecretAgent *self, NMSecretAgentCallId *call_id); #endif /* __NETWORKMANAGER_SECRET_AGENT_H__ */ diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index ca46de68..d21b120e 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 Novell, Inc. * Copyright (C) 2008 - 2014 Red Hat, Inc. @@ -26,346 +26,356 @@ #include "nm-dbus-manager.h" #include "settings/plugins/keyfile/nms-keyfile-storage.h" -#define AUTOCONNECT_RETRIES_UNSET -2 -#define AUTOCONNECT_RETRIES_FOREVER -1 +#define AUTOCONNECT_RETRIES_UNSET -2 +#define AUTOCONNECT_RETRIES_FOREVER -1 #define AUTOCONNECT_RESET_RETRIES_TIMER 300 -#define _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES ((NMSettingsUpdate2Flags) ( NM_SETTINGS_UPDATE2_FLAG_TO_DISK \ - | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY \ - | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED \ - | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY)) +#define _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES \ + ((NMSettingsUpdate2Flags)( \ + NM_SETTINGS_UPDATE2_FLAG_TO_DISK | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY \ + | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY)) /*****************************************************************************/ NMConnection ** -nm_settings_connections_array_to_connections (NMSettingsConnection *const*connections, - gssize n_connections) +nm_settings_connections_array_to_connections(NMSettingsConnection *const *connections, + gssize n_connections) { - NMConnection **arr; - gssize i; + NMConnection **arr; + gssize i; - if (n_connections < 0) - n_connections = NM_PTRARRAY_LEN (connections); - if (n_connections == 0) - return NULL; + if (n_connections < 0) + n_connections = NM_PTRARRAY_LEN(connections); + if (n_connections == 0) + return NULL; - arr = g_new (NMConnection *, n_connections + 1); - for (i = 0; i < n_connections; i++) - arr[i] = nm_settings_connection_get_connection (connections[i]); - arr[i] = NULL; - return arr; + arr = g_new(NMConnection *, n_connections + 1); + for (i = 0; i < n_connections; i++) + arr[i] = nm_settings_connection_get_connection(connections[i]); + arr[i] = NULL; + return arr; } /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMSettingsConnection, - PROP_UNSAVED, - PROP_FLAGS, - PROP_FILENAME, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingsConnection, PROP_UNSAVED, PROP_FLAGS, PROP_FILENAME, ); -enum { - UPDATED_INTERNAL, - FLAGS_CHANGED, - LAST_SIGNAL -}; +enum { UPDATED_INTERNAL, FLAGS_CHANGED, LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = {0}; typedef struct _NMSettingsConnectionPrivate { + NMSettings *settings; - NMSettings *settings; - - NMKeyFileDB *kf_db_timestamps; - NMKeyFileDB *kf_db_seen_bssids; + NMKeyFileDB *kf_db_timestamps; + NMKeyFileDB *kf_db_seen_bssids; - NMAgentManager *agent_mgr; + NMAgentManager *agent_mgr; - /* List of pending authentication requests */ - CList auth_lst_head; + /* List of pending authentication requests */ + CList auth_lst_head; - CList call_ids_lst_head; /* in-progress secrets requests */ + CList call_ids_lst_head; /* in-progress secrets requests */ - NMConnection *connection; + NMConnection *connection; - NMSettingsStorage *storage; + NMSettingsStorage *storage; - char *filename; + char *filename; - NMDevice *default_wired_device; + NMDevice *default_wired_device; - /* Caches secrets from on-disk connections; were they not cached any - * call to nm_connection_clear_secrets() wipes them out and we'd have - * to re-read them from disk which defeats the purpose of having the - * connection in-memory at all. - */ - GVariant *system_secrets; + /* Caches secrets from on-disk connections; were they not cached any + * call to nm_connection_clear_secrets() wipes them out and we'd have + * to re-read them from disk which defeats the purpose of having the + * connection in-memory at all. + */ + GVariant *system_secrets; - /* Caches secrets from agents during the activation process; if new system - * secrets are returned from an agent, they get written out to disk, - * triggering a re-read of the connection, which reads only system - * secrets, and would wipe out any agent-owned or not-saved secrets the - * agent also returned. - */ - GVariant *agent_secrets; + /* Caches secrets from agents during the activation process; if new system + * secrets are returned from an agent, they get written out to disk, + * triggering a re-read of the connection, which reads only system + * secrets, and would wipe out any agent-owned or not-saved secrets the + * agent also returned. + */ + GVariant *agent_secrets; - GHashTable *seen_bssids; /* Up-to-date BSSIDs that's been seen for the connection */ + GHashTable *seen_bssids; /* Up-to-date BSSIDs that's been seen for the connection */ - guint64 timestamp; /* Up-to-date timestamp of connection use */ + guint64 timestamp; /* Up-to-date timestamp of connection use */ - guint64 last_secret_agent_version_id; + guint64 last_secret_agent_version_id; - int autoconnect_retries; + int autoconnect_retries; - gint32 autoconnect_retries_blocked_until; + gint32 autoconnect_retries_blocked_until; - bool timestamp_set:1; + bool timestamp_set : 1; - NMSettingsAutoconnectBlockedReason autoconnect_blocked_reason:4; + NMSettingsAutoconnectBlockedReason autoconnect_blocked_reason : 4; - NMSettingsConnectionIntFlags flags:5; + NMSettingsConnectionIntFlags flags : 5; } NMSettingsConnectionPrivate; struct _NMSettingsConnectionClass { - NMDBusObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMSettingsConnection, nm_settings_connection, NM_TYPE_DBUS_OBJECT) +G_DEFINE_TYPE(NMSettingsConnection, nm_settings_connection, NM_TYPE_DBUS_OBJECT) -#define NM_SETTINGS_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR (self, NMSettingsConnection, NM_IS_SETTINGS_CONNECTION) +#define NM_SETTINGS_CONNECTION_GET_PRIVATE(self) \ + _NM_GET_PRIVATE_PTR(self, NMSettingsConnection, NM_IS_SETTINGS_CONNECTION) /*****************************************************************************/ -#define _NMLOG_DOMAIN LOGD_SETTINGS -#define _NMLOG_PREFIX_NAME "settings-connection" -#define _NMLOG(level, ...) \ - G_STMT_START { \ - const NMLogLevel __level = (level); \ - \ - if (nm_logging_enabled (__level, _NMLOG_DOMAIN)) { \ - char __prefix[128]; \ - const char *__p_prefix = _NMLOG_PREFIX_NAME; \ - const char *__uuid = (self) ? nm_settings_connection_get_uuid (self) : NULL; \ - \ - if (self) { \ - g_snprintf (__prefix, sizeof (__prefix), "%s["NM_HASH_OBFUSCATE_PTR_FMT"%s%s]", _NMLOG_PREFIX_NAME, NM_HASH_OBFUSCATE_PTR (self), __uuid ? "," : "", __uuid ?: ""); \ - __p_prefix = __prefix; \ - } \ - _nm_log (__level, _NMLOG_DOMAIN, 0, NULL, __uuid, \ - "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - __p_prefix _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ - } \ - } G_STMT_END +#define _NMLOG_DOMAIN LOGD_SETTINGS +#define _NMLOG_PREFIX_NAME "settings-connection" +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ + char __prefix[128]; \ + const char *__p_prefix = _NMLOG_PREFIX_NAME; \ + const char *__uuid = (self) ? nm_settings_connection_get_uuid(self) : NULL; \ + \ + if (self) { \ + g_snprintf(__prefix, \ + sizeof(__prefix), \ + "%s[" NM_HASH_OBFUSCATE_PTR_FMT "%s%s]", \ + _NMLOG_PREFIX_NAME, \ + NM_HASH_OBFUSCATE_PTR(self), \ + __uuid ? "," : "", \ + __uuid ?: ""); \ + __p_prefix = __prefix; \ + } \ + _nm_log(__level, \ + _NMLOG_DOMAIN, \ + 0, \ + NULL, \ + __uuid, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __p_prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END /*****************************************************************************/ -static const GDBusSignalInfo signal_info_updated; -static const GDBusSignalInfo signal_info_removed; +static const GDBusSignalInfo signal_info_updated; +static const GDBusSignalInfo signal_info_removed; static const NMDBusInterfaceInfoExtended interface_info_settings_connection; -static void update_system_secrets_cache (NMSettingsConnection *self, NMConnection *new); -static void update_agent_secrets_cache (NMSettingsConnection *self, NMConnection *new); +static void update_system_secrets_cache(NMSettingsConnection *self, NMConnection *new); +static void update_agent_secrets_cache(NMSettingsConnection *self, NMConnection *new); /*****************************************************************************/ NMDevice * -nm_settings_connection_default_wired_get_device (NMSettingsConnection *self) +nm_settings_connection_default_wired_get_device(NMSettingsConnection *self) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - nm_assert (!priv->default_wired_device || NM_IS_DEVICE (priv->default_wired_device)); + nm_assert(!priv->default_wired_device || NM_IS_DEVICE(priv->default_wired_device)); - return priv->default_wired_device; + return priv->default_wired_device; } void -nm_settings_connection_default_wired_set_device (NMSettingsConnection *self, - NMDevice *device) +nm_settings_connection_default_wired_set_device(NMSettingsConnection *self, NMDevice *device) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - nm_assert (!priv->default_wired_device || NM_IS_DEVICE (priv->default_wired_device)); - nm_assert (!device || NM_IS_DEVICE (device)); + nm_assert(!priv->default_wired_device || NM_IS_DEVICE(priv->default_wired_device)); + nm_assert(!device || NM_IS_DEVICE(device)); - nm_assert ((!!priv->default_wired_device) != (!!device)); + nm_assert((!!priv->default_wired_device) != (!!device)); - priv->default_wired_device = device; + priv->default_wired_device = device; } /*****************************************************************************/ NMSettingsStorage * -nm_settings_connection_get_storage (NMSettingsConnection *self) +nm_settings_connection_get_storage(NMSettingsConnection *self) { - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), NULL); - return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->storage; + return NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->storage; } void -_nm_settings_connection_set_storage (NMSettingsConnection *self, - NMSettingsStorage *storage) +_nm_settings_connection_set_storage(NMSettingsConnection *self, NMSettingsStorage *storage) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - const char *filename; + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + const char * filename; - nm_assert (NM_IS_SETTINGS_STORAGE (storage)); - nm_assert ( !priv->storage - || nm_streq (nm_settings_storage_get_uuid (storage), - nm_settings_storage_get_uuid (priv->storage))); + nm_assert(NM_IS_SETTINGS_STORAGE(storage)); + nm_assert(!priv->storage + || nm_streq(nm_settings_storage_get_uuid(storage), + nm_settings_storage_get_uuid(priv->storage))); - nm_g_object_ref_set (&priv->storage, storage); + nm_g_object_ref_set(&priv->storage, storage); - filename = nm_settings_storage_get_filename (priv->storage); + filename = nm_settings_storage_get_filename(priv->storage); - if (!nm_streq0 (priv->filename, filename)) { - g_free (priv->filename); - priv->filename = g_strdup (filename); - _notify (self, PROP_FILENAME); - } + if (!nm_streq0(priv->filename, filename)) { + g_free(priv->filename); + priv->filename = g_strdup(filename); + _notify(self, PROP_FILENAME); + } } /*****************************************************************************/ gboolean -nm_settings_connection_still_valid (NMSettingsConnection *self) +nm_settings_connection_still_valid(NMSettingsConnection *self) { - gboolean valid; + gboolean valid; - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), FALSE); - valid = !c_list_is_empty (&self->_connections_lst); + valid = !c_list_is_empty(&self->_connections_lst); - nm_assert (valid == nm_settings_has_connection (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->settings, self)); + nm_assert( + valid + == nm_settings_has_connection(NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->settings, self)); - return valid; + return valid; } /*****************************************************************************/ static GHashTable * -_seen_bssids_hash_new (void) +_seen_bssids_hash_new(void) { - return g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); + return g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL); } /*****************************************************************************/ NMConnection * -nm_settings_connection_get_connection (NMSettingsConnection *self) +nm_settings_connection_get_connection(NMSettingsConnection *self) { - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), NULL); - return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->connection; + return NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->connection; } void -_nm_settings_connection_set_connection (NMSettingsConnection *self, - NMConnection *new_connection, - NMConnection **out_connection_old, - NMSettingsConnectionUpdateReason update_reason) -{ - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - gs_unref_object NMConnection *connection_old = NULL; - - nm_assert (NM_IS_CONNECTION (new_connection)); - nm_assert (NM_IS_SETTINGS_STORAGE (priv->storage)); - nm_assert (nm_streq0 (nm_settings_storage_get_uuid (priv->storage), nm_connection_get_uuid (new_connection))); - nm_assert (!out_connection_old || !*out_connection_old); - - if ( !priv->connection - || !nm_connection_compare (priv->connection, - new_connection, - NM_SETTING_COMPARE_FLAG_EXACT)) { - connection_old = priv->connection; - priv->connection = g_object_ref (new_connection); - nmtst_connection_assert_unchanging (priv->connection); - - /* note that we only return @connection_old if the new connection actually differs from - * before. - * - * So, there are three cases: - * - * - return %NULL when setting the connection the first time. - * - return %NULL if setting a profile with the same content that we already have. - * - return the previous pointer if the connection changed. */ - NM_SET_OUT (out_connection_old, g_steal_pointer (&connection_old)); - } - - if (NM_FLAGS_HAS (update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS)) - update_system_secrets_cache (self, NULL); - else if (NM_FLAGS_HAS (update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS)) - update_system_secrets_cache (self, priv->connection); - - if (NM_FLAGS_HAS (update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS)) - update_agent_secrets_cache (self, NULL); - else if (NM_FLAGS_HAS (update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS)) - update_agent_secrets_cache (self, priv->connection); +_nm_settings_connection_set_connection(NMSettingsConnection * self, + NMConnection * new_connection, + NMConnection ** out_connection_old, + NMSettingsConnectionUpdateReason update_reason) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + gs_unref_object NMConnection *connection_old = NULL; + + nm_assert(NM_IS_CONNECTION(new_connection)); + nm_assert(NM_IS_SETTINGS_STORAGE(priv->storage)); + nm_assert(nm_streq0(nm_settings_storage_get_uuid(priv->storage), + nm_connection_get_uuid(new_connection))); + nm_assert(!out_connection_old || !*out_connection_old); + + if (!priv->connection + || !nm_connection_compare(priv->connection, + new_connection, + NM_SETTING_COMPARE_FLAG_EXACT)) { + connection_old = priv->connection; + priv->connection = g_object_ref(new_connection); + nmtst_connection_assert_unchanging(priv->connection); + + /* note that we only return @connection_old if the new connection actually differs from + * before. + * + * So, there are three cases: + * + * - return %NULL when setting the connection the first time. + * - return %NULL if setting a profile with the same content that we already have. + * - return the previous pointer if the connection changed. */ + NM_SET_OUT(out_connection_old, g_steal_pointer(&connection_old)); + } + + if (NM_FLAGS_HAS(update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS)) + update_system_secrets_cache(self, NULL); + else if (NM_FLAGS_HAS(update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS)) + update_system_secrets_cache(self, priv->connection); + + if (NM_FLAGS_HAS(update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS)) + update_agent_secrets_cache(self, NULL); + else if (NM_FLAGS_HAS(update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS)) + update_agent_secrets_cache(self, priv->connection); } /*****************************************************************************/ gboolean -nm_settings_connection_has_unmodified_applied_connection (NMSettingsConnection *self, - NMConnection *applied_connection, - NMSettingCompareFlags compare_flags) +nm_settings_connection_has_unmodified_applied_connection(NMSettingsConnection *self, + NMConnection * applied_connection, + NMSettingCompareFlags compare_flags) { - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (applied_connection), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(applied_connection), FALSE); - /* for convenience, we *always* ignore certain settings. */ - compare_flags |= NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS | NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP; + /* for convenience, we *always* ignore certain settings. */ + compare_flags |= + NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS | NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP; - return nm_connection_compare (nm_settings_connection_get_connection (self), - applied_connection, compare_flags); + return nm_connection_compare(nm_settings_connection_get_connection(self), + applied_connection, + compare_flags); } /*****************************************************************************/ guint64 -nm_settings_connection_get_last_secret_agent_version_id (NMSettingsConnection *self) +nm_settings_connection_get_last_secret_agent_version_id(NMSettingsConnection *self) { - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), 0); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), 0); - return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->last_secret_agent_version_id; + return NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->last_secret_agent_version_id; } /*****************************************************************************/ gboolean -nm_settings_connection_check_visibility (NMSettingsConnection *self, - NMSessionMonitor *session_monitor) +nm_settings_connection_check_visibility(NMSettingsConnection *self, + NMSessionMonitor * session_monitor) { - NMSettingConnection *s_con; - guint32 num, i; + NMSettingConnection *s_con; + guint32 num, i; - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), FALSE); - nm_assert (NM_IS_SESSION_MONITOR (session_monitor)); + nm_assert(NM_IS_SESSION_MONITOR(session_monitor)); - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (self)); + s_con = nm_connection_get_setting_connection(nm_settings_connection_get_connection(self)); - /* Check every user in the ACL for a session */ - num = nm_setting_connection_get_num_permissions (s_con); - if (num == 0) - return TRUE; + /* Check every user in the ACL for a session */ + num = nm_setting_connection_get_num_permissions(s_con); + if (num == 0) + return TRUE; - for (i = 0; i < num; i++) { - const char *user; - uid_t uid; + for (i = 0; i < num; i++) { + const char *ptype; + const char *user; + uid_t uid; - if (!nm_setting_connection_get_permission (s_con, i, NULL, &user, NULL)) - continue; - if (!nm_session_monitor_user_to_uid (user, &uid)) - continue; - if (!nm_session_monitor_session_exists (session_monitor, uid, FALSE)) - continue; + if (!nm_setting_connection_get_permission(s_con, i, &ptype, &user, NULL)) + continue; + if (!nm_streq(ptype, NM_SETTINGS_CONNECTION_PERMISSION_USER)) + continue; + if (!nm_utils_name_to_uid(user, &uid)) + continue; + if (!nm_session_monitor_session_exists(session_monitor, uid, FALSE)) + continue; - return TRUE; - } + return TRUE; + } - return FALSE; + return FALSE; } /*****************************************************************************/ @@ -375,651 +385,640 @@ nm_settings_connection_check_visibility (NMSettingsConnection *self, * visible to everyone automatically pass the check. */ gboolean -nm_settings_connection_check_permission (NMSettingsConnection *self, - const char *permission) +nm_settings_connection_check_permission(NMSettingsConnection *self, const char *permission) { - NMSettingsConnectionPrivate *priv; - NMSettingConnection *s_con; - guint32 num, i; - const char *puser; + NMSettingsConnectionPrivate *priv; + NMSettingConnection * s_con; + guint32 num, i; + const char * puser; + + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), FALSE); + + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); + if (!NM_FLAGS_HAS(nm_settings_connection_get_flags(self), + NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) + return FALSE; - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + s_con = nm_connection_get_setting_connection(nm_settings_connection_get_connection(self)); - if (!NM_FLAGS_HAS (nm_settings_connection_get_flags (self), - NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) - return FALSE; + /* Check every user in the ACL for a session */ + num = nm_setting_connection_get_num_permissions(s_con); + if (num == 0) { + /* Visible to all so it's OK to auto-activate */ + return TRUE; + } - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (self)); + for (i = 0; i < num; i++) { + const char *ptype; - /* Check every user in the ACL for a session */ - num = nm_setting_connection_get_num_permissions (s_con); - if (num == 0) { - /* Visible to all so it's OK to auto-activate */ - return TRUE; - } + /* For each user get their secret agent and check if that agent has the + * required permission. + * + * FIXME: what if the user isn't running an agent? PolKit needs a bus + * name or a PID but if the user isn't running an agent they won't have + * either. + */ + if (!nm_setting_connection_get_permission(s_con, i, &ptype, &puser, NULL)) + continue; + if (!nm_streq(ptype, NM_SETTINGS_CONNECTION_PERMISSION_USER)) + continue; - for (i = 0; i < num; i++) { - /* For each user get their secret agent and check if that agent has the - * required permission. - * - * FIXME: what if the user isn't running an agent? PolKit needs a bus - * name or a PID but if the user isn't running an agent they won't have - * either. - */ - if (nm_setting_connection_get_permission (s_con, i, NULL, &puser, NULL)) { - if (nm_agent_manager_has_agent_with_permission (priv->agent_mgr, puser, permission)) - return TRUE; - } - } + if (nm_agent_manager_has_agent_with_permission(priv->agent_mgr, puser, permission)) + return TRUE; + } - return FALSE; + return FALSE; } /*****************************************************************************/ static void -update_system_secrets_cache (NMSettingsConnection *self, NMConnection *new) +update_system_secrets_cache(NMSettingsConnection *self, NMConnection *new) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - gs_unref_object NMConnection *connection_cloned = NULL; - gs_unref_variant GVariant *old_secrets = NULL; + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + gs_unref_object NMConnection *connection_cloned = NULL; + gs_unref_variant GVariant *old_secrets = NULL; - old_secrets = g_steal_pointer (&priv->system_secrets); + old_secrets = g_steal_pointer(&priv->system_secrets); - if (!new) - goto out; + if (!new) + goto out; - /* FIXME: improve NMConnection API so we can avoid the overhead of cloning the connection, - * in particular if there are no secrets to begin with. */ + /* FIXME: improve NMConnection API so we can avoid the overhead of cloning the connection, + * in particular if there are no secrets to begin with. */ - connection_cloned = nm_simple_connection_new_clone (new); + connection_cloned = nm_simple_connection_new_clone(new); - /* Clear out non-system-owned and not-saved secrets */ - _nm_connection_clear_secrets_by_secret_flags (connection_cloned, - NM_SETTING_SECRET_FLAG_NONE); + /* Clear out non-system-owned and not-saved secrets */ + _nm_connection_clear_secrets_by_secret_flags(connection_cloned, NM_SETTING_SECRET_FLAG_NONE); - priv->system_secrets = nm_g_variant_ref_sink (nm_connection_to_dbus (connection_cloned, NM_CONNECTION_SERIALIZE_ONLY_SECRETS)); + priv->system_secrets = nm_g_variant_ref_sink( + nm_connection_to_dbus(connection_cloned, NM_CONNECTION_SERIALIZE_ONLY_SECRETS)); out: - if (_LOGT_ENABLED ()) { - if ((!!old_secrets) != (!!priv->system_secrets)) { - _LOGT ("update system secrets: secrets %s", - old_secrets ? "cleared" : "set"); - } else if ( priv->system_secrets - && !g_variant_equal (old_secrets, priv->system_secrets)) - _LOGT ("update system secrets: secrets updated"); - } + if (_LOGT_ENABLED()) { + if ((!!old_secrets) != (!!priv->system_secrets)) { + _LOGT("update system secrets: secrets %s", old_secrets ? "cleared" : "set"); + } else if (priv->system_secrets && !g_variant_equal(old_secrets, priv->system_secrets)) + _LOGT("update system secrets: secrets updated"); + } } static void -update_agent_secrets_cache (NMSettingsConnection *self, NMConnection *new) +update_agent_secrets_cache(NMSettingsConnection *self, NMConnection *new) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - gs_unref_object NMConnection *connection_cloned = NULL; - gs_unref_variant GVariant *old_secrets = NULL; + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + gs_unref_object NMConnection *connection_cloned = NULL; + gs_unref_variant GVariant *old_secrets = NULL; - old_secrets = g_steal_pointer (&priv->agent_secrets); + old_secrets = g_steal_pointer(&priv->agent_secrets); - if (!new) - goto out; + if (!new) + goto out; - /* FIXME: improve NMConnection API so we can avoid the overhead of cloning the connection, - * in particular if there are no secrets to begin with. */ + /* FIXME: improve NMConnection API so we can avoid the overhead of cloning the connection, + * in particular if there are no secrets to begin with. */ - connection_cloned = nm_simple_connection_new_clone (new); + connection_cloned = nm_simple_connection_new_clone(new); - /* Clear out non-system-owned secrets */ - _nm_connection_clear_secrets_by_secret_flags (connection_cloned, - NM_SETTING_SECRET_FLAG_NOT_SAVED - | NM_SETTING_SECRET_FLAG_AGENT_OWNED); + /* Clear out non-system-owned secrets */ + _nm_connection_clear_secrets_by_secret_flags(connection_cloned, + NM_SETTING_SECRET_FLAG_NOT_SAVED + | NM_SETTING_SECRET_FLAG_AGENT_OWNED); - priv->agent_secrets = nm_g_variant_ref_sink (nm_connection_to_dbus (connection_cloned, NM_CONNECTION_SERIALIZE_ONLY_SECRETS)); + priv->agent_secrets = nm_g_variant_ref_sink( + nm_connection_to_dbus(connection_cloned, NM_CONNECTION_SERIALIZE_ONLY_SECRETS)); out: - if (_LOGT_ENABLED ()) { - if ((!!old_secrets) != (!!priv->agent_secrets)) { - _LOGT ("update agent secrets: secrets %s", - old_secrets ? "cleared" : "set"); - } else if ( priv->agent_secrets - && !g_variant_equal (old_secrets, priv->agent_secrets)) - _LOGT ("update agent secrets: secrets updated"); - } + if (_LOGT_ENABLED()) { + if ((!!old_secrets) != (!!priv->agent_secrets)) { + _LOGT("update agent secrets: secrets %s", old_secrets ? "cleared" : "set"); + } else if (priv->agent_secrets && !g_variant_equal(old_secrets, priv->agent_secrets)) + _LOGT("update agent secrets: secrets updated"); + } } void -nm_settings_connection_clear_secrets (NMSettingsConnection *self, - gboolean clear_cached_system_secrets, - gboolean persist) +nm_settings_connection_clear_secrets(NMSettingsConnection *self, + gboolean clear_cached_system_secrets, + gboolean persist) { - gs_unref_object NMConnection *connection_cloned = NULL; + gs_unref_object NMConnection *connection_cloned = NULL; - if (!nm_settings_connection_still_valid (self)) - return; + if (!nm_settings_connection_still_valid(self)) + return; - /* FIXME: add API to NMConnection so that we can clone a profile without secrets. */ + /* FIXME: add API to NMConnection so that we can clone a profile without secrets. */ - connection_cloned = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self)); + connection_cloned = nm_simple_connection_new_clone(nm_settings_connection_get_connection(self)); - nm_connection_clear_secrets (connection_cloned); + nm_connection_clear_secrets(connection_cloned); - if (!nm_settings_connection_update (self, - connection_cloned, - persist - ? NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP - : NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE - | (clear_cached_system_secrets ? NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS : NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE) - | NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS, - "clear-secrets", - NULL)) - nm_assert_not_reached (); + if (!nm_settings_connection_update( + self, + connection_cloned, + persist ? NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP + : NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE + | (clear_cached_system_secrets + ? NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS + : NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE) + | NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS, + "clear-secrets", + NULL)) + nm_assert_not_reached(); } static gboolean -_secrets_update (NMConnection *connection, - const char *setting_name, - GVariant *secrets, - NMConnection **out_new_connection, - GError **error) -{ - gs_unref_variant GVariant *secrets_setting = NULL; - - nm_assert (NM_IS_CONNECTION (connection)); - - if ( setting_name - && !nm_connection_get_setting_by_name (connection, setting_name)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_SETTING_NOT_FOUND, - setting_name); - return FALSE; - } - - if (!secrets) - return TRUE; - - nm_assert ( g_variant_is_of_type (secrets, NM_VARIANT_TYPE_SETTING) - || g_variant_is_of_type (secrets, NM_VARIANT_TYPE_CONNECTION)); - - if (g_variant_n_children (secrets) == 0) - return TRUE; - - if ( setting_name - && g_variant_is_of_type (secrets, NM_VARIANT_TYPE_CONNECTION)) { - secrets_setting = g_variant_lookup_value (secrets, setting_name, NM_VARIANT_TYPE_SETTING); - if (!secrets_setting) { - /* The connection dictionary didn't contain any secrets for - * @setting_name; just return success. - */ - return TRUE; - } - secrets = secrets_setting; - } - - /* if @out_new_connection is provided, we don't modify @connection but clone - * and return it. Otherwise, we update @connection inplace. */ - if (out_new_connection) { - nm_assert (!*out_new_connection); - connection = nm_simple_connection_new_clone (connection); - *out_new_connection = connection; - } - - if (!nm_connection_update_secrets (connection, - setting_name, - secrets, - error)) - return FALSE; - - return TRUE; +_secrets_update(NMConnection * connection, + const char * setting_name, + GVariant * secrets, + NMConnection **out_new_connection, + GError ** error) +{ + gs_unref_variant GVariant *secrets_setting = NULL; + + nm_assert(NM_IS_CONNECTION(connection)); + + if (setting_name && !nm_connection_get_setting_by_name(connection, setting_name)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + setting_name); + return FALSE; + } + + if (!secrets) + return TRUE; + + nm_assert(g_variant_is_of_type(secrets, NM_VARIANT_TYPE_SETTING) + || g_variant_is_of_type(secrets, NM_VARIANT_TYPE_CONNECTION)); + + if (g_variant_n_children(secrets) == 0) + return TRUE; + + if (setting_name && g_variant_is_of_type(secrets, NM_VARIANT_TYPE_CONNECTION)) { + secrets_setting = g_variant_lookup_value(secrets, setting_name, NM_VARIANT_TYPE_SETTING); + if (!secrets_setting) { + /* The connection dictionary didn't contain any secrets for + * @setting_name; just return success. + */ + return TRUE; + } + secrets = secrets_setting; + } + + /* if @out_new_connection is provided, we don't modify @connection but clone + * and return it. Otherwise, we update @connection inplace. */ + if (out_new_connection) { + nm_assert(!*out_new_connection); + connection = nm_simple_connection_new_clone(connection); + *out_new_connection = connection; + } + + if (!nm_connection_update_secrets(connection, setting_name, secrets, error)) + return FALSE; + + return TRUE; } gboolean -nm_settings_connection_update (NMSettingsConnection *self, - NMConnection *new_connection, - NMSettingsConnectionPersistMode persist_mode, - NMSettingsConnectionIntFlags sett_flags, - NMSettingsConnectionIntFlags sett_mask, - NMSettingsConnectionUpdateReason update_reason, - const char *log_context_name, - GError **error) -{ - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); - - return nm_settings_update_connection (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->settings, - self, - new_connection, - persist_mode, - sett_flags, - sett_mask, - update_reason, - log_context_name, - error); +nm_settings_connection_update(NMSettingsConnection * self, + NMConnection * new_connection, + NMSettingsConnectionPersistMode persist_mode, + NMSettingsConnectionIntFlags sett_flags, + NMSettingsConnectionIntFlags sett_mask, + NMSettingsConnectionUpdateReason update_reason, + const char * log_context_name, + GError ** error) +{ + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), FALSE); + + return nm_settings_update_connection(NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->settings, + self, + new_connection, + persist_mode, + sett_flags, + sett_mask, + update_reason, + log_context_name, + error); } void -nm_settings_connection_delete (NMSettingsConnection *self, - gboolean allow_add_to_no_auto_default) +nm_settings_connection_delete(NMSettingsConnection *self, gboolean allow_add_to_no_auto_default) { - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); + g_return_if_fail(NM_IS_SETTINGS_CONNECTION(self)); - nm_settings_delete_connection (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->settings, - self, - allow_add_to_no_auto_default); + nm_settings_delete_connection(NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->settings, + self, + allow_add_to_no_auto_default); } /*****************************************************************************/ typedef enum { - CALL_ID_TYPE_REQ, - CALL_ID_TYPE_IDLE, + CALL_ID_TYPE_REQ, + CALL_ID_TYPE_IDLE, } CallIdType; struct _NMSettingsConnectionCallId { - NMSettingsConnection *self; - CList call_ids_lst; - gboolean had_applied_connection; - NMConnection *applied_connection; - NMSettingsConnectionSecretsFunc callback; - gpointer callback_data; - - CallIdType type; - union { - struct { - NMAgentManagerCallId id; - } req; - struct { - guint32 id; - GError *error; - } idle; - } t; + NMSettingsConnection * self; + CList call_ids_lst; + gboolean had_applied_connection; + NMConnection * applied_connection; + NMSettingsConnectionSecretsFunc callback; + gpointer callback_data; + + CallIdType type; + union { + struct { + NMAgentManagerCallId id; + } req; + struct { + guint32 id; + GError *error; + } idle; + } t; }; static void -_get_secrets_info_callback (NMSettingsConnectionCallId *call_id, - const char *agent_username, - const char *setting_name, - GError *error) +_get_secrets_info_callback(NMSettingsConnectionCallId *call_id, + const char * agent_username, + const char * setting_name, + GError * error) { - if (call_id->callback) { - call_id->callback (call_id->self, - call_id, - agent_username, - setting_name, - error, - call_id->callback_data); - } + if (call_id->callback) { + call_id->callback(call_id->self, + call_id, + agent_username, + setting_name, + error, + call_id->callback_data); + } } static void -_get_secrets_info_free (NMSettingsConnectionCallId *call_id) +_get_secrets_info_free(NMSettingsConnectionCallId *call_id) { - g_return_if_fail (call_id && call_id->self); - nm_assert (!c_list_is_linked (&call_id->call_ids_lst)); + g_return_if_fail(call_id && call_id->self); + nm_assert(!c_list_is_linked(&call_id->call_ids_lst)); - if (call_id->applied_connection) - g_object_remove_weak_pointer (G_OBJECT (call_id->applied_connection), (gpointer *) &call_id->applied_connection); + if (call_id->applied_connection) + g_object_remove_weak_pointer(G_OBJECT(call_id->applied_connection), + (gpointer *) &call_id->applied_connection); - if (call_id->type == CALL_ID_TYPE_IDLE) - g_clear_error (&call_id->t.idle.error); + if (call_id->type == CALL_ID_TYPE_IDLE) + g_clear_error(&call_id->t.idle.error); - memset (call_id, 0, sizeof (*call_id)); - g_slice_free (NMSettingsConnectionCallId, call_id); + memset(call_id, 0, sizeof(*call_id)); + g_slice_free(NMSettingsConnectionCallId, call_id); } typedef struct { - NMSettingSecretFlags required; - NMSettingSecretFlags forbidden; + NMSettingSecretFlags required; + NMSettingSecretFlags forbidden; } ForEachSecretFlags; static gboolean -validate_secret_flags_cb (NMSettingSecretFlags flags, - gpointer user_data) +validate_secret_flags_cb(NMSettingSecretFlags flags, gpointer user_data) { - ForEachSecretFlags *cmp_flags = user_data; + ForEachSecretFlags *cmp_flags = user_data; - if (!NM_FLAGS_ALL (flags, cmp_flags->required)) - return FALSE; - if (NM_FLAGS_ANY (flags, cmp_flags->forbidden)) - return FALSE; - return TRUE; + if (!NM_FLAGS_ALL(flags, cmp_flags->required)) + return FALSE; + if (NM_FLAGS_ANY(flags, cmp_flags->forbidden)) + return FALSE; + return TRUE; } static GVariant * -validate_secret_flags (NMConnection *connection, - GVariant *secrets, - ForEachSecretFlags *cmp_flags) +validate_secret_flags(NMConnection *connection, GVariant *secrets, ForEachSecretFlags *cmp_flags) { - return g_variant_ref_sink (_nm_connection_for_each_secret (connection, - secrets, - TRUE, - validate_secret_flags_cb, - cmp_flags)); + return g_variant_ref_sink(_nm_connection_for_each_secret(connection, + secrets, + TRUE, + validate_secret_flags_cb, + cmp_flags)); } static gboolean -secret_is_system_owned (NMSettingSecretFlags flags, - gpointer user_data) +secret_is_system_owned(NMSettingSecretFlags flags, gpointer user_data) { - return !NM_FLAGS_HAS (flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED); + return !NM_FLAGS_HAS(flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED); } static void -get_cmp_flags (NMSettingsConnection *self, /* only needed for logging */ - NMSettingsConnectionCallId *call_id, /* only needed for logging */ - NMConnection *connection, - const char *agent_dbus_owner, - gboolean agent_has_modify, - const char *setting_name, /* only needed for logging */ - NMSecretAgentGetSecretsFlags flags, - GVariant *secrets, - gboolean *agent_had_system, - ForEachSecretFlags *cmp_flags) -{ - gboolean is_self = (nm_settings_connection_get_connection (self) == connection); - - g_return_if_fail (secrets); - - cmp_flags->required = NM_SETTING_SECRET_FLAG_NONE; - cmp_flags->forbidden = NM_SETTING_SECRET_FLAG_NONE; - - *agent_had_system = FALSE; - - if (agent_dbus_owner) { - if (is_self) { - _LOGD ("(%s:%p) secrets returned from agent %s", - setting_name, - call_id, - agent_dbus_owner); - } - - /* If the agent returned any system-owned secrets (initial connect and no - * secrets given when the connection was created, or something like that) - * make sure the agent's UID has the 'modify' permission before we use or - * save those system-owned secrets. If not, discard them and use the - * existing secrets, or fail the connection. - */ - *agent_had_system = _nm_connection_find_secret (connection, secrets, secret_is_system_owned, NULL); - if (*agent_had_system) { - if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) { - /* No user interaction was allowed when requesting secrets; the - * agent is being bad. Remove system-owned secrets. - */ - if (is_self) { - _LOGD ("(%s:%p) interaction forbidden but agent %s returned system secrets", - setting_name, - call_id, - agent_dbus_owner); - } - - cmp_flags->required |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; - } else if (agent_has_modify == FALSE) { - /* Agent didn't successfully authenticate; clear system-owned secrets - * from the secrets the agent returned. - */ - if (is_self) { - _LOGD ("(%s:%p) agent failed to authenticate but provided system secrets", - setting_name, - call_id); - } - - cmp_flags->required |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; - } - } - } else { - if (is_self) { - _LOGD ("(%s:%p) existing secrets returned", - setting_name, - call_id); - } - } - - /* If no user interaction was allowed, make sure that no "unsaved" secrets - * came back. Unsaved secrets by definition require user interaction. - */ - if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) { - cmp_flags->forbidden |= ( NM_SETTING_SECRET_FLAG_NOT_SAVED - | NM_SETTING_SECRET_FLAG_NOT_REQUIRED); - } +get_cmp_flags(NMSettingsConnection * self, /* only needed for logging */ + NMSettingsConnectionCallId * call_id, /* only needed for logging */ + NMConnection * connection, + const char * agent_dbus_owner, + gboolean agent_has_modify, + const char * setting_name, /* only needed for logging */ + NMSecretAgentGetSecretsFlags flags, + GVariant * secrets, + gboolean * agent_had_system, + ForEachSecretFlags * cmp_flags) +{ + gboolean is_self = (nm_settings_connection_get_connection(self) == connection); + + g_return_if_fail(secrets); + + cmp_flags->required = NM_SETTING_SECRET_FLAG_NONE; + cmp_flags->forbidden = NM_SETTING_SECRET_FLAG_NONE; + + *agent_had_system = FALSE; + + if (agent_dbus_owner) { + if (is_self) { + _LOGD("(%s:%p) secrets returned from agent %s", + setting_name, + call_id, + agent_dbus_owner); + } + + /* If the agent returned any system-owned secrets (initial connect and no + * secrets given when the connection was created, or something like that) + * make sure the agent's UID has the 'modify' permission before we use or + * save those system-owned secrets. If not, discard them and use the + * existing secrets, or fail the connection. + */ + *agent_had_system = + _nm_connection_find_secret(connection, secrets, secret_is_system_owned, NULL); + if (*agent_had_system) { + if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) { + /* No user interaction was allowed when requesting secrets; the + * agent is being bad. Remove system-owned secrets. + */ + if (is_self) { + _LOGD("(%s:%p) interaction forbidden but agent %s returned system secrets", + setting_name, + call_id, + agent_dbus_owner); + } + + cmp_flags->required |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; + } else if (agent_has_modify == FALSE) { + /* Agent didn't successfully authenticate; clear system-owned secrets + * from the secrets the agent returned. + */ + if (is_self) { + _LOGD("(%s:%p) agent failed to authenticate but provided system secrets", + setting_name, + call_id); + } + + cmp_flags->required |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; + } + } + } else { + if (is_self) { + _LOGD("(%s:%p) existing secrets returned", setting_name, call_id); + } + } + + /* If no user interaction was allowed, make sure that no "unsaved" secrets + * came back. Unsaved secrets by definition require user interaction. + */ + if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) { + cmp_flags->forbidden |= + (NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED); + } } gboolean -nm_settings_connection_new_secrets (NMSettingsConnection *self, - NMConnection *applied_connection, - const char *setting_name, - GVariant *secrets, - GError **error) -{ - gs_unref_object NMConnection *new_connection = NULL; - NMConnection *connection; - - if (!nm_settings_connection_has_unmodified_applied_connection (self, - applied_connection, - NM_SETTING_COMPARE_FLAG_NONE)) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "The connection was modified since activation"); - return FALSE; - } - - connection = nm_settings_connection_get_connection (self); - - if (!_secrets_update (connection, - setting_name, - secrets, - &new_connection, - error)) - return FALSE; - - if (!nm_settings_connection_update (self, - new_connection ?: connection, - NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS, - "new-secrets", - NULL)) - nm_assert_not_reached (); - return TRUE; +nm_settings_connection_new_secrets(NMSettingsConnection *self, + NMConnection * applied_connection, + const char * setting_name, + GVariant * secrets, + GError ** error) +{ + gs_unref_object NMConnection *new_connection = NULL; + NMConnection * connection; + + if (!nm_settings_connection_has_unmodified_applied_connection(self, + applied_connection, + NM_SETTING_COMPARE_FLAG_NONE)) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "The connection was modified since activation"); + return FALSE; + } + + connection = nm_settings_connection_get_connection(self); + + if (!_secrets_update(connection, setting_name, secrets, &new_connection, error)) + return FALSE; + + if (!nm_settings_connection_update( + self, + new_connection ?: connection, + NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS, + "new-secrets", + NULL)) + nm_assert_not_reached(); + return TRUE; } static void -get_secrets_done_cb (NMAgentManager *manager, - NMAgentManagerCallId call_id_a, - const char *agent_dbus_owner, - const char *agent_username, - gboolean agent_has_modify, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags, - GVariant *secrets, - GError *error, - gpointer user_data) -{ - NMSettingsConnectionCallId *call_id = user_data; - NMSettingsConnection *self; - NMSettingsConnectionPrivate *priv; - NMConnection *applied_connection; - gs_free_error GError *local = NULL; - gs_unref_variant GVariant *system_secrets = NULL; - gs_unref_object NMConnection *new_connection = NULL; - gboolean agent_had_system = FALSE; - ForEachSecretFlags cmp_flags = { NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAG_NONE }; - gs_unref_variant GVariant *filtered_secrets = NULL; - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = call_id->self; - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); - - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - - nm_assert (c_list_contains (&priv->call_ids_lst_head, &call_id->call_ids_lst)); - - c_list_unlink (&call_id->call_ids_lst); - - if (error) { - _LOGD ("(%s:%p) secrets request error: %s", - setting_name, call_id, error->message); - - _get_secrets_info_callback (call_id, NULL, setting_name, error); - goto out; - } - - if ( call_id->had_applied_connection - && !call_id->applied_connection) { - g_set_error_literal (&local, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, - "Applied connection deleted since requesting secrets"); - _get_secrets_info_callback (call_id, NULL, setting_name, local); - goto out; - } - - if ( call_id->had_applied_connection - && !nm_settings_connection_has_unmodified_applied_connection (self, call_id->applied_connection, NM_SETTING_COMPARE_FLAG_NONE)) { - g_set_error_literal (&local, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "The connection was modified since activation"); - _get_secrets_info_callback (call_id, NULL, setting_name, local); - goto out; - } - - if (!nm_connection_get_setting_by_name (nm_settings_connection_get_connection (self), setting_name)) { - g_set_error (&local, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, - "Connection didn't have requested setting '%s'.", - setting_name); - _get_secrets_info_callback (call_id, NULL, setting_name, local); - goto out; - } - - get_cmp_flags (self, - call_id, - nm_settings_connection_get_connection (self), - agent_dbus_owner, - agent_has_modify, - setting_name, - flags, - secrets, - &agent_had_system, - &cmp_flags); - - _LOGD ("(%s:%p) secrets request completed", - setting_name, - call_id); - - system_secrets = nm_g_variant_ref (priv->system_secrets); - - new_connection = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self)); - - nm_connection_clear_secrets (new_connection); - - if (!_secrets_update (new_connection, - setting_name, - system_secrets, - NULL, - &local)) { - _LOGD ("(%s:%p) failed to update with existing secrets: %s", - setting_name, - call_id, - local->message); - } - - /* Update the connection with the agent's secrets; by this point if any - * system-owned secrets exist in 'secrets' the agent that provided them - * will have been authenticated, so those secrets can replace the existing - * system secrets. - */ - filtered_secrets = validate_secret_flags (new_connection, secrets, &cmp_flags); - - if (!_secrets_update (new_connection, - setting_name, - filtered_secrets, - NULL, - &local)) { - _LOGD ("(%s:%p) failed to update with agent secrets: %s", - setting_name, - call_id, - local->message); - } - - /* Only save secrets to backing storage if the agent returned any - * new system secrets. If it didn't, then the secrets are agent- - * owned and there's no point to writing out the connection when - * nothing has changed, since agent-owned secrets don't get saved here. - */ - if (agent_had_system) { - _LOGD ("(%s:%p) saving new secrets to backing storage", - setting_name, - call_id); - } else { - _LOGD ("(%s:%p) new agent secrets processed", - setting_name, - call_id); - } - if (!nm_settings_connection_update (self, - new_connection, - agent_had_system - ? NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP - : NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS, - "get-new-secrets", - NULL)) - nm_assert_not_reached (); - - applied_connection = call_id->applied_connection; - if (applied_connection) { - get_cmp_flags (self, - call_id, - applied_connection, - agent_dbus_owner, - agent_has_modify, - setting_name, - flags, - secrets, - &agent_had_system, - &cmp_flags); - - nm_connection_clear_secrets (applied_connection); - - if ( !system_secrets - || nm_connection_update_secrets (applied_connection, setting_name, system_secrets, NULL)) { - gs_unref_variant GVariant *filtered_secrets2 = NULL; - - filtered_secrets2 = validate_secret_flags (applied_connection, secrets, &cmp_flags); - nm_connection_update_secrets (applied_connection, setting_name, filtered_secrets2, NULL); - } - } - - _get_secrets_info_callback (call_id, agent_username, setting_name, local); - g_clear_error (&local); +get_secrets_done_cb(NMAgentManager * manager, + NMAgentManagerCallId call_id_a, + const char * agent_dbus_owner, + const char * agent_username, + gboolean agent_has_modify, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags, + GVariant * secrets, + GError * error, + gpointer user_data) +{ + NMSettingsConnectionCallId * call_id = user_data; + NMSettingsConnection * self; + NMSettingsConnectionPrivate *priv; + NMConnection * applied_connection; + gs_free_error GError *local = NULL; + gs_unref_variant GVariant *system_secrets = NULL; + gs_unref_object NMConnection *new_connection = NULL; + gboolean agent_had_system = FALSE; + ForEachSecretFlags cmp_flags = {NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAG_NONE}; + gs_unref_variant GVariant *filtered_secrets = NULL; + + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = call_id->self; + g_return_if_fail(NM_IS_SETTINGS_CONNECTION(self)); + + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + + nm_assert(c_list_contains(&priv->call_ids_lst_head, &call_id->call_ids_lst)); + + c_list_unlink(&call_id->call_ids_lst); + + if (error) { + _LOGD("(%s:%p) secrets request error: %s", setting_name, call_id, error->message); + + _get_secrets_info_callback(call_id, NULL, setting_name, error); + goto out; + } + + if (call_id->had_applied_connection && !call_id->applied_connection) { + g_set_error_literal(&local, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + "Applied connection deleted since requesting secrets"); + _get_secrets_info_callback(call_id, NULL, setting_name, local); + goto out; + } + + if (call_id->had_applied_connection + && !nm_settings_connection_has_unmodified_applied_connection( + self, + call_id->applied_connection, + NM_SETTING_COMPARE_FLAG_NONE)) { + g_set_error_literal(&local, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "The connection was modified since activation"); + _get_secrets_info_callback(call_id, NULL, setting_name, local); + goto out; + } + + if (!nm_connection_get_setting_by_name(nm_settings_connection_get_connection(self), + setting_name)) { + g_set_error(&local, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + "Connection didn't have requested setting '%s'.", + setting_name); + _get_secrets_info_callback(call_id, NULL, setting_name, local); + goto out; + } + + get_cmp_flags(self, + call_id, + nm_settings_connection_get_connection(self), + agent_dbus_owner, + agent_has_modify, + setting_name, + flags, + secrets, + &agent_had_system, + &cmp_flags); + + _LOGD("(%s:%p) secrets request completed", setting_name, call_id); + + system_secrets = nm_g_variant_ref(priv->system_secrets); + + new_connection = nm_simple_connection_new_clone(nm_settings_connection_get_connection(self)); + + nm_connection_clear_secrets(new_connection); + + if (!_secrets_update(new_connection, setting_name, system_secrets, NULL, &local)) { + _LOGD("(%s:%p) failed to update with existing secrets: %s", + setting_name, + call_id, + local->message); + } + + /* Update the connection with the agent's secrets; by this point if any + * system-owned secrets exist in 'secrets' the agent that provided them + * will have been authenticated, so those secrets can replace the existing + * system secrets. + */ + filtered_secrets = validate_secret_flags(new_connection, secrets, &cmp_flags); + + if (!_secrets_update(new_connection, setting_name, filtered_secrets, NULL, &local)) { + _LOGD("(%s:%p) failed to update with agent secrets: %s", + setting_name, + call_id, + local->message); + } + + /* Only save secrets to backing storage if the agent returned any + * new system secrets. If it didn't, then the secrets are agent- + * owned and there's no point to writing out the connection when + * nothing has changed, since agent-owned secrets don't get saved here. + */ + if (agent_had_system) { + _LOGD("(%s:%p) saving new secrets to backing storage", setting_name, call_id); + } else { + _LOGD("(%s:%p) new agent secrets processed", setting_name, call_id); + } + if (!nm_settings_connection_update( + self, + new_connection, + agent_had_system ? NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP + : NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS, + "get-new-secrets", + NULL)) + nm_assert_not_reached(); + + applied_connection = call_id->applied_connection; + if (applied_connection) { + get_cmp_flags(self, + call_id, + applied_connection, + agent_dbus_owner, + agent_has_modify, + setting_name, + flags, + secrets, + &agent_had_system, + &cmp_flags); + + nm_connection_clear_secrets(applied_connection); + + if (!system_secrets + || nm_connection_update_secrets(applied_connection, + setting_name, + system_secrets, + NULL)) { + gs_unref_variant GVariant *filtered_secrets2 = NULL; + + filtered_secrets2 = validate_secret_flags(applied_connection, secrets, &cmp_flags); + nm_connection_update_secrets(applied_connection, setting_name, filtered_secrets2, NULL); + } + } + + _get_secrets_info_callback(call_id, agent_username, setting_name, local); + g_clear_error(&local); out: - _get_secrets_info_free (call_id); + _get_secrets_info_free(call_id); } static gboolean -get_secrets_idle_cb (NMSettingsConnectionCallId *call_id) +get_secrets_idle_cb(NMSettingsConnectionCallId *call_id) { - NMSettingsConnectionPrivate *priv; + NMSettingsConnectionPrivate *priv; - g_return_val_if_fail (call_id && NM_IS_SETTINGS_CONNECTION (call_id->self), G_SOURCE_REMOVE); + g_return_val_if_fail(call_id && NM_IS_SETTINGS_CONNECTION(call_id->self), G_SOURCE_REMOVE); - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (call_id->self); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(call_id->self); - nm_assert (c_list_contains (&priv->call_ids_lst_head, &call_id->call_ids_lst)); + nm_assert(c_list_contains(&priv->call_ids_lst_head, &call_id->call_ids_lst)); - c_list_unlink (&call_id->call_ids_lst); + c_list_unlink(&call_id->call_ids_lst); - _get_secrets_info_callback (call_id, NULL, NULL, call_id->t.idle.error); + _get_secrets_info_callback(call_id, NULL, NULL, call_id->t.idle.error); - _get_secrets_info_free (call_id); - return G_SOURCE_REMOVE; + _get_secrets_info_free(call_id); + return G_SOURCE_REMOVE; } /** @@ -1048,188 +1047,200 @@ get_secrets_idle_cb (NMSettingsConnectionCallId *call_id) * Returns: a call ID which may be used to cancel the ongoing secrets request. **/ NMSettingsConnectionCallId * -nm_settings_connection_get_secrets (NMSettingsConnection *self, - NMConnection *applied_connection, - NMAuthSubject *subject, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags, - const char *const*hints, - NMSettingsConnectionSecretsFunc callback, - gpointer callback_data) -{ - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - NMAgentManagerCallId call_id_a; - gs_free char *joined_hints = NULL; - NMSettingsConnectionCallId *call_id; - GError *local = NULL; - - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL); - g_return_val_if_fail ( !applied_connection - || ( NM_IS_CONNECTION (applied_connection) - && (nm_settings_connection_get_connection (self) != applied_connection)), NULL); - - call_id = g_slice_new0 (NMSettingsConnectionCallId); - call_id->self = self; - if (applied_connection) { - call_id->had_applied_connection = TRUE; - call_id->applied_connection = applied_connection; - g_object_add_weak_pointer (G_OBJECT (applied_connection), (gpointer *) &call_id->applied_connection); - } - call_id->callback = callback; - call_id->callback_data = callback_data; - c_list_link_tail (&priv->call_ids_lst_head, &call_id->call_ids_lst); - - /* Make sure the request actually requests something we can return */ - if (!nm_connection_get_setting_by_name (nm_settings_connection_get_connection (self), setting_name)) { - g_set_error (&local, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, - "Connection didn't have requested setting '%s'.", - setting_name); - goto schedule_dummy; - } - - if ( applied_connection - && !nm_settings_connection_has_unmodified_applied_connection (self, applied_connection, NM_SETTING_COMPARE_FLAG_NONE)) { - g_set_error_literal (&local, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "The connection was modified since activation"); - goto schedule_dummy; - } - - /* we remember the current version-id of the secret-agents. The version-id is strictly increasing, - * as new agents register the number. We know hence, that this request was made against a certain - * set of secret-agents. - * If after making this request a new secret-agent registers, the version-id increases. - * Then we know that the this request probably did not yet include the latest secret-agent. */ - priv->last_secret_agent_version_id = nm_agent_manager_get_agent_version_id (priv->agent_mgr); - - /* Use priv->system_secrets to work around the fact that nm_connection_clear_secrets() - * will clear secrets on this object's settings. - */ - call_id_a = nm_agent_manager_get_secrets (priv->agent_mgr, - nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), - nm_settings_connection_get_connection (self), - subject, - priv->system_secrets, - setting_name, - flags, - hints, - get_secrets_done_cb, - call_id); - nm_assert (call_id_a); - - _LOGD ("(%s:%p) secrets requested flags 0x%X hints '%s'", - setting_name, - call_id_a, - flags, - (hints && hints[0]) ? (joined_hints = g_strjoinv (",", (char **) hints)) : "(none)"); - - if (call_id_a) { - call_id->type = CALL_ID_TYPE_REQ; - call_id->t.req.id = call_id_a; - } else { +nm_settings_connection_get_secrets(NMSettingsConnection * self, + NMConnection * applied_connection, + NMAuthSubject * subject, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags, + const char *const * hints, + NMSettingsConnectionSecretsFunc callback, + gpointer callback_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + NMAgentManagerCallId call_id_a; + gs_free char * joined_hints = NULL; + NMSettingsConnectionCallId * call_id; + GError * local = NULL; + + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), NULL); + g_return_val_if_fail( + !applied_connection + || (NM_IS_CONNECTION(applied_connection) + && (nm_settings_connection_get_connection(self) != applied_connection)), + NULL); + + call_id = g_slice_new0(NMSettingsConnectionCallId); + call_id->self = self; + if (applied_connection) { + call_id->had_applied_connection = TRUE; + call_id->applied_connection = applied_connection; + g_object_add_weak_pointer(G_OBJECT(applied_connection), + (gpointer *) &call_id->applied_connection); + } + call_id->callback = callback; + call_id->callback_data = callback_data; + c_list_link_tail(&priv->call_ids_lst_head, &call_id->call_ids_lst); + + /* Make sure the request actually requests something we can return */ + if (!nm_connection_get_setting_by_name(nm_settings_connection_get_connection(self), + setting_name)) { + g_set_error(&local, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + "Connection didn't have requested setting '%s'.", + setting_name); + goto schedule_dummy; + } + + if (applied_connection + && !nm_settings_connection_has_unmodified_applied_connection( + self, + applied_connection, + NM_SETTING_COMPARE_FLAG_NONE)) { + g_set_error_literal(&local, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "The connection was modified since activation"); + goto schedule_dummy; + } + + /* we remember the current version-id of the secret-agents. The version-id is strictly increasing, + * as new agents register the number. We know hence, that this request was made against a certain + * set of secret-agents. + * If after making this request a new secret-agent registers, the version-id increases. + * Then we know that the this request probably did not yet include the latest secret-agent. */ + priv->last_secret_agent_version_id = nm_agent_manager_get_agent_version_id(priv->agent_mgr); + + /* Use priv->system_secrets to work around the fact that nm_connection_clear_secrets() + * will clear secrets on this object's settings. + */ + call_id_a = nm_agent_manager_get_secrets(priv->agent_mgr, + nm_dbus_object_get_path(NM_DBUS_OBJECT(self)), + nm_settings_connection_get_connection(self), + subject, + priv->system_secrets, + setting_name, + flags, + hints, + get_secrets_done_cb, + call_id); + nm_assert(call_id_a); + + _LOGD("(%s:%p) secrets requested flags 0x%X hints '%s'", + setting_name, + call_id_a, + flags, + (hints && hints[0]) ? (joined_hints = g_strjoinv(",", (char **) hints)) : "(none)"); + + if (call_id_a) { + call_id->type = CALL_ID_TYPE_REQ; + call_id->t.req.id = call_id_a; + } else { schedule_dummy: - call_id->type = CALL_ID_TYPE_IDLE; - g_propagate_error (&call_id->t.idle.error, local); - call_id->t.idle.id = g_idle_add ((GSourceFunc) get_secrets_idle_cb, call_id); - } - return call_id; + call_id->type = CALL_ID_TYPE_IDLE; + g_propagate_error(&call_id->t.idle.error, local); + call_id->t.idle.id = g_idle_add((GSourceFunc) get_secrets_idle_cb, call_id); + } + return call_id; } static void -_get_secrets_cancel (NMSettingsConnection *self, - NMSettingsConnectionCallId *call_id, - gboolean is_disposing) +_get_secrets_cancel(NMSettingsConnection * self, + NMSettingsConnectionCallId *call_id, + gboolean is_disposing) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - gs_free_error GError *error = NULL; + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + gs_free_error GError *error = NULL; - nm_assert (c_list_contains (&priv->call_ids_lst_head, &call_id->call_ids_lst)); + nm_assert(c_list_contains(&priv->call_ids_lst_head, &call_id->call_ids_lst)); - c_list_unlink (&call_id->call_ids_lst); + c_list_unlink(&call_id->call_ids_lst); - if (call_id->type == CALL_ID_TYPE_REQ) - nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id->t.req.id); - else - g_source_remove (call_id->t.idle.id); + if (call_id->type == CALL_ID_TYPE_REQ) + nm_agent_manager_cancel_secrets(priv->agent_mgr, call_id->t.req.id); + else + g_source_remove(call_id->t.idle.id); - nm_utils_error_set_cancelled (&error, is_disposing, "NMSettingsConnection"); + nm_utils_error_set_cancelled(&error, is_disposing, "NMSettingsConnection"); - _get_secrets_info_callback (call_id, NULL, NULL, error); + _get_secrets_info_callback(call_id, NULL, NULL, error); - _get_secrets_info_free (call_id); + _get_secrets_info_free(call_id); } void -nm_settings_connection_cancel_secrets (NMSettingsConnection *self, - NMSettingsConnectionCallId *call_id) +nm_settings_connection_cancel_secrets(NMSettingsConnection * self, + NMSettingsConnectionCallId *call_id) { - _LOGD ("(%p) secrets canceled", call_id); + _LOGD("(%p) secrets canceled", call_id); - _get_secrets_cancel (self, call_id, FALSE); + _get_secrets_cancel(self, call_id, FALSE); } /*****************************************************************************/ -typedef void (*AuthCallback) (NMSettingsConnection *self, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer data); +typedef void (*AuthCallback)(NMSettingsConnection * self, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + GError * error, + gpointer data); typedef struct { - CList auth_lst; - NMAuthManagerCallId *call_id; - NMSettingsConnection *self; - AuthCallback callback; - gpointer callback_data; - GDBusMethodInvocation *invocation; - NMAuthSubject *subject; + CList auth_lst; + NMAuthManagerCallId * call_id; + NMSettingsConnection * self; + AuthCallback callback; + gpointer callback_data; + GDBusMethodInvocation *invocation; + NMAuthSubject * subject; } AuthData; static void -pk_auth_cb (NMAuthManager *auth_manager, - NMAuthManagerCallId *auth_call_id, - gboolean is_authorized, - gboolean is_challenge, - GError *auth_error, - gpointer user_data) -{ - AuthData *auth_data = user_data; - NMSettingsConnection *self; - gs_free_error GError *error = NULL; - - nm_assert (auth_data); - nm_assert (NM_IS_SETTINGS_CONNECTION (auth_data->self)); - - self = auth_data->self; - - auth_data->call_id = NULL; - - c_list_unlink (&auth_data->auth_lst); - - if (g_error_matches (auth_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_FAILED, - "Error checking authorization: connection was deleted"); - } else if (auth_error) { - error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_FAILED, - "Error checking authorization: %s", - auth_error->message); - } else if (nm_auth_call_result_eval (is_authorized, is_challenge, auth_error) != NM_AUTH_CALL_RESULT_YES) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - NM_UTILS_ERROR_MSG_INSUFF_PRIV); - } - - auth_data->callback (self, - auth_data->invocation, - auth_data->subject, - error, - auth_data->callback_data); - - g_object_unref (auth_data->invocation); - g_object_unref (auth_data->subject); - g_slice_free (AuthData, auth_data); +pk_auth_cb(NMAuthManager * auth_manager, + NMAuthManagerCallId *auth_call_id, + gboolean is_authorized, + gboolean is_challenge, + GError * auth_error, + gpointer user_data) +{ + AuthData * auth_data = user_data; + NMSettingsConnection *self; + gs_free_error GError *error = NULL; + + nm_assert(auth_data); + nm_assert(NM_IS_SETTINGS_CONNECTION(auth_data->self)); + + self = auth_data->self; + + auth_data->call_id = NULL; + + c_list_unlink(&auth_data->auth_lst); + + if (g_error_matches(auth_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + error = g_error_new(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Error checking authorization: connection was deleted"); + } else if (auth_error) { + error = g_error_new(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Error checking authorization: %s", + auth_error->message); + } else if (nm_auth_call_result_eval(is_authorized, is_challenge, auth_error) + != NM_AUTH_CALL_RESULT_YES) { + error = g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + NM_UTILS_ERROR_MSG_INSUFF_PRIV); + } + + auth_data->callback(self, + auth_data->invocation, + auth_data->subject, + error, + auth_data->callback_data); + + g_object_unref(auth_data->invocation); + g_object_unref(auth_data->subject); + g_slice_free(AuthData, auth_data); } /** @@ -1242,875 +1253,896 @@ pk_auth_cb (NMAuthManager *auth_manager, * Returns: the #NMAuthSubject on success, or %NULL on failure and sets @error */ static NMAuthSubject * -_new_auth_subject (GDBusMethodInvocation *context, GError **error) +_new_auth_subject(GDBusMethodInvocation *context, GError **error) { - NMAuthSubject *subject; + NMAuthSubject *subject; - subject = nm_dbus_manager_new_auth_subject_from_context (context); - if (!subject) { - g_set_error_literal (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - NM_UTILS_ERROR_MSG_REQ_UID_UKNOWN); - } + subject = nm_dbus_manager_new_auth_subject_from_context(context); + if (!subject) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + NM_UTILS_ERROR_MSG_REQ_UID_UKNOWN); + } - return subject; + return subject; } /* may either invoke callback synchronously or asynchronously. */ static void -auth_start (NMSettingsConnection *self, - GDBusMethodInvocation *invocation, - NMAuthSubject *subject, - const char *check_permission, - AuthCallback callback, - gpointer callback_data) -{ - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - AuthData *auth_data; - GError *error = NULL; - - nm_assert (nm_dbus_object_is_exported (NM_DBUS_OBJECT (self))); - nm_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); - nm_assert (NM_IS_AUTH_SUBJECT (subject)); - - if (!nm_auth_is_subject_in_acl_set_error (nm_settings_connection_get_connection (self), - subject, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - &error)) { - callback (self, invocation, subject, error, callback_data); - g_clear_error (&error); - return; - } - - if (!check_permission) { - /* Don't need polkit auth, automatic success */ - callback (self, invocation, subject, NULL, callback_data); - return; - } - - auth_data = g_slice_new (AuthData); - auth_data->self = self; - auth_data->callback = callback; - auth_data->callback_data = callback_data; - auth_data->invocation = g_object_ref (invocation); - auth_data->subject = g_object_ref (subject); - c_list_link_tail (&priv->auth_lst_head, &auth_data->auth_lst); - auth_data->call_id = nm_auth_manager_check_authorization (nm_auth_manager_get (), - subject, - check_permission, - TRUE, - pk_auth_cb, - auth_data); +auth_start(NMSettingsConnection * self, + GDBusMethodInvocation *invocation, + NMAuthSubject * subject, + const char * check_permission, + AuthCallback callback, + gpointer callback_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + AuthData * auth_data; + GError * error = NULL; + + nm_assert(nm_dbus_object_is_exported(NM_DBUS_OBJECT(self))); + nm_assert(G_IS_DBUS_METHOD_INVOCATION(invocation)); + nm_assert(NM_IS_AUTH_SUBJECT(subject)); + + if (!nm_auth_is_subject_in_acl_set_error(nm_settings_connection_get_connection(self), + subject, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + &error)) { + callback(self, invocation, subject, error, callback_data); + g_clear_error(&error); + return; + } + + if (!check_permission) { + /* Don't need polkit auth, automatic success */ + callback(self, invocation, subject, NULL, callback_data); + return; + } + + auth_data = g_slice_new(AuthData); + auth_data->self = self; + auth_data->callback = callback; + auth_data->callback_data = callback_data; + auth_data->invocation = g_object_ref(invocation); + auth_data->subject = g_object_ref(subject); + c_list_link_tail(&priv->auth_lst_head, &auth_data->auth_lst); + auth_data->call_id = nm_auth_manager_check_authorization(nm_auth_manager_get(), + subject, + check_permission, + TRUE, + pk_auth_cb, + auth_data); } /**** DBus method handlers ************************************/ static void -get_settings_auth_cb (NMSettingsConnection *self, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer data) -{ - gs_free const char **seen_bssids = NULL; - NMConnectionSerializationOptions options = { - }; - GVariant *settings; - - if (error) { - g_dbus_method_invocation_return_gerror (context, error); - return; - } - - /* Timestamp is not updated in connection's 'timestamp' property, - * because it would force updating the connection and in turn - * writing to /etc periodically, which we want to avoid. Rather real - * timestamps are kept track of in a private variable. So, substitute - * timestamp property with the real one here before returning the settings. - */ - options.timestamp.has = TRUE; - nm_settings_connection_get_timestamp (self, &options.timestamp.val); - - /* Seen BSSIDs are not updated in 802-11-wireless 'seen-bssids' property - * from the same reason as timestamp. Thus we put it here to GetSettings() - * return settings too. - */ - seen_bssids = nm_settings_connection_get_seen_bssids (self); - options.seen_bssids = seen_bssids; - - /* Secrets should *never* be returned by the GetSettings method, they - * get returned by the GetSecrets method which can be better - * protected against leakage of secrets to unprivileged callers. - */ - settings = nm_connection_to_dbus_full (nm_settings_connection_get_connection (self), - NM_CONNECTION_SERIALIZE_NO_SECRETS, - &options); - g_dbus_method_invocation_return_value (context, - g_variant_new ("(@a{sa{sv}})", settings)); +get_settings_auth_cb(NMSettingsConnection * self, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + GError * error, + gpointer data) +{ + gs_free const char ** seen_bssids = NULL; + NMConnectionSerializationOptions options = {}; + GVariant * settings; + + if (error) { + g_dbus_method_invocation_return_gerror(context, error); + return; + } + + /* Timestamp is not updated in connection's 'timestamp' property, + * because it would force updating the connection and in turn + * writing to /etc periodically, which we want to avoid. Rather real + * timestamps are kept track of in a private variable. So, substitute + * timestamp property with the real one here before returning the settings. + */ + options.timestamp.has = TRUE; + nm_settings_connection_get_timestamp(self, &options.timestamp.val); + + /* Seen BSSIDs are not updated in 802-11-wireless 'seen-bssids' property + * from the same reason as timestamp. Thus we put it here to GetSettings() + * return settings too. + */ + seen_bssids = nm_settings_connection_get_seen_bssids(self); + options.seen_bssids = seen_bssids; + + /* Secrets should *never* be returned by the GetSettings method, they + * get returned by the GetSecrets method which can be better + * protected against leakage of secrets to unprivileged callers. + */ + settings = nm_connection_to_dbus_full(nm_settings_connection_get_connection(self), + NM_CONNECTION_SERIALIZE_NO_SECRETS, + &options); + g_dbus_method_invocation_return_value(context, g_variant_new("(@a{sa{sv}})", settings)); } static void -impl_settings_connection_get_settings (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_connection_get_settings(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); - gs_unref_object NMAuthSubject *subject = NULL; - GError *error = NULL; + NMSettingsConnection *self = NM_SETTINGS_CONNECTION(obj); + gs_unref_object NMAuthSubject *subject = NULL; + GError * error = NULL; - subject = _new_auth_subject (invocation, &error); - if (!subject) { - g_dbus_method_invocation_take_error (invocation, error); - return; - } + subject = _new_auth_subject(invocation, &error); + if (!subject) { + g_dbus_method_invocation_take_error(invocation, error); + return; + } - auth_start (self, invocation, subject, NULL, get_settings_auth_cb, NULL); + auth_start(self, invocation, subject, NULL, get_settings_auth_cb, NULL); } typedef struct { - GDBusMethodInvocation *context; - NMAgentManager *agent_mgr; - NMAuthSubject *subject; - NMConnection *new_settings; - NMSettingsUpdate2Flags flags; - char *audit_args; - bool is_update2:1; + GDBusMethodInvocation *context; + NMAgentManager * agent_mgr; + NMAuthSubject * subject; + NMConnection * new_settings; + NMSettingsUpdate2Flags flags; + char * audit_args; + bool is_update2 : 1; } UpdateInfo; static void -update_complete (NMSettingsConnection *self, - UpdateInfo *info, - GError *error) +update_complete(NMSettingsConnection *self, UpdateInfo *info, GError *error) { - if (error) - g_dbus_method_invocation_return_gerror (info->context, error); - else if (info->is_update2) { - GVariantBuilder result; + if (error) + g_dbus_method_invocation_return_gerror(info->context, error); + else if (info->is_update2) { + GVariantBuilder result; - g_variant_builder_init (&result, G_VARIANT_TYPE ("a{sv}")); - g_dbus_method_invocation_return_value (info->context, - g_variant_new ("(a{sv})", &result)); - } else - g_dbus_method_invocation_return_value (info->context, NULL); + g_variant_builder_init(&result, G_VARIANT_TYPE("a{sv}")); + g_dbus_method_invocation_return_value(info->context, g_variant_new("(a{sv})", &result)); + } else + g_dbus_method_invocation_return_value(info->context, NULL); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, !error, info->audit_args, - info->subject, error ? error->message : NULL); + nm_audit_log_connection_op(NM_AUDIT_OP_CONN_UPDATE, + self, + !error, + info->audit_args, + info->subject, + error ? error->message : NULL); - g_clear_object (&info->subject); - g_clear_object (&info->agent_mgr); - g_clear_object (&info->new_settings); - g_free (info->audit_args); - g_slice_free (UpdateInfo, info); + g_clear_object(&info->subject); + g_clear_object(&info->agent_mgr); + g_clear_object(&info->new_settings); + g_free(info->audit_args); + g_slice_free(UpdateInfo, info); } static int -_autoconnect_retries_initial (NMSettingsConnection *self) +_autoconnect_retries_initial(NMSettingsConnection *self) { - NMSettingConnection *s_con; - int retries = -1; + NMSettingConnection *s_con; + int retries = -1; - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (self)); - if (s_con) - retries = nm_setting_connection_get_autoconnect_retries (s_con); + s_con = nm_connection_get_setting_connection(nm_settings_connection_get_connection(self)); + if (s_con) + retries = nm_setting_connection_get_autoconnect_retries(s_con); - /* -1 means 'default' */ - if (retries == -1) - retries = nm_config_data_get_autoconnect_retries_default (NM_CONFIG_GET_DATA); + /* -1 means 'default' */ + if (retries == -1) + retries = nm_config_data_get_autoconnect_retries_default(NM_CONFIG_GET_DATA); - /* 0 means 'forever', which is translated to a retry count of -1 */ - if (retries == 0) - retries = AUTOCONNECT_RETRIES_FOREVER; + /* 0 means 'forever', which is translated to a retry count of -1 */ + if (retries == 0) + retries = AUTOCONNECT_RETRIES_FOREVER; - nm_assert (retries == AUTOCONNECT_RETRIES_FOREVER || retries >= 0); - return retries; + nm_assert(retries == AUTOCONNECT_RETRIES_FOREVER || retries >= 0); + return retries; } static void -_autoconnect_retries_set (NMSettingsConnection *self, - int retries, - gboolean is_reset) +_autoconnect_retries_set(NMSettingsConnection *self, int retries, gboolean is_reset) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - g_return_if_fail (retries == AUTOCONNECT_RETRIES_FOREVER || retries >= 0); + g_return_if_fail(retries == AUTOCONNECT_RETRIES_FOREVER || retries >= 0); - if (priv->autoconnect_retries != retries) { - _LOGT ("autoconnect: retries set %d%s", retries, - is_reset ? " (reset)" : ""); - priv->autoconnect_retries = retries; - } + if (priv->autoconnect_retries != retries) { + _LOGT("autoconnect: retries set %d%s", retries, is_reset ? " (reset)" : ""); + priv->autoconnect_retries = retries; + } - if (retries) - priv->autoconnect_retries_blocked_until = 0; - else { - /* NOTE: the blocked time must be identical for all connections, otherwise - * the tracking of resetting the retry count in NMPolicy needs adjustment - * in _connection_autoconnect_retries_set() (as it would need to re-evaluate - * the next-timeout every time a connection gets blocked). */ - priv->autoconnect_retries_blocked_until = nm_utils_get_monotonic_timestamp_sec () + AUTOCONNECT_RESET_RETRIES_TIMER; - } + if (retries) + priv->autoconnect_retries_blocked_until = 0; + else { + /* NOTE: the blocked time must be identical for all connections, otherwise + * the tracking of resetting the retry count in NMPolicy needs adjustment + * in _connection_autoconnect_retries_set() (as it would need to re-evaluate + * the next-timeout every time a connection gets blocked). */ + priv->autoconnect_retries_blocked_until = + nm_utils_get_monotonic_timestamp_sec() + AUTOCONNECT_RESET_RETRIES_TIMER; + } } static void -update_auth_cb (NMSettingsConnection *self, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer data) -{ - NMSettingsConnectionPrivate *priv; - UpdateInfo *info = data; - gs_free_error GError *local = NULL; - NMSettingsConnectionPersistMode persist_mode; - - if (error) { - update_complete (self, info, error); - return; - } - - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - - if (info->new_settings) { - if (!_nm_connection_aggregate (info->new_settings, NM_CONNECTION_AGGREGATE_ANY_SECRETS, NULL)) { - /* If the new connection has no secrets, we do not want to remove all - * secrets, rather we keep all the existing ones. Do that by merging - * them in to the new connection. - */ - if (priv->agent_secrets) - nm_connection_update_secrets (info->new_settings, NULL, priv->agent_secrets, NULL); - if (priv->system_secrets) - nm_connection_update_secrets (info->new_settings, NULL, priv->system_secrets, NULL); - } else { - /* Cache the new secrets from the agent, as stuff like inotify-triggered - * changes to connection's backing config files will blow them away if - * they're in the main connection. - */ - update_agent_secrets_cache (self, info->new_settings); - - /* New secrets, allow autoconnection again */ - if ( nm_settings_connection_autoconnect_blocked_reason_set (self, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, FALSE) - && !nm_settings_connection_autoconnect_blocked_reason_get (self)) - nm_settings_connection_autoconnect_retries_reset (self); - } - } - - if (info->new_settings) { - if (nm_audit_manager_audit_enabled (nm_audit_manager_get ())) { - gs_unref_hashtable GHashTable *diff = NULL; - gboolean same; - - same = nm_connection_diff (nm_settings_connection_get_connection (self), info->new_settings, - NM_SETTING_COMPARE_FLAG_EXACT | - NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT, - &diff); - if (!same && diff) - info->audit_args = nm_utils_format_con_diff_for_audit (diff); - } - } - - nm_assert ( !NM_FLAGS_ANY (info->flags, _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES) - || nm_utils_is_power_of_two (info->flags & _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES)); - - if (NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_TO_DISK)) - persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK; - else if (NM_FLAGS_ANY (info->flags, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY)) - persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY; - else if (NM_FLAGS_ANY (info->flags, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED)) - persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED; - else if (NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY)) { - persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY; - } else - persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP; - - nm_settings_connection_update (self, - info->new_settings, - persist_mode, - ( NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_VOLATILE) - ? NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - : NM_SETTINGS_CONNECTION_INT_FLAGS_NONE), - NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL, - NM_SETTINGS_CONNECTION_UPDATE_REASON_FORCE_RENAME - | ( NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY) - ? NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE - : NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL) - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS - | ( NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT) - ? NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT - : NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE), - "update-from-dbus", - &local); - - if (!local) { - gs_unref_object NMConnection *for_agent = NULL; - - /* Dupe the connection so we can clear out non-agent-owned secrets, - * as agent-owned secrets are the only ones we send back be saved. - * Only send secrets to agents of the same UID that called update too. - */ - for_agent = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self)); - _nm_connection_clear_secrets_by_secret_flags (for_agent, - NM_SETTING_SECRET_FLAG_AGENT_OWNED); - nm_agent_manager_save_secrets (info->agent_mgr, - nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), - for_agent, - info->subject); - } - - /* Reset auto retries back to default since connection was updated */ - nm_settings_connection_autoconnect_retries_reset (self); - - update_complete (self, info, local); +update_auth_cb(NMSettingsConnection * self, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + GError * error, + gpointer data) +{ + NMSettingsConnectionPrivate *priv; + UpdateInfo * info = data; + gs_free_error GError * local = NULL; + NMSettingsConnectionPersistMode persist_mode; + + if (error) { + update_complete(self, info, error); + return; + } + + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + + if (info->new_settings) { + if (!_nm_connection_aggregate(info->new_settings, + NM_CONNECTION_AGGREGATE_ANY_SECRETS, + NULL)) { + /* If the new connection has no secrets, we do not want to remove all + * secrets, rather we keep all the existing ones. Do that by merging + * them in to the new connection. + */ + if (priv->agent_secrets) + nm_connection_update_secrets(info->new_settings, NULL, priv->agent_secrets, NULL); + if (priv->system_secrets) + nm_connection_update_secrets(info->new_settings, NULL, priv->system_secrets, NULL); + } else { + /* Cache the new secrets from the agent, as stuff like inotify-triggered + * changes to connection's backing config files will blow them away if + * they're in the main connection. + */ + update_agent_secrets_cache(self, info->new_settings); + + /* New secrets, allow autoconnection again */ + if (nm_settings_connection_autoconnect_blocked_reason_set( + self, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, + FALSE) + && !nm_settings_connection_autoconnect_blocked_reason_get(self)) + nm_settings_connection_autoconnect_retries_reset(self); + } + } + + if (info->new_settings) { + if (nm_audit_manager_audit_enabled(nm_audit_manager_get())) { + gs_unref_hashtable GHashTable *diff = NULL; + gboolean same; + + same = nm_connection_diff(nm_settings_connection_get_connection(self), + info->new_settings, + NM_SETTING_COMPARE_FLAG_EXACT + | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT, + &diff); + if (!same && diff) + info->audit_args = nm_utils_format_con_diff_for_audit(diff); + } + } + + nm_assert( + !NM_FLAGS_ANY(info->flags, _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES) + || nm_utils_is_power_of_two(info->flags & _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES)); + + if (NM_FLAGS_HAS(info->flags, NM_SETTINGS_UPDATE2_FLAG_TO_DISK)) + persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK; + else if (NM_FLAGS_ANY(info->flags, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY)) + persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY; + else if (NM_FLAGS_ANY(info->flags, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED)) + persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED; + else if (NM_FLAGS_HAS(info->flags, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY)) { + persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY; + } else + persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP; + + nm_settings_connection_update( + self, + info->new_settings, + persist_mode, + (NM_FLAGS_HAS(info->flags, NM_SETTINGS_UPDATE2_FLAG_VOLATILE) + ? NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + : NM_SETTINGS_CONNECTION_INT_FLAGS_NONE), + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL, + NM_SETTINGS_CONNECTION_UPDATE_REASON_FORCE_RENAME + | (NM_FLAGS_HAS(info->flags, NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY) + ? NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE + : NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL) + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS + | (NM_FLAGS_HAS(info->flags, NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT) + ? NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT + : NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE), + "update-from-dbus", + &local); + + if (!local) { + gs_unref_object NMConnection *for_agent = NULL; + + /* Dupe the connection so we can clear out non-agent-owned secrets, + * as agent-owned secrets are the only ones we send back be saved. + * Only send secrets to agents of the same UID that called update too. + */ + for_agent = nm_simple_connection_new_clone(nm_settings_connection_get_connection(self)); + _nm_connection_clear_secrets_by_secret_flags(for_agent, NM_SETTING_SECRET_FLAG_AGENT_OWNED); + nm_agent_manager_save_secrets(info->agent_mgr, + nm_dbus_object_get_path(NM_DBUS_OBJECT(self)), + for_agent, + info->subject); + } + + /* Reset auto retries back to default since connection was updated */ + nm_settings_connection_autoconnect_retries_reset(self); + + update_complete(self, info, local); } static const char * -get_update_modify_permission (NMConnection *old, NMConnection *new) +get_update_modify_permission(NMConnection *old, NMConnection *new) { - NMSettingConnection *s_con; - guint32 orig_num = 0, new_num = 0; + NMSettingConnection *s_con; + guint32 orig_num = 0, new_num = 0; - s_con = nm_connection_get_setting_connection (old); - orig_num = nm_setting_connection_get_num_permissions (s_con); + s_con = nm_connection_get_setting_connection(old); + orig_num = nm_setting_connection_get_num_permissions(s_con); - s_con = nm_connection_get_setting_connection (new); - new_num = nm_setting_connection_get_num_permissions (s_con); + s_con = nm_connection_get_setting_connection(new); + new_num = nm_setting_connection_get_num_permissions(s_con); - /* If the caller is the only user in either connection's permissions, then - * we use the 'modify.own' permission instead of 'modify.system'. - */ - if (orig_num == 1 && new_num == 1) - return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + /* If the caller is the only user in either connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. + */ + if (orig_num == 1 && new_num == 1) + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; - /* If the update request affects more than just the caller (ie if the old - * settings were system-wide, or the new ones are), require 'modify.system'. - */ - return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; + /* If the update request affects more than just the caller (ie if the old + * settings were system-wide, or the new ones are), require 'modify.system'. + */ + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; } static void -settings_connection_update (NMSettingsConnection *self, - gboolean is_update2, - GDBusMethodInvocation *context, - GVariant *new_settings, - NMSettingsUpdate2Flags flags) -{ - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - NMAuthSubject *subject = NULL; - NMConnection *tmp = NULL; - GError *error = NULL; - UpdateInfo *info; - const char *permission; - - /* Check if the settings are valid first */ - if (new_settings) { - if (!g_variant_is_of_type (new_settings, NM_VARIANT_TYPE_CONNECTION)) { - g_set_error_literal (&error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_ARGUMENTS, - "settings is of invalid type"); - goto error; - } - - if (g_variant_n_children (new_settings) > 0) { - tmp = _nm_simple_connection_new_from_dbus (new_settings, - NM_SETTING_PARSE_FLAGS_STRICT - | NM_SETTING_PARSE_FLAGS_NORMALIZE, - &error); - if (!tmp) - goto error; - - if (!nm_connection_verify_secrets (tmp, &error)) - goto error; - } - } - - subject = _new_auth_subject (context, &error); - if (!subject) - goto error; - - /* And that the new connection settings will be visible to the user - * that's sending the update request. You can't make a connection - * invisible to yourself. - */ - if (!nm_auth_is_subject_in_acl_set_error (tmp ?: nm_settings_connection_get_connection (self), - subject, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - &error)) - goto error; - - info = g_slice_new0 (UpdateInfo); - info->is_update2 = is_update2; - info->context = context; - info->agent_mgr = g_object_ref (priv->agent_mgr); - info->subject = subject; - info->flags = flags; - info->new_settings = tmp; - - permission = get_update_modify_permission (nm_settings_connection_get_connection (self), - tmp ?: nm_settings_connection_get_connection (self)); - auth_start (self, context, subject, permission, update_auth_cb, info); - return; +settings_connection_update(NMSettingsConnection * self, + gboolean is_update2, + GDBusMethodInvocation *context, + GVariant * new_settings, + NMSettingsUpdate2Flags flags) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + NMAuthSubject * subject = NULL; + NMConnection * tmp = NULL; + GError * error = NULL; + UpdateInfo * info; + const char * permission; + + /* Check if the settings are valid first */ + if (new_settings) { + if (!g_variant_is_of_type(new_settings, NM_VARIANT_TYPE_CONNECTION)) { + g_set_error_literal(&error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_ARGUMENTS, + "settings is of invalid type"); + goto error; + } + + if (g_variant_n_children(new_settings) > 0) { + tmp = _nm_simple_connection_new_from_dbus(new_settings, + NM_SETTING_PARSE_FLAGS_STRICT + | NM_SETTING_PARSE_FLAGS_NORMALIZE, + &error); + if (!tmp) + goto error; + + if (!nm_connection_verify_secrets(tmp, &error)) + goto error; + } + } + + subject = _new_auth_subject(context, &error); + if (!subject) + goto error; + + /* And that the new connection settings will be visible to the user + * that's sending the update request. You can't make a connection + * invisible to yourself. + */ + if (!nm_auth_is_subject_in_acl_set_error(tmp ?: nm_settings_connection_get_connection(self), + subject, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + &error)) + goto error; + + info = g_slice_new0(UpdateInfo); + info->is_update2 = is_update2; + info->context = context; + info->agent_mgr = g_object_ref(priv->agent_mgr); + info->subject = subject; + info->flags = flags; + info->new_settings = tmp; + + permission = get_update_modify_permission(nm_settings_connection_get_connection(self), + tmp ?: nm_settings_connection_get_connection(self)); + auth_start(self, context, subject, permission, update_auth_cb, info); + return; error: - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, FALSE, NULL, subject, - error->message); + nm_audit_log_connection_op(NM_AUDIT_OP_CONN_UPDATE, self, FALSE, NULL, subject, error->message); - g_clear_object (&tmp); - g_clear_object (&subject); + g_clear_object(&tmp); + g_clear_object(&subject); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error(context, error); } static void -impl_settings_connection_update (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_connection_update(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); - gs_unref_variant GVariant *settings = NULL; + NMSettingsConnection *self = NM_SETTINGS_CONNECTION(obj); + gs_unref_variant GVariant *settings = NULL; - g_variant_get (parameters, "(@a{sa{sv}})", &settings); - settings_connection_update (self, FALSE, invocation, settings, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); + g_variant_get(parameters, "(@a{sa{sv}})", &settings); + settings_connection_update(self, FALSE, invocation, settings, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); } static void -impl_settings_connection_update_unsaved (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_connection_update_unsaved(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); - gs_unref_variant GVariant *settings = NULL; + NMSettingsConnection *self = NM_SETTINGS_CONNECTION(obj); + gs_unref_variant GVariant *settings = NULL; - g_variant_get (parameters, "(@a{sa{sv}})", &settings); - settings_connection_update (self, FALSE, invocation, settings, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY); + g_variant_get(parameters, "(@a{sa{sv}})", &settings); + settings_connection_update(self, + FALSE, + invocation, + settings, + NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY); } static void -impl_settings_connection_save (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_connection_save(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); + NMSettingsConnection *self = NM_SETTINGS_CONNECTION(obj); - settings_connection_update (self, FALSE, invocation, NULL, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); + settings_connection_update(self, FALSE, invocation, NULL, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); } static void -impl_settings_connection_update2 (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); - gs_unref_variant GVariant *settings = NULL; - gs_unref_variant GVariant *args = NULL; - guint32 flags_u; - GError *error = NULL; - GVariantIter iter; - const char *args_name; - NMSettingsUpdate2Flags flags; - - g_variant_get (parameters, "(@a{sa{sv}}u@a{sv})", &settings, &flags_u, &args); - - if (NM_FLAGS_ANY (flags_u, ~((guint32) ( _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES - | NM_SETTINGS_UPDATE2_FLAG_VOLATILE - | NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT - | NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY)))) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_ARGUMENTS, - "Unknown flags"); - g_dbus_method_invocation_take_error (invocation, error); - return; - } - - flags = (NMSettingsUpdate2Flags) flags_u; - - if ( ( NM_FLAGS_ANY (flags, _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES) - && !nm_utils_is_power_of_two (flags & _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES)) - || ( NM_FLAGS_HAS (flags, NM_SETTINGS_UPDATE2_FLAG_VOLATILE) - && !NM_FLAGS_ANY (flags, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY - | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED - | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY))) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_ARGUMENTS, - "Conflicting flags"); - g_dbus_method_invocation_take_error (invocation, error); - return; - } - - nm_assert (g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}"))); - - g_variant_iter_init (&iter, args); - while (g_variant_iter_next (&iter, "{&sv}", &args_name, NULL)) { - error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_ARGUMENTS, - "Unsupported argument '%s'", args_name); - g_dbus_method_invocation_take_error (invocation, error); - return; - } - - settings_connection_update (self, - TRUE, - invocation, - settings, - flags); +impl_settings_connection_update2(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION(obj); + gs_unref_variant GVariant *settings = NULL; + gs_unref_variant GVariant *args = NULL; + guint32 flags_u; + GError * error = NULL; + GVariantIter iter; + const char * args_name; + NMSettingsUpdate2Flags flags; + + g_variant_get(parameters, "(@a{sa{sv}}u@a{sv})", &settings, &flags_u, &args); + + if (NM_FLAGS_ANY(flags_u, + ~((guint32)(_NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES + | NM_SETTINGS_UPDATE2_FLAG_VOLATILE + | NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT + | NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY)))) { + error = g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_ARGUMENTS, + "Unknown flags"); + g_dbus_method_invocation_take_error(invocation, error); + return; + } + + flags = (NMSettingsUpdate2Flags) flags_u; + + if ((NM_FLAGS_ANY(flags, _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES) + && !nm_utils_is_power_of_two(flags & _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES)) + || (NM_FLAGS_HAS(flags, NM_SETTINGS_UPDATE2_FLAG_VOLATILE) + && !NM_FLAGS_ANY(flags, + NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY + | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED + | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY))) { + error = g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_ARGUMENTS, + "Conflicting flags"); + g_dbus_method_invocation_take_error(invocation, error); + return; + } + + nm_assert(g_variant_is_of_type(args, G_VARIANT_TYPE("a{sv}"))); + + g_variant_iter_init(&iter, args); + while (g_variant_iter_next(&iter, "{&sv}", &args_name, NULL)) { + error = g_error_new(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_ARGUMENTS, + "Unsupported argument '%s'", + args_name); + g_dbus_method_invocation_take_error(invocation, error); + return; + } + + settings_connection_update(self, TRUE, invocation, settings, flags); } static void -delete_auth_cb (NMSettingsConnection *self, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer data) +delete_auth_cb(NMSettingsConnection * self, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + GError * error, + gpointer data) { - gs_unref_object NMSettingsConnection *self_keep_alive = NULL; + gs_unref_object NMSettingsConnection *self_keep_alive = NULL; - self_keep_alive = g_object_ref (self); + self_keep_alive = g_object_ref(self); - if (error) { - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, NULL, subject, - error->message); - g_dbus_method_invocation_return_gerror (context, error); - return; - } + if (error) { + nm_audit_log_connection_op(NM_AUDIT_OP_CONN_DELETE, + self, + FALSE, + NULL, + subject, + error->message); + g_dbus_method_invocation_return_gerror(context, error); + return; + } - nm_settings_connection_delete (self, TRUE); + nm_settings_connection_delete(self, TRUE); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, - TRUE, NULL, subject, NULL); - g_dbus_method_invocation_return_value (context, NULL); + nm_audit_log_connection_op(NM_AUDIT_OP_CONN_DELETE, self, TRUE, NULL, subject, NULL); + g_dbus_method_invocation_return_value(context, NULL); } static const char * -get_modify_permission_basic (NMSettingsConnection *self) +get_modify_permission_basic(NMSettingsConnection *self) { - NMSettingConnection *s_con; + NMSettingConnection *s_con; - /* If the caller is the only user in the connection's permissions, then - * we use the 'modify.own' permission instead of 'modify.system'. If the - * request affects more than just the caller, require 'modify.system'. - */ - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (self)); - if (nm_setting_connection_get_num_permissions (s_con) == 1) - return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + /* If the caller is the only user in the connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. If the + * request affects more than just the caller, require 'modify.system'. + */ + s_con = nm_connection_get_setting_connection(nm_settings_connection_get_connection(self)); + if (nm_setting_connection_get_num_permissions(s_con) == 1) + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; - return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; } static void -impl_settings_connection_delete (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); - gs_unref_object NMAuthSubject *subject = NULL; - GError *error = NULL; - - nm_assert (nm_settings_connection_still_valid (self)); - - subject = _new_auth_subject (invocation, &error); - if (!subject) - goto err; - - auth_start (self, invocation, subject, get_modify_permission_basic (self), delete_auth_cb, NULL); - return; +impl_settings_connection_delete(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION(obj); + gs_unref_object NMAuthSubject *subject = NULL; + GError * error = NULL; + + nm_assert(nm_settings_connection_still_valid(self)); + + subject = _new_auth_subject(invocation, &error); + if (!subject) + goto err; + + auth_start(self, invocation, subject, get_modify_permission_basic(self), delete_auth_cb, NULL); + return; err: - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, NULL, subject, error->message); - g_dbus_method_invocation_take_error (invocation, error); + nm_audit_log_connection_op(NM_AUDIT_OP_CONN_DELETE, self, FALSE, NULL, subject, error->message); + g_dbus_method_invocation_take_error(invocation, error); } /*****************************************************************************/ static void -dbus_get_agent_secrets_cb (NMSettingsConnection *self, - NMSettingsConnectionCallId *call_id, - const char *agent_username, - const char *setting_name, - GError *error, - gpointer user_data) -{ - GDBusMethodInvocation *context = user_data; - GVariant *dict; - - if (error) - g_dbus_method_invocation_return_gerror (context, error); - else { - /* Return secrets from agent and backing storage to the D-Bus caller; - * nm_settings_connection_get_secrets() will have updated itself with - * secrets from backing storage and those returned from the agent - * by the time we get here. - */ - dict = nm_connection_to_dbus (nm_settings_connection_get_connection (self), NM_CONNECTION_SERIALIZE_ONLY_SECRETS); - if (!dict) - dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); - g_dbus_method_invocation_return_value (context, g_variant_new ("(@a{sa{sv}})", dict)); - } +dbus_get_agent_secrets_cb(NMSettingsConnection * self, + NMSettingsConnectionCallId *call_id, + const char * agent_username, + const char * setting_name, + GError * error, + gpointer user_data) +{ + GDBusMethodInvocation *context = user_data; + GVariant * dict; + + if (error) + g_dbus_method_invocation_return_gerror(context, error); + else { + /* Return secrets from agent and backing storage to the D-Bus caller; + * nm_settings_connection_get_secrets() will have updated itself with + * secrets from backing storage and those returned from the agent + * by the time we get here. + */ + dict = nm_connection_to_dbus(nm_settings_connection_get_connection(self), + NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (!dict) + dict = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0); + g_dbus_method_invocation_return_value(context, g_variant_new("(@a{sa{sv}})", dict)); + } } static void -dbus_get_secrets_auth_cb (NMSettingsConnection *self, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer user_data) +dbus_get_secrets_auth_cb(NMSettingsConnection * self, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + GError * error, + gpointer user_data) { - char *setting_name = user_data; + char *setting_name = user_data; - if (!error) { - nm_settings_connection_get_secrets (self, - NULL, - subject, - setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED - | NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS, - NULL, - dbus_get_agent_secrets_cb, - context); - } + if (!error) { + nm_settings_connection_get_secrets(self, + NULL, + subject, + setting_name, + NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED + | NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS, + NULL, + dbus_get_agent_secrets_cb, + context); + } - if (error) - g_dbus_method_invocation_return_gerror (context, error); + if (error) + g_dbus_method_invocation_return_gerror(context, error); - g_free (setting_name); + g_free(setting_name); } static void -impl_settings_connection_get_secrets (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); - gs_unref_object NMAuthSubject *subject = NULL; - GError *error = NULL; - const char *setting_name; - - subject = _new_auth_subject (invocation, &error); - if (!subject) { - g_dbus_method_invocation_take_error (invocation, error); - return; - } - - g_variant_get (parameters, "(&s)", &setting_name); - - auth_start (self, - invocation, - subject, - get_modify_permission_basic (self), - dbus_get_secrets_auth_cb, - g_strdup (setting_name)); +impl_settings_connection_get_secrets(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION(obj); + gs_unref_object NMAuthSubject *subject = NULL; + GError * error = NULL; + const char * setting_name; + + subject = _new_auth_subject(invocation, &error); + if (!subject) { + g_dbus_method_invocation_take_error(invocation, error); + return; + } + + g_variant_get(parameters, "(&s)", &setting_name); + + auth_start(self, + invocation, + subject, + get_modify_permission_basic(self), + dbus_get_secrets_auth_cb, + g_strdup(setting_name)); } static void -dbus_clear_secrets_auth_cb (NMSettingsConnection *self, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer user_data) -{ - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - gs_free_error GError *local = NULL; - - if (error) { - g_dbus_method_invocation_return_gerror (context, error); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self, - FALSE, NULL, subject, error->message); - return; - } - - nm_settings_connection_clear_secrets (self, TRUE, TRUE); - - /* Tell agents to remove secrets for this connection */ - nm_agent_manager_delete_secrets (priv->agent_mgr, - nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), - nm_settings_connection_get_connection (self)); - - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self, - !local, NULL, subject, local ? local->message : NULL); - - if (local) - g_dbus_method_invocation_return_gerror (context, local); - else - g_dbus_method_invocation_return_value (context, NULL); +dbus_clear_secrets_auth_cb(NMSettingsConnection * self, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + GError * error, + gpointer user_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + gs_free_error GError *local = NULL; + + if (error) { + g_dbus_method_invocation_return_gerror(context, error); + nm_audit_log_connection_op(NM_AUDIT_OP_CONN_CLEAR_SECRETS, + self, + FALSE, + NULL, + subject, + error->message); + return; + } + + nm_settings_connection_clear_secrets(self, TRUE, TRUE); + + /* Tell agents to remove secrets for this connection */ + nm_agent_manager_delete_secrets(priv->agent_mgr, + nm_dbus_object_get_path(NM_DBUS_OBJECT(self)), + nm_settings_connection_get_connection(self)); + + nm_audit_log_connection_op(NM_AUDIT_OP_CONN_CLEAR_SECRETS, + self, + !local, + NULL, + subject, + local ? local->message : NULL); + + if (local) + g_dbus_method_invocation_return_gerror(context, local); + else + g_dbus_method_invocation_return_value(context, NULL); } static void -impl_settings_connection_clear_secrets (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); - gs_unref_object NMAuthSubject *subject = NULL; - GError *error = NULL; - - subject = _new_auth_subject (invocation, &error); - if (!subject) { - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self, - FALSE, NULL, NULL, error->message); - g_dbus_method_invocation_take_error (invocation, error); - return; - } - auth_start (self, - invocation, - subject, - get_modify_permission_basic (self), - dbus_clear_secrets_auth_cb, - NULL); +impl_settings_connection_clear_secrets(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION(obj); + gs_unref_object NMAuthSubject *subject = NULL; + GError * error = NULL; + + subject = _new_auth_subject(invocation, &error); + if (!subject) { + nm_audit_log_connection_op(NM_AUDIT_OP_CONN_CLEAR_SECRETS, + self, + FALSE, + NULL, + NULL, + error->message); + g_dbus_method_invocation_take_error(invocation, error); + return; + } + auth_start(self, + invocation, + subject, + get_modify_permission_basic(self), + dbus_clear_secrets_auth_cb, + NULL); } /*****************************************************************************/ void -_nm_settings_connection_emit_dbus_signal_updated (NMSettingsConnection *self) +_nm_settings_connection_emit_dbus_signal_updated(NMSettingsConnection *self) { - nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), - &interface_info_settings_connection, - &signal_info_updated, - "()"); + nm_dbus_object_emit_signal(NM_DBUS_OBJECT(self), + &interface_info_settings_connection, + &signal_info_updated, + "()"); } void -_nm_settings_connection_emit_dbus_signal_removed (NMSettingsConnection *self) +_nm_settings_connection_emit_dbus_signal_removed(NMSettingsConnection *self) { - nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), - &interface_info_settings_connection, - &signal_info_removed, - "()"); + nm_dbus_object_emit_signal(NM_DBUS_OBJECT(self), + &interface_info_settings_connection, + &signal_info_removed, + "()"); } void -_nm_settings_connection_emit_signal_updated_internal (NMSettingsConnection *self, - NMSettingsConnectionUpdateReason update_reason) +_nm_settings_connection_emit_signal_updated_internal(NMSettingsConnection * self, + NMSettingsConnectionUpdateReason update_reason) { - g_signal_emit (self, signals[UPDATED_INTERNAL], 0, (guint) update_reason); + g_signal_emit(self, signals[UPDATED_INTERNAL], 0, (guint) update_reason); } /*****************************************************************************/ -static -NM_UTILS_FLAGS2STR_DEFINE (_settings_connection_flags_to_string, NMSettingsConnectionIntFlags, - NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, "none"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED, "unsaved"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, "nm-generated"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE, "volatile"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE, "visible"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL, "external"), -); +static NM_UTILS_FLAGS2STR_DEFINE( + _settings_connection_flags_to_string, + NMSettingsConnectionIntFlags, + NM_UTILS_FLAGS2STR(NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, "none"), + NM_UTILS_FLAGS2STR(NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED, "unsaved"), + NM_UTILS_FLAGS2STR(NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, "nm-generated"), + NM_UTILS_FLAGS2STR(NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE, "volatile"), + NM_UTILS_FLAGS2STR(NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE, "visible"), + NM_UTILS_FLAGS2STR(NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL, "external"), ); NMSettingsConnectionIntFlags -nm_settings_connection_get_flags (NMSettingsConnection *self) +nm_settings_connection_get_flags(NMSettingsConnection *self) { - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_INT_FLAGS_NONE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), NM_SETTINGS_CONNECTION_INT_FLAGS_NONE); - return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->flags; + return NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->flags; } NMSettingsConnectionIntFlags -nm_settings_connection_set_flags_full (NMSettingsConnection *self, - NMSettingsConnectionIntFlags mask, - NMSettingsConnectionIntFlags value) +nm_settings_connection_set_flags_full(NMSettingsConnection * self, + NMSettingsConnectionIntFlags mask, + NMSettingsConnectionIntFlags value) { - NMSettingsConnectionPrivate *priv; - NMSettingsConnectionIntFlags old_flags; + NMSettingsConnectionPrivate *priv; + NMSettingsConnectionIntFlags old_flags; - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_INT_FLAGS_NONE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), NM_SETTINGS_CONNECTION_INT_FLAGS_NONE); - nm_assert (!NM_FLAGS_ANY (mask, ~_NM_SETTINGS_CONNECTION_INT_FLAGS_ALL)); - nm_assert (!NM_FLAGS_ANY (value, ~mask)); + nm_assert(!NM_FLAGS_ANY(mask, ~_NM_SETTINGS_CONNECTION_INT_FLAGS_ALL)); + nm_assert(!NM_FLAGS_ANY(value, ~mask)); - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - value = (priv->flags & ~mask) | value; + value = (priv->flags & ~mask) | value; - old_flags = priv->flags; - if (old_flags != value) { - gboolean notify_unsaved = FALSE; - char buf1[255], buf2[255]; + old_flags = priv->flags; + if (old_flags != value) { + gboolean notify_unsaved = FALSE; + char buf1[255], buf2[255]; - _LOGT ("update settings-connection flags to %s (was %s)", - _settings_connection_flags_to_string (value, buf1, sizeof (buf1)), - _settings_connection_flags_to_string (priv->flags, buf2, sizeof (buf2))); - priv->flags = value; - nm_assert (priv->flags == value); + _LOGT("update settings-connection flags to %s (was %s)", + _settings_connection_flags_to_string(value, buf1, sizeof(buf1)), + _settings_connection_flags_to_string(priv->flags, buf2, sizeof(buf2))); + priv->flags = value; + nm_assert(priv->flags == value); - if (NM_FLAGS_HAS (old_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED) != NM_FLAGS_HAS (value, NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED)) { - g_object_freeze_notify (G_OBJECT (self)); - _notify (self, PROP_UNSAVED); - notify_unsaved = TRUE; - } - _notify (self, PROP_FLAGS); - if (notify_unsaved) - g_object_thaw_notify (G_OBJECT (self)); + if (NM_FLAGS_HAS(old_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED) + != NM_FLAGS_HAS(value, NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED)) { + g_object_freeze_notify(G_OBJECT(self)); + _notify(self, PROP_UNSAVED); + notify_unsaved = TRUE; + } + _notify(self, PROP_FLAGS); + if (notify_unsaved) + g_object_thaw_notify(G_OBJECT(self)); - g_signal_emit (self, signals[FLAGS_CHANGED], 0); - } - return old_flags; + g_signal_emit(self, signals[FLAGS_CHANGED], 0); + } + return old_flags; } /*****************************************************************************/ static int -_cmp_timestamp (NMSettingsConnection *a, NMSettingsConnection *b) +_cmp_timestamp(NMSettingsConnection *a, NMSettingsConnection *b) { - gboolean a_has_ts, b_has_ts; - guint64 ats = 0, bts = 0; + gboolean a_has_ts, b_has_ts; + guint64 ats = 0, bts = 0; - nm_assert (NM_IS_SETTINGS_CONNECTION (a)); - nm_assert (NM_IS_SETTINGS_CONNECTION (b)); + nm_assert(NM_IS_SETTINGS_CONNECTION(a)); + nm_assert(NM_IS_SETTINGS_CONNECTION(b)); - a_has_ts = !!nm_settings_connection_get_timestamp (a, &ats); - b_has_ts = !!nm_settings_connection_get_timestamp (b, &bts); - if (a_has_ts != b_has_ts) - return a_has_ts ? -1 : 1; - if (a_has_ts && ats != bts) - return (ats > bts) ? -1 : 1; - return 0; + a_has_ts = !!nm_settings_connection_get_timestamp(a, &ats); + b_has_ts = !!nm_settings_connection_get_timestamp(b, &bts); + if (a_has_ts != b_has_ts) + return a_has_ts ? -1 : 1; + if (a_has_ts && ats != bts) + return (ats > bts) ? -1 : 1; + return 0; } static int -_cmp_last_resort (NMSettingsConnection *a, NMSettingsConnection *b) +_cmp_last_resort(NMSettingsConnection *a, NMSettingsConnection *b) { - NM_CMP_DIRECT_STRCMP0 (nm_settings_connection_get_uuid (a), - nm_settings_connection_get_uuid (b)); + NM_CMP_DIRECT_STRCMP0(nm_settings_connection_get_uuid(a), nm_settings_connection_get_uuid(b)); - /* hm, same UUID. Use their pointer value to give them a stable - * order. */ - return (a > b) ? -1 : 1; + /* hm, same UUID. Use their pointer value to give them a stable + * order. */ + return (a > b) ? -1 : 1; } /* sorting for "best" connections. @@ -2119,39 +2151,45 @@ _cmp_last_resort (NMSettingsConnection *a, NMSettingsConnection *b) * a newer one. */ int -nm_settings_connection_cmp_timestamp (NMSettingsConnection *a, NMSettingsConnection *b) +nm_settings_connection_cmp_timestamp(NMSettingsConnection *a, NMSettingsConnection *b) { - NM_CMP_SELF (a, b); + NM_CMP_SELF(a, b); - NM_CMP_RETURN (_cmp_timestamp (a, b)); - NM_CMP_RETURN (nm_utils_cmp_connection_by_autoconnect_priority (nm_settings_connection_get_connection (a), - nm_settings_connection_get_connection (b))); - return _cmp_last_resort (a, b); + NM_CMP_RETURN(_cmp_timestamp(a, b)); + NM_CMP_RETURN( + nm_utils_cmp_connection_by_autoconnect_priority(nm_settings_connection_get_connection(a), + nm_settings_connection_get_connection(b))); + return _cmp_last_resort(a, b); } int -nm_settings_connection_cmp_timestamp_p_with_data (gconstpointer pa, gconstpointer pb, gpointer user_data) +nm_settings_connection_cmp_timestamp_p_with_data(gconstpointer pa, + gconstpointer pb, + gpointer user_data) { - return nm_settings_connection_cmp_timestamp (*((NMSettingsConnection **) pa), - *((NMSettingsConnection **) pb)); + return nm_settings_connection_cmp_timestamp(*((NMSettingsConnection **) pa), + *((NMSettingsConnection **) pb)); } int -nm_settings_connection_cmp_autoconnect_priority (NMSettingsConnection *a, NMSettingsConnection *b) +nm_settings_connection_cmp_autoconnect_priority(NMSettingsConnection *a, NMSettingsConnection *b) { - if (a == b) - return 0; - NM_CMP_RETURN (nm_utils_cmp_connection_by_autoconnect_priority (nm_settings_connection_get_connection (a), - nm_settings_connection_get_connection (b))); - NM_CMP_RETURN (_cmp_timestamp (a, b)); - return _cmp_last_resort (a, b); + if (a == b) + return 0; + NM_CMP_RETURN( + nm_utils_cmp_connection_by_autoconnect_priority(nm_settings_connection_get_connection(a), + nm_settings_connection_get_connection(b))); + NM_CMP_RETURN(_cmp_timestamp(a, b)); + return _cmp_last_resort(a, b); } int -nm_settings_connection_cmp_autoconnect_priority_p_with_data (gconstpointer pa, gconstpointer pb, gpointer user_data) +nm_settings_connection_cmp_autoconnect_priority_p_with_data(gconstpointer pa, + gconstpointer pb, + gpointer user_data) { - return nm_settings_connection_cmp_autoconnect_priority (*((NMSettingsConnection **) pa), - *((NMSettingsConnection **) pb)); + return nm_settings_connection_cmp_autoconnect_priority(*((NMSettingsConnection **) pa), + *((NMSettingsConnection **) pb)); } /*****************************************************************************/ @@ -2167,16 +2205,15 @@ nm_settings_connection_cmp_autoconnect_priority_p_with_data (gconstpointer pa, g * Returns: %TRUE if the timestamp has ever been set, otherwise %FALSE. **/ gboolean -nm_settings_connection_get_timestamp (NMSettingsConnection *self, - guint64 *out_timestamp) +nm_settings_connection_get_timestamp(NMSettingsConnection *self, guint64 *out_timestamp) { - NMSettingsConnectionPrivate *priv; + NMSettingsConnectionPrivate *priv; - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), FALSE); - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - NM_SET_OUT (out_timestamp, priv->timestamp); - return priv->timestamp_set; + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + NM_SET_OUT(out_timestamp, priv->timestamp); + return priv->timestamp_set; } /** @@ -2188,118 +2225,117 @@ nm_settings_connection_get_timestamp (NMSettingsConnection *self, * Updates the connection and timestamps database with the provided timestamp. **/ void -nm_settings_connection_update_timestamp (NMSettingsConnection *self, - guint64 timestamp) +nm_settings_connection_update_timestamp(NMSettingsConnection *self, guint64 timestamp) { - NMSettingsConnectionPrivate *priv; - const char *connection_uuid; - char sbuf[60]; + NMSettingsConnectionPrivate *priv; + const char * connection_uuid; + char sbuf[60]; - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); + g_return_if_fail(NM_IS_SETTINGS_CONNECTION(self)); - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - if ( priv->timestamp == timestamp - && priv->timestamp_set) - return; + if (priv->timestamp == timestamp && priv->timestamp_set) + return; - priv->timestamp = timestamp; - priv->timestamp_set = TRUE; + priv->timestamp = timestamp; + priv->timestamp_set = TRUE; - _LOGT ("timestamp: set timestamp %"G_GUINT64_FORMAT, - timestamp); + _LOGT("timestamp: set timestamp %" G_GUINT64_FORMAT, timestamp); - if (!priv->kf_db_timestamps) - return; + if (!priv->kf_db_timestamps) + return; - connection_uuid = nm_settings_connection_get_uuid (self); - if (connection_uuid) { - nm_key_file_db_set_value (priv->kf_db_timestamps, - connection_uuid, - nm_sprintf_buf (sbuf, "%" G_GUINT64_FORMAT, timestamp)); - } + connection_uuid = nm_settings_connection_get_uuid(self); + if (connection_uuid) { + nm_key_file_db_set_value(priv->kf_db_timestamps, + connection_uuid, + nm_sprintf_buf(sbuf, "%" G_GUINT64_FORMAT, timestamp)); + } } void -_nm_settings_connection_register_kf_dbs (NMSettingsConnection *self, - NMKeyFileDB *kf_db_timestamps, - NMKeyFileDB *kf_db_seen_bssids) -{ - NMSettingsConnectionPrivate *priv; - const char *connection_uuid; - - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); - g_return_if_fail (kf_db_timestamps); - g_return_if_fail (kf_db_seen_bssids); - - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - - connection_uuid = nm_settings_connection_get_uuid (self); - - if (priv->kf_db_timestamps != kf_db_timestamps) { - gs_free char *tmp_str = NULL; - guint64 timestamp; - - nm_key_file_db_unref (priv->kf_db_timestamps); - priv->kf_db_timestamps = nm_key_file_db_ref (kf_db_timestamps); - - tmp_str = nm_key_file_db_get_value (priv->kf_db_timestamps, connection_uuid); - - timestamp = _nm_utils_ascii_str_to_uint64 (tmp_str, 10, 0, G_MAXUINT64, G_MAXUINT64); - if (timestamp != G_MAXUINT64) { - priv->timestamp = timestamp; - priv->timestamp_set = TRUE; - _LOGT ("timestamp: read timestamp %"G_GUINT64_FORMAT" from keyfile database \"%s\"", - timestamp, nm_key_file_db_get_filename (priv->kf_db_timestamps)); - } else - _LOGT ("timestamp: no timestamp from keyfile database \"%s\"", - nm_key_file_db_get_filename (priv->kf_db_timestamps)); - } - - if (priv->kf_db_seen_bssids != kf_db_seen_bssids) { - gs_strfreev char **tmp_strv = NULL; - gsize i, len; - - nm_key_file_db_unref (priv->kf_db_seen_bssids); - priv->kf_db_seen_bssids = nm_key_file_db_ref (kf_db_seen_bssids); - - tmp_strv = nm_key_file_db_get_string_list (priv->kf_db_seen_bssids, connection_uuid, &len); - - nm_clear_pointer (&priv->seen_bssids, g_hash_table_unref); - - if (len > 0) { - _LOGT ("read %zu seen-bssids from keyfile database \"%s\"", - len, - nm_key_file_db_get_filename (priv->kf_db_seen_bssids)); - priv->seen_bssids = _seen_bssids_hash_new (); - for (i = len; i > 0; ) - g_hash_table_add (priv->seen_bssids, g_steal_pointer (&tmp_strv[--i])); - nm_clear_g_free (&tmp_strv); - } else { - NMSettingWireless *s_wifi; - - _LOGT ("no seen-bssids from keyfile database \"%s\"", - nm_key_file_db_get_filename (priv->kf_db_seen_bssids)); - - /* If this connection didn't have an entry in the seen-bssids database, - * maybe this is the first time we've read it in, so populate the - * seen-bssids list from the deprecated seen-bssids property of the - * wifi setting. - */ - s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (self)); - if (s_wifi) { - len = nm_setting_wireless_get_num_seen_bssids (s_wifi); - if (len > 0) { - priv->seen_bssids = _seen_bssids_hash_new (); - for (i = 0; i < len; i++) { - const char *bssid = nm_setting_wireless_get_seen_bssid (s_wifi, i); - - g_hash_table_add (priv->seen_bssids, g_strdup (bssid)); - } - } - } - } - } +_nm_settings_connection_register_kf_dbs(NMSettingsConnection *self, + NMKeyFileDB * kf_db_timestamps, + NMKeyFileDB * kf_db_seen_bssids) +{ + NMSettingsConnectionPrivate *priv; + const char * connection_uuid; + + g_return_if_fail(NM_IS_SETTINGS_CONNECTION(self)); + g_return_if_fail(kf_db_timestamps); + g_return_if_fail(kf_db_seen_bssids); + + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + + connection_uuid = nm_settings_connection_get_uuid(self); + + if (priv->kf_db_timestamps != kf_db_timestamps) { + gs_free char *tmp_str = NULL; + guint64 timestamp; + + nm_key_file_db_unref(priv->kf_db_timestamps); + priv->kf_db_timestamps = nm_key_file_db_ref(kf_db_timestamps); + + tmp_str = nm_key_file_db_get_value(priv->kf_db_timestamps, connection_uuid); + + timestamp = _nm_utils_ascii_str_to_uint64(tmp_str, 10, 0, G_MAXUINT64, G_MAXUINT64); + if (timestamp != G_MAXUINT64) { + priv->timestamp = timestamp; + priv->timestamp_set = TRUE; + _LOGT("timestamp: read timestamp %" G_GUINT64_FORMAT " from keyfile database \"%s\"", + timestamp, + nm_key_file_db_get_filename(priv->kf_db_timestamps)); + } else + _LOGT("timestamp: no timestamp from keyfile database \"%s\"", + nm_key_file_db_get_filename(priv->kf_db_timestamps)); + } + + if (priv->kf_db_seen_bssids != kf_db_seen_bssids) { + gs_strfreev char **tmp_strv = NULL; + gsize i, len; + + nm_key_file_db_unref(priv->kf_db_seen_bssids); + priv->kf_db_seen_bssids = nm_key_file_db_ref(kf_db_seen_bssids); + + tmp_strv = nm_key_file_db_get_string_list(priv->kf_db_seen_bssids, connection_uuid, &len); + + nm_clear_pointer(&priv->seen_bssids, g_hash_table_unref); + + if (len > 0) { + _LOGT("read %zu seen-bssids from keyfile database \"%s\"", + len, + nm_key_file_db_get_filename(priv->kf_db_seen_bssids)); + priv->seen_bssids = _seen_bssids_hash_new(); + for (i = len; i > 0;) + g_hash_table_add(priv->seen_bssids, g_steal_pointer(&tmp_strv[--i])); + nm_clear_g_free(&tmp_strv); + } else { + NMSettingWireless *s_wifi; + + _LOGT("no seen-bssids from keyfile database \"%s\"", + nm_key_file_db_get_filename(priv->kf_db_seen_bssids)); + + /* If this connection didn't have an entry in the seen-bssids database, + * maybe this is the first time we've read it in, so populate the + * seen-bssids list from the deprecated seen-bssids property of the + * wifi setting. + */ + s_wifi = + nm_connection_get_setting_wireless(nm_settings_connection_get_connection(self)); + if (s_wifi) { + len = nm_setting_wireless_get_num_seen_bssids(s_wifi); + if (len > 0) { + priv->seen_bssids = _seen_bssids_hash_new(); + for (i = 0; i < len; i++) { + const char *bssid = nm_setting_wireless_get_seen_bssid(s_wifi, i); + + g_hash_table_add(priv->seen_bssids, g_strdup(bssid)); + } + } + } + } + } } /** @@ -2312,13 +2348,13 @@ _nm_settings_connection_register_kf_dbs (NMSettingsConnection *self, * The caller is responsible for freeing the list, but not the content. **/ const char ** -nm_settings_connection_get_seen_bssids (NMSettingsConnection *self) +nm_settings_connection_get_seen_bssids(NMSettingsConnection *self) { - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), NULL); - return nm_utils_strdict_get_keys (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->seen_bssids, - TRUE, - NULL); + return nm_utils_strdict_get_keys(NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->seen_bssids, + TRUE, + NULL); } /** @@ -2329,18 +2365,17 @@ nm_settings_connection_get_seen_bssids (NMSettingsConnection *self) * Returns: %TRUE if the given @bssid is in the seen BSSIDs list **/ gboolean -nm_settings_connection_has_seen_bssid (NMSettingsConnection *self, - const char *bssid) +nm_settings_connection_has_seen_bssid(NMSettingsConnection *self, const char *bssid) { - NMSettingsConnectionPrivate *priv; + NMSettingsConnectionPrivate *priv; - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); - g_return_val_if_fail (bssid, FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), FALSE); + g_return_val_if_fail(bssid, FALSE); - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - return priv->seen_bssids - && g_hash_table_contains (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->seen_bssids, bssid); + return priv->seen_bssids + && g_hash_table_contains(NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->seen_bssids, bssid); } /** @@ -2352,33 +2387,32 @@ nm_settings_connection_has_seen_bssid (NMSettingsConnection *self, * Updates the connection and seen-bssids database with the provided BSSID. **/ void -nm_settings_connection_add_seen_bssid (NMSettingsConnection *self, - const char *seen_bssid) +nm_settings_connection_add_seen_bssid(NMSettingsConnection *self, const char *seen_bssid) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - gs_free const char **strv = NULL; - const char *connection_uuid; + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + gs_free const char ** strv = NULL; + const char * connection_uuid; - g_return_if_fail (seen_bssid != NULL); + g_return_if_fail(seen_bssid != NULL); - if (!priv->seen_bssids) - priv->seen_bssids = _seen_bssids_hash_new (); + if (!priv->seen_bssids) + priv->seen_bssids = _seen_bssids_hash_new(); - g_hash_table_add (priv->seen_bssids, g_strdup (seen_bssid)); + g_hash_table_add(priv->seen_bssids, g_strdup(seen_bssid)); - if (!priv->kf_db_seen_bssids) - return; + if (!priv->kf_db_seen_bssids) + return; - connection_uuid = nm_settings_connection_get_uuid (self); - if (!connection_uuid) - return; + connection_uuid = nm_settings_connection_get_uuid(self); + if (!connection_uuid) + return; - strv = nm_utils_strdict_get_keys (priv->seen_bssids, TRUE, NULL); + strv = nm_utils_strdict_get_keys(priv->seen_bssids, TRUE, NULL); - nm_key_file_db_set_string_list (priv->kf_db_seen_bssids, - connection_uuid, - strv ?: NM_PTRARRAY_EMPTY (const char *), - -1); + nm_key_file_db_set_string_list(priv->kf_db_seen_bssids, + connection_uuid, + strv ?: NM_PTRARRAY_EMPTY(const char *), + -1); } /*****************************************************************************/ @@ -2392,104 +2426,101 @@ nm_settings_connection_add_seen_bssid (NMSettingsConnection *self, * with the global default. */ int -nm_settings_connection_autoconnect_retries_get (NMSettingsConnection *self) +nm_settings_connection_autoconnect_retries_get(NMSettingsConnection *self) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - if (G_UNLIKELY (priv->autoconnect_retries == AUTOCONNECT_RETRIES_UNSET)) { - _autoconnect_retries_set (self, - _autoconnect_retries_initial (self), - TRUE); - } - return priv->autoconnect_retries; + if (G_UNLIKELY(priv->autoconnect_retries == AUTOCONNECT_RETRIES_UNSET)) { + _autoconnect_retries_set(self, _autoconnect_retries_initial(self), TRUE); + } + return priv->autoconnect_retries; } void -nm_settings_connection_autoconnect_retries_set (NMSettingsConnection *self, - int retries) +nm_settings_connection_autoconnect_retries_set(NMSettingsConnection *self, int retries) { - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); - g_return_if_fail (retries >= 0); + g_return_if_fail(NM_IS_SETTINGS_CONNECTION(self)); + g_return_if_fail(retries >= 0); - _autoconnect_retries_set (self, retries, FALSE); + _autoconnect_retries_set(self, retries, FALSE); } void -nm_settings_connection_autoconnect_retries_reset (NMSettingsConnection *self) +nm_settings_connection_autoconnect_retries_reset(NMSettingsConnection *self) { - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); + g_return_if_fail(NM_IS_SETTINGS_CONNECTION(self)); - _autoconnect_retries_set (self, - _autoconnect_retries_initial (self), - TRUE); + _autoconnect_retries_set(self, _autoconnect_retries_initial(self), TRUE); } gint32 -nm_settings_connection_autoconnect_retries_blocked_until (NMSettingsConnection *self) +nm_settings_connection_autoconnect_retries_blocked_until(NMSettingsConnection *self) { - return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->autoconnect_retries_blocked_until; + return NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->autoconnect_retries_blocked_until; } -static -NM_UTILS_FLAGS2STR_DEFINE (_autoconnect_blocked_reason_to_string, NMSettingsAutoconnectBlockedReason, - NM_UTILS_FLAGS2STR (NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE, "none"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST, "user-request"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, "failed"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, "no-secrets"), -); +static NM_UTILS_FLAGS2STR_DEFINE( + _autoconnect_blocked_reason_to_string, + NMSettingsAutoconnectBlockedReason, + NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE, "none"), + NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST, "user-request"), + NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, "failed"), + NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, "no-secrets"), ); NMSettingsAutoconnectBlockedReason -nm_settings_connection_autoconnect_blocked_reason_get (NMSettingsConnection *self) +nm_settings_connection_autoconnect_blocked_reason_get(NMSettingsConnection *self) { - return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->autoconnect_blocked_reason; + return NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->autoconnect_blocked_reason; } gboolean -nm_settings_connection_autoconnect_blocked_reason_set_full (NMSettingsConnection *self, - NMSettingsAutoconnectBlockedReason mask, - NMSettingsAutoconnectBlockedReason value) +nm_settings_connection_autoconnect_blocked_reason_set_full(NMSettingsConnection * self, + NMSettingsAutoconnectBlockedReason mask, + NMSettingsAutoconnectBlockedReason value) { - NMSettingsAutoconnectBlockedReason v; - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - char buf[100]; + NMSettingsAutoconnectBlockedReason v; + NMSettingsConnectionPrivate * priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + char buf[100]; - nm_assert (mask); - nm_assert (!NM_FLAGS_ANY (value, ~mask)); + nm_assert(mask); + nm_assert(!NM_FLAGS_ANY(value, ~mask)); - v = priv->autoconnect_blocked_reason; - v = (v & ~mask) | (value & mask); + v = priv->autoconnect_blocked_reason; + v = (v & ~mask) | (value & mask); - if (priv->autoconnect_blocked_reason == v) - return FALSE; + if (priv->autoconnect_blocked_reason == v) + return FALSE; - _LOGT ("autoconnect: blocked reason: %s", _autoconnect_blocked_reason_to_string (v, buf, sizeof (buf))); - priv->autoconnect_blocked_reason = v; - return TRUE; + _LOGT("autoconnect: blocked reason: %s", + _autoconnect_blocked_reason_to_string(v, buf, sizeof(buf))); + priv->autoconnect_blocked_reason = v; + return TRUE; } gboolean -nm_settings_connection_autoconnect_is_blocked (NMSettingsConnection *self) +nm_settings_connection_autoconnect_is_blocked(NMSettingsConnection *self) { - NMSettingsConnectionPrivate *priv; - NMSettingsConnectionIntFlags flags; + NMSettingsConnectionPrivate *priv; + NMSettingsConnectionIntFlags flags; - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), TRUE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), TRUE); - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - if (priv->autoconnect_blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE) - return TRUE; - if (priv->autoconnect_retries == 0) - return TRUE; + if (priv->autoconnect_blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE) + return TRUE; + if (priv->autoconnect_retries == 0) + return TRUE; - flags = priv->flags; - if (NM_FLAGS_ANY (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) - return TRUE; - if (!NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) - return TRUE; + flags = priv->flags; + if (NM_FLAGS_ANY(flags, + NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) + return TRUE; + if (!NM_FLAGS_HAS(flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) + return TRUE; - return FALSE; + return FALSE; } /*****************************************************************************/ @@ -2505,296 +2536,275 @@ nm_settings_connection_autoconnect_is_blocked (NMSettingsConnection *self) * Returns: @self's filename. */ const char * -nm_settings_connection_get_filename (NMSettingsConnection *self) +nm_settings_connection_get_filename(NMSettingsConnection *self) { - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), NULL); - return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->filename; + return NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->filename; } const char * -nm_settings_connection_get_id (NMSettingsConnection *self) +nm_settings_connection_get_id(NMSettingsConnection *self) { - return nm_connection_get_id (nm_settings_connection_get_connection (self)); + return nm_connection_get_id(nm_settings_connection_get_connection(self)); } const char * -nm_settings_connection_get_uuid (NMSettingsConnection *self) +nm_settings_connection_get_uuid(NMSettingsConnection *self) { - NMSettingsConnectionPrivate *priv; - const char *uuid; + NMSettingsConnectionPrivate *priv; + const char * uuid; - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), NULL); - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); - uuid = nm_settings_storage_get_uuid (priv->storage); + uuid = nm_settings_storage_get_uuid(priv->storage); - nm_assert (uuid && nm_streq0 (uuid, nm_connection_get_uuid (nm_settings_connection_get_connection (self)))); + nm_assert( + uuid + && nm_streq0(uuid, nm_connection_get_uuid(nm_settings_connection_get_connection(self)))); - return uuid; + return uuid; } const char * -nm_settings_connection_get_connection_type (NMSettingsConnection *self) +nm_settings_connection_get_connection_type(NMSettingsConnection *self) { - return nm_connection_get_connection_type (nm_settings_connection_get_connection (self)); + return nm_connection_get_connection_type(nm_settings_connection_get_connection(self)); } /*****************************************************************************/ void -_nm_settings_connection_cleanup_after_remove (NMSettingsConnection *self) +_nm_settings_connection_cleanup_after_remove(NMSettingsConnection *self) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - AuthData *auth_data; + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + AuthData * auth_data; - while ((auth_data = c_list_first_entry (&priv->auth_lst_head, AuthData, auth_lst))) - nm_auth_manager_check_authorization_cancel (auth_data->call_id); + while ((auth_data = c_list_first_entry(&priv->auth_lst_head, AuthData, auth_lst))) + nm_auth_manager_check_authorization_cancel(auth_data->call_id); } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object); - - switch (prop_id) { - case PROP_UNSAVED: - g_value_set_boolean (value, nm_settings_connection_get_unsaved (self)); - break; - case PROP_FLAGS: - g_value_set_uint (value, - nm_settings_connection_get_flags (self) & _NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK); - break; - case PROP_FILENAME: - g_value_set_string (value, nm_settings_connection_get_filename (self)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION(object); + + switch (prop_id) { + case PROP_UNSAVED: + g_value_set_boolean(value, nm_settings_connection_get_unsaved(self)); + break; + case PROP_FLAGS: + g_value_set_uint(value, + nm_settings_connection_get_flags(self) + & _NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK); + break; + case PROP_FILENAME: + g_value_set_string(value, nm_settings_connection_get_filename(self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_settings_connection_init (NMSettingsConnection *self) +nm_settings_connection_init(NMSettingsConnection *self) { - NMSettingsConnectionPrivate *priv; + NMSettingsConnectionPrivate *priv; - priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionPrivate); - self->_priv = priv; + priv = + G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionPrivate); + self->_priv = priv; - c_list_init (&self->_connections_lst); + c_list_init(&self->_connections_lst); - c_list_init (&priv->call_ids_lst_head); - c_list_init (&priv->auth_lst_head); + c_list_init(&priv->call_ids_lst_head); + c_list_init(&priv->auth_lst_head); - priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); - priv->settings = g_object_ref (nm_settings_get ()); + priv->agent_mgr = g_object_ref(nm_agent_manager_get()); + priv->settings = g_object_ref(nm_settings_get()); - priv->autoconnect_retries = AUTOCONNECT_RETRIES_UNSET; + priv->autoconnect_retries = AUTOCONNECT_RETRIES_UNSET; } NMSettingsConnection * -nm_settings_connection_new (void) +nm_settings_connection_new(void) { - return g_object_new (NM_TYPE_SETTINGS_CONNECTION, NULL); + return g_object_new(NM_TYPE_SETTINGS_CONNECTION, NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object); - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - NMSettingsConnectionCallId *call_id, *call_id_safe; + NMSettingsConnection * self = NM_SETTINGS_CONNECTION(object); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self); + NMSettingsConnectionCallId * call_id, *call_id_safe; - _LOGD ("disposing"); + _LOGD("disposing"); - nm_assert (!priv->default_wired_device); + nm_assert(!priv->default_wired_device); - nm_assert (c_list_is_empty (&self->_connections_lst)); - nm_assert (c_list_is_empty (&priv->auth_lst_head)); + nm_assert(c_list_is_empty(&self->_connections_lst)); + nm_assert(c_list_is_empty(&priv->auth_lst_head)); - /* Cancel in-progress secrets requests */ - if (priv->agent_mgr) { - c_list_for_each_entry_safe (call_id, call_id_safe, &priv->call_ids_lst_head, call_ids_lst) - _get_secrets_cancel (self, call_id, TRUE); - } + /* Cancel in-progress secrets requests */ + if (priv->agent_mgr) { + c_list_for_each_entry_safe (call_id, call_id_safe, &priv->call_ids_lst_head, call_ids_lst) + _get_secrets_cancel(self, call_id, TRUE); + } - nm_clear_pointer (&priv->system_secrets, g_variant_unref); - nm_clear_pointer (&priv->agent_secrets, g_variant_unref); + nm_clear_pointer(&priv->system_secrets, g_variant_unref); + nm_clear_pointer(&priv->agent_secrets, g_variant_unref); - nm_clear_pointer (&priv->seen_bssids, g_hash_table_destroy); + nm_clear_pointer(&priv->seen_bssids, g_hash_table_destroy); - g_clear_object (&priv->agent_mgr); + g_clear_object(&priv->agent_mgr); - g_clear_object (&priv->connection); + g_clear_object(&priv->connection); - nm_clear_pointer (&priv->kf_db_timestamps, nm_key_file_db_unref); - nm_clear_pointer (&priv->kf_db_seen_bssids, nm_key_file_db_unref); + nm_clear_pointer(&priv->kf_db_timestamps, nm_key_file_db_unref); + nm_clear_pointer(&priv->kf_db_seen_bssids, nm_key_file_db_unref); - G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_settings_connection_parent_class)->dispose(object); - g_clear_object (&priv->storage); + g_clear_object(&priv->storage); - nm_clear_g_free (&priv->filename); + nm_clear_g_free(&priv->filename); - g_clear_object (&priv->settings); + g_clear_object(&priv->settings); } /*****************************************************************************/ -static const GDBusSignalInfo signal_info_updated = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( - "Updated", -); +static const GDBusSignalInfo signal_info_updated = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT("Updated", ); -static const GDBusSignalInfo signal_info_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( - "Removed", -); +static const GDBusSignalInfo signal_info_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT("Removed", ); static const NMDBusInterfaceInfoExtended interface_info_settings_connection = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_SETTINGS_CONNECTION, - .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "Update", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("properties", "a{sa{sv}}"), - ), - ), - .handle = impl_settings_connection_update, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "UpdateUnsaved", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("properties", "a{sa{sv}}"), - ), - ), - .handle = impl_settings_connection_update_unsaved, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "Delete", - ), - .handle = impl_settings_connection_delete, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "GetSettings", - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("settings", "a{sa{sv}}"), - ), - ), - .handle = impl_settings_connection_get_settings, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "GetSecrets", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("setting_name", "s"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("secrets", "a{sa{sv}}"), - ), - ), - .handle = impl_settings_connection_get_secrets, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "ClearSecrets", - ), - .handle = impl_settings_connection_clear_secrets, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "Save", - ), - .handle = impl_settings_connection_save, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "Update2", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("settings", "a{sa{sv}}"), - NM_DEFINE_GDBUS_ARG_INFO ("flags", "u"), - NM_DEFINE_GDBUS_ARG_INFO ("args", "a{sv}"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("result", "a{sv}"), - ), - ), - .handle = impl_settings_connection_update2, - ), - ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - &signal_info_updated, - &signal_info_removed, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Unsaved", "b", NM_SETTINGS_CONNECTION_UNSAVED), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Flags", "u", NM_SETTINGS_CONNECTION_FLAGS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Filename", "s", NM_SETTINGS_CONNECTION_FILENAME), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "Update", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("properties", "a{sa{sv}}"), ), ), + .handle = impl_settings_connection_update, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "UpdateUnsaved", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("properties", "a{sa{sv}}"), ), ), + .handle = impl_settings_connection_update_unsaved, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(NM_DEFINE_GDBUS_METHOD_INFO_INIT("Delete", ), + .handle = impl_settings_connection_delete, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "GetSettings", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("settings", "a{sa{sv}}"), ), ), + .handle = impl_settings_connection_get_settings, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "GetSecrets", + .in_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("setting_name", "s"), ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("secrets", "a{sa{sv}}"), ), ), + .handle = impl_settings_connection_get_secrets, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(NM_DEFINE_GDBUS_METHOD_INFO_INIT("ClearSecrets", ), + .handle = impl_settings_connection_clear_secrets, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(NM_DEFINE_GDBUS_METHOD_INFO_INIT("Save", ), + .handle = impl_settings_connection_save, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "Update2", + .in_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("settings", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO("flags", "u"), + NM_DEFINE_GDBUS_ARG_INFO("args", "a{sv}"), ), + .out_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("result", "a{sv}"), ), ), + .handle = impl_settings_connection_update2, ), ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, + &signal_info_updated, + &signal_info_removed, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Unsaved", + "b", + NM_SETTINGS_CONNECTION_UNSAVED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Flags", + "u", + NM_SETTINGS_CONNECTION_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Filename", + "s", + NM_SETTINGS_CONNECTION_FILENAME), ), ), + .legacy_property_changed = TRUE, }; static void -nm_settings_connection_class_init (NMSettingsConnectionClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (NMSettingsConnectionPrivate)); - - dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED (NM_DBUS_PATH_SETTINGS); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_settings_connection); - - object_class->dispose = dispose; - object_class->get_property = get_property; - - obj_properties[PROP_UNSAVED] = - g_param_spec_boolean (NM_SETTINGS_CONNECTION_UNSAVED, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_FLAGS] = - g_param_spec_uint (NM_SETTINGS_CONNECTION_FLAGS, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_FILENAME] = - g_param_spec_string (NM_SETTINGS_CONNECTION_FILENAME, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - /* internal signal, with an argument (NMSettingsConnectionUpdateReason update_reason) as - * guint. */ - signals[UPDATED_INTERNAL] = - g_signal_new (NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); - - signals[FLAGS_CHANGED] = - g_signal_new (NM_SETTINGS_CONNECTION_FLAGS_CHANGED, - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); +nm_settings_connection_class_init(NMSettingsConnectionClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingsConnectionPrivate)); + + dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH_SETTINGS); + dbus_object_class->interface_infos = + NM_DBUS_INTERFACE_INFOS(&interface_info_settings_connection); + + object_class->dispose = dispose; + object_class->get_property = get_property; + + obj_properties[PROP_UNSAVED] = g_param_spec_boolean(NM_SETTINGS_CONNECTION_UNSAVED, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_FLAGS] = g_param_spec_uint(NM_SETTINGS_CONNECTION_FLAGS, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_FILENAME] = g_param_spec_string(NM_SETTINGS_CONNECTION_FILENAME, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + /* internal signal, with an argument (NMSettingsConnectionUpdateReason update_reason) as + * guint. */ + signals[UPDATED_INTERNAL] = g_signal_new(NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, + 1, + G_TYPE_UINT); + + signals[FLAGS_CHANGED] = g_signal_new(NM_SETTINGS_CONNECTION_FLAGS_CHANGED, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); } diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index 17573bbe..b1665cc5 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 Novell, Inc. * Copyright (C) 2008 - 2013 Red Hat, Inc. @@ -16,116 +16,121 @@ typedef enum { - NM_SETTINGS_CONNECTION_ADD_REASON_NONE = 0, + NM_SETTINGS_CONNECTION_ADD_REASON_NONE = 0, - NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT = (1u << 0), + NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT = (1u << 0), } NMSettingsConnectionAddReason; typedef enum { - NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE = 0, - - /* with persist-mode != NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, and - * update tries to update the profile on disk (which can always fail). - * In some cases we want to ignore such failure and proceed. For example, - * when we receive secrets from a secret-agent, we want to update the connection - * at all cost and ignore failures to write them to disk. */ - NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE = (1u << 0), - - /* When updating the profile, force renaming the file on disk. That matters - * only for keyfile plugin. Keyfile prefers a filename based on connection.id. - * When the connection.id changes we might want to rename the file on disk - * (that is, don't overwrite the existing file, but delete it and write it - * with the new name). - * This flag forces such rename. */ - NM_SETTINGS_CONNECTION_UPDATE_REASON_FORCE_RENAME = (1u << 1), - - /* Usually, changing a profile that is currently active does not immediately - * reapply the changes. The exception are connection.zone and connection.metered - * properties. When this flag is set, then these two properties are reapplied - * right away. - * - * See also %NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY flag, to prevent partial reapply - * during Update2(). */ - NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL = (1u << 2), - - NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS = (1u << 3), - NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS = (1u << 4), - - NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS = (1u << 5), - NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS = (1u << 6), - - /* if a profile was greated as default-wired connection for a device, then - * when the user modifies it via D-Bus, the profile should become persisted - * to disk and it the purpose why the profile was created should be forgotten. */ - NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_DEFAULT_WIRED = (1u << 7), - - NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT = (1u << 8), + NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE = 0, + + /* with persist-mode != NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, and + * update tries to update the profile on disk (which can always fail). + * In some cases we want to ignore such failure and proceed. For example, + * when we receive secrets from a secret-agent, we want to update the connection + * at all cost and ignore failures to write them to disk. */ + NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE = (1u << 0), + + /* When updating the profile, force renaming the file on disk. That matters + * only for keyfile plugin. Keyfile prefers a filename based on connection.id. + * When the connection.id changes we might want to rename the file on disk + * (that is, don't overwrite the existing file, but delete it and write it + * with the new name). + * This flag forces such rename. */ + NM_SETTINGS_CONNECTION_UPDATE_REASON_FORCE_RENAME = (1u << 1), + + /* Usually, changing a profile that is currently active does not immediately + * reapply the changes. The exception are connection.zone and connection.metered + * properties. When this flag is set, then these two properties are reapplied + * right away. + * + * See also %NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY flag, to prevent partial reapply + * during Update2(). */ + NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL = (1u << 2), + + NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS = (1u << 3), + NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS = (1u << 4), + + NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS = (1u << 5), + NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS = (1u << 6), + + /* if a profile was greated as default-wired connection for a device, then + * when the user modifies it via D-Bus, the profile should become persisted + * to disk and it the purpose why the profile was created should be forgotten. */ + NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_DEFAULT_WIRED = (1u << 7), + + NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT = (1u << 8), } NMSettingsConnectionUpdateReason; typedef enum { - /* if the profile is in-memory, update it in-memory and keep it. - * if the profile is on-disk, update it on-disk, and keep it. */ - NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP, - - /* persist to disk. If the profile is currently in-memory, remove - * it from /run. Depending on the shadowed-storage, the pre-existing - * file is reused when moving the storage. - * - * Corresponds to %NM_SETTINGS_UPDATE2_FLAG_TO_DISK. */ - NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK, - - /* Update in-memory (i.e. persist to /run). If the profile is currently on disk, - * then a reference to the profile is remembered as "shadowed-storage". - * Later, when storing again to persistant storage, the shawowed-storage is - * updated. When deleting the profile, the shadowed-storage is also deleted - * from disk. - * - * Corresponds to %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY. */ - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, - - /* Update in-memory (i.e. persist to /run). This is almost like - * %NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, except the in-memory profile - * remembers not to own the shadowed-storage ("shadowed-owned"). - * The diffrence is that when deleting the in-memory profile, the original - * profile is not deleted but instead the nmmeta tombstone remembers the - * shadowed-storage and re-used it when re-adding the profile. - * - * Corresponds to %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED. */ - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED, - - /* Update in-memory (i.e. persist to /run). If the profile is currently on disk, - * delete it from disk. - * - * If the profile is in-memory and has a shadowed-storage, the original profile - * will be deleted from disk. - * - * Corresponds to %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY. */ - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, - - /* This only updates the connection in-memory. Note that "in-memory" above - * means to write to keyfile in /run. This mode really means to not notify the - * settings plugin about the change. This should be only used for updating - * secrets. - */ - NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST, + /* if the profile is in-memory, update it in-memory and keep it. + * if the profile is on-disk, update it on-disk, and keep it. */ + NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP, + + /* persist to disk. If the profile is currently in-memory, remove + * it from /run. Depending on the shadowed-storage, the pre-existing + * file is reused when moving the storage. + * + * Corresponds to %NM_SETTINGS_UPDATE2_FLAG_TO_DISK. */ + NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK, + + /* Update in-memory (i.e. persist to /run). If the profile is currently on disk, + * then a reference to the profile is remembered as "shadowed-storage". + * Later, when storing again to persistent storage, the shadowed-storage is + * updated. When deleting the profile, the shadowed-storage is also deleted + * from disk. + * + * Corresponds to %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY. */ + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, + + /* Update in-memory (i.e. persist to /run). This is almost like + * %NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, except the in-memory profile + * remembers not to own the shadowed-storage ("shadowed-owned"). + * The difference is that when deleting the in-memory profile, the original + * profile is not deleted but instead the nmmeta tombstone remembers the + * shadowed-storage and re-used it when re-adding the profile. + * + * Corresponds to %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED. */ + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED, + + /* Update in-memory (i.e. persist to /run). If the profile is currently on disk, + * delete it from disk. + * + * If the profile is in-memory and has a shadowed-storage, the original profile + * will be deleted from disk. + * + * Corresponds to %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY. */ + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, + + /* This only updates the connection in-memory. Note that "in-memory" above + * means to write to keyfile in /run. This mode really means to not notify the + * settings plugin about the change. This should be only used for updating + * secrets. + */ + NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST, } NMSettingsConnectionPersistMode; /*****************************************************************************/ -#define NM_TYPE_SETTINGS_CONNECTION (nm_settings_connection_get_type ()) -#define NM_SETTINGS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnection)) -#define NM_SETTINGS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass)) -#define NM_IS_SETTINGS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_CONNECTION)) -#define NM_IS_SETTINGS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS_CONNECTION)) -#define NM_SETTINGS_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass)) - -#define NM_SETTINGS_CONNECTION_GET_SECRETS "get-secrets" -#define NM_SETTINGS_CONNECTION_CANCEL_SECRETS "cancel-secrets" +#define NM_TYPE_SETTINGS_CONNECTION (nm_settings_connection_get_type()) +#define NM_SETTINGS_CONNECTION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnection)) +#define NM_SETTINGS_CONNECTION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass)) +#define NM_IS_SETTINGS_CONNECTION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTINGS_CONNECTION)) +#define NM_IS_SETTINGS_CONNECTION_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTINGS_CONNECTION)) +#define NM_SETTINGS_CONNECTION_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass)) + +#define NM_SETTINGS_CONNECTION_GET_SECRETS "get-secrets" +#define NM_SETTINGS_CONNECTION_CANCEL_SECRETS "cancel-secrets" #define NM_SETTINGS_CONNECTION_UPDATED_INTERNAL "updated-internal" #define NM_SETTINGS_CONNECTION_FLAGS_CHANGED "flags-changed" @@ -158,43 +163,39 @@ typedef enum { * #NMSettingsConnection flags. **/ typedef enum _NMSettingsConnectionIntFlags { - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE = 0, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE = 0, - NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED = NM_SETTINGS_CONNECTION_FLAG_UNSAVED, - NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED = NM_SETTINGS_CONNECTION_FLAG_NM_GENERATED, - NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE = NM_SETTINGS_CONNECTION_FLAG_VOLATILE, - NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL = NM_SETTINGS_CONNECTION_FLAG_EXTERNAL, + NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED = NM_SETTINGS_CONNECTION_FLAG_UNSAVED, + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED = NM_SETTINGS_CONNECTION_FLAG_NM_GENERATED, + NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE = NM_SETTINGS_CONNECTION_FLAG_VOLATILE, + NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL = NM_SETTINGS_CONNECTION_FLAG_EXTERNAL, - NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE = 0x10, + NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE = 0x10, - _NM_SETTINGS_CONNECTION_INT_FLAGS_LAST, + _NM_SETTINGS_CONNECTION_INT_FLAGS_LAST, - _NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK = 0 - | NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED - | NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL - | 0, + _NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK = + 0 | NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED | NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL | 0, - _NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK = 0 - | NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL - | 0, + _NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK = + 0 | NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL | 0, - _NM_SETTINGS_CONNECTION_INT_FLAGS_ALL = ((_NM_SETTINGS_CONNECTION_INT_FLAGS_LAST - 1) << 1) - 1, + _NM_SETTINGS_CONNECTION_INT_FLAGS_ALL = ((_NM_SETTINGS_CONNECTION_INT_FLAGS_LAST - 1) << 1) - 1, } NMSettingsConnectionIntFlags; typedef enum { - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE = 0, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE = 0, - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST = (1LL << 0), - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED = (1LL << 1), - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS = (1LL << 2), + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST = (1LL << 0), + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED = (1LL << 1), + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS = (1LL << 2), - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL = ( NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST - | NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED - | NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS), + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL = + (NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST + | NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED + | NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS), } NMSettingsAutoconnectBlockedReason; typedef struct _NMSettingsConnectionCallId NMSettingsConnectionCallId; @@ -204,176 +205,190 @@ typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass; struct _NMSettingsConnectionPrivate; struct _NMSettingsConnection { - NMDBusObject parent; - CList _connections_lst; - struct _NMSettingsConnectionPrivate *_priv; + NMDBusObject parent; + CList _connections_lst; + struct _NMSettingsConnectionPrivate *_priv; }; -GType nm_settings_connection_get_type (void); +GType nm_settings_connection_get_type(void); -NMSettingsConnection *nm_settings_connection_new (void); +NMSettingsConnection *nm_settings_connection_new(void); -NMConnection *nm_settings_connection_get_connection (NMSettingsConnection *self); +NMConnection *nm_settings_connection_get_connection(NMSettingsConnection *self); -void _nm_settings_connection_set_connection (NMSettingsConnection *self, - NMConnection *new_connection, - NMConnection **out_old_connection, - NMSettingsConnectionUpdateReason update_reason); +void _nm_settings_connection_set_connection(NMSettingsConnection * self, + NMConnection * new_connection, + NMConnection ** out_old_connection, + NMSettingsConnectionUpdateReason update_reason); -NMSettingsStorage *nm_settings_connection_get_storage (NMSettingsConnection *self); +NMSettingsStorage *nm_settings_connection_get_storage(NMSettingsConnection *self); -void _nm_settings_connection_set_storage (NMSettingsConnection *self, - NMSettingsStorage *storage); +void _nm_settings_connection_set_storage(NMSettingsConnection *self, NMSettingsStorage *storage); -gboolean nm_settings_connection_still_valid (NMSettingsConnection *self); +gboolean nm_settings_connection_still_valid(NMSettingsConnection *self); -const char *nm_settings_connection_get_filename (NMSettingsConnection *self); +const char *nm_settings_connection_get_filename(NMSettingsConnection *self); -guint64 nm_settings_connection_get_last_secret_agent_version_id (NMSettingsConnection *self); +guint64 nm_settings_connection_get_last_secret_agent_version_id(NMSettingsConnection *self); -gboolean nm_settings_connection_has_unmodified_applied_connection (NMSettingsConnection *self, - NMConnection *applied_connection, - NMSettingCompareFlags compare_flage); +gboolean +nm_settings_connection_has_unmodified_applied_connection(NMSettingsConnection *self, + NMConnection * applied_connection, + NMSettingCompareFlags compare_flage); -gboolean nm_settings_connection_update (NMSettingsConnection *self, - NMConnection *new_connection, - NMSettingsConnectionPersistMode persist_mode, - NMSettingsConnectionIntFlags sett_flags, - NMSettingsConnectionIntFlags sett_mask, - NMSettingsConnectionUpdateReason update_reason, - const char *log_context_name, - GError **error); +gboolean nm_settings_connection_update(NMSettingsConnection * self, + NMConnection * new_connection, + NMSettingsConnectionPersistMode persist_mode, + NMSettingsConnectionIntFlags sett_flags, + NMSettingsConnectionIntFlags sett_mask, + NMSettingsConnectionUpdateReason update_reason, + const char * log_context_name, + GError ** error); -void nm_settings_connection_delete (NMSettingsConnection *self, - gboolean allow_add_to_no_auto_default); +void nm_settings_connection_delete(NMSettingsConnection *self, + gboolean allow_add_to_no_auto_default); -typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *self, - NMSettingsConnectionCallId *call_id, - const char *agent_username, - const char *setting_name, - GError *error, - gpointer user_data); +typedef void (*NMSettingsConnectionSecretsFunc)(NMSettingsConnection * self, + NMSettingsConnectionCallId *call_id, + const char * agent_username, + const char * setting_name, + GError * error, + gpointer user_data); -gboolean nm_settings_connection_new_secrets (NMSettingsConnection *self, - NMConnection *applied_connection, - const char *setting_name, - GVariant *secrets, - GError **error); +gboolean nm_settings_connection_new_secrets(NMSettingsConnection *self, + NMConnection * applied_connection, + const char * setting_name, + GVariant * secrets, + GError ** error); -NMSettingsConnectionCallId *nm_settings_connection_get_secrets (NMSettingsConnection *self, - NMConnection *applied_connection, - NMAuthSubject *subject, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags, - const char *const*hints, - NMSettingsConnectionSecretsFunc callback, - gpointer callback_data); +NMSettingsConnectionCallId * +nm_settings_connection_get_secrets(NMSettingsConnection * self, + NMConnection * applied_connection, + NMAuthSubject * subject, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags, + const char *const * hints, + NMSettingsConnectionSecretsFunc callback, + gpointer callback_data); -void nm_settings_connection_cancel_secrets (NMSettingsConnection *self, - NMSettingsConnectionCallId *call_id); +void nm_settings_connection_cancel_secrets(NMSettingsConnection * self, + NMSettingsConnectionCallId *call_id); -void nm_settings_connection_clear_secrets (NMSettingsConnection *self, - gboolean clear_cached_system_secrets, - gboolean persist); +void nm_settings_connection_clear_secrets(NMSettingsConnection *self, + gboolean clear_cached_system_secrets, + gboolean persist); -gboolean nm_settings_connection_check_visibility (NMSettingsConnection *self, - NMSessionMonitor *session_monitor); +gboolean nm_settings_connection_check_visibility(NMSettingsConnection *self, + NMSessionMonitor * session_monitor); -gboolean nm_settings_connection_check_permission (NMSettingsConnection *self, - const char *permission); +gboolean nm_settings_connection_check_permission(NMSettingsConnection *self, + const char * permission); /*****************************************************************************/ -NMDevice *nm_settings_connection_default_wired_get_device (NMSettingsConnection *self); -void nm_settings_connection_default_wired_set_device (NMSettingsConnection *self, - NMDevice *device); +NMDevice *nm_settings_connection_default_wired_get_device(NMSettingsConnection *self); +void nm_settings_connection_default_wired_set_device(NMSettingsConnection *self, NMDevice *device); /*****************************************************************************/ -NMSettingsConnectionIntFlags nm_settings_connection_get_flags (NMSettingsConnection *self); +NMSettingsConnectionIntFlags nm_settings_connection_get_flags(NMSettingsConnection *self); static inline gboolean -nm_settings_connection_get_unsaved (NMSettingsConnection *self) +nm_settings_connection_get_unsaved(NMSettingsConnection *self) { - return NM_FLAGS_HAS (nm_settings_connection_get_flags (self), NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED); + return NM_FLAGS_HAS(nm_settings_connection_get_flags(self), + NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED); } -NMSettingsConnectionIntFlags nm_settings_connection_set_flags_full (NMSettingsConnection *self, NMSettingsConnectionIntFlags mask, NMSettingsConnectionIntFlags value); +NMSettingsConnectionIntFlags +nm_settings_connection_set_flags_full(NMSettingsConnection * self, + NMSettingsConnectionIntFlags mask, + NMSettingsConnectionIntFlags value); static inline NMSettingsConnectionIntFlags -nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionIntFlags flags, gboolean set) +nm_settings_connection_set_flags(NMSettingsConnection * self, + NMSettingsConnectionIntFlags flags, + gboolean set) { - return nm_settings_connection_set_flags_full (self, - flags, - set ? flags : NM_SETTINGS_CONNECTION_INT_FLAGS_NONE); + return nm_settings_connection_set_flags_full(self, + flags, + set ? flags + : NM_SETTINGS_CONNECTION_INT_FLAGS_NONE); } /*****************************************************************************/ -int nm_settings_connection_cmp_timestamp (NMSettingsConnection *ac, NMSettingsConnection *ab); -int nm_settings_connection_cmp_timestamp_p_with_data (gconstpointer pa, gconstpointer pb, gpointer user_data); -int nm_settings_connection_cmp_autoconnect_priority (NMSettingsConnection *a, NMSettingsConnection *b); -int nm_settings_connection_cmp_autoconnect_priority_p_with_data (gconstpointer pa, gconstpointer pb, gpointer user_data); +int nm_settings_connection_cmp_timestamp(NMSettingsConnection *ac, NMSettingsConnection *ab); +int nm_settings_connection_cmp_timestamp_p_with_data(gconstpointer pa, + gconstpointer pb, + gpointer user_data); +int nm_settings_connection_cmp_autoconnect_priority(NMSettingsConnection *a, + NMSettingsConnection *b); +int nm_settings_connection_cmp_autoconnect_priority_p_with_data(gconstpointer pa, + gconstpointer pb, + gpointer user_data); struct _NMKeyFileDB; -void _nm_settings_connection_register_kf_dbs (NMSettingsConnection *self, - struct _NMKeyFileDB *kf_db_timestamps, - struct _NMKeyFileDB *kf_db_seen_bssids); +void _nm_settings_connection_register_kf_dbs(NMSettingsConnection *self, + struct _NMKeyFileDB * kf_db_timestamps, + struct _NMKeyFileDB * kf_db_seen_bssids); -gboolean nm_settings_connection_get_timestamp (NMSettingsConnection *self, - guint64 *out_timestamp); +gboolean nm_settings_connection_get_timestamp(NMSettingsConnection *self, guint64 *out_timestamp); -void nm_settings_connection_update_timestamp (NMSettingsConnection *self, - guint64 timestamp); +void nm_settings_connection_update_timestamp(NMSettingsConnection *self, guint64 timestamp); -const char **nm_settings_connection_get_seen_bssids (NMSettingsConnection *self); +const char **nm_settings_connection_get_seen_bssids(NMSettingsConnection *self); -gboolean nm_settings_connection_has_seen_bssid (NMSettingsConnection *self, - const char *bssid); +gboolean nm_settings_connection_has_seen_bssid(NMSettingsConnection *self, const char *bssid); -void nm_settings_connection_add_seen_bssid (NMSettingsConnection *self, - const char *seen_bssid); +void nm_settings_connection_add_seen_bssid(NMSettingsConnection *self, const char *seen_bssid); -int nm_settings_connection_autoconnect_retries_get (NMSettingsConnection *self); -void nm_settings_connection_autoconnect_retries_set (NMSettingsConnection *self, - int retries); -void nm_settings_connection_autoconnect_retries_reset (NMSettingsConnection *self); +int nm_settings_connection_autoconnect_retries_get(NMSettingsConnection *self); +void nm_settings_connection_autoconnect_retries_set(NMSettingsConnection *self, int retries); +void nm_settings_connection_autoconnect_retries_reset(NMSettingsConnection *self); -gint32 nm_settings_connection_autoconnect_retries_blocked_until (NMSettingsConnection *self); +gint32 nm_settings_connection_autoconnect_retries_blocked_until(NMSettingsConnection *self); -NMSettingsAutoconnectBlockedReason nm_settings_connection_autoconnect_blocked_reason_get (NMSettingsConnection *self); -gboolean nm_settings_connection_autoconnect_blocked_reason_set_full (NMSettingsConnection *self, - NMSettingsAutoconnectBlockedReason mask, - NMSettingsAutoconnectBlockedReason value); +NMSettingsAutoconnectBlockedReason + nm_settings_connection_autoconnect_blocked_reason_get(NMSettingsConnection *self); +gboolean nm_settings_connection_autoconnect_blocked_reason_set_full( + NMSettingsConnection * self, + NMSettingsAutoconnectBlockedReason mask, + NMSettingsAutoconnectBlockedReason value); static inline gboolean -nm_settings_connection_autoconnect_blocked_reason_set (NMSettingsConnection *self, - NMSettingsAutoconnectBlockedReason mask, - gboolean set) +nm_settings_connection_autoconnect_blocked_reason_set(NMSettingsConnection * self, + NMSettingsAutoconnectBlockedReason mask, + gboolean set) { - return nm_settings_connection_autoconnect_blocked_reason_set_full (self, mask, set ? mask : NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE); + return nm_settings_connection_autoconnect_blocked_reason_set_full( + self, + mask, + set ? mask : NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE); } -gboolean nm_settings_connection_autoconnect_is_blocked (NMSettingsConnection *self); +gboolean nm_settings_connection_autoconnect_is_blocked(NMSettingsConnection *self); -const char *nm_settings_connection_get_id (NMSettingsConnection *connection); -const char *nm_settings_connection_get_uuid (NMSettingsConnection *connection); -const char *nm_settings_connection_get_connection_type (NMSettingsConnection *connection); +const char *nm_settings_connection_get_id(NMSettingsConnection *connection); +const char *nm_settings_connection_get_uuid(NMSettingsConnection *connection); +const char *nm_settings_connection_get_connection_type(NMSettingsConnection *connection); /*****************************************************************************/ -NMConnection **nm_settings_connections_array_to_connections (NMSettingsConnection *const*connections, - gssize n_connections); +NMConnection ** +nm_settings_connections_array_to_connections(NMSettingsConnection *const *connections, + gssize n_connections); /*****************************************************************************/ -void _nm_settings_connection_emit_dbus_signal_updated (NMSettingsConnection *self); -void _nm_settings_connection_emit_dbus_signal_removed (NMSettingsConnection *self); +void _nm_settings_connection_emit_dbus_signal_updated(NMSettingsConnection *self); +void _nm_settings_connection_emit_dbus_signal_removed(NMSettingsConnection *self); -void _nm_settings_connection_emit_signal_updated_internal (NMSettingsConnection *self, - NMSettingsConnectionUpdateReason update_reason); +void _nm_settings_connection_emit_signal_updated_internal( + NMSettingsConnection * self, + NMSettingsConnectionUpdateReason update_reason); -void _nm_settings_connection_cleanup_after_remove (NMSettingsConnection *self); +void _nm_settings_connection_cleanup_after_remove(NMSettingsConnection *self); #endif /* __NETWORKMANAGER_SETTINGS_CONNECTION_H__ */ diff --git a/src/settings/nm-settings-plugin.c b/src/settings/nm-settings-plugin.c index 630532ef..79451bae 100644 --- a/src/settings/nm-settings-plugin.c +++ b/src/settings/nm-settings-plugin.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2007 - 2018 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. @@ -16,281 +16,275 @@ /*****************************************************************************/ enum { - UNMANAGED_SPECS_CHANGED, - UNRECOGNIZED_SPECS_CHANGED, + UNMANAGED_SPECS_CHANGED, + UNRECOGNIZED_SPECS_CHANGED, - LAST_SIGNAL + LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = {0}; -G_DEFINE_TYPE (NMSettingsPlugin, nm_settings_plugin, G_TYPE_OBJECT) +G_DEFINE_TYPE(NMSettingsPlugin, nm_settings_plugin, G_TYPE_OBJECT) /*****************************************************************************/ int -nm_settings_plugin_cmp_by_priority (const NMSettingsPlugin *a, - const NMSettingsPlugin *b, - const GSList *plugin_list) +nm_settings_plugin_cmp_by_priority(const NMSettingsPlugin *a, + const NMSettingsPlugin *b, + const GSList * plugin_list) { - nm_assert (NM_IS_SETTINGS_PLUGIN (a)); - nm_assert (NM_IS_SETTINGS_PLUGIN (b)); + nm_assert(NM_IS_SETTINGS_PLUGIN(a)); + nm_assert(NM_IS_SETTINGS_PLUGIN(b)); - if (a != b) { - int idx_a = g_slist_index ((GSList *) plugin_list, a); - int idx_b = g_slist_index ((GSList *) plugin_list, b); + if (a != b) { + int idx_a = g_slist_index((GSList *) plugin_list, a); + int idx_b = g_slist_index((GSList *) plugin_list, b); - /* the plugins must be found in the list. */ - nm_assert (idx_a >= 0); - nm_assert (idx_b >= 0); + /* the plugins must be found in the list. */ + nm_assert(idx_a >= 0); + nm_assert(idx_b >= 0); - /* plugins that appear first in @plugin_list have higher priority. - * That means: smaller index -> higher priority. Reverse sort. */ - NM_CMP_DIRECT (idx_b, idx_a); - } + /* plugins that appear first in @plugin_list have higher priority. + * That means: smaller index -> higher priority. Reverse sort. */ + NM_CMP_DIRECT(idx_b, idx_a); + } - return 0; + return 0; } /*****************************************************************************/ GSList * -nm_settings_plugin_get_unmanaged_specs (NMSettingsPlugin *self) +nm_settings_plugin_get_unmanaged_specs(NMSettingsPlugin *self) { - NMSettingsPluginClass *klass; + NMSettingsPluginClass *klass; - g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_PLUGIN(self), NULL); - klass = NM_SETTINGS_PLUGIN_GET_CLASS (self); - if (!klass->get_unmanaged_specs) - return NULL; - return klass->get_unmanaged_specs (self); + klass = NM_SETTINGS_PLUGIN_GET_CLASS(self); + if (!klass->get_unmanaged_specs) + return NULL; + return klass->get_unmanaged_specs(self); } GSList * -nm_settings_plugin_get_unrecognized_specs (NMSettingsPlugin *self) +nm_settings_plugin_get_unrecognized_specs(NMSettingsPlugin *self) { - NMSettingsPluginClass *klass; + NMSettingsPluginClass *klass; - g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_PLUGIN(self), NULL); - klass = NM_SETTINGS_PLUGIN_GET_CLASS (self); - if (!klass->get_unrecognized_specs) - return NULL; - return klass->get_unrecognized_specs (self); + klass = NM_SETTINGS_PLUGIN_GET_CLASS(self); + if (!klass->get_unrecognized_specs) + return NULL; + return klass->get_unrecognized_specs(self); } void -nm_settings_plugin_reload_connections (NMSettingsPlugin *self, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data) +nm_settings_plugin_reload_connections(NMSettingsPlugin * self, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data) { - NMSettingsPluginClass *klass; + NMSettingsPluginClass *klass; - g_return_if_fail (NM_IS_SETTINGS_PLUGIN (self)); - g_return_if_fail (callback); + g_return_if_fail(NM_IS_SETTINGS_PLUGIN(self)); + g_return_if_fail(callback); - klass = NM_SETTINGS_PLUGIN_GET_CLASS (self); - if (klass->reload_connections) - klass->reload_connections (self, callback, user_data); + klass = NM_SETTINGS_PLUGIN_GET_CLASS(self); + if (klass->reload_connections) + klass->reload_connections(self, callback, user_data); } NMSettingsPluginConnectionLoadEntry * -nm_settings_plugin_create_connection_load_entries (const char *const*filenames, - gsize *out_len) +nm_settings_plugin_create_connection_load_entries(const char *const *filenames, gsize *out_len) { - NMSettingsPluginConnectionLoadEntry *entries; - gsize len; - gsize i; - - len = NM_PTRARRAY_LEN (filenames); - if (len == 0) { - *out_len = 0; - return NULL; - } - - entries = g_new (NMSettingsPluginConnectionLoadEntry, len); - for (i = 0; i < len; i++) { - entries[i] = (NMSettingsPluginConnectionLoadEntry) { - .filename = filenames[i], - .error = NULL, - .handled = FALSE, - }; - } - - *out_len = len; - return entries; + NMSettingsPluginConnectionLoadEntry *entries; + gsize len; + gsize i; + + len = NM_PTRARRAY_LEN(filenames); + if (len == 0) { + *out_len = 0; + return NULL; + } + + entries = g_new(NMSettingsPluginConnectionLoadEntry, len); + for (i = 0; i < len; i++) { + entries[i] = (NMSettingsPluginConnectionLoadEntry){ + .filename = filenames[i], + .error = NULL, + .handled = FALSE, + }; + } + + *out_len = len; + return entries; } void -nm_settings_plugin_load_connections (NMSettingsPlugin *self, - NMSettingsPluginConnectionLoadEntry *entries, - gsize n_entries, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data) +nm_settings_plugin_load_connections(NMSettingsPlugin * self, + NMSettingsPluginConnectionLoadEntry * entries, + gsize n_entries, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data) { - NMSettingsPluginClass *klass; + NMSettingsPluginClass *klass; - g_return_if_fail (NM_IS_SETTINGS_PLUGIN (self)); + g_return_if_fail(NM_IS_SETTINGS_PLUGIN(self)); - klass = NM_SETTINGS_PLUGIN_GET_CLASS (self); - if (klass->load_connections) - klass->load_connections (self, entries, n_entries, callback, user_data); + klass = NM_SETTINGS_PLUGIN_GET_CLASS(self); + if (klass->load_connections) + klass->load_connections(self, entries, n_entries, callback, user_data); } void -nm_settings_plugin_load_connections_done (NMSettingsPlugin *self) +nm_settings_plugin_load_connections_done(NMSettingsPlugin *self) { - NMSettingsPluginClass *klass; + NMSettingsPluginClass *klass; - g_return_if_fail (NM_IS_SETTINGS_PLUGIN (self)); + g_return_if_fail(NM_IS_SETTINGS_PLUGIN(self)); - klass = NM_SETTINGS_PLUGIN_GET_CLASS (self); - if (klass->load_connections_done) - klass->load_connections_done (self); + klass = NM_SETTINGS_PLUGIN_GET_CLASS(self); + if (klass->load_connections_done) + klass->load_connections_done(self); } gboolean -nm_settings_plugin_add_connection (NMSettingsPlugin *self, - NMConnection *connection, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error) +nm_settings_plugin_add_connection(NMSettingsPlugin * self, + NMConnection * connection, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error) { - NMSettingsPluginClass *klass; + NMSettingsPluginClass *klass; - g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_PLUGIN(self), FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); #if NM_MORE_ASSERTS > 5 - nm_assert (nm_connection_verify (connection, NULL)); + nm_assert(nm_connection_verify(connection, NULL)); #endif - NM_SET_OUT (out_storage, NULL); - NM_SET_OUT (out_connection, NULL); - - klass = NM_SETTINGS_PLUGIN_GET_CLASS (self); - if (!klass->add_connection) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, - "settings plugin does not support adding connections"); - return FALSE; - } - return klass->add_connection (self, - connection, - out_storage, - out_connection, - error); + NM_SET_OUT(out_storage, NULL); + NM_SET_OUT(out_connection, NULL); + + klass = NM_SETTINGS_PLUGIN_GET_CLASS(self); + if (!klass->add_connection) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_SUPPORTED, + "settings plugin does not support adding connections"); + return FALSE; + } + return klass->add_connection(self, connection, out_storage, out_connection, error); } gboolean -nm_settings_plugin_update_connection (NMSettingsPlugin *self, - NMSettingsStorage *storage, - NMConnection *connection, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error) +nm_settings_plugin_update_connection(NMSettingsPlugin * self, + NMSettingsStorage * storage, + NMConnection * connection, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error) { - NMSettingsPluginClass *klass = NULL; + NMSettingsPluginClass *klass = NULL; - g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (storage), FALSE); - g_return_val_if_fail (nm_settings_storage_get_plugin (storage) == self, FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_PLUGIN(self), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(storage), FALSE); + g_return_val_if_fail(nm_settings_storage_get_plugin(storage) == self, FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); #if NM_MORE_ASSERTS > 5 - nm_assert (nm_connection_verify (connection, NULL)); - nm_assert (nm_streq (nm_connection_get_uuid (connection), nm_settings_storage_get_uuid (storage))); + nm_assert(nm_connection_verify(connection, NULL)); + nm_assert(nm_streq(nm_connection_get_uuid(connection), nm_settings_storage_get_uuid(storage))); #endif - klass = NM_SETTINGS_PLUGIN_GET_CLASS (self); - - NM_SET_OUT (out_storage, NULL); - NM_SET_OUT (out_connection, NULL); - - if (!klass->update_connection) { - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_NOT_SUPPORTED, - "settings plugin does not support modifying connections"); - return FALSE; - } - return klass->update_connection (self, - storage, - connection, - out_storage, - out_connection, - error); + klass = NM_SETTINGS_PLUGIN_GET_CLASS(self); + + NM_SET_OUT(out_storage, NULL); + NM_SET_OUT(out_connection, NULL); + + if (!klass->update_connection) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_SUPPORTED, + "settings plugin does not support modifying connections"); + return FALSE; + } + return klass->update_connection(self, storage, connection, out_storage, out_connection, error); } gboolean -nm_settings_plugin_delete_connection (NMSettingsPlugin *self, - NMSettingsStorage *storage, - GError **error) +nm_settings_plugin_delete_connection(NMSettingsPlugin * self, + NMSettingsStorage *storage, + GError ** error) { - NMSettingsPluginClass *klass = NULL; + NMSettingsPluginClass *klass = NULL; - g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (storage), FALSE); - g_return_val_if_fail (nm_settings_storage_get_plugin (storage) == self, FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_PLUGIN(self), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(storage), FALSE); + g_return_val_if_fail(nm_settings_storage_get_plugin(storage) == self, FALSE); - klass = NM_SETTINGS_PLUGIN_GET_CLASS (self); + klass = NM_SETTINGS_PLUGIN_GET_CLASS(self); - if (!klass->delete_connection) { - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_NOT_SUPPORTED, - "settings plugin does not support deleting connections"); - return FALSE; - } + if (!klass->delete_connection) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_SUPPORTED, + "settings plugin does not support deleting connections"); + return FALSE; + } - return klass->delete_connection (self, - storage, - error); + return klass->delete_connection(self, storage, error); } /*****************************************************************************/ void -_nm_settings_plugin_emit_signal_unmanaged_specs_changed (NMSettingsPlugin *self) +_nm_settings_plugin_emit_signal_unmanaged_specs_changed(NMSettingsPlugin *self) { - nm_assert (NM_IS_SETTINGS_PLUGIN (self)); + nm_assert(NM_IS_SETTINGS_PLUGIN(self)); - g_signal_emit (self, signals[UNMANAGED_SPECS_CHANGED], 0); + g_signal_emit(self, signals[UNMANAGED_SPECS_CHANGED], 0); } void -_nm_settings_plugin_emit_signal_unrecognized_specs_changed (NMSettingsPlugin *self) +_nm_settings_plugin_emit_signal_unrecognized_specs_changed(NMSettingsPlugin *self) { - nm_assert (NM_IS_SETTINGS_PLUGIN (self)); + nm_assert(NM_IS_SETTINGS_PLUGIN(self)); - g_signal_emit (self, signals[UNRECOGNIZED_SPECS_CHANGED], 0); + g_signal_emit(self, signals[UNRECOGNIZED_SPECS_CHANGED], 0); } /*****************************************************************************/ static void -nm_settings_plugin_init (NMSettingsPlugin *self) -{ -} +nm_settings_plugin_init(NMSettingsPlugin *self) +{} static void -nm_settings_plugin_class_init (NMSettingsPluginClass *klass) +nm_settings_plugin_class_init(NMSettingsPluginClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - signals[UNMANAGED_SPECS_CHANGED] = - g_signal_new (NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[UNRECOGNIZED_SPECS_CHANGED] = - g_signal_new (NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + signals[UNMANAGED_SPECS_CHANGED] = g_signal_new(NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + signals[UNRECOGNIZED_SPECS_CHANGED] = + g_signal_new(NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); } diff --git a/src/settings/nm-settings-plugin.h b/src/settings/nm-settings-plugin.h index d27429db..d4e8d396 100644 --- a/src/settings/nm-settings-plugin.h +++ b/src/settings/nm-settings-plugin.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2007 - 2018 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. @@ -13,186 +13,188 @@ typedef struct _NMSettingsPlugin NMSettingsPlugin; -typedef void (*NMSettingsPluginConnectionLoadCallback) (NMSettingsPlugin *self, - NMSettingsStorage *storage, - NMConnection *connection, - gpointer user_data); +typedef void (*NMSettingsPluginConnectionLoadCallback)(NMSettingsPlugin * self, + NMSettingsStorage *storage, + NMConnection * connection, + gpointer user_data); typedef struct { - const char *filename; - GError *error; - bool handled:1; + const char *filename; + GError * error; + bool handled : 1; } NMSettingsPluginConnectionLoadEntry; -#define NM_TYPE_SETTINGS_PLUGIN (nm_settings_plugin_get_type ()) -#define NM_SETTINGS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPlugin)) -#define NM_SETTINGS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPluginClass)) -#define NM_IS_SETTINGS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_PLUGIN)) -#define NM_IS_SETTINGS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS_PLUGIN)) -#define NM_SETTINGS_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPluginClass)) +#define NM_TYPE_SETTINGS_PLUGIN (nm_settings_plugin_get_type()) +#define NM_SETTINGS_PLUGIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPlugin)) +#define NM_SETTINGS_PLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPluginClass)) +#define NM_IS_SETTINGS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTINGS_PLUGIN)) +#define NM_IS_SETTINGS_PLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTINGS_PLUGIN)) +#define NM_SETTINGS_PLUGIN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPluginClass)) #define NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED "unmanaged-specs-changed" #define NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED "unrecognized-specs-changed" struct _NMSettingsPlugin { - GObject parent; + GObject parent; }; typedef struct { - GObjectClass parent; - - /* - * Return a string list of specifications of devices which NetworkManager - * should not manage. Returned list will be freed by the system settings - * service, and each element must be allocated using g_malloc() or its - * variants (g_strdup, g_strdup_printf, etc). - * - * Each string in the list must be in one of the formats recognized by - * nm_device_spec_match_list(). - */ - GSList * (*get_unmanaged_specs) (NMSettingsPlugin *self); - - /* - * Return a string list of specifications of devices for which at least - * one non-NetworkManager-based configuration is defined. Returned list - * will be freed by the system settings service, and each element must be - * allocated using g_malloc() or its variants (g_strdup, g_strdup_printf, - * etc). - * - * Each string in the list must be in one of the formats recognized by - * nm_device_spec_match_list(). - */ - GSList * (*get_unrecognized_specs) (NMSettingsPlugin *self); - - /* Requests that the plugin load/reload a set of filenames. - */ - void (*load_connections) (NMSettingsPlugin *self, - NMSettingsPluginConnectionLoadEntry *entries, - gsize n_entries, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data); - - /* Requests that the plugin reload all connection files from disk, - * and emit signals reflecting new, changed, and removed connections. - */ - void (*reload_connections) (NMSettingsPlugin *self, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data); - - void (*load_connections_done) (NMSettingsPlugin *self); - - gboolean (*add_connection) (NMSettingsPlugin *self, - NMConnection *connection, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error); - - gboolean (*update_connection) (NMSettingsPlugin *self, - NMSettingsStorage *storage, - NMConnection *connection, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error); - - gboolean (*delete_connection) (NMSettingsPlugin *self, - NMSettingsStorage *storage, - GError **error); - - const char *plugin_name; + GObjectClass parent; + + /* + * Return a string list of specifications of devices which NetworkManager + * should not manage. Returned list will be freed by the system settings + * service, and each element must be allocated using g_malloc() or its + * variants (g_strdup, g_strdup_printf, etc). + * + * Each string in the list must be in one of the formats recognized by + * nm_device_spec_match_list(). + */ + GSList *(*get_unmanaged_specs)(NMSettingsPlugin *self); + + /* + * Return a string list of specifications of devices for which at least + * one non-NetworkManager-based configuration is defined. Returned list + * will be freed by the system settings service, and each element must be + * allocated using g_malloc() or its variants (g_strdup, g_strdup_printf, + * etc). + * + * Each string in the list must be in one of the formats recognized by + * nm_device_spec_match_list(). + */ + GSList *(*get_unrecognized_specs)(NMSettingsPlugin *self); + + /* Requests that the plugin load/reload a set of filenames. + */ + void (*load_connections)(NMSettingsPlugin * self, + NMSettingsPluginConnectionLoadEntry * entries, + gsize n_entries, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data); + + /* Requests that the plugin reload all connection files from disk, + * and emit signals reflecting new, changed, and removed connections. + */ + void (*reload_connections)(NMSettingsPlugin * self, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data); + + void (*load_connections_done)(NMSettingsPlugin *self); + + gboolean (*add_connection)(NMSettingsPlugin * self, + NMConnection * connection, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error); + + gboolean (*update_connection)(NMSettingsPlugin * self, + NMSettingsStorage * storage, + NMConnection * connection, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error); + + gboolean (*delete_connection)(NMSettingsPlugin * self, + NMSettingsStorage *storage, + GError ** error); + + const char *plugin_name; } NMSettingsPluginClass; /*****************************************************************************/ -GType nm_settings_plugin_get_type (void); +GType nm_settings_plugin_get_type(void); /*****************************************************************************/ -#define NM_SETTINGS_STORAGE_PRINT_FMT \ - NM_HASH_OBFUSCATE_PTR_FMT"/%s" +#define NM_SETTINGS_STORAGE_PRINT_FMT NM_HASH_OBFUSCATE_PTR_FMT "/%s" -#define NM_SETTINGS_STORAGE_PRINT_ARG(storage) \ - NM_HASH_OBFUSCATE_PTR (storage), \ - nm_settings_plugin_get_plugin_name (nm_settings_storage_get_plugin (storage)) +#define NM_SETTINGS_STORAGE_PRINT_ARG(storage) \ + NM_HASH_OBFUSCATE_PTR(storage), \ + nm_settings_plugin_get_plugin_name(nm_settings_storage_get_plugin(storage)) static inline const char * -nm_settings_plugin_get_plugin_name (NMSettingsPlugin *self) +nm_settings_plugin_get_plugin_name(NMSettingsPlugin *self) { - NMSettingsPluginClass *klass; + NMSettingsPluginClass *klass; - nm_assert (NM_SETTINGS_PLUGIN (self)); + nm_assert(NM_SETTINGS_PLUGIN(self)); - klass = NM_SETTINGS_PLUGIN_GET_CLASS (self); + klass = NM_SETTINGS_PLUGIN_GET_CLASS(self); - nm_assert (klass && klass->plugin_name && strlen (klass->plugin_name) > 0); + nm_assert(klass && klass->plugin_name && strlen(klass->plugin_name) > 0); - return klass->plugin_name; + return klass->plugin_name; } /*****************************************************************************/ -GSList *nm_settings_plugin_get_unmanaged_specs (NMSettingsPlugin *self); -GSList *nm_settings_plugin_get_unrecognized_specs (NMSettingsPlugin *self); +GSList *nm_settings_plugin_get_unmanaged_specs(NMSettingsPlugin *self); +GSList *nm_settings_plugin_get_unrecognized_specs(NMSettingsPlugin *self); -void nm_settings_plugin_reload_connections (NMSettingsPlugin *self, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data); +void nm_settings_plugin_reload_connections(NMSettingsPlugin * self, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data); -NMSettingsPluginConnectionLoadEntry *nm_settings_plugin_create_connection_load_entries (const char *const*filenames, - gsize *out_len); +NMSettingsPluginConnectionLoadEntry * +nm_settings_plugin_create_connection_load_entries(const char *const *filenames, gsize *out_len); -void nm_settings_plugin_load_connections (NMSettingsPlugin *self, - NMSettingsPluginConnectionLoadEntry *entries, - gsize n_entries, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data); +void nm_settings_plugin_load_connections(NMSettingsPlugin * self, + NMSettingsPluginConnectionLoadEntry * entries, + gsize n_entries, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data); -void nm_settings_plugin_load_connections_done (NMSettingsPlugin *self); +void nm_settings_plugin_load_connections_done(NMSettingsPlugin *self); -gboolean nm_settings_plugin_add_connection (NMSettingsPlugin *self, - NMConnection *connection, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error); +gboolean nm_settings_plugin_add_connection(NMSettingsPlugin * self, + NMConnection * connection, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error); -gboolean nm_settings_plugin_update_connection (NMSettingsPlugin *self, - NMSettingsStorage *storage, - NMConnection *connection, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error); +gboolean nm_settings_plugin_update_connection(NMSettingsPlugin * self, + NMSettingsStorage * storage, + NMConnection * connection, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error); -gboolean nm_settings_plugin_delete_connection (NMSettingsPlugin *self, - NMSettingsStorage *storage, - GError **error); +gboolean nm_settings_plugin_delete_connection(NMSettingsPlugin * self, + NMSettingsStorage *storage, + GError ** error); /*****************************************************************************/ -typedef NMSettingsPlugin *(*NMSettingsPluginFactoryFunc) (void); +typedef NMSettingsPlugin *(*NMSettingsPluginFactoryFunc)(void); -NMSettingsPlugin *nm_settings_plugin_factory (void); +NMSettingsPlugin *nm_settings_plugin_factory(void); /***************************************************************************** * Internal API *****************************************************************************/ -void _nm_settings_plugin_emit_signal_unmanaged_specs_changed (NMSettingsPlugin *self); +void _nm_settings_plugin_emit_signal_unmanaged_specs_changed(NMSettingsPlugin *self); -void _nm_settings_plugin_emit_signal_unrecognized_specs_changed (NMSettingsPlugin *self); +void _nm_settings_plugin_emit_signal_unrecognized_specs_changed(NMSettingsPlugin *self); /*****************************************************************************/ -int nm_settings_plugin_cmp_by_priority (const NMSettingsPlugin *a, - const NMSettingsPlugin *b, - const GSList *plugin_list); +int nm_settings_plugin_cmp_by_priority(const NMSettingsPlugin *a, + const NMSettingsPlugin *b, + const GSList * plugin_list); /*****************************************************************************/ /* forward declare this function from NMSettings. It's used by the ifcfg-rh plugin, * but that shouldn't include all "nm-settings.h" header. */ -NMSettings *nm_settings_get (void); +NMSettings *nm_settings_get(void); -const char *nm_settings_get_dbus_path_for_uuid (NMSettings *self, - const char *uuid); +const char *nm_settings_get_dbus_path_for_uuid(NMSettings *self, const char *uuid); #endif /* __NM_SETTINGS_PLUGIN_H__ */ diff --git a/src/settings/nm-settings-storage.c b/src/settings/nm-settings-storage.c index 483773f6..7fa83e21 100644 --- a/src/settings/nm-settings-storage.c +++ b/src/settings/nm-settings-storage.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -15,150 +15,143 @@ /*****************************************************************************/ int -nm_settings_storage_cmp (NMSettingsStorage *a, - NMSettingsStorage *b, - const GSList *plugin_list) +nm_settings_storage_cmp(NMSettingsStorage *a, NMSettingsStorage *b, const GSList *plugin_list) { - NMSettingsStorageClass *klass; - - /* Sort by priority. - * - * If a > b (by priority), we return a positive number (as one - * would expect by a cmp() function). */ - - nm_assert (NM_IS_SETTINGS_STORAGE (a)); - nm_assert (NM_IS_SETTINGS_STORAGE (b)); - nm_assert (a != b); - nm_assert (nm_streq (nm_settings_storage_get_uuid (a), nm_settings_storage_get_uuid (b))); - - /* in-memory has always higher priority */ - NM_CMP_DIRECT (nm_settings_storage_is_keyfile_run (a), - nm_settings_storage_is_keyfile_run (b)); - - NM_CMP_RETURN (nm_settings_plugin_cmp_by_priority (nm_settings_storage_get_plugin (a), - nm_settings_storage_get_plugin (b), - plugin_list)); - - klass = NM_SETTINGS_STORAGE_GET_CLASS (a); - if (klass != NM_SETTINGS_STORAGE_GET_CLASS (b)) { - /* one plugin must return storages of the same type. Otherwise, it's - * unclear how cmp_fcn() should compare them. */ - nm_assert_not_reached (); - return 0; - } - - if (klass->cmp_fcn) - NM_CMP_RETURN (klass->cmp_fcn (a, b)); - - return 0; + NMSettingsStorageClass *klass; + + /* Sort by priority. + * + * If a > b (by priority), we return a positive number (as one + * would expect by a cmp() function). */ + + nm_assert(NM_IS_SETTINGS_STORAGE(a)); + nm_assert(NM_IS_SETTINGS_STORAGE(b)); + nm_assert(a != b); + nm_assert(nm_streq(nm_settings_storage_get_uuid(a), nm_settings_storage_get_uuid(b))); + + /* in-memory has always higher priority */ + NM_CMP_DIRECT(nm_settings_storage_is_keyfile_run(a), nm_settings_storage_is_keyfile_run(b)); + + NM_CMP_RETURN(nm_settings_plugin_cmp_by_priority(nm_settings_storage_get_plugin(a), + nm_settings_storage_get_plugin(b), + plugin_list)); + + klass = NM_SETTINGS_STORAGE_GET_CLASS(a); + if (klass != NM_SETTINGS_STORAGE_GET_CLASS(b)) { + /* one plugin must return storages of the same type. Otherwise, it's + * unclear how cmp_fcn() should compare them. */ + nm_assert_not_reached(); + return 0; + } + + if (klass->cmp_fcn) + NM_CMP_RETURN(klass->cmp_fcn(a, b)); + + return 0; } /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_PLUGIN, - PROP_UUID, - PROP_FILENAME, -); +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PLUGIN, PROP_UUID, PROP_FILENAME, ); -G_DEFINE_TYPE (NMSettingsStorage, nm_settings_storage, G_TYPE_OBJECT) +G_DEFINE_TYPE(NMSettingsStorage, nm_settings_storage, G_TYPE_OBJECT) /*****************************************************************************/ static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMSettingsStorage *self = NM_SETTINGS_STORAGE (object); - - switch (prop_id) { - case PROP_PLUGIN: - /* construct-only */ - self->_plugin = g_object_ref (g_value_get_object (value)); - nm_assert (NM_IS_SETTINGS_PLUGIN (self->_plugin)); - break; - case PROP_UUID: - /* construct-only */ - self->_uuid = g_value_dup_string (value); - nm_assert (!self->_uuid || nm_utils_is_uuid (self->_uuid)); - break; - case PROP_FILENAME: - /* construct-only */ - self->_filename = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMSettingsStorage *self = NM_SETTINGS_STORAGE(object); + + switch (prop_id) { + case PROP_PLUGIN: + /* construct-only */ + self->_plugin = g_object_ref(g_value_get_object(value)); + nm_assert(NM_IS_SETTINGS_PLUGIN(self->_plugin)); + break; + case PROP_UUID: + /* construct-only */ + self->_uuid = g_value_dup_string(value); + nm_assert(!self->_uuid || nm_utils_is_uuid(self->_uuid)); + break; + case PROP_FILENAME: + /* construct-only */ + self->_filename = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_settings_storage_init (NMSettingsStorage *self) +nm_settings_storage_init(NMSettingsStorage *self) { - c_list_init (&self->_storage_lst); - c_list_init (&self->_storage_by_uuid_lst); + c_list_init(&self->_storage_lst); + c_list_init(&self->_storage_by_uuid_lst); } NMSettingsStorage * -nm_settings_storage_new (NMSettingsPlugin *plugin, - const char *uuid, - const char *filename) +nm_settings_storage_new(NMSettingsPlugin *plugin, const char *uuid, const char *filename) { - nm_assert (NM_IS_SETTINGS_PLUGIN (plugin)); - nm_assert (nm_utils_is_uuid (uuid)); - - return g_object_new (NM_TYPE_SETTINGS_STORAGE, - NM_SETTINGS_STORAGE_PLUGIN, plugin, - NM_SETTINGS_STORAGE_UUID, uuid, - NM_SETTINGS_STORAGE_FILENAME, filename, - NULL); + nm_assert(NM_IS_SETTINGS_PLUGIN(plugin)); + nm_assert(nm_utils_is_uuid(uuid)); + + return g_object_new(NM_TYPE_SETTINGS_STORAGE, + NM_SETTINGS_STORAGE_PLUGIN, + plugin, + NM_SETTINGS_STORAGE_UUID, + uuid, + NM_SETTINGS_STORAGE_FILENAME, + filename, + NULL); } static void -finalize (GObject *object) +finalize(GObject *object) { - NMSettingsStorage *self = NM_SETTINGS_STORAGE (object); + NMSettingsStorage *self = NM_SETTINGS_STORAGE(object); - c_list_unlink_stale (&self->_storage_lst); - c_list_unlink_stale (&self->_storage_by_uuid_lst); + c_list_unlink_stale(&self->_storage_lst); + c_list_unlink_stale(&self->_storage_by_uuid_lst); - g_object_unref (self->_plugin); - g_free (self->_uuid); - g_free (self->_filename); + g_object_unref(self->_plugin); + g_free(self->_uuid); + g_free(self->_filename); - G_OBJECT_CLASS (nm_settings_storage_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_settings_storage_parent_class)->finalize(object); } static void -nm_settings_storage_class_init (NMSettingsStorageClass *klass) +nm_settings_storage_class_init(NMSettingsStorageClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = set_property; - object_class->finalize = finalize; - - obj_properties[PROP_PLUGIN] = - g_param_spec_object (NM_SETTINGS_STORAGE_PLUGIN, "", "", - NM_TYPE_SETTINGS_PLUGIN, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_UUID] = - g_param_spec_string (NM_SETTINGS_STORAGE_UUID, "", "", - NULL, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_FILENAME] = - g_param_spec_string (NM_SETTINGS_STORAGE_FILENAME, "", "", - NULL, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->set_property = set_property; + object_class->finalize = finalize; + + obj_properties[PROP_PLUGIN] = + g_param_spec_object(NM_SETTINGS_STORAGE_PLUGIN, + "", + "", + NM_TYPE_SETTINGS_PLUGIN, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_UUID] = + g_param_spec_string(NM_SETTINGS_STORAGE_UUID, + "", + "", + NULL, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_FILENAME] = + g_param_spec_string(NM_SETTINGS_STORAGE_FILENAME, + "", + "", + NULL, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/settings/nm-settings-storage.h b/src/settings/nm-settings-storage.h index 62ee8876..8f2bc3d2 100644 --- a/src/settings/nm-settings-storage.h +++ b/src/settings/nm-settings-storage.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -10,12 +10,16 @@ #include "c-list/src/c-list.h" -#define NM_TYPE_SETTINGS_STORAGE (nm_settings_storage_get_type ()) -#define NM_SETTINGS_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_STORAGE, NMSettingsStorage)) -#define NM_SETTINGS_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_STORAGE, NMSettingsStorageClass)) -#define NM_IS_SETTINGS_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_STORAGE)) -#define NM_IS_SETTINGS_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS_STORAGE)) -#define NM_SETTINGS_STORAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_STORAGE, NMSettingsStorageClass)) +#define NM_TYPE_SETTINGS_STORAGE (nm_settings_storage_get_type()) +#define NM_SETTINGS_STORAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTINGS_STORAGE, NMSettingsStorage)) +#define NM_SETTINGS_STORAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTINGS_STORAGE, NMSettingsStorageClass)) +#define NM_IS_SETTINGS_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTINGS_STORAGE)) +#define NM_IS_SETTINGS_STORAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTINGS_STORAGE)) +#define NM_SETTINGS_STORAGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTINGS_STORAGE, NMSettingsStorageClass)) #define NM_SETTINGS_STORAGE_PLUGIN "plugin" #define NM_SETTINGS_STORAGE_UUID "uuid" @@ -24,85 +28,85 @@ struct _NMSettingsPlugin; typedef struct NMSettingsStorage { - GObject parent; - struct _NMSettingsPlugin *_plugin; - char *_uuid; - char *_filename; - CList _storage_lst; - CList _storage_by_uuid_lst; + GObject parent; + struct _NMSettingsPlugin *_plugin; + char * _uuid; + char * _filename; + CList _storage_lst; + CList _storage_by_uuid_lst; } NMSettingsStorage; typedef struct { - GObjectClass parent; + GObjectClass parent; - int (*cmp_fcn) (NMSettingsStorage *a, - NMSettingsStorage *b); + int (*cmp_fcn)(NMSettingsStorage *a, NMSettingsStorage *b); } NMSettingsStorageClass; -GType nm_settings_storage_get_type (void); +GType nm_settings_storage_get_type(void); -NMSettingsStorage *nm_settings_storage_new (struct _NMSettingsPlugin *plugin, - const char *uuid, - const char *filename); +NMSettingsStorage * +nm_settings_storage_new(struct _NMSettingsPlugin *plugin, const char *uuid, const char *filename); static inline struct _NMSettingsPlugin * -nm_settings_storage_get_plugin (const NMSettingsStorage *self) +nm_settings_storage_get_plugin(const NMSettingsStorage *self) { - GType nm_settings_plugin_get_type (void); + GType nm_settings_plugin_get_type(void); - g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(self), NULL); - nm_assert (G_TYPE_CHECK_INSTANCE_TYPE (self->_plugin, nm_settings_plugin_get_type ())); - return self->_plugin; + nm_assert(G_TYPE_CHECK_INSTANCE_TYPE(self->_plugin, nm_settings_plugin_get_type())); + return self->_plugin; } static inline const char * -nm_settings_storage_get_uuid (const NMSettingsStorage *self) +nm_settings_storage_get_uuid(const NMSettingsStorage *self) { - gboolean nm_utils_is_uuid (const char *str); + gboolean nm_utils_is_uuid(const char *str); - g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(self), NULL); - nm_assert (nm_utils_is_uuid (self->_uuid)); - return self->_uuid; + nm_assert(nm_utils_is_uuid(self->_uuid)); + return self->_uuid; } static inline const char * -nm_settings_storage_get_uuid_opt (const NMSettingsStorage *self) +nm_settings_storage_get_uuid_opt(const NMSettingsStorage *self) { - gboolean nm_utils_is_uuid (const char *str); + gboolean nm_utils_is_uuid(const char *str); - g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(self), NULL); - nm_assert (!self->_uuid || nm_utils_is_uuid (self->_uuid)); - return self->_uuid; + nm_assert(!self->_uuid || nm_utils_is_uuid(self->_uuid)); + return self->_uuid; } static inline const char * -nm_settings_storage_get_filename (const NMSettingsStorage *self) +nm_settings_storage_get_filename(const NMSettingsStorage *self) { - g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(self), NULL); - return self->_filename; + return self->_filename; } /*****************************************************************************/ -#define nm_assert_valid_settings_storage(plugin, storage) \ - G_STMT_START { \ - NMSettingsPlugin *const _plugin = (plugin); \ - NMSettingsStorage *const _storage = (storage); \ - \ - nm_assert (!_plugin || NM_IS_SETTINGS_PLUGIN (_plugin)); \ - nm_assert (NM_IS_SETTINGS_STORAGE (_storage)); \ - nm_assert (!_plugin || nm_settings_storage_get_plugin (_storage) == _plugin); \ - } G_STMT_END +#define nm_assert_valid_settings_storage(plugin, storage) \ + G_STMT_START \ + { \ + NMSettingsPlugin *const _plugin = (plugin); \ + NMSettingsStorage *const _storage = (storage); \ + \ + nm_assert(!_plugin || NM_IS_SETTINGS_PLUGIN(_plugin)); \ + nm_assert(NM_IS_SETTINGS_STORAGE(_storage)); \ + nm_assert(!_plugin || nm_settings_storage_get_plugin(_storage) == _plugin); \ + } \ + G_STMT_END /*****************************************************************************/ -int nm_settings_storage_cmp (NMSettingsStorage *sd_a, - NMSettingsStorage *sd_b, - const GSList *plugin_list); +int nm_settings_storage_cmp(NMSettingsStorage *sd_a, + NMSettingsStorage *sd_b, + const GSList * plugin_list); #endif /* __NM_SETTINGS_STORAGE_H__ */ diff --git a/src/settings/nm-settings-utils.c b/src/settings/nm-settings-utils.c index c5ec6c31..8e032c44 100644 --- a/src/settings/nm-settings-utils.c +++ b/src/settings/nm-settings-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2019 Red Hat, Inc. */ @@ -17,145 +17,145 @@ /*****************************************************************************/ const struct timespec * -nm_sett_util_stat_mtime (const char *filename, - gboolean do_lstat, - struct timespec *out_val) +nm_sett_util_stat_mtime(const char *filename, gboolean do_lstat, struct timespec *out_val) { - struct stat st; - struct timeval now_tv; - - if (filename) { - if (do_lstat) { - if (lstat (filename, &st) == 0) { - *out_val = st.st_mtim; - return out_val; - } - } else { - if (stat (filename, &st) == 0) { - *out_val = st.st_mtim; - return out_val; - } - } - } - - if (gettimeofday (&now_tv, NULL) == 0) { - *out_val = (struct timespec) { - .tv_sec = now_tv.tv_sec, - .tv_nsec = now_tv.tv_usec * 1000u, - }; - return out_val; - } - - *out_val = (struct timespec) { }; - return out_val; + struct stat st; + struct timeval now_tv; + + if (filename) { + if (do_lstat) { + if (lstat(filename, &st) == 0) { + *out_val = st.st_mtim; + return out_val; + } + } else { + if (stat(filename, &st) == 0) { + *out_val = st.st_mtim; + return out_val; + } + } + } + + if (gettimeofday(&now_tv, NULL) == 0) { + *out_val = (struct timespec){ + .tv_sec = now_tv.tv_sec, + .tv_nsec = now_tv.tv_usec * 1000u, + }; + return out_val; + } + + *out_val = (struct timespec){}; + return out_val; } /*****************************************************************************/ gboolean -nm_sett_util_allow_filename_cb (const char *filename, - gpointer user_data) +nm_sett_util_allow_filename_cb(const char *filename, gpointer user_data) { - const NMSettUtilAllowFilenameData *allow_filename_data = user_data; + const NMSettUtilAllowFilenameData *allow_filename_data = user_data; - if ( allow_filename_data->allowed_filename - && nm_streq (allow_filename_data->allowed_filename, filename)) - return TRUE; + if (allow_filename_data->allowed_filename + && nm_streq(allow_filename_data->allowed_filename, filename)) + return TRUE; - return !g_hash_table_contains (allow_filename_data->idx_by_filename, filename); + return !g_hash_table_contains(allow_filename_data->idx_by_filename, filename); } /*****************************************************************************/ void -nm_sett_util_storage_by_uuid_head_destroy (NMSettUtilStorageByUuidHead *sbuh) +nm_sett_util_storage_by_uuid_head_destroy(NMSettUtilStorageByUuidHead *sbuh) { - CList *iter; + CList *iter; - while ((iter = c_list_first (&sbuh->_storage_by_uuid_lst_head))) - c_list_unlink (iter); - g_free (sbuh); + while ((iter = c_list_first(&sbuh->_storage_by_uuid_lst_head))) + c_list_unlink(iter); + g_free(sbuh); } /*****************************************************************************/ void -nm_sett_util_storages_clear (NMSettUtilStorages *storages) +nm_sett_util_storages_clear(NMSettUtilStorages *storages) { - nm_clear_pointer (&storages->idx_by_uuid, g_hash_table_destroy); - nm_clear_pointer (&storages->idx_by_filename, g_hash_table_destroy); - nm_assert (c_list_is_empty (&storages->_storage_lst_head)); + nm_clear_pointer(&storages->idx_by_uuid, g_hash_table_destroy); + nm_clear_pointer(&storages->idx_by_filename, g_hash_table_destroy); + nm_assert(c_list_is_empty(&storages->_storage_lst_head)); } void -nm_sett_util_storages_add_take (NMSettUtilStorages *storages, - gpointer storage_take_p /* NMSettingsStorage *, take reference */) +nm_sett_util_storages_add_take(NMSettUtilStorages *storages, + gpointer storage_take_p /* NMSettingsStorage *, take reference */) { - NMSettingsStorage *storage_take = storage_take_p; - NMSettUtilStorageByUuidHead *sbuh; - const char *uuid; - - nm_assert (storage_take); - nm_assert (c_list_is_empty (&storage_take->_storage_lst)); - nm_assert (c_list_is_empty (&storage_take->_storage_by_uuid_lst)); - nm_assert (nm_settings_storage_get_filename (storage_take)); - - if (!g_hash_table_replace (storages->idx_by_filename, - (char *) nm_settings_storage_get_filename (storage_take), - storage_take /* takes ownership of reference. */)) - nm_assert_not_reached (); - - uuid = nm_settings_storage_get_uuid_opt (storage_take); - - if (uuid) { - sbuh = nm_sett_util_storages_lookup_by_uuid (storages, uuid); - if (!sbuh) { - gsize l = strlen (uuid) + 1; - - sbuh = g_malloc (sizeof (NMSettUtilStorageByUuidHead) + l); - sbuh->uuid = sbuh->uuid_data; - c_list_init (&sbuh->_storage_by_uuid_lst_head); - memcpy (sbuh->uuid_data, uuid, l); - g_hash_table_add (storages->idx_by_uuid, sbuh); - } - c_list_link_tail (&sbuh->_storage_by_uuid_lst_head, &storage_take->_storage_by_uuid_lst); - } - - c_list_link_tail (&storages->_storage_lst_head, &storage_take->_storage_lst); + NMSettingsStorage * storage_take = storage_take_p; + NMSettUtilStorageByUuidHead *sbuh; + const char * uuid; + + nm_assert(storage_take); + nm_assert(c_list_is_empty(&storage_take->_storage_lst)); + nm_assert(c_list_is_empty(&storage_take->_storage_by_uuid_lst)); + nm_assert(nm_settings_storage_get_filename(storage_take)); + + if (!g_hash_table_replace(storages->idx_by_filename, + (char *) nm_settings_storage_get_filename(storage_take), + storage_take /* takes ownership of reference. */)) + nm_assert_not_reached(); + + uuid = nm_settings_storage_get_uuid_opt(storage_take); + + if (uuid) { + sbuh = nm_sett_util_storages_lookup_by_uuid(storages, uuid); + if (!sbuh) { + gsize l = strlen(uuid) + 1; + + sbuh = g_malloc(sizeof(NMSettUtilStorageByUuidHead) + l); + sbuh->uuid = sbuh->uuid_data; + c_list_init(&sbuh->_storage_by_uuid_lst_head); + memcpy(sbuh->uuid_data, uuid, l); + g_hash_table_add(storages->idx_by_uuid, sbuh); + } + c_list_link_tail(&sbuh->_storage_by_uuid_lst_head, &storage_take->_storage_by_uuid_lst); + } + + c_list_link_tail(&storages->_storage_lst_head, &storage_take->_storage_lst); } gpointer /* NMSettingsStorage * */ -nm_sett_util_storages_steal (NMSettUtilStorages *storages, - gpointer storage_p /* NMSettingsStorage **/) +nm_sett_util_storages_steal(NMSettUtilStorages *storages, + gpointer storage_p /* NMSettingsStorage **/) { - NMSettingsStorage *storage = storage_p; - NMSettUtilStorageByUuidHead *sbuh; - const char *uuid; + NMSettingsStorage * storage = storage_p; + NMSettUtilStorageByUuidHead *sbuh; + const char * uuid; - nm_assert (storage); - nm_assert (nm_sett_util_storages_lookup_by_filename (storages, nm_settings_storage_get_filename (storage)) == storage); - nm_assert (c_list_contains (&storages->_storage_lst_head, &storage->_storage_lst)); + nm_assert(storage); + nm_assert(nm_sett_util_storages_lookup_by_filename(storages, + nm_settings_storage_get_filename(storage)) + == storage); + nm_assert(c_list_contains(&storages->_storage_lst_head, &storage->_storage_lst)); - uuid = nm_settings_storage_get_uuid_opt (storage); + uuid = nm_settings_storage_get_uuid_opt(storage); - if (!uuid) { - nm_assert (c_list_is_empty (&storage->_storage_by_uuid_lst)); - } else { - nm_assert (!c_list_is_empty (&storage->_storage_by_uuid_lst)); + if (!uuid) { + nm_assert(c_list_is_empty(&storage->_storage_by_uuid_lst)); + } else { + nm_assert(!c_list_is_empty(&storage->_storage_by_uuid_lst)); - sbuh = nm_sett_util_storages_lookup_by_uuid (storages, uuid); + sbuh = nm_sett_util_storages_lookup_by_uuid(storages, uuid); - nm_assert (sbuh); - nm_assert (c_list_contains (&sbuh->_storage_by_uuid_lst_head, &storage->_storage_by_uuid_lst)); - c_list_unlink (&storage->_storage_by_uuid_lst); + nm_assert(sbuh); + nm_assert( + c_list_contains(&sbuh->_storage_by_uuid_lst_head, &storage->_storage_by_uuid_lst)); + c_list_unlink(&storage->_storage_by_uuid_lst); - if (c_list_is_empty (&sbuh->_storage_by_uuid_lst_head)) - g_hash_table_remove (storages->idx_by_uuid, sbuh); - } + if (c_list_is_empty(&sbuh->_storage_by_uuid_lst_head)) + g_hash_table_remove(storages->idx_by_uuid, sbuh); + } - c_list_unlink (&storage->_storage_lst); + c_list_unlink(&storage->_storage_lst); - g_hash_table_steal (storages->idx_by_filename, nm_settings_storage_get_filename (storage)); + g_hash_table_steal(storages->idx_by_filename, nm_settings_storage_get_filename(storage)); - return storage; + return storage; } diff --git a/src/settings/nm-settings-utils.h b/src/settings/nm-settings-utils.h index 1f9a6ea1..b03c14b0 100644 --- a/src/settings/nm-settings-utils.h +++ b/src/settings/nm-settings-utils.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2019 Red Hat, Inc. */ @@ -12,85 +12,80 @@ struct timespec; -const struct timespec *nm_sett_util_stat_mtime (const char *filename, - gboolean do_lstat, - struct timespec *out_val); +const struct timespec * +nm_sett_util_stat_mtime(const char *filename, gboolean do_lstat, struct timespec *out_val); /*****************************************************************************/ typedef struct { - const char *uuid; + const char *uuid; - CList _storage_by_uuid_lst_head; + CList _storage_by_uuid_lst_head; - char uuid_data[]; + char uuid_data[]; } NMSettUtilStorageByUuidHead; typedef struct { - CList _storage_lst_head; - GHashTable *idx_by_filename; - GHashTable *idx_by_uuid; + CList _storage_lst_head; + GHashTable *idx_by_filename; + GHashTable *idx_by_uuid; } NMSettUtilStorages; -void nm_sett_util_storage_by_uuid_head_destroy (NMSettUtilStorageByUuidHead *sbuh); +void nm_sett_util_storage_by_uuid_head_destroy(NMSettUtilStorageByUuidHead *sbuh); -#define NM_SETT_UTIL_STORAGES_INIT(storages, storage_destroy_fcn) \ - { \ - ._storage_lst_head = C_LIST_INIT (((storages)._storage_lst_head)), \ - .idx_by_filename = g_hash_table_new_full (nm_str_hash, \ - g_str_equal, \ - NULL, \ - (GDestroyNotify) storage_destroy_fcn), \ - .idx_by_uuid = g_hash_table_new_full (nm_pstr_hash, \ - nm_pstr_equal, \ - NULL, \ - (GDestroyNotify) nm_sett_util_storage_by_uuid_head_destroy), \ - } +#define NM_SETT_UTIL_STORAGES_INIT(storages, storage_destroy_fcn) \ + { \ + ._storage_lst_head = C_LIST_INIT(((storages)._storage_lst_head)), \ + .idx_by_filename = g_hash_table_new_full(nm_str_hash, \ + g_str_equal, \ + NULL, \ + (GDestroyNotify) storage_destroy_fcn), \ + .idx_by_uuid = \ + g_hash_table_new_full(nm_pstr_hash, \ + nm_pstr_equal, \ + NULL, \ + (GDestroyNotify) nm_sett_util_storage_by_uuid_head_destroy), \ + } -void nm_sett_util_storages_clear (NMSettUtilStorages *storages); +void nm_sett_util_storages_clear(NMSettUtilStorages *storages); #define nm_auto_clear_sett_util_storages nm_auto(nm_sett_util_storages_clear) -void nm_sett_util_storages_add_take (NMSettUtilStorages *storages, - gpointer storage_take_p); +void nm_sett_util_storages_add_take(NMSettUtilStorages *storages, gpointer storage_take_p); -gpointer nm_sett_util_storages_steal (NMSettUtilStorages *storages, - gpointer storage_p); +gpointer nm_sett_util_storages_steal(NMSettUtilStorages *storages, gpointer storage_p); /*****************************************************************************/ static inline gpointer /* NMSettingsStorage * */ -nm_sett_util_storages_lookup_by_filename (NMSettUtilStorages *storages, - const char *filename) +nm_sett_util_storages_lookup_by_filename(NMSettUtilStorages *storages, const char *filename) { - nm_assert (filename); + nm_assert(filename); - return g_hash_table_lookup (storages->idx_by_filename, filename); + return g_hash_table_lookup(storages->idx_by_filename, filename); } static inline NMSettUtilStorageByUuidHead * -nm_sett_util_storages_lookup_by_uuid (NMSettUtilStorages *storages, - const char *uuid) +nm_sett_util_storages_lookup_by_uuid(NMSettUtilStorages *storages, const char *uuid) { - nm_assert (uuid); + nm_assert(uuid); - return g_hash_table_lookup (storages->idx_by_uuid, &uuid); + return g_hash_table_lookup(storages->idx_by_uuid, &uuid); } /*****************************************************************************/ typedef struct { - GHashTable *idx_by_filename; - const char *allowed_filename; + GHashTable *idx_by_filename; + const char *allowed_filename; } NMSettUtilAllowFilenameData; #define NM_SETT_UTIL_ALLOW_FILENAME_DATA(_storages, _allowed_filename) \ - (&((NMSettUtilAllowFilenameData) { \ - .idx_by_filename = (_storages)->idx_by_filename, \ - .allowed_filename = (_allowed_filename), \ + (&((NMSettUtilAllowFilenameData){ \ + .idx_by_filename = (_storages)->idx_by_filename, \ + .allowed_filename = (_allowed_filename), \ })) -gboolean nm_sett_util_allow_filename_cb (const char *filename, - gpointer user_data); +gboolean nm_sett_util_allow_filename_cb(const char *filename, gpointer user_data); #endif /* __NM_SETTINGS_UTILS_H__ */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 4573d5f7..6b9d5083 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Søren Sandmann * Dan Williams @@ -17,7 +17,7 @@ #include #if HAVE_SELINUX -#include + #include #endif #include "nm-libnm-core-intern/nm-common-macros.h" @@ -68,154 +68,153 @@ /*****************************************************************************/ -static -NM_CACHED_QUARK_FCN ("default-wired-connection", _default_wired_connection_quark) +static NM_CACHED_QUARK_FCN("default-wired-connection", _default_wired_connection_quark); -static -NM_CACHED_QUARK_FCN ("default-wired-connection-blocked", _default_wired_connection_blocked_quark) +static NM_CACHED_QUARK_FCN("default-wired-connection-blocked", + _default_wired_connection_blocked_quark); /*****************************************************************************/ typedef struct _StorageData { - CList sd_lst; - NMSettingsStorage *storage; - NMConnection *connection; - bool prioritize:1; + CList sd_lst; + NMSettingsStorage *storage; + NMConnection * connection; + bool prioritize : 1; } StorageData; static StorageData * -_storage_data_new_stale (NMSettingsStorage *storage, - NMConnection *connection) +_storage_data_new_stale(NMSettingsStorage *storage, NMConnection *connection) { - StorageData *sd; + StorageData *sd; - sd = g_slice_new (StorageData); - sd->storage = g_object_ref (storage); - sd->connection = nm_g_object_ref (connection); - sd->prioritize = FALSE; - return sd; + sd = g_slice_new(StorageData); + sd->storage = g_object_ref(storage); + sd->connection = nm_g_object_ref(connection); + sd->prioritize = FALSE; + return sd; } static void -_storage_data_destroy (StorageData *sd) +_storage_data_destroy(StorageData *sd) { - c_list_unlink_stale (&sd->sd_lst); - g_object_unref (sd->storage); - nm_g_object_unref (sd->connection); - g_slice_free (StorageData, sd); + c_list_unlink_stale(&sd->sd_lst); + g_object_unref(sd->storage); + nm_g_object_unref(sd->connection); + g_slice_free(StorageData, sd); } static StorageData * -_storage_data_find_in_lst (CList *head, - NMSettingsStorage *storage) +_storage_data_find_in_lst(CList *head, NMSettingsStorage *storage) { - StorageData *sd; + StorageData *sd; - nm_assert (head); - nm_assert (NM_IS_SETTINGS_STORAGE (storage)); + nm_assert(head); + nm_assert(NM_IS_SETTINGS_STORAGE(storage)); - c_list_for_each_entry (sd, head, sd_lst) { - if (sd->storage == storage) - return sd; - } - return NULL; + c_list_for_each_entry (sd, head, sd_lst) { + if (sd->storage == storage) + return sd; + } + return NULL; } static void -nm_assert_storage_data_lst (CList *head) +nm_assert_storage_data_lst(CList *head) { #if NM_MORE_ASSERTS > 5 - const char *uuid = NULL; - StorageData *sd; - CList *iter; - - nm_assert (head); - - if (c_list_is_empty (head)) - return; - - c_list_for_each_entry (sd, head, sd_lst) { - const char *u; - - nm_assert (NM_IS_SETTINGS_STORAGE (sd->storage)); - nm_assert (!sd->connection || NM_IS_CONNECTION (sd->connection)); - u = nm_settings_storage_get_uuid (sd->storage); - if (!uuid) { - uuid = u; - nm_assert (nm_utils_is_uuid (uuid)); - } else - nm_assert (nm_streq0 (uuid, u)); - } - - /* assert that all storages are unique. */ - c_list_for_each_entry (sd, head, sd_lst) { - for (iter = sd->sd_lst.next; iter != head; iter = iter->next) - nm_assert (c_list_entry (iter, StorageData, sd_lst)->storage != sd->storage); - } + const char * uuid = NULL; + StorageData *sd; + CList * iter; + + nm_assert(head); + + if (c_list_is_empty(head)) + return; + + c_list_for_each_entry (sd, head, sd_lst) { + const char *u; + + nm_assert(NM_IS_SETTINGS_STORAGE(sd->storage)); + nm_assert(!sd->connection || NM_IS_CONNECTION(sd->connection)); + u = nm_settings_storage_get_uuid(sd->storage); + if (!uuid) { + uuid = u; + nm_assert(nm_utils_is_uuid(uuid)); + } else + nm_assert(nm_streq0(uuid, u)); + } + + /* assert that all storages are unique. */ + c_list_for_each_entry (sd, head, sd_lst) { + for (iter = sd->sd_lst.next; iter != head; iter = iter->next) + nm_assert(c_list_entry(iter, StorageData, sd_lst)->storage != sd->storage); + } #endif } static gboolean -_storage_data_is_alive (StorageData *sd) +_storage_data_is_alive(StorageData *sd) { - /* If the storage tracks a connection, it is considered alive. - * - * Meta-data storages are special: they never track a connection. - * We need to check them specially to know when to drop them. */ - return sd->connection - || nm_settings_storage_is_meta_data_alive (sd->storage); + /* If the storage tracks a connection, it is considered alive. + * + * Meta-data storages are special: they never track a connection. + * We need to check them specially to know when to drop them. */ + return sd->connection || nm_settings_storage_is_meta_data_alive(sd->storage); } /*****************************************************************************/ typedef struct { - const char *uuid; - NMSettingsConnection *sett_conn; - NMSettingsStorage *storage; - CList sd_lst_head; - CList dirty_sd_lst_head; + const char * uuid; + NMSettingsConnection *sett_conn; + NMSettingsStorage * storage; + CList sd_lst_head; + CList dirty_sd_lst_head; - CList sce_dirty_lst; + CList sce_dirty_lst; - char _uuid_data[]; + char _uuid_data[]; } SettConnEntry; static SettConnEntry * -_sett_conn_entry_new (const char *uuid) +_sett_conn_entry_new(const char *uuid) { - SettConnEntry *sett_conn_entry; - gsize l_p_1; - - nm_assert (nm_utils_is_uuid (uuid)); - - l_p_1 = strlen (uuid) + 1; - - sett_conn_entry = g_malloc (sizeof (SettConnEntry) + l_p_1); - sett_conn_entry->uuid = sett_conn_entry->_uuid_data; - sett_conn_entry->sett_conn = NULL; - sett_conn_entry->storage = NULL; - c_list_init (&sett_conn_entry->sd_lst_head); - c_list_init (&sett_conn_entry->dirty_sd_lst_head); - c_list_init (&sett_conn_entry->sce_dirty_lst); - memcpy (sett_conn_entry->_uuid_data, uuid, l_p_1); - return sett_conn_entry; + SettConnEntry *sett_conn_entry; + gsize l_p_1; + + nm_assert(nm_utils_is_uuid(uuid)); + + l_p_1 = strlen(uuid) + 1; + + sett_conn_entry = g_malloc(sizeof(SettConnEntry) + l_p_1); + sett_conn_entry->uuid = sett_conn_entry->_uuid_data; + sett_conn_entry->sett_conn = NULL; + sett_conn_entry->storage = NULL; + c_list_init(&sett_conn_entry->sd_lst_head); + c_list_init(&sett_conn_entry->dirty_sd_lst_head); + c_list_init(&sett_conn_entry->sce_dirty_lst); + memcpy(sett_conn_entry->_uuid_data, uuid, l_p_1); + return sett_conn_entry; } static void -_sett_conn_entry_free (SettConnEntry *sett_conn_entry) +_sett_conn_entry_free(SettConnEntry *sett_conn_entry) { - c_list_unlink_stale (&sett_conn_entry->sce_dirty_lst); - nm_c_list_free_all (&sett_conn_entry->sd_lst_head, StorageData, sd_lst, _storage_data_destroy); - nm_c_list_free_all (&sett_conn_entry->dirty_sd_lst_head, StorageData, sd_lst, _storage_data_destroy); - nm_g_object_unref (sett_conn_entry->sett_conn); - nm_g_object_unref (sett_conn_entry->storage); - g_free (sett_conn_entry); + c_list_unlink_stale(&sett_conn_entry->sce_dirty_lst); + nm_c_list_free_all(&sett_conn_entry->sd_lst_head, StorageData, sd_lst, _storage_data_destroy); + nm_c_list_free_all(&sett_conn_entry->dirty_sd_lst_head, + StorageData, + sd_lst, + _storage_data_destroy); + nm_g_object_unref(sett_conn_entry->sett_conn); + nm_g_object_unref(sett_conn_entry->storage); + g_free(sett_conn_entry); } static NMSettingsConnection * -_sett_conn_entry_get_conn (SettConnEntry *sett_conn_entry) +_sett_conn_entry_get_conn(SettConnEntry *sett_conn_entry) { - return sett_conn_entry ? sett_conn_entry->sett_conn : NULL; + return sett_conn_entry ? sett_conn_entry->sett_conn : NULL; } /** @@ -239,1438 +238,1434 @@ _sett_conn_entry_get_conn (SettConnEntry *sett_conn_entry) * Returns: the conflicting storage or %NULL if there is none. */ static NMSettingsStorage * -_sett_conn_entry_storage_find_conflicting_storage (SettConnEntry *sett_conn_entry, - NMSettingsPlugin *target_plugin, - NMSettingsStorage *storage_check_including, - const GSList *plugins) +_sett_conn_entry_storage_find_conflicting_storage(SettConnEntry * sett_conn_entry, + NMSettingsPlugin * target_plugin, + NMSettingsStorage *storage_check_including, + const GSList * plugins) { - StorageData *sd; - - if (!sett_conn_entry) - return NULL; - - if ( storage_check_including - && nm_settings_storage_is_keyfile_run (storage_check_including)) { - /* the storage we check against is in-memory. It always has highest - * priority, so there can be no other conflicting storages. */ - return NULL; - } - - /* Finds the first (highest priority) storage that has a connection. - * Note that due to tombstones (that have a high priority), the connection - * may not actually be exposed. This is to find hidden/shadowed storages - * that provide a connection. */ - c_list_for_each_entry (sd, &sett_conn_entry->sd_lst_head, sd_lst) { - nm_assert (NM_IS_SETTINGS_STORAGE (sd->storage)); - - if (!sd->connection) { - /* We only consider storages with connection. In particular, - * tombstones are not relevant, because we can delete them to - * resolve the conflict. */ - continue; - } - - if (sd->storage == storage_check_including) { - /* ok, the storage is the one we are about to check. All other - * storages are lower priority, so there is no storage that hides - * our storage_check_including. */ - return NULL; - } - - if (nm_settings_plugin_cmp_by_priority (nm_settings_storage_get_plugin (sd->storage), - target_plugin, - plugins) <= 0) { - /* the plugin of the existing storage is less important than @target_plugin. - * We have no conflicting/hiding storage. */ - return NULL; - } - - /* Found. If we would add the profile to @target_plugin, then it would be hidden - * by existing_storage. */ - return sd->storage; - } - - return NULL; + StorageData *sd; + + if (!sett_conn_entry) + return NULL; + + if (storage_check_including && nm_settings_storage_is_keyfile_run(storage_check_including)) { + /* the storage we check against is in-memory. It always has highest + * priority, so there can be no other conflicting storages. */ + return NULL; + } + + /* Finds the first (highest priority) storage that has a connection. + * Note that due to tombstones (that have a high priority), the connection + * may not actually be exposed. This is to find hidden/shadowed storages + * that provide a connection. */ + c_list_for_each_entry (sd, &sett_conn_entry->sd_lst_head, sd_lst) { + nm_assert(NM_IS_SETTINGS_STORAGE(sd->storage)); + + if (!sd->connection) { + /* We only consider storages with connection. In particular, + * tombstones are not relevant, because we can delete them to + * resolve the conflict. */ + continue; + } + + if (sd->storage == storage_check_including) { + /* ok, the storage is the one we are about to check. All other + * storages are lower priority, so there is no storage that hides + * our storage_check_including. */ + return NULL; + } + + if (nm_settings_plugin_cmp_by_priority(nm_settings_storage_get_plugin(sd->storage), + target_plugin, + plugins) + <= 0) { + /* the plugin of the existing storage is less important than @target_plugin. + * We have no conflicting/hiding storage. */ + return NULL; + } + + /* Found. If we would add the profile to @target_plugin, then it would be hidden + * by existing_storage. */ + return sd->storage; + } + + return NULL; } static NMSettingsStorage * -_sett_conn_entry_find_shadowed_storage (SettConnEntry *sett_conn_entry, - const char *shadowed_storage_filename, - NMSettingsStorage *blacklisted_storage) +_sett_conn_entry_find_shadowed_storage(SettConnEntry * sett_conn_entry, + const char * shadowed_storage_filename, + NMSettingsStorage *blacklisted_storage) { - StorageData *sd; + StorageData *sd; - if (!shadowed_storage_filename) - return NULL; + if (!shadowed_storage_filename) + return NULL; - c_list_for_each_entry (sd, &sett_conn_entry->sd_lst_head, sd_lst) { + c_list_for_each_entry (sd, &sett_conn_entry->sd_lst_head, sd_lst) { + nm_assert(NM_IS_SETTINGS_STORAGE(sd->storage)); - nm_assert (NM_IS_SETTINGS_STORAGE (sd->storage)); + if (!sd->connection) + continue; - if (!sd->connection) - continue; + if (blacklisted_storage == sd->storage) + continue; - if (blacklisted_storage == sd->storage) - continue; + if (!nm_streq0(nm_settings_storage_get_filename_for_shadowed_storage(sd->storage), + shadowed_storage_filename)) + continue; - if (!nm_streq0 (nm_settings_storage_get_filename_for_shadowed_storage (sd->storage), shadowed_storage_filename)) - continue; + return sd->storage; + } - return sd->storage; - } - - return NULL; + return NULL; } /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMSettings, - PROP_MANAGER, - PROP_UNMANAGED_SPECS, - PROP_HOSTNAME, - PROP_CAN_MODIFY, - PROP_CONNECTIONS, - PROP_STARTUP_COMPLETE, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMSettings, + PROP_MANAGER, + PROP_UNMANAGED_SPECS, + PROP_HOSTNAME, + PROP_CAN_MODIFY, + PROP_CONNECTIONS, + PROP_STARTUP_COMPLETE, ); enum { - CONNECTION_ADDED, - CONNECTION_UPDATED, - CONNECTION_REMOVED, - CONNECTION_FLAGS_CHANGED, - LAST_SIGNAL + CONNECTION_ADDED, + CONNECTION_UPDATED, + CONNECTION_REMOVED, + CONNECTION_FLAGS_CHANGED, + LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = {0}; typedef struct { - NMAgentManager *agent_mgr; + NMAgentManager *agent_mgr; - NMConfig *config; + NMConfig *config; - NMPlatform *platform; + NMPlatform *platform; - NMManager *manager; + NMManager *manager; - NMHostnameManager *hostname_manager; + NMHostnameManager *hostname_manager; - NMSessionMonitor *session_monitor; + NMSessionMonitor *session_monitor; - CList auth_lst_head; + CList auth_lst_head; - NMSKeyfilePlugin *keyfile_plugin; + NMSKeyfilePlugin *keyfile_plugin; - GSList *plugins; + GSList *plugins; - NMKeyFileDB *kf_db_timestamps; - NMKeyFileDB *kf_db_seen_bssids; + NMKeyFileDB *kf_db_timestamps; + NMKeyFileDB *kf_db_seen_bssids; - GHashTable *sce_idx; + GHashTable *sce_idx; - CList sce_dirty_lst_head; + CList sce_dirty_lst_head; - CList connections_lst_head; + CList connections_lst_head; - NMSettingsConnection **connections_cached_list; + NMSettingsConnection **connections_cached_list; - GSList *unmanaged_specs; - GSList *unrecognized_specs; + GSList *unmanaged_specs; + GSList *unrecognized_specs; - gint64 startup_complete_start_timestamp_msec; - GHashTable *startup_complete_idx; - CList startup_complete_scd_lst_head; - guint startup_complete_timeout_id; + gint64 startup_complete_start_timestamp_msec; + GHashTable *startup_complete_idx; + CList startup_complete_scd_lst_head; + guint startup_complete_timeout_id; - guint connections_len; + guint connections_len; - guint connections_generation; + guint connections_generation; - guint kf_db_flush_idle_id_timestamps; - guint kf_db_flush_idle_id_seen_bssids; + guint kf_db_flush_idle_id_timestamps; + guint kf_db_flush_idle_id_seen_bssids; - bool started:1; + bool started : 1; } NMSettingsPrivate; struct _NMSettings { - NMDBusObject parent; - NMSettingsPrivate _priv; + NMDBusObject parent; + NMSettingsPrivate _priv; }; struct _NMSettingsClass { - NMDBusObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_DBUS_OBJECT); +G_DEFINE_TYPE(NMSettings, nm_settings, NM_TYPE_DBUS_OBJECT); -#define NM_SETTINGS_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSettings, NM_IS_SETTINGS) +#define NM_SETTINGS_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMSettings, NM_IS_SETTINGS) /*****************************************************************************/ /* FIXME: a lot of logging lines are directly connected to a profile. Set the @con_uuid * argument for structured logging. */ -#define _NMLOG_DOMAIN LOGD_SETTINGS -#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "settings", __VA_ARGS__) +#define _NMLOG_DOMAIN LOGD_SETTINGS +#define _NMLOG(level, ...) __NMLOG_DEFAULT(level, _NMLOG_DOMAIN, "settings", __VA_ARGS__) /*****************************************************************************/ static const NMDBusInterfaceInfoExtended interface_info_settings; -static const GDBusSignalInfo signal_info_new_connection; -static const GDBusSignalInfo signal_info_connection_removed; +static const GDBusSignalInfo signal_info_new_connection; +static const GDBusSignalInfo signal_info_connection_removed; -static void default_wired_clear_tag (NMSettings *self, - NMDevice *device, - NMSettingsConnection *sett_conn, - gboolean add_to_no_auto_default); +static void default_wired_clear_tag(NMSettings * self, + NMDevice * device, + NMSettingsConnection *sett_conn, + gboolean add_to_no_auto_default); -static void _clear_connections_cached_list (NMSettingsPrivate *priv); +static void _clear_connections_cached_list(NMSettingsPrivate *priv); -static void _startup_complete_check (NMSettings *self, - gint64 now_msec); +static void _startup_complete_check(NMSettings *self, gint64 now_msec); /*****************************************************************************/ static void -_emit_connection_added (NMSettings *self, - NMSettingsConnection *sett_conn) +_emit_connection_added(NMSettings *self, NMSettingsConnection *sett_conn) { - g_signal_emit (self, signals[CONNECTION_ADDED], 0, sett_conn); + g_signal_emit(self, signals[CONNECTION_ADDED], 0, sett_conn); } static void -_emit_connection_updated (NMSettings *self, - NMSettingsConnection *sett_conn, - NMSettingsConnectionUpdateReason update_reason) +_emit_connection_updated(NMSettings * self, + NMSettingsConnection * sett_conn, + NMSettingsConnectionUpdateReason update_reason) { - _nm_settings_connection_emit_signal_updated_internal (sett_conn, update_reason); - g_signal_emit (self, signals[CONNECTION_UPDATED], 0, sett_conn, (guint) update_reason); + _nm_settings_connection_emit_signal_updated_internal(sett_conn, update_reason); + g_signal_emit(self, signals[CONNECTION_UPDATED], 0, sett_conn, (guint) update_reason); } static void -_emit_connection_removed (NMSettings *self, - NMSettingsConnection *sett_conn) +_emit_connection_removed(NMSettings *self, NMSettingsConnection *sett_conn) { - g_signal_emit (self, signals[CONNECTION_REMOVED], 0, sett_conn); + g_signal_emit(self, signals[CONNECTION_REMOVED], 0, sett_conn); } static void -_emit_connection_flags_changed (NMSettings *self, - NMSettingsConnection *sett_conn) +_emit_connection_flags_changed(NMSettings *self, NMSettingsConnection *sett_conn) { - g_signal_emit (self, signals[CONNECTION_FLAGS_CHANGED], 0, sett_conn); + g_signal_emit(self, signals[CONNECTION_FLAGS_CHANGED], 0, sett_conn); } /*****************************************************************************/ typedef struct { - NMSettingsConnection *sett_conn; - CList scd_lst; - gint64 timeout_msec; + NMSettingsConnection *sett_conn; + CList scd_lst; + gint64 timeout_msec; } StartupCompleteData; static void -_startup_complete_data_destroy (StartupCompleteData *scd) +_startup_complete_data_destroy(StartupCompleteData *scd) { - c_list_unlink_stale (&scd->scd_lst); - g_object_unref (scd->sett_conn); - nm_g_slice_free (scd); + c_list_unlink_stale(&scd->scd_lst); + g_object_unref(scd->sett_conn); + nm_g_slice_free(scd); } static gboolean -_startup_complete_check_is_ready (NMSettings *self, - NMSettingsConnection *sett_conn, - gboolean ignore_pending_actions) +_startup_complete_check_is_ready(NMSettings * self, + NMSettingsConnection *sett_conn, + gboolean ignore_pending_actions) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - NMConnection *conn; - const CList *tmp_lst; - NMDevice *device; - - if (!priv->manager) - return TRUE; + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + NMConnection * conn; + const CList * tmp_lst; + NMDevice * device; - conn = nm_settings_connection_get_connection (sett_conn); + if (!priv->manager) + return TRUE; - nm_manager_for_each_device (priv->manager, device, tmp_lst) { + conn = nm_settings_connection_get_connection(sett_conn); - if (!nm_device_is_real (device)) - continue; + nm_manager_for_each_device (priv->manager, device, tmp_lst) { + if (!nm_device_is_real(device)) + continue; - if ( nm_device_get_state (device) < NM_DEVICE_STATE_UNAVAILABLE - || ( !ignore_pending_actions - && nm_device_has_pending_action (device))) { - /* while a device is not yet available and still has a pending - * action itself, it's not a suitable candidate. */ - continue; - } + if (nm_device_get_state(device) < NM_DEVICE_STATE_UNAVAILABLE + || (!ignore_pending_actions && nm_device_has_pending_action(device))) { + /* while a device is not yet available and still has a pending + * action itself, it's not a suitable candidate. */ + continue; + } - if (!nm_device_check_connection_compatible (device, conn, NULL)) - continue; + if (!nm_device_check_connection_compatible(device, conn, NULL)) + continue; - return TRUE; - } + return TRUE; + } - return FALSE; + return FALSE; } static gboolean -_startup_complete_timeout_cb (gpointer user_data) +_startup_complete_timeout_cb(gpointer user_data) { - NMSettings *self = user_data; - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettings * self = user_data; + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); - priv->startup_complete_timeout_id = 0; - _startup_complete_check (self, 0); - return G_SOURCE_REMOVE; + priv->startup_complete_timeout_id = 0; + _startup_complete_check(self, 0); + return G_SOURCE_REMOVE; } static void -_startup_complete_check (NMSettings *self, - gint64 now_msec) +_startup_complete_check(NMSettings *self, gint64 now_msec) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - StartupCompleteData *scd_not_ready; - StartupCompleteData *scd_safe; - StartupCompleteData *scd; - gint64 elapsed_msec; - CList ready_lst; - - if (priv->startup_complete_start_timestamp_msec == 0) { - /* we are already done for good or didn't start yet. */ - return; - } - - if (!priv->started) { - /* before we are started there is no need to evaluate our list because - * we are anyway blocking startup-complete. */ - return; - } - - if (c_list_is_empty (&priv->startup_complete_scd_lst_head)) - goto ready; - - nm_utils_get_monotonic_timestamp_msec_cached (&now_msec); - - elapsed_msec = now_msec - priv->startup_complete_start_timestamp_msec; - - /* We search the entire list whether they all timed-out or found a compatible device. - * We do that by appending elements that are ready to the end of the list, so that - * we hopefully keep testing the elements that are ready already (and can shortcut - * the test in common cases). - * - * Note that all profiles that we wait for need to have their dependencies satisfied - * at the same time. For example, consider connection A is waiting for device A' which is ready. - * Connection B waits for device B', which isn't ready. Once B'/B becomes ready, A/A' must - * still be ready. Otherwise, we would wait for A/A' to become ready again. */ - scd_not_ready = NULL; - c_list_init (&ready_lst); - c_list_for_each_entry_safe (scd, scd_safe, &priv->startup_complete_scd_lst_head, scd_lst) { - - if (scd->timeout_msec <= elapsed_msec) - goto next_with_ready; - - if (_startup_complete_check_is_ready (self, scd->sett_conn, FALSE)) - goto next_with_ready; - - scd_not_ready = scd; - break; + NMSettingsPrivate * priv = NM_SETTINGS_GET_PRIVATE(self); + StartupCompleteData *scd_not_ready; + StartupCompleteData *scd_safe; + StartupCompleteData *scd; + gint64 elapsed_msec; + CList ready_lst; + + if (priv->startup_complete_start_timestamp_msec == 0) { + /* we are already done for good or didn't start yet. */ + return; + } + + if (!priv->started) { + /* before we are started there is no need to evaluate our list because + * we are anyway blocking startup-complete. */ + return; + } + + if (c_list_is_empty(&priv->startup_complete_scd_lst_head)) + goto ready; + + nm_utils_get_monotonic_timestamp_msec_cached(&now_msec); + + elapsed_msec = now_msec - priv->startup_complete_start_timestamp_msec; + + /* We search the entire list whether they all timed-out or found a compatible device. + * We do that by appending elements that are ready to the end of the list, so that + * we hopefully keep testing the elements that are ready already (and can shortcut + * the test in common cases). + * + * Note that all profiles that we wait for need to have their dependencies satisfied + * at the same time. For example, consider connection A is waiting for device A' which is ready. + * Connection B waits for device B', which isn't ready. Once B'/B becomes ready, A/A' must + * still be ready. Otherwise, we would wait for A/A' to become ready again. */ + scd_not_ready = NULL; + c_list_init(&ready_lst); + c_list_for_each_entry_safe (scd, scd_safe, &priv->startup_complete_scd_lst_head, scd_lst) { + if (scd->timeout_msec <= elapsed_msec) + goto next_with_ready; + + if (_startup_complete_check_is_ready(self, scd->sett_conn, FALSE)) + goto next_with_ready; + + scd_not_ready = scd; + break; next_with_ready: - /* this element is ready. We move it to a temporary list, so that we - * can reorder the list (to next time evaluate the non-ready element first). */ - nm_c_list_move_tail (&ready_lst, &scd->scd_lst); - } - c_list_splice (&priv->startup_complete_scd_lst_head, &ready_lst); - - nm_clear_g_source (&priv->startup_complete_timeout_id); - - if (scd_not_ready) { - gint64 timeout_msec; - - timeout_msec = priv->startup_complete_start_timestamp_msec + scd_not_ready->timeout_msec - nm_utils_get_monotonic_timestamp_msec (); - priv->startup_complete_timeout_id = g_timeout_add (NM_CLAMP (0, timeout_msec, 60000), - _startup_complete_timeout_cb, - self); - _LOGT ("startup-complete: wait for suitable device for connection \"%s\" (%s) which has \"connection.wait-device-timeout\" set", - nm_settings_connection_get_id (scd_not_ready->sett_conn), - nm_settings_connection_get_uuid (scd_not_ready->sett_conn)); - return; - } - - if (_LOGW_ENABLED ()) { - c_list_for_each_entry (scd, &priv->startup_complete_scd_lst_head, scd_lst) { - if (!_startup_complete_check_is_ready (self, scd->sett_conn, TRUE)) { - _LOGW ("startup-complete: profile \"%s\" (%s) was waiting for non-existing device (with timeout \"connection.wait-device-timeout=%"G_GINT64_FORMAT"\")", - nm_settings_connection_get_id (scd->sett_conn), - nm_settings_connection_get_uuid (scd->sett_conn), - scd->timeout_msec); - } - } - } + /* this element is ready. We move it to a temporary list, so that we + * can reorder the list (to next time evaluate the non-ready element first). */ + nm_c_list_move_tail(&ready_lst, &scd->scd_lst); + } + c_list_splice(&priv->startup_complete_scd_lst_head, &ready_lst); + + nm_clear_g_source(&priv->startup_complete_timeout_id); + + if (scd_not_ready) { + gint64 timeout_msec; + + timeout_msec = priv->startup_complete_start_timestamp_msec + scd_not_ready->timeout_msec + - nm_utils_get_monotonic_timestamp_msec(); + priv->startup_complete_timeout_id = + g_timeout_add(NM_CLAMP(0, timeout_msec, 60000), _startup_complete_timeout_cb, self); + _LOGT("startup-complete: wait for suitable device for connection \"%s\" (%s) which has " + "\"connection.wait-device-timeout\" set", + nm_settings_connection_get_id(scd_not_ready->sett_conn), + nm_settings_connection_get_uuid(scd_not_ready->sett_conn)); + return; + } + + if (_LOGW_ENABLED()) { + c_list_for_each_entry (scd, &priv->startup_complete_scd_lst_head, scd_lst) { + if (!_startup_complete_check_is_ready(self, scd->sett_conn, TRUE)) { + _LOGW("startup-complete: profile \"%s\" (%s) was waiting for non-existing device " + "(with timeout \"connection.wait-device-timeout=%" G_GINT64_FORMAT "\")", + nm_settings_connection_get_id(scd->sett_conn), + nm_settings_connection_get_uuid(scd->sett_conn), + scd->timeout_msec); + } + } + } ready: - nm_clear_pointer (&priv->startup_complete_idx, g_hash_table_destroy); - nm_assert (c_list_is_empty (&priv->startup_complete_scd_lst_head)); - nm_assert (priv->started); - _LOGT ("startup-complete: ready, no more profiles to wait for"); - priv->startup_complete_start_timestamp_msec = 0; - nm_assert (!priv->startup_complete_idx); - nm_assert (priv->startup_complete_timeout_id == 0); - _notify (self, PROP_STARTUP_COMPLETE); + nm_clear_pointer(&priv->startup_complete_idx, g_hash_table_destroy); + nm_assert(c_list_is_empty(&priv->startup_complete_scd_lst_head)); + nm_assert(priv->started); + _LOGT("startup-complete: ready, no more profiles to wait for"); + priv->startup_complete_start_timestamp_msec = 0; + nm_assert(!priv->startup_complete_idx); + nm_assert(priv->startup_complete_timeout_id == 0); + _notify(self, PROP_STARTUP_COMPLETE); } static void -_startup_complete_notify_connection (NMSettings *self, - NMSettingsConnection *sett_conn, - gboolean forget) +_startup_complete_notify_connection(NMSettings * self, + NMSettingsConnection *sett_conn, + gboolean forget) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - StartupCompleteData *scd; - gint64 timeout_msec; - gint64 now_msec = 0; - NMSettingConnection *s_con; - gint32 v; - - nm_assert (priv->startup_complete_start_timestamp_msec != 0); - - if (forget) { - if (!priv->startup_complete_idx) - return; - if (!g_hash_table_remove (priv->startup_complete_idx, &sett_conn)) - return; - goto check; - } - - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (sett_conn)); - v = nm_setting_connection_get_wait_device_timeout (s_con); - if (v > 0) - timeout_msec = v; - else - timeout_msec = 0; - - if (!priv->startup_complete_idx) { - nm_assert (!priv->started); - - if (timeout_msec == 0) - return; - - priv->startup_complete_idx = g_hash_table_new_full (nm_pdirect_hash, - nm_pdirect_equal, - NULL, - (GDestroyNotify) _startup_complete_data_destroy); - scd = NULL; - } else - scd = g_hash_table_lookup (priv->startup_complete_idx, &sett_conn); - - if (!scd) { - if (timeout_msec == 0) - return; - scd = g_slice_new (StartupCompleteData); - *scd = (StartupCompleteData) { - .sett_conn = g_object_ref (sett_conn), - .timeout_msec = timeout_msec, - }; - g_hash_table_add (priv->startup_complete_idx, scd); - c_list_link_tail (&priv->startup_complete_scd_lst_head, &scd->scd_lst); - } else { - scd->timeout_msec = timeout_msec; - nm_c_list_move_front (&priv->startup_complete_scd_lst_head, &scd->scd_lst); - } + NMSettingsPrivate * priv = NM_SETTINGS_GET_PRIVATE(self); + StartupCompleteData *scd; + gint64 timeout_msec; + gint64 now_msec = 0; + NMSettingConnection *s_con; + gint32 v; + + nm_assert(priv->startup_complete_start_timestamp_msec != 0); + + if (forget) { + if (!priv->startup_complete_idx) + return; + if (!g_hash_table_remove(priv->startup_complete_idx, &sett_conn)) + return; + goto check; + } + + s_con = nm_connection_get_setting_connection(nm_settings_connection_get_connection(sett_conn)); + v = nm_setting_connection_get_wait_device_timeout(s_con); + if (v > 0) + timeout_msec = v; + else + timeout_msec = 0; + + if (!priv->startup_complete_idx) { + nm_assert(!priv->started); + + if (timeout_msec == 0) + return; + + priv->startup_complete_idx = + g_hash_table_new_full(nm_pdirect_hash, + nm_pdirect_equal, + NULL, + (GDestroyNotify) _startup_complete_data_destroy); + scd = NULL; + } else + scd = g_hash_table_lookup(priv->startup_complete_idx, &sett_conn); + + if (!scd) { + if (timeout_msec == 0) + return; + scd = g_slice_new(StartupCompleteData); + *scd = (StartupCompleteData){ + .sett_conn = g_object_ref(sett_conn), + .timeout_msec = timeout_msec, + }; + g_hash_table_add(priv->startup_complete_idx, scd); + c_list_link_tail(&priv->startup_complete_scd_lst_head, &scd->scd_lst); + } else { + scd->timeout_msec = timeout_msec; + nm_c_list_move_front(&priv->startup_complete_scd_lst_head, &scd->scd_lst); + } check: - _startup_complete_check (self, now_msec); + _startup_complete_check(self, now_msec); } const char * -nm_settings_get_startup_complete_blocked_reason (NMSettings *self, - gboolean force_reload) +nm_settings_get_startup_complete_blocked_reason(NMSettings *self, gboolean force_reload) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - StartupCompleteData *scd; - const char *uuid; + NMSettingsPrivate * priv = NM_SETTINGS_GET_PRIVATE(self); + StartupCompleteData *scd; + const char * uuid; - if (priv->startup_complete_start_timestamp_msec == 0) - goto out_done; + if (priv->startup_complete_start_timestamp_msec == 0) + goto out_done; - if (force_reload) - _startup_complete_check (self, 0); + if (force_reload) + _startup_complete_check(self, 0); - if (c_list_is_empty (&priv->startup_complete_scd_lst_head)) - goto out_done; + if (c_list_is_empty(&priv->startup_complete_scd_lst_head)) + goto out_done; - scd = c_list_first_entry (&priv->startup_complete_scd_lst_head, StartupCompleteData, scd_lst); + scd = c_list_first_entry(&priv->startup_complete_scd_lst_head, StartupCompleteData, scd_lst); - nm_assert (scd); - nm_assert (NM_IS_SETTINGS_CONNECTION (scd->sett_conn)); - nm_assert (scd == nm_g_hash_table_lookup (priv->startup_complete_idx, &scd->sett_conn)); + nm_assert(scd); + nm_assert(NM_IS_SETTINGS_CONNECTION(scd->sett_conn)); + nm_assert(scd == nm_g_hash_table_lookup(priv->startup_complete_idx, &scd->sett_conn)); - uuid = nm_settings_connection_get_uuid (scd->sett_conn); - if (uuid) - return uuid; + uuid = nm_settings_connection_get_uuid(scd->sett_conn); + if (uuid) + return uuid; - g_return_val_if_reached ("settings-starting"); + g_return_val_if_reached("settings-starting"); out_done: - if (!priv->started) - return "settings-starting"; - return NULL; + if (!priv->started) + return "settings-starting"; + return NULL; } /*****************************************************************************/ const GSList * -nm_settings_get_unmanaged_specs (NMSettings *self) +nm_settings_get_unmanaged_specs(NMSettings *self) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); - return priv->unmanaged_specs; + return priv->unmanaged_specs; } static gboolean -update_specs (NMSettings *self, GSList **specs_ptr, - GSList * (*get_specs_func) (NMSettingsPlugin *)) +update_specs(NMSettings *self, GSList **specs_ptr, GSList *(*get_specs_func)(NMSettingsPlugin *) ) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GSList *new = NULL; - GSList *iter; - - for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { - GSList *specs; - - specs = get_specs_func (iter->data); - while (specs) { - GSList *s = specs; - - specs = g_slist_remove_link (specs, s); - if (nm_utils_g_slist_find_str (new, s->data)) { - g_free (s->data); - g_slist_free_1 (s); - continue; - } - s->next = new; - new = s; - } - } - - if (nm_utils_g_slist_strlist_cmp (new, *specs_ptr) == 0) { - g_slist_free_full (new, g_free); - return FALSE; - } - - g_slist_free_full (*specs_ptr, g_free); - *specs_ptr = new; - return TRUE; - + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + GSList *new = NULL; + GSList *iter; + + for (iter = priv->plugins; iter; iter = g_slist_next(iter)) { + GSList *specs; + + specs = get_specs_func(iter->data); + while (specs) { + GSList *s = specs; + + specs = g_slist_remove_link(specs, s); + if (nm_utils_g_slist_find_str(new, s->data)) { + g_free(s->data); + g_slist_free_1(s); + continue; + } + s->next = new; + new = s; + } + } + + if (nm_utils_g_slist_strlist_cmp(new, *specs_ptr) == 0) { + g_slist_free_full(new, g_free); + return FALSE; + } + + g_slist_free_full(*specs_ptr, g_free); + *specs_ptr = new; + return TRUE; } static void -_plugin_unmanaged_specs_changed (NMSettingsPlugin *config, - gpointer user_data) +_plugin_unmanaged_specs_changed(NMSettingsPlugin *config, gpointer user_data) { - NMSettings *self = NM_SETTINGS (user_data); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettings * self = NM_SETTINGS(user_data); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); - if (update_specs (self, &priv->unmanaged_specs, - nm_settings_plugin_get_unmanaged_specs)) - _notify (self, PROP_UNMANAGED_SPECS); + if (update_specs(self, &priv->unmanaged_specs, nm_settings_plugin_get_unmanaged_specs)) + _notify(self, PROP_UNMANAGED_SPECS); } static void -_plugin_unrecognized_specs_changed (NMSettingsPlugin *config, - gpointer user_data) +_plugin_unrecognized_specs_changed(NMSettingsPlugin *config, gpointer user_data) { - NMSettings *self = NM_SETTINGS (user_data); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettings * self = NM_SETTINGS(user_data); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); - update_specs (self, &priv->unrecognized_specs, - nm_settings_plugin_get_unrecognized_specs); + update_specs(self, &priv->unrecognized_specs, nm_settings_plugin_get_unrecognized_specs); } /*****************************************************************************/ static void -connection_flags_changed (NMSettingsConnection *sett_conn, - gpointer user_data) +connection_flags_changed(NMSettingsConnection *sett_conn, gpointer user_data) { - _emit_connection_flags_changed (NM_SETTINGS (user_data), sett_conn); + _emit_connection_flags_changed(NM_SETTINGS(user_data), sett_conn); } /*****************************************************************************/ static SettConnEntry * -_sett_conn_entries_get (NMSettings *self, - const char *uuid) +_sett_conn_entries_get(NMSettings *self, const char *uuid) { - nm_assert (uuid); - return g_hash_table_lookup (NM_SETTINGS_GET_PRIVATE (self)->sce_idx, &uuid); + nm_assert(uuid); + return g_hash_table_lookup(NM_SETTINGS_GET_PRIVATE(self)->sce_idx, &uuid); } static SettConnEntry * -_sett_conn_entries_create_and_add (NMSettings *self, - const char *uuid) +_sett_conn_entries_create_and_add(NMSettings *self, const char *uuid) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - SettConnEntry *sett_conn_entry; + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + SettConnEntry * sett_conn_entry; - sett_conn_entry = _sett_conn_entry_new (uuid); + sett_conn_entry = _sett_conn_entry_new(uuid); - if (!g_hash_table_add (priv->sce_idx, sett_conn_entry)) - nm_assert_not_reached (); - else if (g_hash_table_size (priv->sce_idx) == 1) - g_object_ref (self); + if (!g_hash_table_add(priv->sce_idx, sett_conn_entry)) + nm_assert_not_reached(); + else if (g_hash_table_size(priv->sce_idx) == 1) + g_object_ref(self); - return sett_conn_entry; + return sett_conn_entry; } static void -_sett_conn_entries_remove_and_destroy (NMSettings *self, - SettConnEntry *sett_conn_entry) +_sett_conn_entries_remove_and_destroy(NMSettings *self, SettConnEntry *sett_conn_entry) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); - if (!g_hash_table_remove (priv->sce_idx, sett_conn_entry)) - nm_assert_not_reached (); - else if (g_hash_table_size (priv->sce_idx) == 0) - g_object_unref (self); + if (!g_hash_table_remove(priv->sce_idx, sett_conn_entry)) + nm_assert_not_reached(); + else if (g_hash_table_size(priv->sce_idx) == 0) + g_object_unref(self); } /*****************************************************************************/ static int -_sett_conn_entry_sds_update_cmp_ascending (const StorageData *sd_a, - const StorageData *sd_b, - const GSList *plugins) +_sett_conn_entry_sds_update_cmp_ascending(const StorageData *sd_a, + const StorageData *sd_b, + const GSList * plugins) { - const NMSettingsMetaData *meta_data_a; - const NMSettingsMetaData *meta_data_b; - bool is_keyfile_run_a; - bool is_keyfile_run_b; - - /* Sort storages by priority. More important storages are sorted - * higher (ascending sort). For example, if "sd_a" is more important than - * "sd_b" (sd_a>sd_b), a positive integer is returned. */ - - meta_data_a = nm_settings_storage_is_meta_data (sd_a->storage); - meta_data_b = nm_settings_storage_is_meta_data (sd_b->storage); - - /* runtime storages (both connections and meta-data) are always more - * important. */ - is_keyfile_run_a = nm_settings_storage_is_keyfile_run (sd_a->storage); - is_keyfile_run_b = nm_settings_storage_is_keyfile_run (sd_b->storage); - if (is_keyfile_run_a != is_keyfile_run_b) { - - if ( !meta_data_a - && !meta_data_b) { - /* Ok, both are non-meta-data providing actual profiles. But one is in /run and one is in - * another storage. In this case we first honor whether one of the storages is explicitly - * prioritized. The prioritize flag is an in-memory hack to overwrite relative priorities - * contrary to what exists on-disk. - * - * This is done because when we use explicit D-Bus API (like update-connection) - * to update a profile, then we really want to prioritize the candidate - * despite having multiple other profiles. - * - * The example is if you have the same UUID twice in /run (one of them shadowed). - * If you move it to disk, then one of the profiles gets deleted and re-created - * on disk, but that on-disk profile must win against the remainging profile in - * /run. At least until the next reload/restart. */ - NM_CMP_FIELD_UNSAFE (sd_a, sd_b, prioritize); - } - - /* in-memory has higher priority. That is regardless of whether any of - * them is meta-data/tombstone or a profile. - * - * That works, because if any of them are tombstones/metadata, then we are in full - * control. There can by only one meta-data file, which is fully owned (and accordingly - * created/deleted) by NetworkManager. - * - * The only case where this might not be right is if we have profiles - * in /run that are shadowed. When we move such a profile to disk, then - * a conflict might arise. That is handled by "prioritize" above! */ - NM_CMP_DIRECT (is_keyfile_run_a, is_keyfile_run_b); - } - - /* After we determined that both profiles are either in /run or not, - * tombstones are always more important than non-tombstones. */ - NM_CMP_DIRECT (meta_data_a && meta_data_a->is_tombstone, - meta_data_b && meta_data_b->is_tombstone); - - /* Again, prioritized entries are sorted first (higher priority). */ - NM_CMP_FIELD_UNSAFE (sd_a, sd_b, prioritize); - - /* finally, compare the storages. This basically honors the timestamp - * of the profile and the relative order of the source plugin (via the - * @plugins list). */ - return nm_settings_storage_cmp (sd_a->storage, sd_b->storage, plugins); + const NMSettingsMetaData *meta_data_a; + const NMSettingsMetaData *meta_data_b; + bool is_keyfile_run_a; + bool is_keyfile_run_b; + + /* Sort storages by priority. More important storages are sorted + * higher (ascending sort). For example, if "sd_a" is more important than + * "sd_b" (sd_a>sd_b), a positive integer is returned. */ + + meta_data_a = nm_settings_storage_is_meta_data(sd_a->storage); + meta_data_b = nm_settings_storage_is_meta_data(sd_b->storage); + + /* runtime storages (both connections and meta-data) are always more + * important. */ + is_keyfile_run_a = nm_settings_storage_is_keyfile_run(sd_a->storage); + is_keyfile_run_b = nm_settings_storage_is_keyfile_run(sd_b->storage); + if (is_keyfile_run_a != is_keyfile_run_b) { + if (!meta_data_a && !meta_data_b) { + /* Ok, both are non-meta-data providing actual profiles. But one is in /run and one is in + * another storage. In this case we first honor whether one of the storages is explicitly + * prioritized. The prioritize flag is an in-memory hack to overwrite relative priorities + * contrary to what exists on-disk. + * + * This is done because when we use explicit D-Bus API (like update-connection) + * to update a profile, then we really want to prioritize the candidate + * despite having multiple other profiles. + * + * The example is if you have the same UUID twice in /run (one of them shadowed). + * If you move it to disk, then one of the profiles gets deleted and re-created + * on disk, but that on-disk profile must win against the remainging profile in + * /run. At least until the next reload/restart. */ + NM_CMP_FIELD_UNSAFE(sd_a, sd_b, prioritize); + } + + /* in-memory has higher priority. That is regardless of whether any of + * them is meta-data/tombstone or a profile. + * + * That works, because if any of them are tombstones/metadata, then we are in full + * control. There can by only one meta-data file, which is fully owned (and accordingly + * created/deleted) by NetworkManager. + * + * The only case where this might not be right is if we have profiles + * in /run that are shadowed. When we move such a profile to disk, then + * a conflict might arise. That is handled by "prioritize" above! */ + NM_CMP_DIRECT(is_keyfile_run_a, is_keyfile_run_b); + } + + /* After we determined that both profiles are either in /run or not, + * tombstones are always more important than non-tombstones. */ + NM_CMP_DIRECT(meta_data_a && meta_data_a->is_tombstone, + meta_data_b && meta_data_b->is_tombstone); + + /* Again, prioritized entries are sorted first (higher priority). */ + NM_CMP_FIELD_UNSAFE(sd_a, sd_b, prioritize); + + /* finally, compare the storages. This basically honors the timestamp + * of the profile and the relative order of the source plugin (via the + * @plugins list). */ + return nm_settings_storage_cmp(sd_a->storage, sd_b->storage, plugins); } static int -_sett_conn_entry_sds_update_cmp (const CList *ls_a, - const CList *ls_b, - gconstpointer user_data) +_sett_conn_entry_sds_update_cmp(const CList *ls_a, const CList *ls_b, gconstpointer user_data) { - /* we sort highest priority storages first (descending). Hence, the order is swapped. */ - return _sett_conn_entry_sds_update_cmp_ascending (c_list_entry (ls_b, StorageData, sd_lst), - c_list_entry (ls_a, StorageData, sd_lst), - user_data); + /* we sort highest priority storages first (descending). Hence, the order is swapped. */ + return _sett_conn_entry_sds_update_cmp_ascending(c_list_entry(ls_b, StorageData, sd_lst), + c_list_entry(ls_a, StorageData, sd_lst), + user_data); } static void -_sett_conn_entry_sds_update (NMSettings *self, - SettConnEntry *sett_conn_entry) +_sett_conn_entry_sds_update(NMSettings *self, SettConnEntry *sett_conn_entry) { - StorageData *sd; - StorageData *sd_safe; - StorageData *sd_dirty; - gboolean reprioritize; - - nm_assert_storage_data_lst (&sett_conn_entry->sd_lst_head); - nm_assert_storage_data_lst (&sett_conn_entry->dirty_sd_lst_head); - - /* we merge the dirty list with the previous list. - * - * The idea is: - * - * - _connection_changed_track() appends events for the same UUID. Meaning: - * if the storage is new, it get appended (having lower priority). - * If it already exist and is an update for an event that we already - * track it, it keeps the list position in @dirty_sd_lst_head unchanged. - * - * - during merge, we want to preserve the previous order (with higher - * priority first in the list). - */ - - /* first go through all storages that we track and check whether they - * got an update...*/ - - reprioritize = FALSE; - c_list_for_each_entry (sd, &sett_conn_entry->dirty_sd_lst_head, sd_lst) { - if (sd->prioritize) { - reprioritize = TRUE; - break; - } - } - - nm_assert_storage_data_lst (&sett_conn_entry->sd_lst_head); - - c_list_for_each_entry_safe (sd, sd_safe, &sett_conn_entry->sd_lst_head, sd_lst) { - - sd_dirty = _storage_data_find_in_lst (&sett_conn_entry->dirty_sd_lst_head, sd->storage); - if (!sd_dirty) { - /* there is no update for this storage (except maybe reprioritize). */ - if (reprioritize) - sd->prioritize = FALSE; - continue; - } - - nm_g_object_ref_set (&sd->connection, sd_dirty->connection); - sd->prioritize = sd_dirty->prioritize; - - _storage_data_destroy (sd_dirty); - } - - nm_assert_storage_data_lst (&sett_conn_entry->sd_lst_head); - - /* all remaining (so far unseen) dirty entries are appended to the merged list. - * (append means lower priority). */ - - c_list_splice (&sett_conn_entry->sd_lst_head, &sett_conn_entry->dirty_sd_lst_head); - - nm_assert_storage_data_lst (&sett_conn_entry->sd_lst_head); - - /* we drop the entries that are no longer "alive" (meaning, they no longer - * indicate a connection and are not a tombstone). */ - c_list_for_each_entry_safe (sd, sd_safe, &sett_conn_entry->sd_lst_head, sd_lst) { - if (!_storage_data_is_alive (sd)) - _storage_data_destroy (sd); - } - - nm_assert_storage_data_lst (&sett_conn_entry->sd_lst_head); - nm_assert (c_list_is_empty (&sett_conn_entry->dirty_sd_lst_head)); - - /* as last, we sort the entries. Note that this is a stable-sort... */ - c_list_sort (&sett_conn_entry->sd_lst_head, - _sett_conn_entry_sds_update_cmp, - NM_SETTINGS_GET_PRIVATE (self)->plugins); - - nm_assert_storage_data_lst (&sett_conn_entry->sd_lst_head); - nm_assert (c_list_is_empty (&sett_conn_entry->dirty_sd_lst_head)); + StorageData *sd; + StorageData *sd_safe; + StorageData *sd_dirty; + gboolean reprioritize; + + nm_assert_storage_data_lst(&sett_conn_entry->sd_lst_head); + nm_assert_storage_data_lst(&sett_conn_entry->dirty_sd_lst_head); + + /* we merge the dirty list with the previous list. + * + * The idea is: + * + * - _connection_changed_track() appends events for the same UUID. Meaning: + * if the storage is new, it get appended (having lower priority). + * If it already exist and is an update for an event that we already + * track it, it keeps the list position in @dirty_sd_lst_head unchanged. + * + * - during merge, we want to preserve the previous order (with higher + * priority first in the list). + */ + + /* first go through all storages that we track and check whether they + * got an update...*/ + + reprioritize = FALSE; + c_list_for_each_entry (sd, &sett_conn_entry->dirty_sd_lst_head, sd_lst) { + if (sd->prioritize) { + reprioritize = TRUE; + break; + } + } + + nm_assert_storage_data_lst(&sett_conn_entry->sd_lst_head); + + c_list_for_each_entry_safe (sd, sd_safe, &sett_conn_entry->sd_lst_head, sd_lst) { + sd_dirty = _storage_data_find_in_lst(&sett_conn_entry->dirty_sd_lst_head, sd->storage); + if (!sd_dirty) { + /* there is no update for this storage (except maybe reprioritize). */ + if (reprioritize) + sd->prioritize = FALSE; + continue; + } + + nm_g_object_ref_set(&sd->connection, sd_dirty->connection); + sd->prioritize = sd_dirty->prioritize; + + _storage_data_destroy(sd_dirty); + } + + nm_assert_storage_data_lst(&sett_conn_entry->sd_lst_head); + + /* all remaining (so far unseen) dirty entries are appended to the merged list. + * (append means lower priority). */ + + c_list_splice(&sett_conn_entry->sd_lst_head, &sett_conn_entry->dirty_sd_lst_head); + + nm_assert_storage_data_lst(&sett_conn_entry->sd_lst_head); + + /* we drop the entries that are no longer "alive" (meaning, they no longer + * indicate a connection and are not a tombstone). */ + c_list_for_each_entry_safe (sd, sd_safe, &sett_conn_entry->sd_lst_head, sd_lst) { + if (!_storage_data_is_alive(sd)) + _storage_data_destroy(sd); + } + + nm_assert_storage_data_lst(&sett_conn_entry->sd_lst_head); + nm_assert(c_list_is_empty(&sett_conn_entry->dirty_sd_lst_head)); + + /* as last, we sort the entries. Note that this is a stable-sort... */ + c_list_sort(&sett_conn_entry->sd_lst_head, + _sett_conn_entry_sds_update_cmp, + NM_SETTINGS_GET_PRIVATE(self)->plugins); + + nm_assert_storage_data_lst(&sett_conn_entry->sd_lst_head); + nm_assert(c_list_is_empty(&sett_conn_entry->dirty_sd_lst_head)); } /*****************************************************************************/ static NMConnection * -_connection_changed_normalize_connection (NMSettingsStorage *storage, - NMConnection *connection, - GVariant *secrets_to_merge, - NMConnection **out_connection_cloned) +_connection_changed_normalize_connection(NMSettingsStorage *storage, + NMConnection * connection, + GVariant * secrets_to_merge, + NMConnection ** out_connection_cloned) { - gs_unref_object NMConnection *connection_cloned = NULL; - gs_free_error GError *error = NULL; - const char *uuid; - - nm_assert (NM_IS_SETTINGS_STORAGE (storage)); - nm_assert (out_connection_cloned && !*out_connection_cloned); - - if (!connection) - return NULL; - - nm_assert (NM_IS_CONNECTION (connection)); - - uuid = nm_settings_storage_get_uuid (storage); - - if (secrets_to_merge) { - connection_cloned = nm_simple_connection_new_clone (connection); - connection = connection_cloned; - nm_connection_update_secrets (connection, - NULL, - secrets_to_merge, - NULL); - } - - if (!_nm_connection_ensure_normalized (connection, - !!connection_cloned, - uuid, - FALSE, - connection_cloned ? NULL : &connection_cloned, - &error)) { - /* this is most likely a bug in the plugin. It provided a connection that no longer verifies. - * Well, I guess it could also happen when we merge @secrets_to_merge above. In any case - * somewhere is a bug. */ - _LOGT ("storage[%s,"NM_SETTINGS_STORAGE_PRINT_FMT"]: plugin provided an invalid connection: %s", - uuid, - NM_SETTINGS_STORAGE_PRINT_ARG (storage), - error->message); - return NULL; - } - if (connection_cloned) - connection = connection_cloned; - - *out_connection_cloned = g_steal_pointer (&connection_cloned); - return connection; + gs_unref_object NMConnection *connection_cloned = NULL; + gs_free_error GError *error = NULL; + const char * uuid; + + nm_assert(NM_IS_SETTINGS_STORAGE(storage)); + nm_assert(out_connection_cloned && !*out_connection_cloned); + + if (!connection) + return NULL; + + nm_assert(NM_IS_CONNECTION(connection)); + + uuid = nm_settings_storage_get_uuid(storage); + + if (secrets_to_merge) { + connection_cloned = nm_simple_connection_new_clone(connection); + connection = connection_cloned; + nm_connection_update_secrets(connection, NULL, secrets_to_merge, NULL); + } + + if (!_nm_connection_ensure_normalized(connection, + !!connection_cloned, + uuid, + FALSE, + connection_cloned ? NULL : &connection_cloned, + &error)) { + /* this is most likely a bug in the plugin. It provided a connection that no longer verifies. + * Well, I guess it could also happen when we merge @secrets_to_merge above. In any case + * somewhere is a bug. */ + _LOGT("storage[%s," NM_SETTINGS_STORAGE_PRINT_FMT + "]: plugin provided an invalid connection: %s", + uuid, + NM_SETTINGS_STORAGE_PRINT_ARG(storage), + error->message); + return NULL; + } + if (connection_cloned) + connection = connection_cloned; + + *out_connection_cloned = g_steal_pointer(&connection_cloned); + return connection; } /*****************************************************************************/ static void -_connection_changed_update (NMSettings *self, - SettConnEntry *sett_conn_entry, - NMConnection *connection, - NMSettingsConnectionIntFlags sett_flags, - NMSettingsConnectionIntFlags sett_mask, - NMSettingsConnectionUpdateReason update_reason) +_connection_changed_update(NMSettings * self, + SettConnEntry * sett_conn_entry, + NMConnection * connection, + NMSettingsConnectionIntFlags sett_flags, + NMSettingsConnectionIntFlags sett_mask, + NMSettingsConnectionUpdateReason update_reason) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - gs_unref_object NMConnection *connection_old = NULL; - NMSettingsStorage *storage = sett_conn_entry->storage; - gs_unref_object NMSettingsConnection *sett_conn = g_object_ref (sett_conn_entry->sett_conn); - const char *path; - gboolean is_new; - - nm_assert (!NM_FLAGS_ANY (sett_mask, ~_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK)); - nm_assert (!NM_FLAGS_ANY (sett_flags, ~sett_mask)); - - is_new = c_list_is_empty (&sett_conn->_connections_lst); - - _LOGT ("update[%s]: %s connection \"%s\" ("NM_SETTINGS_STORAGE_PRINT_FMT")", - nm_settings_storage_get_uuid (storage), - is_new ? "adding" : "updating", - nm_connection_get_id (connection), - NM_SETTINGS_STORAGE_PRINT_ARG (storage)); - - _nm_settings_connection_set_storage (sett_conn, storage); - - _nm_settings_connection_set_connection (sett_conn, connection, &connection_old, update_reason); - - - if (is_new) { - _nm_settings_connection_register_kf_dbs (sett_conn, - priv->kf_db_timestamps, - priv->kf_db_seen_bssids); - - _clear_connections_cached_list (priv); - c_list_link_tail (&priv->connections_lst_head, &sett_conn->_connections_lst); - priv->connections_len++; - priv->connections_generation++; - - g_signal_connect (sett_conn, NM_SETTINGS_CONNECTION_FLAGS_CHANGED, G_CALLBACK (connection_flags_changed), self); - } - - if (NM_FLAGS_HAS (update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT)) { - nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST, - TRUE); - } - - sett_mask |= NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE; - if (nm_settings_connection_check_visibility (sett_conn, priv->session_monitor)) - sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE; - else - nm_assert (!NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)); - - sett_mask |= NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED; - if (nm_settings_storage_is_keyfile_run (storage)) - sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED; - else { - nm_assert (!NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED)); - - /* Profiles that don't reside in /run, are never nm-generated, - * volatile, and external. */ - sett_mask |= ( NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL); - sett_flags &= ~( NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL); - } - - nm_settings_connection_set_flags_full (sett_conn, - sett_mask, - sett_flags); - - if (is_new) { - /* FIXME(shutdown): The NMSettings instance can't be disposed - * while there is any exported connection. Ideally we should - * unexport all connections on NMSettings' disposal, but for now - * leak @self on termination when there are connections alive. */ - path = nm_dbus_object_export (NM_DBUS_OBJECT (sett_conn)); - } else - path = nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn)); - - if ( is_new - || connection_old) { - nm_utils_log_connection_diff (nm_settings_connection_get_connection (sett_conn), - connection_old, - LOGL_DEBUG, - LOGD_CORE, - is_new ? "new connection" : "update connection", - "++ ", - path); - } - - if (is_new) { - nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), - &interface_info_settings, - &signal_info_new_connection, - "(o)", - path); - _notify (self, PROP_CONNECTIONS); - _emit_connection_added (self, sett_conn); - } else { - _nm_settings_connection_emit_dbus_signal_updated (sett_conn); - _emit_connection_updated (self, sett_conn, update_reason); - } - - if (priv->startup_complete_start_timestamp_msec != 0) { - if (nm_settings_has_connection (self, sett_conn)) - _startup_complete_notify_connection (self, sett_conn, FALSE); - } + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + gs_unref_object NMConnection *connection_old = NULL; + NMSettingsStorage * storage = sett_conn_entry->storage; + gs_unref_object NMSettingsConnection *sett_conn = g_object_ref(sett_conn_entry->sett_conn); + const char * path; + gboolean is_new; + + nm_assert(!NM_FLAGS_ANY(sett_mask, ~_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK)); + nm_assert(!NM_FLAGS_ANY(sett_flags, ~sett_mask)); + + is_new = c_list_is_empty(&sett_conn->_connections_lst); + + _LOGT("update[%s]: %s connection \"%s\" (" NM_SETTINGS_STORAGE_PRINT_FMT ")", + nm_settings_storage_get_uuid(storage), + is_new ? "adding" : "updating", + nm_connection_get_id(connection), + NM_SETTINGS_STORAGE_PRINT_ARG(storage)); + + _nm_settings_connection_set_storage(sett_conn, storage); + + _nm_settings_connection_set_connection(sett_conn, connection, &connection_old, update_reason); + + if (is_new) { + _nm_settings_connection_register_kf_dbs(sett_conn, + priv->kf_db_timestamps, + priv->kf_db_seen_bssids); + + _clear_connections_cached_list(priv); + c_list_link_tail(&priv->connections_lst_head, &sett_conn->_connections_lst); + priv->connections_len++; + priv->connections_generation++; + + g_signal_connect(sett_conn, + NM_SETTINGS_CONNECTION_FLAGS_CHANGED, + G_CALLBACK(connection_flags_changed), + self); + } + + if (NM_FLAGS_HAS(update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT)) { + nm_settings_connection_autoconnect_blocked_reason_set( + sett_conn, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST, + TRUE); + } + + sett_mask |= NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE; + if (nm_settings_connection_check_visibility(sett_conn, priv->session_monitor)) + sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE; + else + nm_assert(!NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)); + + sett_mask |= NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED; + if (nm_settings_storage_is_keyfile_run(storage)) + sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED; + else { + nm_assert(!NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED)); + + /* Profiles that don't reside in /run, are never nm-generated, + * volatile, and external. */ + sett_mask |= (NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL); + sett_flags &= ~(NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL); + } + + nm_settings_connection_set_flags_full(sett_conn, sett_mask, sett_flags); + + if (is_new) { + /* FIXME(shutdown): The NMSettings instance can't be disposed + * while there is any exported connection. Ideally we should + * unexport all connections on NMSettings' disposal, but for now + * leak @self on termination when there are connections alive. */ + path = nm_dbus_object_export(NM_DBUS_OBJECT(sett_conn)); + } else + path = nm_dbus_object_get_path(NM_DBUS_OBJECT(sett_conn)); + + if (is_new || connection_old) { + nm_utils_log_connection_diff(nm_settings_connection_get_connection(sett_conn), + connection_old, + LOGL_DEBUG, + LOGD_CORE, + is_new ? "new connection" : "update connection", + "++ ", + path); + } + + if (is_new) { + nm_dbus_object_emit_signal(NM_DBUS_OBJECT(self), + &interface_info_settings, + &signal_info_new_connection, + "(o)", + path); + _notify(self, PROP_CONNECTIONS); + _emit_connection_added(self, sett_conn); + } else { + _nm_settings_connection_emit_dbus_signal_updated(sett_conn); + _emit_connection_updated(self, sett_conn, update_reason); + } + + if (priv->startup_complete_start_timestamp_msec != 0) { + if (nm_settings_has_connection(self, sett_conn)) + _startup_complete_notify_connection(self, sett_conn, FALSE); + } } static void -_connection_changed_delete (NMSettings *self, - NMSettingsStorage *storage, - NMSettingsConnection *sett_conn, - gboolean allow_add_to_no_auto_default) +_connection_changed_delete(NMSettings * self, + NMSettingsStorage * storage, + NMSettingsConnection *sett_conn, + gboolean allow_add_to_no_auto_default) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - gs_unref_object NMConnection *connection_for_agents = NULL; - NMDevice *device; - const char *uuid; - - nm_assert (NM_IS_SETTINGS_CONNECTION (sett_conn)); - nm_assert (c_list_contains (&priv->connections_lst_head, &sett_conn->_connections_lst)); - nm_assert (nm_dbus_object_is_exported (NM_DBUS_OBJECT (sett_conn))); - - uuid = nm_settings_storage_get_uuid (storage); - - _LOGT ("update[%s]: delete connection \"%s\" ("NM_SETTINGS_STORAGE_PRINT_FMT")", - uuid, - nm_settings_connection_get_id (sett_conn), - NM_SETTINGS_STORAGE_PRINT_ARG (storage)); - - /* When the default wired sett_conn is removed (either deleted or saved to - * a new persistent sett_conn by a plugin), write the MAC address of the - * wired device to the config file and don't create a new default wired - * sett_conn for that device again. - */ - device = nm_settings_connection_default_wired_get_device (sett_conn); - if (device) - default_wired_clear_tag (self, device, sett_conn, allow_add_to_no_auto_default); - - g_signal_handlers_disconnect_by_func (sett_conn, G_CALLBACK (connection_flags_changed), self); - - _clear_connections_cached_list (priv); - c_list_unlink (&sett_conn->_connections_lst); - priv->connections_len--; - priv->connections_generation++; - - /* Tell agents to remove secrets for this connection */ - connection_for_agents = nm_simple_connection_new_clone (nm_settings_connection_get_connection (sett_conn)); - nm_connection_clear_secrets (connection_for_agents); - nm_agent_manager_delete_secrets (priv->agent_mgr, - nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), - connection_for_agents); - - _notify (self, PROP_CONNECTIONS); - _nm_settings_connection_emit_dbus_signal_removed (sett_conn); - nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), - &interface_info_settings, - &signal_info_connection_removed, - "(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn))); - - nm_dbus_object_unexport (NM_DBUS_OBJECT (sett_conn)); - - nm_settings_connection_set_flags (sett_conn, - NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL, - FALSE); - - _emit_connection_removed (self, sett_conn); - - _nm_settings_connection_cleanup_after_remove (sett_conn); - - nm_key_file_db_remove_key (priv->kf_db_timestamps, uuid); - nm_key_file_db_remove_key (priv->kf_db_seen_bssids, uuid); - - if (priv->startup_complete_start_timestamp_msec != 0) - _startup_complete_notify_connection (self, sett_conn, TRUE); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + gs_unref_object NMConnection *connection_for_agents = NULL; + NMDevice * device; + const char * uuid; + + nm_assert(NM_IS_SETTINGS_CONNECTION(sett_conn)); + nm_assert(c_list_contains(&priv->connections_lst_head, &sett_conn->_connections_lst)); + nm_assert(nm_dbus_object_is_exported(NM_DBUS_OBJECT(sett_conn))); + + uuid = nm_settings_storage_get_uuid(storage); + + _LOGT("update[%s]: delete connection \"%s\" (" NM_SETTINGS_STORAGE_PRINT_FMT ")", + uuid, + nm_settings_connection_get_id(sett_conn), + NM_SETTINGS_STORAGE_PRINT_ARG(storage)); + + /* When the default wired sett_conn is removed (either deleted or saved to + * a new persistent sett_conn by a plugin), write the MAC address of the + * wired device to the config file and don't create a new default wired + * sett_conn for that device again. + */ + device = nm_settings_connection_default_wired_get_device(sett_conn); + if (device) + default_wired_clear_tag(self, device, sett_conn, allow_add_to_no_auto_default); + + g_signal_handlers_disconnect_by_func(sett_conn, G_CALLBACK(connection_flags_changed), self); + + _clear_connections_cached_list(priv); + c_list_unlink(&sett_conn->_connections_lst); + priv->connections_len--; + priv->connections_generation++; + + /* Tell agents to remove secrets for this connection */ + connection_for_agents = + nm_simple_connection_new_clone(nm_settings_connection_get_connection(sett_conn)); + nm_connection_clear_secrets(connection_for_agents); + nm_agent_manager_delete_secrets(priv->agent_mgr, + nm_dbus_object_get_path(NM_DBUS_OBJECT(self)), + connection_for_agents); + + _notify(self, PROP_CONNECTIONS); + _nm_settings_connection_emit_dbus_signal_removed(sett_conn); + nm_dbus_object_emit_signal(NM_DBUS_OBJECT(self), + &interface_info_settings, + &signal_info_connection_removed, + "(o)", + nm_dbus_object_get_path(NM_DBUS_OBJECT(sett_conn))); + + nm_dbus_object_unexport(NM_DBUS_OBJECT(sett_conn)); + + nm_settings_connection_set_flags(sett_conn, + NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL, + FALSE); + + _emit_connection_removed(self, sett_conn); + + _nm_settings_connection_cleanup_after_remove(sett_conn); + + nm_key_file_db_remove_key(priv->kf_db_timestamps, uuid); + nm_key_file_db_remove_key(priv->kf_db_seen_bssids, uuid); + + if (priv->startup_complete_start_timestamp_msec != 0) + _startup_complete_notify_connection(self, sett_conn, TRUE); } static void -_connection_changed_process_one (NMSettings *self, - SettConnEntry *sett_conn_entry, - gboolean allow_add_to_no_auto_default, - NMSettingsConnectionIntFlags sett_flags, - NMSettingsConnectionIntFlags sett_mask, - gboolean override_sett_flags, - NMSettingsConnectionUpdateReason update_reason) +_connection_changed_process_one(NMSettings * self, + SettConnEntry * sett_conn_entry, + gboolean allow_add_to_no_auto_default, + NMSettingsConnectionIntFlags sett_flags, + NMSettingsConnectionIntFlags sett_mask, + gboolean override_sett_flags, + NMSettingsConnectionUpdateReason update_reason) { - StorageData *sd_best; + StorageData *sd_best; - c_list_unlink (&sett_conn_entry->sce_dirty_lst); + c_list_unlink(&sett_conn_entry->sce_dirty_lst); - _sett_conn_entry_sds_update (self, sett_conn_entry); + _sett_conn_entry_sds_update(self, sett_conn_entry); - sd_best = c_list_first_entry (&sett_conn_entry->sd_lst_head, StorageData, sd_lst);; + sd_best = c_list_first_entry(&sett_conn_entry->sd_lst_head, StorageData, sd_lst); - if ( !sd_best - || !sd_best->connection) { - gs_unref_object NMSettingsConnection *sett_conn = NULL; - gs_unref_object NMSettingsStorage *storage = NULL; + if (!sd_best || !sd_best->connection) { + gs_unref_object NMSettingsConnection *sett_conn = NULL; + gs_unref_object NMSettingsStorage *storage = NULL; - if (!sett_conn_entry->sett_conn) { + if (!sett_conn_entry->sett_conn) { + if (!sd_best) { + _sett_conn_entries_remove_and_destroy(self, sett_conn_entry); + return; + } - if (!sd_best) { - _sett_conn_entries_remove_and_destroy (self, sett_conn_entry); - return; - } + if (sett_conn_entry->storage != sd_best->storage) { + _LOGT("update[%s]: shadow UUID (" NM_SETTINGS_STORAGE_PRINT_FMT ")", + sett_conn_entry->uuid, + NM_SETTINGS_STORAGE_PRINT_ARG(sd_best->storage)); + } - if (sett_conn_entry->storage != sd_best->storage) { - _LOGT ("update[%s]: shadow UUID ("NM_SETTINGS_STORAGE_PRINT_FMT")", - sett_conn_entry->uuid, - NM_SETTINGS_STORAGE_PRINT_ARG (sd_best->storage)); - } + nm_g_object_ref_set(&sett_conn_entry->storage, sd_best->storage); + return; + } - nm_g_object_ref_set (&sett_conn_entry->storage, sd_best->storage); - return; - } + sett_conn = g_steal_pointer(&sett_conn_entry->sett_conn); + if (sd_best) { + storage = g_object_ref(sd_best->storage); + nm_g_object_ref_set(&sett_conn_entry->storage, storage); + nm_assert_valid_settings_storage(NULL, storage); + } else { + storage = g_object_ref(sett_conn_entry->storage); + _sett_conn_entries_remove_and_destroy(self, sett_conn_entry); + } - sett_conn = g_steal_pointer (&sett_conn_entry->sett_conn); - if (sd_best) { - storage = g_object_ref (sd_best->storage); - nm_g_object_ref_set (&sett_conn_entry->storage, storage); - nm_assert_valid_settings_storage (NULL, storage); - } else { - storage = g_object_ref (sett_conn_entry->storage); - _sett_conn_entries_remove_and_destroy (self, sett_conn_entry); - } + _connection_changed_delete(self, storage, sett_conn, allow_add_to_no_auto_default); + return; + } - _connection_changed_delete (self, storage, sett_conn, allow_add_to_no_auto_default); - return; - } + if (override_sett_flags) { + NMSettingsConnectionIntFlags s_f, s_m; - if (override_sett_flags) { - NMSettingsConnectionIntFlags s_f, s_m; + nm_settings_storage_load_sett_flags(sd_best->storage, &s_f, &s_m); - nm_settings_storage_load_sett_flags (sd_best->storage, &s_f, &s_m); + nm_assert(!NM_FLAGS_ANY(s_f, ~s_m)); - nm_assert (!NM_FLAGS_ANY (s_f, ~s_m)); + sett_mask |= s_m; + sett_flags = (sett_flags & ~s_m) | (s_f & s_m); + } - sett_mask |= s_m; - sett_flags = (sett_flags & ~s_m) | (s_f & s_m); - } + nm_g_object_ref_set(&sett_conn_entry->storage, sd_best->storage); - nm_g_object_ref_set (&sett_conn_entry->storage, sd_best->storage); + if (!sett_conn_entry->sett_conn) + sett_conn_entry->sett_conn = nm_settings_connection_new(); - if (!sett_conn_entry->sett_conn) - sett_conn_entry->sett_conn = nm_settings_connection_new (); - - _connection_changed_update (self, - sett_conn_entry, - sd_best->connection, - sett_flags, - sett_mask, - update_reason); + _connection_changed_update(self, + sett_conn_entry, + sd_best->connection, + sett_flags, + sett_mask, + update_reason); } static void -_connection_changed_process_all_dirty (NMSettings *self, - gboolean allow_add_to_no_auto_default, - NMSettingsConnectionIntFlags sett_flags, - NMSettingsConnectionIntFlags sett_mask, - gboolean override_sett_flags, - NMSettingsConnectionUpdateReason update_reason) +_connection_changed_process_all_dirty(NMSettings * self, + gboolean allow_add_to_no_auto_default, + NMSettingsConnectionIntFlags sett_flags, + NMSettingsConnectionIntFlags sett_mask, + gboolean override_sett_flags, + NMSettingsConnectionUpdateReason update_reason) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - SettConnEntry *sett_conn_entry; - - while ((sett_conn_entry = c_list_first_entry (&priv->sce_dirty_lst_head, SettConnEntry, sce_dirty_lst))) { - _connection_changed_process_one (self, - sett_conn_entry, - allow_add_to_no_auto_default, - sett_flags, - sett_mask, - override_sett_flags, - update_reason); - } + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + SettConnEntry * sett_conn_entry; + + while ((sett_conn_entry = + c_list_first_entry(&priv->sce_dirty_lst_head, SettConnEntry, sce_dirty_lst))) { + _connection_changed_process_one(self, + sett_conn_entry, + allow_add_to_no_auto_default, + sett_flags, + sett_mask, + override_sett_flags, + update_reason); + } } static SettConnEntry * -_connection_changed_track (NMSettings *self, - NMSettingsStorage *storage, - NMConnection *connection, - gboolean prioritize) +_connection_changed_track(NMSettings * self, + NMSettingsStorage *storage, + NMConnection * connection, + gboolean prioritize) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - SettConnEntry *sett_conn_entry; - StorageData *sd; - const char *uuid; - - nm_assert_valid_settings_storage (NULL, storage); - - uuid = nm_settings_storage_get_uuid (storage); - - nm_assert (!connection || NM_IS_CONNECTION (connection)); - nm_assert (!connection || (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS)); - nm_assert (!connection || nm_streq0 (uuid, nm_connection_get_uuid (connection))); - - nmtst_connection_assert_unchanging (connection); - - sett_conn_entry = _sett_conn_entries_get (self, uuid) - ?: _sett_conn_entries_create_and_add (self, uuid); - - if (_LOGT_ENABLED ()) { - const char *filename; - const NMSettingsMetaData *meta_data; - const char *shadowed_storage; - gboolean shadowed_owned; - - filename = nm_settings_storage_get_filename (storage); - if (connection) { - shadowed_storage = nm_settings_storage_get_shadowed_storage (storage, &shadowed_owned); - _LOGT ("storage[%s,"NM_SETTINGS_STORAGE_PRINT_FMT"]: change event with connection \"%s\"%s%s%s%s%s%s", - sett_conn_entry->uuid, - NM_SETTINGS_STORAGE_PRINT_ARG (storage), - nm_connection_get_id (connection), - NM_PRINT_FMT_QUOTED (filename, " (file \"", filename, "\")", ""), - NM_PRINT_FMT_QUOTED (shadowed_storage, shadowed_owned ? " (owns \"" : " (shadows \"", shadowed_storage, "\")", "")); - } else if ((meta_data = nm_settings_storage_is_meta_data (storage))) { - nm_assert (meta_data->is_tombstone); - shadowed_storage = nm_settings_storage_get_shadowed_storage (storage, &shadowed_owned); - _LOGT ("storage[%s,"NM_SETTINGS_STORAGE_PRINT_FMT"]: change event for %shiding profile%s%s%s%s%s%s", - sett_conn_entry->uuid, - NM_SETTINGS_STORAGE_PRINT_ARG (storage), - nm_settings_storage_is_meta_data_alive (storage) ? "" : "dropping ", - NM_PRINT_FMT_QUOTED (filename, " (file \"", filename, "\")", ""), - NM_PRINT_FMT_QUOTED (shadowed_storage, shadowed_owned ? " (owns \"" : " (shadows \"", shadowed_storage, "\")", "")); - } else { - _LOGT ("storage[%s,"NM_SETTINGS_STORAGE_PRINT_FMT"]: change event for dropping profile%s%s%s", - sett_conn_entry->uuid, - NM_SETTINGS_STORAGE_PRINT_ARG (storage), - NM_PRINT_FMT_QUOTED (filename, " (file \"", filename, "\")", "")); - } - } - - /* see _sett_conn_entry_sds_update() for why we append the new events - * and leave existing ones at their position. */ - sd = _storage_data_find_in_lst (&sett_conn_entry->dirty_sd_lst_head, storage); - if (sd) - nm_g_object_ref_set (&sd->connection, connection); - else { - sd = _storage_data_new_stale (storage, connection); - c_list_link_tail (&sett_conn_entry->dirty_sd_lst_head, &sd->sd_lst); - } - - if (prioritize) { - StorageData *sd2; - - /* only one entry can be prioritized. */ - c_list_for_each_entry (sd2, &sett_conn_entry->dirty_sd_lst_head, sd_lst) - sd2->prioritize = FALSE; - sd->prioritize = TRUE; - } - - nm_c_list_move_tail (&priv->sce_dirty_lst_head, &sett_conn_entry->sce_dirty_lst); - - return sett_conn_entry; + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + SettConnEntry * sett_conn_entry; + StorageData * sd; + const char * uuid; + + nm_assert_valid_settings_storage(NULL, storage); + + uuid = nm_settings_storage_get_uuid(storage); + + nm_assert(!connection || NM_IS_CONNECTION(connection)); + nm_assert(!connection + || (_nm_connection_verify(connection, NULL) == NM_SETTING_VERIFY_SUCCESS)); + nm_assert(!connection || nm_streq0(uuid, nm_connection_get_uuid(connection))); + + nmtst_connection_assert_unchanging(connection); + + sett_conn_entry = + _sett_conn_entries_get(self, uuid) ?: _sett_conn_entries_create_and_add(self, uuid); + + if (_LOGT_ENABLED()) { + const char * filename; + const NMSettingsMetaData *meta_data; + const char * shadowed_storage; + gboolean shadowed_owned; + + filename = nm_settings_storage_get_filename(storage); + if (connection) { + shadowed_storage = nm_settings_storage_get_shadowed_storage(storage, &shadowed_owned); + _LOGT("storage[%s," NM_SETTINGS_STORAGE_PRINT_FMT + "]: change event with connection \"%s\"%s%s%s%s%s%s", + sett_conn_entry->uuid, + NM_SETTINGS_STORAGE_PRINT_ARG(storage), + nm_connection_get_id(connection), + NM_PRINT_FMT_QUOTED(filename, " (file \"", filename, "\")", ""), + NM_PRINT_FMT_QUOTED(shadowed_storage, + shadowed_owned ? " (owns \"" : " (shadows \"", + shadowed_storage, + "\")", + "")); + } else if ((meta_data = nm_settings_storage_is_meta_data(storage))) { + nm_assert(meta_data->is_tombstone); + shadowed_storage = nm_settings_storage_get_shadowed_storage(storage, &shadowed_owned); + _LOGT("storage[%s," NM_SETTINGS_STORAGE_PRINT_FMT + "]: change event for %shiding profile%s%s%s%s%s%s", + sett_conn_entry->uuid, + NM_SETTINGS_STORAGE_PRINT_ARG(storage), + nm_settings_storage_is_meta_data_alive(storage) ? "" : "dropping ", + NM_PRINT_FMT_QUOTED(filename, " (file \"", filename, "\")", ""), + NM_PRINT_FMT_QUOTED(shadowed_storage, + shadowed_owned ? " (owns \"" : " (shadows \"", + shadowed_storage, + "\")", + "")); + } else { + _LOGT("storage[%s," NM_SETTINGS_STORAGE_PRINT_FMT + "]: change event for dropping profile%s%s%s", + sett_conn_entry->uuid, + NM_SETTINGS_STORAGE_PRINT_ARG(storage), + NM_PRINT_FMT_QUOTED(filename, " (file \"", filename, "\")", "")); + } + } + + /* see _sett_conn_entry_sds_update() for why we append the new events + * and leave existing ones at their position. */ + sd = _storage_data_find_in_lst(&sett_conn_entry->dirty_sd_lst_head, storage); + if (sd) + nm_g_object_ref_set(&sd->connection, connection); + else { + sd = _storage_data_new_stale(storage, connection); + c_list_link_tail(&sett_conn_entry->dirty_sd_lst_head, &sd->sd_lst); + } + + if (prioritize) { + StorageData *sd2; + + /* only one entry can be prioritized. */ + c_list_for_each_entry (sd2, &sett_conn_entry->dirty_sd_lst_head, sd_lst) + sd2->prioritize = FALSE; + sd->prioritize = TRUE; + } + + nm_c_list_move_tail(&priv->sce_dirty_lst_head, &sett_conn_entry->sce_dirty_lst); + + return sett_conn_entry; } /*****************************************************************************/ static void -_plugin_connections_reload_cb (NMSettingsPlugin *plugin, - NMSettingsStorage *storage, - NMConnection *connection, - gpointer user_data) +_plugin_connections_reload_cb(NMSettingsPlugin * plugin, + NMSettingsStorage *storage, + NMConnection * connection, + gpointer user_data) { - _connection_changed_track (user_data, storage, connection, FALSE); + _connection_changed_track(user_data, storage, connection, FALSE); } static void -_plugin_connections_reload (NMSettings *self) +_plugin_connections_reload(NMSettings *self) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GSList *iter; - - for (iter = priv->plugins; iter; iter = iter->next) { - nm_settings_plugin_reload_connections (iter->data, - _plugin_connections_reload_cb, - self); - } - - _connection_changed_process_all_dirty (self, - FALSE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - TRUE, - NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS); - - for (iter = priv->plugins; iter; iter = iter->next) - nm_settings_plugin_load_connections_done (iter->data); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + GSList * iter; + + for (iter = priv->plugins; iter; iter = iter->next) { + nm_settings_plugin_reload_connections(iter->data, _plugin_connections_reload_cb, self); + } + + _connection_changed_process_all_dirty( + self, + FALSE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + TRUE, + NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS); + + for (iter = priv->plugins; iter; iter = iter->next) + nm_settings_plugin_load_connections_done(iter->data); } /*****************************************************************************/ static gboolean -_add_connection_to_first_plugin (NMSettings *self, - SettConnEntry *sett_conn_entry, - NMConnection *new_connection, - gboolean in_memory, - NMSettingsConnectionIntFlags sett_flags, - const char *shadowed_storage, - gboolean shadowed_owned, - NMSettingsStorage **out_new_storage, - NMConnection **out_new_connection, - GError **error) +_add_connection_to_first_plugin(NMSettings * self, + SettConnEntry * sett_conn_entry, + NMConnection * new_connection, + gboolean in_memory, + NMSettingsConnectionIntFlags sett_flags, + const char * shadowed_storage, + gboolean shadowed_owned, + NMSettingsStorage ** out_new_storage, + NMConnection ** out_new_connection, + GError ** error) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - gs_free_error GError *first_error = NULL; - GSList *iter; - const char *uuid; - - uuid = nm_connection_get_uuid (new_connection); - - nm_assert (nm_utils_is_uuid (uuid)); - - for (iter = priv->plugins; iter; iter = iter->next) { - NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); - gs_unref_object NMSettingsStorage *storage = NULL; - gs_unref_object NMConnection *connection_to_add = NULL; - gs_unref_object NMConnection *connection_to_add_cloned = NULL; - NMConnection *connection_to_add_real = NULL; - gs_unref_variant GVariant *agent_owned_secrets = NULL; - gs_free_error GError *add_error = NULL; - gboolean success; - const char *filename; - - if (!in_memory) { - NMSettingsStorage *conflicting_storage; - - conflicting_storage = _sett_conn_entry_storage_find_conflicting_storage (sett_conn_entry, plugin, NULL, priv->plugins); - if (conflicting_storage) { - /* we have a connection provided by a plugin with higher priority than the one - * we would want to add the connection. We cannot do that, because doing so - * would result in adding a connection that gets hidden by the existing profile. - * Also, since we test the plugins in order of priority, all following plugins - * are unsuitable. - * - * Multiple connection plugins are so cumbersome, especially if they are unable - * to add the connection. I suggest to disable all plugins except keyfile. */ - _LOGT ("add-connection: failed to add %s/'%s': there is an existing storage "NM_SETTINGS_STORAGE_PRINT_FMT" with higher priority", - nm_connection_get_uuid (new_connection), - nm_connection_get_id (new_connection), - NM_SETTINGS_STORAGE_PRINT_ARG (conflicting_storage)); - nm_assert (first_error); - break; - } - } - - if (plugin == (NMSettingsPlugin *) priv->keyfile_plugin) { - success = nms_keyfile_plugin_add_connection (priv->keyfile_plugin, - new_connection, - in_memory, - NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED), - NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE), - NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL), - shadowed_storage, - shadowed_owned, - &storage, - &connection_to_add, - &add_error); - } else { - if (in_memory) - continue; - nm_assert (!NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)); - nm_assert (!NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)); - nm_assert (!NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)); - success = nm_settings_plugin_add_connection (plugin, - new_connection, - &storage, - &connection_to_add, - &add_error); - } - - if (!success) { - _LOGT ("add-connection: failed to add %s/'%s': %s", - nm_connection_get_uuid (new_connection), - nm_connection_get_id (new_connection), - add_error->message); - if (!first_error) - first_error = g_steal_pointer (&add_error); - continue; - } - - if (!nm_streq0 (nm_settings_storage_get_uuid (storage), uuid)) { - nm_assert_not_reached (); - continue; - } - - agent_owned_secrets = nm_connection_to_dbus (new_connection, - NM_CONNECTION_SERIALIZE_ONLY_SECRETS - | NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED); - connection_to_add_real = _connection_changed_normalize_connection (storage, - connection_to_add, - agent_owned_secrets, - &connection_to_add_cloned); - if (!connection_to_add_real) { - nm_assert_not_reached (); - continue; - } - - filename = nm_settings_storage_get_filename (storage); - _LOGT ("add-connection: successfully added connection %s,'%s' ("NM_SETTINGS_STORAGE_PRINT_FMT"%s%s%s", - nm_settings_storage_get_uuid (storage), - nm_connection_get_id (new_connection), - NM_SETTINGS_STORAGE_PRINT_ARG (storage), - NM_PRINT_FMT_QUOTED (filename, ", \"", filename, "\")", ")")); - - *out_new_storage = g_steal_pointer (&storage); - *out_new_connection = g_steal_pointer (&connection_to_add_cloned) - ?: g_steal_pointer (&connection_to_add); - nm_assert (NM_IS_CONNECTION (*out_new_connection)); - return TRUE; - } - - nm_assert (first_error); - g_propagate_error (error, g_steal_pointer (&first_error)); - return FALSE; + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + gs_free_error GError *first_error = NULL; + GSList * iter; + const char * uuid; + + uuid = nm_connection_get_uuid(new_connection); + + nm_assert(nm_utils_is_uuid(uuid)); + + for (iter = priv->plugins; iter; iter = iter->next) { + NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN(iter->data); + gs_unref_object NMSettingsStorage *storage = NULL; + gs_unref_object NMConnection *connection_to_add = NULL; + gs_unref_object NMConnection *connection_to_add_cloned = NULL; + NMConnection * connection_to_add_real = NULL; + gs_unref_variant GVariant *agent_owned_secrets = NULL; + gs_free_error GError *add_error = NULL; + gboolean success; + const char * filename; + + if (!in_memory) { + NMSettingsStorage *conflicting_storage; + + conflicting_storage = _sett_conn_entry_storage_find_conflicting_storage(sett_conn_entry, + plugin, + NULL, + priv->plugins); + if (conflicting_storage) { + /* we have a connection provided by a plugin with higher priority than the one + * we would want to add the connection. We cannot do that, because doing so + * would result in adding a connection that gets hidden by the existing profile. + * Also, since we test the plugins in order of priority, all following plugins + * are unsuitable. + * + * Multiple connection plugins are so cumbersome, especially if they are unable + * to add the connection. I suggest to disable all plugins except keyfile. */ + _LOGT("add-connection: failed to add %s/'%s': there is an existing " + "storage " NM_SETTINGS_STORAGE_PRINT_FMT " with higher priority", + nm_connection_get_uuid(new_connection), + nm_connection_get_id(new_connection), + NM_SETTINGS_STORAGE_PRINT_ARG(conflicting_storage)); + nm_assert(first_error); + break; + } + } + + if (plugin == (NMSettingsPlugin *) priv->keyfile_plugin) { + success = nms_keyfile_plugin_add_connection( + priv->keyfile_plugin, + new_connection, + in_memory, + NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED), + NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE), + NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL), + shadowed_storage, + shadowed_owned, + &storage, + &connection_to_add, + &add_error); + } else { + if (in_memory) + continue; + nm_assert(!NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)); + nm_assert(!NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)); + nm_assert(!NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)); + success = nm_settings_plugin_add_connection(plugin, + new_connection, + &storage, + &connection_to_add, + &add_error); + } + + if (!success) { + _LOGT("add-connection: failed to add %s/'%s': %s", + nm_connection_get_uuid(new_connection), + nm_connection_get_id(new_connection), + add_error->message); + if (!first_error) + first_error = g_steal_pointer(&add_error); + continue; + } + + if (!nm_streq0(nm_settings_storage_get_uuid(storage), uuid)) { + nm_assert_not_reached(); + continue; + } + + agent_owned_secrets = + nm_connection_to_dbus(new_connection, + NM_CONNECTION_SERIALIZE_ONLY_SECRETS + | NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED); + connection_to_add_real = + _connection_changed_normalize_connection(storage, + connection_to_add, + agent_owned_secrets, + &connection_to_add_cloned); + if (!connection_to_add_real) { + nm_assert_not_reached(); + continue; + } + + filename = nm_settings_storage_get_filename(storage); + _LOGT( + "add-connection: successfully added connection %s,'%s' (" NM_SETTINGS_STORAGE_PRINT_FMT + "%s%s%s", + nm_settings_storage_get_uuid(storage), + nm_connection_get_id(new_connection), + NM_SETTINGS_STORAGE_PRINT_ARG(storage), + NM_PRINT_FMT_QUOTED(filename, ", \"", filename, "\")", ")")); + + *out_new_storage = g_steal_pointer(&storage); + *out_new_connection = + g_steal_pointer(&connection_to_add_cloned) ?: g_steal_pointer(&connection_to_add); + nm_assert(NM_IS_CONNECTION(*out_new_connection)); + return TRUE; + } + + nm_assert(first_error); + g_propagate_error(error, g_steal_pointer(&first_error)); + return FALSE; } static gboolean -_update_connection_to_plugin (NMSettings *self, - NMSettingsStorage *storage, - NMConnection *connection, - NMSettingsConnectionIntFlags sett_flags, - gboolean force_rename, - const char *shadowed_storage, - gboolean shadowed_owned, - NMSettingsStorage **out_new_storage, - NMConnection **out_new_connection, - GError **error) +_update_connection_to_plugin(NMSettings * self, + NMSettingsStorage * storage, + NMConnection * connection, + NMSettingsConnectionIntFlags sett_flags, + gboolean force_rename, + const char * shadowed_storage, + gboolean shadowed_owned, + NMSettingsStorage ** out_new_storage, + NMConnection ** out_new_connection, + GError ** error) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - NMSettingsPlugin *plugin; - gboolean success; - - plugin = nm_settings_storage_get_plugin (storage); - - if (plugin == (NMSettingsPlugin *) priv->keyfile_plugin) { - success = nms_keyfile_plugin_update_connection (priv->keyfile_plugin, - storage, - connection, - NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED), - NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE), - NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL), - shadowed_storage, - shadowed_owned, - force_rename, - out_new_storage, - out_new_connection, - error); - } else { - nm_assert (!shadowed_storage); - nm_assert (!shadowed_owned); - success = nm_settings_plugin_update_connection (plugin, - storage, - connection, - out_new_storage, - out_new_connection, - error); - } - - return success; + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + NMSettingsPlugin * plugin; + gboolean success; + + plugin = nm_settings_storage_get_plugin(storage); + + if (plugin == (NMSettingsPlugin *) priv->keyfile_plugin) { + success = nms_keyfile_plugin_update_connection( + priv->keyfile_plugin, + storage, + connection, + NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED), + NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE), + NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL), + shadowed_storage, + shadowed_owned, + force_rename, + out_new_storage, + out_new_connection, + error); + } else { + nm_assert(!shadowed_storage); + nm_assert(!shadowed_owned); + success = nm_settings_plugin_update_connection(plugin, + storage, + connection, + out_new_storage, + out_new_connection, + error); + } + + return success; } static void -_set_nmmeta_tombstone (NMSettings *self, - const char *uuid, - gboolean tombstone_on_disk, - gboolean tombstone_in_memory, - const char *shadowed_storage) +_set_nmmeta_tombstone(NMSettings *self, + const char *uuid, + gboolean tombstone_on_disk, + gboolean tombstone_in_memory, + const char *shadowed_storage) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - gs_unref_object NMSettingsStorage *tombstone_1_storage = NULL; - gs_unref_object NMSettingsStorage *tombstone_2_storage = NULL; - - if (tombstone_on_disk) { - if (!nms_keyfile_plugin_set_nmmeta_tombstone (priv->keyfile_plugin, - FALSE, - uuid, - FALSE, - TRUE, - NULL, - &tombstone_1_storage, - NULL)) - tombstone_in_memory = TRUE; - if (tombstone_1_storage) - _connection_changed_track (self, tombstone_1_storage, NULL, FALSE); - } - - if (tombstone_in_memory) { - if (!nms_keyfile_plugin_set_nmmeta_tombstone (priv->keyfile_plugin, - FALSE, - uuid, - TRUE, - TRUE, - shadowed_storage, - &tombstone_2_storage, - NULL)) { - nms_keyfile_plugin_set_nmmeta_tombstone (priv->keyfile_plugin, - TRUE, - uuid, - TRUE, - TRUE, - shadowed_storage, - &tombstone_2_storage, - NULL); - } - _connection_changed_track (self, tombstone_2_storage, NULL, FALSE); - } + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + gs_unref_object NMSettingsStorage *tombstone_1_storage = NULL; + gs_unref_object NMSettingsStorage *tombstone_2_storage = NULL; + + if (tombstone_on_disk) { + if (!nms_keyfile_plugin_set_nmmeta_tombstone(priv->keyfile_plugin, + FALSE, + uuid, + FALSE, + TRUE, + NULL, + &tombstone_1_storage, + NULL)) + tombstone_in_memory = TRUE; + if (tombstone_1_storage) + _connection_changed_track(self, tombstone_1_storage, NULL, FALSE); + } + + if (tombstone_in_memory) { + if (!nms_keyfile_plugin_set_nmmeta_tombstone(priv->keyfile_plugin, + FALSE, + uuid, + TRUE, + TRUE, + shadowed_storage, + &tombstone_2_storage, + NULL)) { + nms_keyfile_plugin_set_nmmeta_tombstone(priv->keyfile_plugin, + TRUE, + uuid, + TRUE, + TRUE, + shadowed_storage, + &tombstone_2_storage, + NULL); + } + _connection_changed_track(self, tombstone_2_storage, NULL, FALSE); + } } /** @@ -1690,1294 +1685,1310 @@ _set_nmmeta_tombstone (NMSettings *self, * Returns: TRUE on success. */ gboolean -nm_settings_add_connection (NMSettings *self, - NMConnection *connection, - NMSettingsConnectionPersistMode persist_mode, - NMSettingsConnectionAddReason add_reason, - NMSettingsConnectionIntFlags sett_flags, - NMSettingsConnection **out_sett_conn, - GError **error) +nm_settings_add_connection(NMSettings * self, + NMConnection * connection, + NMSettingsConnectionPersistMode persist_mode, + NMSettingsConnectionAddReason add_reason, + NMSettingsConnectionIntFlags sett_flags, + NMSettingsConnection ** out_sett_conn, + GError ** error) { - NMSettingsPrivate *priv; - gs_unref_object NMConnection *connection_cloned_1 = NULL; - gs_unref_object NMConnection *new_connection = NULL; - gs_unref_object NMSettingsStorage *new_storage = NULL; - gs_unref_object NMSettingsStorage *shadowed_storage = NULL; - NMSettingsStorage *update_storage = NULL; - gs_free_error GError *local = NULL; - SettConnEntry *sett_conn_entry; - const char *uuid; - StorageData *sd; - gboolean new_in_memory; - gboolean success; - const char *shadowed_storage_filename = NULL; - - priv = NM_SETTINGS_GET_PRIVATE (self); - - nm_assert (NM_IN_SET (persist_mode, NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK, - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY)); - - new_in_memory = (persist_mode != NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK); - - nm_assert (!NM_FLAGS_ANY (sett_flags, ~_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK)); - - if (NM_FLAGS_ANY (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) { - nm_assert (new_in_memory); - new_in_memory = TRUE; - } - - nm_assert (!NM_FLAGS_ANY (add_reason, ~NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT)); - - NM_SET_OUT (out_sett_conn, NULL); - - uuid = nm_connection_get_uuid (connection); - - sett_conn_entry = _sett_conn_entries_get (self, uuid); - if (_sett_conn_entry_get_conn (sett_conn_entry)) { - g_set_error_literal (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_UUID_EXISTS, - "a connection with this UUID already exists"); - return FALSE; - } - - if (!_nm_connection_ensure_normalized (connection, - FALSE, - NULL, - FALSE, - &connection_cloned_1, - &local)) { - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "connection is invalid: %s", - local->message); - return FALSE; - } - if (connection_cloned_1) - connection = connection_cloned_1; - - if (sett_conn_entry) { - c_list_for_each_entry (sd, &sett_conn_entry->sd_lst_head, sd_lst) { - if (!nm_settings_storage_is_meta_data (sd->storage)) - continue; - shadowed_storage = nm_g_object_ref (_sett_conn_entry_find_shadowed_storage (sett_conn_entry, - nm_settings_storage_get_shadowed_storage (sd->storage, NULL), - NULL)); - if (shadowed_storage) { - /* We have a nmmeta tombstone that indicates that a storage is shadowed. - * - * This happens when deleting a in-memory profile that was decoupled from - * the persitant storage with NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED. - * We need to take over this storage again... */ - break; - } - } - } - - if ( shadowed_storage - && !new_in_memory) { - NMSettingsStorage *conflicting_storage; - - conflicting_storage = _sett_conn_entry_storage_find_conflicting_storage (sett_conn_entry, - nm_settings_storage_get_plugin (shadowed_storage), - shadowed_storage, - priv->plugins); - if (conflicting_storage) { - /* We cannot add the profile as @shadowed_storage, because there is another, existing storage - * that would hide it. Just add it as new storage. In general, this leads to duplication of profiles, - * but the circumstances where this happens are very exotic (you need at least one additional settings - * plugin, then going through the paths of making shadowed_storage in-memory-detached and delete it, - * and finally adding the conflicting storage outside of NM and restart/reload). */ - _LOGT ("ignore shadowed storage "NM_SETTINGS_STORAGE_PRINT_FMT" due to conflicting storage "NM_SETTINGS_STORAGE_PRINT_FMT, - NM_SETTINGS_STORAGE_PRINT_ARG (shadowed_storage), - NM_SETTINGS_STORAGE_PRINT_ARG (conflicting_storage)); - } else - update_storage = shadowed_storage; - } - - shadowed_storage_filename = ( shadowed_storage - && !update_storage) - ? nm_settings_storage_get_filename_for_shadowed_storage (shadowed_storage) - : NULL; + NMSettingsPrivate *priv; + gs_unref_object NMConnection *connection_cloned_1 = NULL; + gs_unref_object NMConnection *new_connection = NULL; + gs_unref_object NMSettingsStorage *new_storage = NULL; + gs_unref_object NMSettingsStorage *shadowed_storage = NULL; + NMSettingsStorage * update_storage = NULL; + gs_free_error GError *local = NULL; + SettConnEntry * sett_conn_entry; + const char * uuid; + StorageData * sd; + gboolean new_in_memory; + gboolean success; + const char * shadowed_storage_filename = NULL; + + priv = NM_SETTINGS_GET_PRIVATE(self); + + nm_assert(NM_IN_SET(persist_mode, + NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY)); + + new_in_memory = (persist_mode != NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK); + + nm_assert(!NM_FLAGS_ANY(sett_flags, ~_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK)); + + if (NM_FLAGS_ANY(sett_flags, + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) { + nm_assert(new_in_memory); + new_in_memory = TRUE; + } + + nm_assert(!NM_FLAGS_ANY(add_reason, ~NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT)); + + NM_SET_OUT(out_sett_conn, NULL); + + uuid = nm_connection_get_uuid(connection); + + sett_conn_entry = _sett_conn_entries_get(self, uuid); + if (_sett_conn_entry_get_conn(sett_conn_entry)) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_UUID_EXISTS, + "a connection with this UUID already exists"); + return FALSE; + } + + if (!_nm_connection_ensure_normalized(connection, + FALSE, + NULL, + FALSE, + &connection_cloned_1, + &local)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "connection is invalid: %s", + local->message); + return FALSE; + } + if (connection_cloned_1) + connection = connection_cloned_1; + + if (sett_conn_entry) { + c_list_for_each_entry (sd, &sett_conn_entry->sd_lst_head, sd_lst) { + if (!nm_settings_storage_is_meta_data(sd->storage)) + continue; + shadowed_storage = nm_g_object_ref(_sett_conn_entry_find_shadowed_storage( + sett_conn_entry, + nm_settings_storage_get_shadowed_storage(sd->storage, NULL), + NULL)); + if (shadowed_storage) { + /* We have a nmmeta tombstone that indicates that a storage is shadowed. + * + * This happens when deleting a in-memory profile that was decoupled from + * the persistent storage with NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED. + * We need to take over this storage again... */ + break; + } + } + } + + if (shadowed_storage && !new_in_memory) { + NMSettingsStorage *conflicting_storage; + + conflicting_storage = _sett_conn_entry_storage_find_conflicting_storage( + sett_conn_entry, + nm_settings_storage_get_plugin(shadowed_storage), + shadowed_storage, + priv->plugins); + if (conflicting_storage) { + /* We cannot add the profile as @shadowed_storage, because there is another, existing storage + * that would hide it. Just add it as new storage. In general, this leads to duplication of profiles, + * but the circumstances where this happens are very exotic (you need at least one additional settings + * plugin, then going through the paths of making shadowed_storage in-memory-detached and delete it, + * and finally adding the conflicting storage outside of NM and restart/reload). */ + _LOGT("ignore shadowed storage " NM_SETTINGS_STORAGE_PRINT_FMT + " due to conflicting storage " NM_SETTINGS_STORAGE_PRINT_FMT, + NM_SETTINGS_STORAGE_PRINT_ARG(shadowed_storage), + NM_SETTINGS_STORAGE_PRINT_ARG(conflicting_storage)); + } else + update_storage = shadowed_storage; + } + + shadowed_storage_filename = + (shadowed_storage && !update_storage) + ? nm_settings_storage_get_filename_for_shadowed_storage(shadowed_storage) + : NULL; again_add_connection: - if (!update_storage) { - success = _add_connection_to_first_plugin (self, - sett_conn_entry, - connection, - new_in_memory, - sett_flags, - shadowed_storage_filename, - FALSE, - &new_storage, - &new_connection, - &local); - } else { - success = _update_connection_to_plugin (self, - update_storage, - connection, - sett_flags, - FALSE, - shadowed_storage_filename, - FALSE, - &new_storage, - &new_connection, - &local); - if (!success) { - if (!NMS_IS_KEYFILE_STORAGE (update_storage)) { - /* hm, the intended storage is not keyfile (it's ifcfg-rh). This settings - * plugin may not support the new connection. So step back and retry adding - * the profile anew. */ - _LOGT ("failure to add profile as existing storage \"%s\": %s", - nm_settings_storage_get_filename (update_storage), - local->message); - update_storage = NULL; - g_clear_object (&shadowed_storage); - shadowed_storage_filename = NULL; - g_clear_error (&local); - goto again_add_connection; - } - } - } - - if (!success) { - if (!update_storage) { - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_FAILED, - "failure adding connection: %s", - local->message); - } else { - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_FAILED, - "failure writing connection to existing storage \"%s\": %s", - nm_settings_storage_get_filename (update_storage), - local->message); - } - return FALSE; - } - - sett_conn_entry = _connection_changed_track (self, new_storage, new_connection, TRUE); - - c_list_for_each_entry (sd, &sett_conn_entry->sd_lst_head, sd_lst) { - const NMSettingsMetaData *meta_data; - gs_unref_object NMSettingsStorage *new_tombstone_storage = NULL; - gboolean in_memory; - gboolean simulate; - - meta_data = nm_settings_storage_is_meta_data_alive (sd->storage); - if ( !meta_data - || !meta_data->is_tombstone) - continue; - - if (nm_settings_storage_is_keyfile_run (sd->storage)) - in_memory = TRUE; - else { - if (nm_settings_storage_is_keyfile_run (new_storage)) { - /* Don't remove the file from /etc if we just wrote an in-memory connection */ - continue; - } - in_memory = FALSE; - } - - simulate = FALSE; + if (!update_storage) { + success = _add_connection_to_first_plugin(self, + sett_conn_entry, + connection, + new_in_memory, + sett_flags, + shadowed_storage_filename, + FALSE, + &new_storage, + &new_connection, + &local); + } else { + success = _update_connection_to_plugin(self, + update_storage, + connection, + sett_flags, + FALSE, + shadowed_storage_filename, + FALSE, + &new_storage, + &new_connection, + &local); + if (!success) { + if (!NMS_IS_KEYFILE_STORAGE(update_storage)) { + /* hm, the intended storage is not keyfile (it's ifcfg-rh). This settings + * plugin may not support the new connection. So step back and retry adding + * the profile anew. */ + _LOGT("failure to add profile as existing storage \"%s\": %s", + nm_settings_storage_get_filename(update_storage), + local->message); + update_storage = NULL; + g_clear_object(&shadowed_storage); + shadowed_storage_filename = NULL; + g_clear_error(&local); + goto again_add_connection; + } + } + } + + if (!success) { + if (!update_storage) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "failure adding connection: %s", + local->message); + } else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "failure writing connection to existing storage \"%s\": %s", + nm_settings_storage_get_filename(update_storage), + local->message); + } + return FALSE; + } + + sett_conn_entry = _connection_changed_track(self, new_storage, new_connection, TRUE); + + c_list_for_each_entry (sd, &sett_conn_entry->sd_lst_head, sd_lst) { + const NMSettingsMetaData *meta_data; + gs_unref_object NMSettingsStorage *new_tombstone_storage = NULL; + gboolean in_memory; + gboolean simulate; + + meta_data = nm_settings_storage_is_meta_data_alive(sd->storage); + if (!meta_data || !meta_data->is_tombstone) + continue; + + if (nm_settings_storage_is_keyfile_run(sd->storage)) + in_memory = TRUE; + else { + if (nm_settings_storage_is_keyfile_run(new_storage)) { + /* Don't remove the file from /etc if we just wrote an in-memory connection */ + continue; + } + in_memory = FALSE; + } + + simulate = FALSE; again_delete_tombstone: - if (!nms_keyfile_plugin_set_nmmeta_tombstone (priv->keyfile_plugin, - simulate, - uuid, - in_memory, - FALSE, - NULL, - &new_tombstone_storage, - NULL)) { - /* Ups, something went wrong. We really need to get rid of the tombstone. At least - * forget about it in-memory. Upong next restart/reload, this might be reverted - * however :( .*/ - if (!simulate) { - simulate = TRUE; - goto again_delete_tombstone; - } - } - if (new_tombstone_storage) - _connection_changed_track (self, new_tombstone_storage, NULL, FALSE); - } - - _connection_changed_process_all_dirty (self, - FALSE, - sett_flags, - _NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK, - FALSE, - NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS - | ( NM_FLAGS_HAS (add_reason, NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT) - ? NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT - : NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE)); - - nm_assert (sett_conn_entry == _sett_conn_entries_get (self, sett_conn_entry->uuid)); - nm_assert (NM_IS_SETTINGS_CONNECTION (sett_conn_entry->sett_conn)); - - NM_SET_OUT (out_sett_conn, _sett_conn_entry_get_conn (sett_conn_entry)); - return TRUE; + if (!nms_keyfile_plugin_set_nmmeta_tombstone(priv->keyfile_plugin, + simulate, + uuid, + in_memory, + FALSE, + NULL, + &new_tombstone_storage, + NULL)) { + /* Ups, something went wrong. We really need to get rid of the tombstone. At least + * forget about it in-memory. Upong next restart/reload, this might be reverted + * however :( .*/ + if (!simulate) { + simulate = TRUE; + goto again_delete_tombstone; + } + } + if (new_tombstone_storage) + _connection_changed_track(self, new_tombstone_storage, NULL, FALSE); + } + + _connection_changed_process_all_dirty( + self, + FALSE, + sett_flags, + _NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK, + FALSE, + NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS + | (NM_FLAGS_HAS(add_reason, NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT) + ? NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT + : NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE)); + + nm_assert(sett_conn_entry == _sett_conn_entries_get(self, sett_conn_entry->uuid)); + nm_assert(NM_IS_SETTINGS_CONNECTION(sett_conn_entry->sett_conn)); + + NM_SET_OUT(out_sett_conn, _sett_conn_entry_get_conn(sett_conn_entry)); + return TRUE; } /*****************************************************************************/ gboolean -nm_settings_update_connection (NMSettings *self, - NMSettingsConnection *sett_conn, - NMConnection *connection, - NMSettingsConnectionPersistMode persist_mode, - NMSettingsConnectionIntFlags sett_flags, - NMSettingsConnectionIntFlags sett_mask, - NMSettingsConnectionUpdateReason update_reason, - const char *log_context_name, - GError **error) +nm_settings_update_connection(NMSettings * self, + NMSettingsConnection * sett_conn, + NMConnection * connection, + NMSettingsConnectionPersistMode persist_mode, + NMSettingsConnectionIntFlags sett_flags, + NMSettingsConnectionIntFlags sett_mask, + NMSettingsConnectionUpdateReason update_reason, + const char * log_context_name, + GError ** error) { - gs_unref_object NMConnection *connection_cloned_1 = NULL; - gs_unref_object NMConnection *new_connection_cloned = NULL; - gs_unref_object NMConnection *new_connection = NULL; - NMConnection *new_connection_real; - gs_unref_object NMSettingsStorage *cur_storage = NULL; - gs_unref_object NMSettingsStorage *new_storage = NULL; - NMSettingsStorage *drop_storage = NULL; - SettConnEntry *sett_conn_entry; - gboolean cur_in_memory; - gboolean new_in_memory; - const char *uuid; - gboolean tombstone_in_memory = FALSE; - gboolean tombstone_on_disk = FALSE; - - g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn), FALSE); - g_return_val_if_fail (!connection || NM_IS_CONNECTION (connection), FALSE); - - nm_assert (!NM_FLAGS_ANY (sett_mask, ~_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK)); - nm_assert (!NM_FLAGS_ANY (sett_flags, ~sett_mask)); - nm_assert (NM_IN_SET (persist_mode, NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP, - NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST, - NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK, - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED, - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY)); - - cur_storage = g_object_ref (nm_settings_connection_get_storage (sett_conn)); - - uuid = nm_settings_storage_get_uuid (cur_storage); - - nm_assert (NM_IS_SETTINGS_STORAGE (cur_storage)); - - sett_conn_entry = _sett_conn_entries_get (self, uuid); - - nm_assert (_sett_conn_entry_get_conn (sett_conn_entry) == sett_conn); - - if (connection) { - gs_free_error GError *local = NULL; - - if (!_nm_connection_ensure_normalized (connection, - FALSE, - uuid, - TRUE, - &connection_cloned_1, - &local)) { - _LOGT ("update[%s]: %s: failed because profile is invalid: %s", - nm_settings_storage_get_uuid (cur_storage), - log_context_name, - local->message); - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "connection is invalid: %s", - local->message); - return FALSE; - } - if (connection_cloned_1) - connection = connection_cloned_1; - } else - connection = nm_settings_connection_get_connection (sett_conn); - - cur_in_memory = nm_settings_storage_is_keyfile_run (cur_storage); - - if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP) { - persist_mode = cur_in_memory - ? NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY - : NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK; - } - - if ( NM_FLAGS_HAS (sett_mask, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED) - && !NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) { - NMDevice *device; - - /* The connection has been changed by the user, it should no longer be - * considered a default wired connection, and should no longer affect - * the no-auto-default configuration option. - */ - device = nm_settings_connection_default_wired_get_device (sett_conn); - if (device) { - - nm_assert (cur_in_memory); - nm_assert (NM_FLAGS_HAS (nm_settings_connection_get_flags (sett_conn), - NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)); - - default_wired_clear_tag (self, device, sett_conn, FALSE); - - if (NM_IN_SET (persist_mode, NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST)) { - /* making a default-wired-connection a regular connection implies persisting - * it to disk (unless specified differently). - * - * Actually, this line is probably unreached, because we should not use - * NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST to toggle the nm-generated - * flag. */ - nm_assert_not_reached (); - persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK; - } - } - } - - if ( persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST - && NM_FLAGS_ANY (sett_mask, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL) - && NM_FLAGS_ANY ((sett_flags ^ nm_settings_connection_get_flags (sett_conn)) & sett_mask, - NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) { - /* we update the nm-generated/volatile setting of a profile (which is inherently - * in-memory. The caller did not request to persist this to disk, however we need - * to store the flags in run. */ - nm_assert (cur_in_memory); - persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY; - } - - if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK) - new_in_memory = FALSE; - else if (NM_IN_SET (persist_mode, NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED, - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY)) - new_in_memory = TRUE; - else { - nm_assert (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST); - new_in_memory = cur_in_memory; - } - - if (!new_in_memory) { - /* Persistent connections cannot be volatile nor nm-generated. - * - * That is obviously true for volatile, as it is enforced by Update2() API. - * - * For nm-generated profiles also, because the nm-generated flag is only stored - * for in-memory profiles. If we would persist the profile to /etc it would loose - * the nm-generated flag after restart/reload, and that cannot be right. If a profile - * ends up on disk, the information who created it gets lost. */ - nm_assert (!NM_FLAGS_ANY (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)); - sett_mask |= NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL; - sett_flags &= ~( NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL); - } - - if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST) { - new_storage = g_object_ref (cur_storage); - new_connection_real = connection; - _LOGT ("update[%s]: %s: update profile \"%s\" (not persisted)", - nm_settings_storage_get_uuid (cur_storage), - log_context_name, - nm_connection_get_id (connection)); - } else { - NMSettingsStorage *shadowed_storage; - const char *cur_shadowed_storage_filename; - const char *new_shadowed_storage_filename = NULL; - gboolean cur_shadowed_owned; - gboolean new_shadowed_owned = FALSE; - NMSettingsStorage *update_storage = NULL; - gs_free_error GError *local = NULL; - gboolean success; - - cur_shadowed_storage_filename = nm_settings_storage_get_shadowed_storage (cur_storage, &cur_shadowed_owned); - - shadowed_storage = _sett_conn_entry_find_shadowed_storage (sett_conn_entry, cur_shadowed_storage_filename, cur_storage); - if (!shadowed_storage) { - cur_shadowed_storage_filename = NULL; - cur_shadowed_owned = FALSE; - } - - if ( new_in_memory - && persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY) { - if (cur_in_memory) { - drop_storage = shadowed_storage; - update_storage = cur_storage; - } else - drop_storage = cur_storage; - } else if ( !new_in_memory - && cur_in_memory - && shadowed_storage) { - drop_storage = cur_storage; - update_storage = shadowed_storage; - } else if (new_in_memory != cur_in_memory) { - if (!new_in_memory) - drop_storage = cur_storage; - else if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY) - drop_storage = cur_storage; - else { - nm_assert (NM_IN_SET (persist_mode, NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED)); - } - } else if (nm_settings_storage_is_keyfile_lib (cur_storage)) { - /* the profile is a keyfile in /usr/lib. It cannot be overwritten, we must migrate it - * from /usr/lib to /etc. */ - } else - update_storage = cur_storage; - - if (new_in_memory) { - if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY) { - /* pass */ - } else if (!cur_in_memory) { - new_shadowed_storage_filename = nm_settings_storage_get_filename_for_shadowed_storage (cur_storage); - if ( new_shadowed_storage_filename - && persist_mode != NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED) - new_shadowed_owned = TRUE; - } else { - new_shadowed_storage_filename = cur_shadowed_storage_filename; - if ( new_shadowed_storage_filename - && persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY) - new_shadowed_owned = TRUE; - } - } - - if (!update_storage) { - success = _add_connection_to_first_plugin (self, - sett_conn_entry, - connection, - new_in_memory, - sett_flags, - new_shadowed_storage_filename, - new_shadowed_owned, - &new_storage, - &new_connection, - &local); - } else { - success = _update_connection_to_plugin (self, - update_storage, - connection, - sett_flags, - update_reason, - new_shadowed_storage_filename, - new_shadowed_owned, - &new_storage, - &new_connection, - &local); - } - if (!success) { - gboolean ignore_failure; - - ignore_failure = NM_FLAGS_ANY (update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE); - - _LOGT ("update[%s]: %s: %sfailure to %s connection \"%s\" on storage: %s", - nm_settings_storage_get_uuid (cur_storage), - log_context_name, - ignore_failure ? "ignore " : "", - update_storage ? "update" : "write", - nm_connection_get_id (connection), - local->message); - if (!ignore_failure) { - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "failed to %s connection: %s", - update_storage ? "update" : "write", - local->message); - return FALSE; - } - - new_storage = g_object_ref (cur_storage); - new_connection_real = connection; - } else { - gs_unref_variant GVariant *agent_owned_secrets = NULL; - - _LOGT ("update[%s]: %s: %s profile \"%s\"", - nm_settings_storage_get_uuid (cur_storage), - log_context_name, - update_storage ? "update" : "write", - nm_connection_get_id (connection)); - - nm_assert_valid_settings_storage (NULL, new_storage); - nm_assert (NM_IS_CONNECTION (new_connection)); - nm_assert (nm_streq (uuid, nm_settings_storage_get_uuid (new_storage))); - - - agent_owned_secrets = nm_connection_to_dbus (connection, - NM_CONNECTION_SERIALIZE_ONLY_SECRETS - | NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED); - new_connection_real = _connection_changed_normalize_connection (new_storage, - new_connection, - agent_owned_secrets, - &new_connection_cloned); - if (!new_connection_real) { - nm_assert_not_reached (); - new_connection_real = new_connection; - } - } - } - - nm_assert (NM_IS_SETTINGS_STORAGE (new_storage)); - nm_assert (NM_IS_CONNECTION (new_connection_real)); - - _connection_changed_track (self, new_storage, new_connection_real, TRUE); - - if ( drop_storage - && drop_storage != new_storage) { - gs_free_error GError *local = NULL; - - if (!nm_settings_plugin_delete_connection (nm_settings_storage_get_plugin (drop_storage), - drop_storage, - &local)) { - const char *filename; - - filename = nm_settings_storage_get_filename (drop_storage); - _LOGT ("update[%s]: failed to delete moved storage "NM_SETTINGS_STORAGE_PRINT_FMT"%s%s%s: %s", - nm_settings_storage_get_uuid (drop_storage), - NM_SETTINGS_STORAGE_PRINT_ARG (drop_storage), - NM_PRINT_FMT_QUOTED (filename, " (file \"", filename, "\")", ""), - local->message); - /* there is no aborting back form this. We must get rid of the connection and - * cannot do better than log a message. Proceed, but remember to write tombstones. */ - if (nm_settings_storage_is_keyfile_run (cur_storage)) - tombstone_in_memory = TRUE; - else - tombstone_on_disk = TRUE; - } else - _connection_changed_track (self, drop_storage, NULL, FALSE); - } - - _set_nmmeta_tombstone (self, - uuid, - tombstone_on_disk, - tombstone_in_memory, - NULL); - - _connection_changed_process_all_dirty (self, - FALSE, - sett_flags, - sett_mask, - FALSE, - update_reason); - - return TRUE; + gs_unref_object NMConnection *connection_cloned_1 = NULL; + gs_unref_object NMConnection *new_connection_cloned = NULL; + gs_unref_object NMConnection *new_connection = NULL; + NMConnection * new_connection_real; + gs_unref_object NMSettingsStorage *cur_storage = NULL; + gs_unref_object NMSettingsStorage *new_storage = NULL; + NMSettingsStorage * drop_storage = NULL; + SettConnEntry * sett_conn_entry; + gboolean cur_in_memory; + gboolean new_in_memory; + const char * uuid; + gboolean tombstone_in_memory = FALSE; + gboolean tombstone_on_disk = FALSE; + + g_return_val_if_fail(NM_IS_SETTINGS(self), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(sett_conn), FALSE); + g_return_val_if_fail(!connection || NM_IS_CONNECTION(connection), FALSE); + + nm_assert(!NM_FLAGS_ANY(sett_mask, ~_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK)); + nm_assert(!NM_FLAGS_ANY(sett_flags, ~sett_mask)); + nm_assert(NM_IN_SET(persist_mode, + NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP, + NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST, + NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY)); + + cur_storage = g_object_ref(nm_settings_connection_get_storage(sett_conn)); + + uuid = nm_settings_storage_get_uuid(cur_storage); + + nm_assert(NM_IS_SETTINGS_STORAGE(cur_storage)); + + sett_conn_entry = _sett_conn_entries_get(self, uuid); + + nm_assert(_sett_conn_entry_get_conn(sett_conn_entry) == sett_conn); + + if (connection) { + gs_free_error GError *local = NULL; + + if (!_nm_connection_ensure_normalized(connection, + FALSE, + uuid, + TRUE, + &connection_cloned_1, + &local)) { + _LOGT("update[%s]: %s: failed because profile is invalid: %s", + nm_settings_storage_get_uuid(cur_storage), + log_context_name, + local->message); + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "connection is invalid: %s", + local->message); + return FALSE; + } + if (connection_cloned_1) + connection = connection_cloned_1; + } else + connection = nm_settings_connection_get_connection(sett_conn); + + cur_in_memory = nm_settings_storage_is_keyfile_run(cur_storage); + + if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP) { + persist_mode = cur_in_memory ? NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY + : NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK; + } + + if (NM_FLAGS_HAS(sett_mask, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED) + && !NM_FLAGS_HAS(sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) { + NMDevice *device; + + /* The connection has been changed by the user, it should no longer be + * considered a default wired connection, and should no longer affect + * the no-auto-default configuration option. + */ + device = nm_settings_connection_default_wired_get_device(sett_conn); + if (device) { + nm_assert(cur_in_memory); + nm_assert(NM_FLAGS_HAS(nm_settings_connection_get_flags(sett_conn), + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)); + + default_wired_clear_tag(self, device, sett_conn, FALSE); + + if (NM_IN_SET(persist_mode, NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST)) { + /* making a default-wired-connection a regular connection implies persisting + * it to disk (unless specified differently). + * + * Actually, this line is probably unreached, because we should not use + * NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST to toggle the nm-generated + * flag. */ + nm_assert_not_reached(); + persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK; + } + } + } + + if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST + && NM_FLAGS_ANY(sett_mask, + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL) + && NM_FLAGS_ANY((sett_flags ^ nm_settings_connection_get_flags(sett_conn)) & sett_mask, + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) { + /* we update the nm-generated/volatile setting of a profile (which is inherently + * in-memory. The caller did not request to persist this to disk, however we need + * to store the flags in run. */ + nm_assert(cur_in_memory); + persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY; + } + + if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK) + new_in_memory = FALSE; + else if (NM_IN_SET(persist_mode, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY)) + new_in_memory = TRUE; + else { + nm_assert(persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST); + new_in_memory = cur_in_memory; + } + + if (!new_in_memory) { + /* Persistent connections cannot be volatile nor nm-generated. + * + * That is obviously true for volatile, as it is enforced by Update2() API. + * + * For nm-generated profiles also, because the nm-generated flag is only stored + * for in-memory profiles. If we would persist the profile to /etc it would loose + * the nm-generated flag after restart/reload, and that cannot be right. If a profile + * ends up on disk, the information who created it gets lost. */ + nm_assert(!NM_FLAGS_ANY(sett_flags, + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)); + sett_mask |= NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL; + sett_flags &= ~(NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL); + } + + if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST) { + new_storage = g_object_ref(cur_storage); + new_connection_real = connection; + _LOGT("update[%s]: %s: update profile \"%s\" (not persisted)", + nm_settings_storage_get_uuid(cur_storage), + log_context_name, + nm_connection_get_id(connection)); + } else { + NMSettingsStorage *shadowed_storage; + const char * cur_shadowed_storage_filename; + const char * new_shadowed_storage_filename = NULL; + gboolean cur_shadowed_owned; + gboolean new_shadowed_owned = FALSE; + NMSettingsStorage *update_storage = NULL; + gs_free_error GError *local = NULL; + gboolean success; + + cur_shadowed_storage_filename = + nm_settings_storage_get_shadowed_storage(cur_storage, &cur_shadowed_owned); + + shadowed_storage = _sett_conn_entry_find_shadowed_storage(sett_conn_entry, + cur_shadowed_storage_filename, + cur_storage); + if (!shadowed_storage) { + cur_shadowed_storage_filename = NULL; + cur_shadowed_owned = FALSE; + } + + if (new_in_memory && persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY) { + if (cur_in_memory) { + drop_storage = shadowed_storage; + update_storage = cur_storage; + } else + drop_storage = cur_storage; + } else if (!new_in_memory && cur_in_memory && shadowed_storage) { + drop_storage = cur_storage; + update_storage = shadowed_storage; + } else if (new_in_memory != cur_in_memory) { + if (!new_in_memory) + drop_storage = cur_storage; + else if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY) + drop_storage = cur_storage; + else { + nm_assert(NM_IN_SET(persist_mode, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED)); + } + } else if (nm_settings_storage_is_keyfile_lib(cur_storage)) { + /* the profile is a keyfile in /usr/lib. It cannot be overwritten, we must migrate it + * from /usr/lib to /etc. */ + } else + update_storage = cur_storage; + + if (new_in_memory) { + if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY) { + /* pass */ + } else if (!cur_in_memory) { + new_shadowed_storage_filename = + nm_settings_storage_get_filename_for_shadowed_storage(cur_storage); + if (new_shadowed_storage_filename + && persist_mode != NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED) + new_shadowed_owned = TRUE; + } else { + new_shadowed_storage_filename = cur_shadowed_storage_filename; + if (new_shadowed_storage_filename + && persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY) + new_shadowed_owned = TRUE; + } + } + + if (!update_storage) { + success = _add_connection_to_first_plugin(self, + sett_conn_entry, + connection, + new_in_memory, + sett_flags, + new_shadowed_storage_filename, + new_shadowed_owned, + &new_storage, + &new_connection, + &local); + } else { + success = _update_connection_to_plugin(self, + update_storage, + connection, + sett_flags, + update_reason, + new_shadowed_storage_filename, + new_shadowed_owned, + &new_storage, + &new_connection, + &local); + } + if (!success) { + gboolean ignore_failure; + + ignore_failure = + NM_FLAGS_ANY(update_reason, + NM_SETTINGS_CONNECTION_UPDATE_REASON_IGNORE_PERSIST_FAILURE); + + _LOGT("update[%s]: %s: %sfailure to %s connection \"%s\" on storage: %s", + nm_settings_storage_get_uuid(cur_storage), + log_context_name, + ignore_failure ? "ignore " : "", + update_storage ? "update" : "write", + nm_connection_get_id(connection), + local->message); + if (!ignore_failure) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "failed to %s connection: %s", + update_storage ? "update" : "write", + local->message); + return FALSE; + } + + new_storage = g_object_ref(cur_storage); + new_connection_real = connection; + } else { + gs_unref_variant GVariant *agent_owned_secrets = NULL; + + _LOGT("update[%s]: %s: %s profile \"%s\"", + nm_settings_storage_get_uuid(cur_storage), + log_context_name, + update_storage ? "update" : "write", + nm_connection_get_id(connection)); + + nm_assert_valid_settings_storage(NULL, new_storage); + nm_assert(NM_IS_CONNECTION(new_connection)); + nm_assert(nm_streq(uuid, nm_settings_storage_get_uuid(new_storage))); + + agent_owned_secrets = + nm_connection_to_dbus(connection, + NM_CONNECTION_SERIALIZE_ONLY_SECRETS + | NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED); + new_connection_real = _connection_changed_normalize_connection(new_storage, + new_connection, + agent_owned_secrets, + &new_connection_cloned); + if (!new_connection_real) { + nm_assert_not_reached(); + new_connection_real = new_connection; + } + } + } + + nm_assert(NM_IS_SETTINGS_STORAGE(new_storage)); + nm_assert(NM_IS_CONNECTION(new_connection_real)); + + _connection_changed_track(self, new_storage, new_connection_real, TRUE); + + if (drop_storage && drop_storage != new_storage) { + gs_free_error GError *local = NULL; + + if (!nm_settings_plugin_delete_connection(nm_settings_storage_get_plugin(drop_storage), + drop_storage, + &local)) { + const char *filename; + + filename = nm_settings_storage_get_filename(drop_storage); + _LOGT("update[%s]: failed to delete moved storage " NM_SETTINGS_STORAGE_PRINT_FMT + "%s%s%s: %s", + nm_settings_storage_get_uuid(drop_storage), + NM_SETTINGS_STORAGE_PRINT_ARG(drop_storage), + NM_PRINT_FMT_QUOTED(filename, " (file \"", filename, "\")", ""), + local->message); + /* there is no aborting back form this. We must get rid of the connection and + * cannot do better than log a message. Proceed, but remember to write tombstones. */ + if (nm_settings_storage_is_keyfile_run(cur_storage)) + tombstone_in_memory = TRUE; + else + tombstone_on_disk = TRUE; + } else + _connection_changed_track(self, drop_storage, NULL, FALSE); + } + + _set_nmmeta_tombstone(self, uuid, tombstone_on_disk, tombstone_in_memory, NULL); + + _connection_changed_process_all_dirty(self, FALSE, sett_flags, sett_mask, FALSE, update_reason); + + return TRUE; } void -nm_settings_delete_connection (NMSettings *self, - NMSettingsConnection *sett_conn, - gboolean allow_add_to_no_auto_default) +nm_settings_delete_connection(NMSettings * self, + NMSettingsConnection *sett_conn, + gboolean allow_add_to_no_auto_default) { - NMSettingsStorage *cur_storage; - NMSettingsStorage *shadowed_storage; - NMSettingsStorage *shadowed_storage_unowned = NULL; - NMSettingsStorage *drop_storages[2] = { }; - gs_free_error GError *local = NULL; - SettConnEntry *sett_conn_entry; - const char *cur_shadowed_storage_filename; - const char *new_shadowed_storage_filename = NULL; - gboolean cur_shadowed_owned; - const char *uuid; - gboolean tombstone_in_memory = FALSE; - gboolean tombstone_on_disk = FALSE; - int i; - - g_return_if_fail (NM_IS_SETTINGS (self)); - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn)); - g_return_if_fail (nm_settings_has_connection (self, sett_conn)); - - cur_storage = nm_settings_connection_get_storage (sett_conn); - - nm_assert (NM_IS_SETTINGS_STORAGE (cur_storage)); - - uuid = nm_settings_storage_get_uuid (cur_storage); - nm_assert (nm_utils_is_uuid (uuid)); - - sett_conn_entry = _sett_conn_entries_get (self, uuid); - - g_return_if_fail (sett_conn_entry); - nm_assert (sett_conn_entry->sett_conn == sett_conn); - g_return_if_fail (sett_conn_entry->storage == cur_storage); - - if (NMS_IS_KEYFILE_STORAGE (cur_storage)) { - NMSKeyfileStorage *s = NMS_KEYFILE_STORAGE (cur_storage); - - if (NM_IN_SET (s->storage_type, NMS_KEYFILE_STORAGE_TYPE_RUN, - NMS_KEYFILE_STORAGE_TYPE_ETC)) - drop_storages[0] = cur_storage; - else - tombstone_on_disk = TRUE; - } else - drop_storages[0] = cur_storage; - - cur_shadowed_storage_filename = nm_settings_storage_get_shadowed_storage (cur_storage, &cur_shadowed_owned); - - shadowed_storage = _sett_conn_entry_find_shadowed_storage (sett_conn_entry, cur_shadowed_storage_filename, cur_storage); - if (shadowed_storage) { - if (!cur_shadowed_owned) - shadowed_storage_unowned = g_steal_pointer (&shadowed_storage); - } - drop_storages[1] = shadowed_storage; - - for (i = 0; i < (int) G_N_ELEMENTS (drop_storages); i++) { - NMSettingsStorage *storage; - StorageData *sd; - - storage = drop_storages[i]; - if (!storage) - continue; - - if (!nm_settings_plugin_delete_connection (nm_settings_storage_get_plugin (storage), - storage, - &local)) { - _LOGT ("delete-connection: failed to delete storage "NM_SETTINGS_STORAGE_PRINT_FMT": %s", - NM_SETTINGS_STORAGE_PRINT_ARG (storage), - local->message); - g_clear_error (&local); - /* there is no aborting back form this. We must get rid of the connection and - * cannot do better than log a message. Proceed, but remember to write tombstones. */ - if (nm_settings_storage_is_keyfile_run (cur_storage)) - tombstone_in_memory = TRUE; - else - tombstone_on_disk = TRUE; - sett_conn_entry = _sett_conn_entries_get (self, uuid); - } else - sett_conn_entry = _connection_changed_track (self, storage, NULL, FALSE); - - c_list_for_each_entry (sd, &sett_conn_entry->sd_lst_head, sd_lst) { - if (NM_IN_SET (sd->storage, drop_storages[0], - drop_storages[1])) - continue; - if (!_storage_data_is_alive (sd)) - continue; - if (nm_settings_storage_is_meta_data (sd->storage)) - continue; - - if (sd->storage == shadowed_storage_unowned) { - /* this only happens if we leak a profile on disk after NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED. - * We need to write a tombstone and remember the shadowed-storage. */ - tombstone_in_memory = TRUE; - new_shadowed_storage_filename = nm_settings_storage_get_filename (shadowed_storage_unowned); - continue; - } - - /* we have still conflicting storages. We need to hide them with tombstones. */ - if (nm_settings_storage_is_keyfile_run (sd->storage)) { - tombstone_in_memory = TRUE; - continue; - } - tombstone_on_disk = TRUE; - } - } - - _set_nmmeta_tombstone (self, - uuid, - tombstone_on_disk, - tombstone_in_memory, - new_shadowed_storage_filename); - - _connection_changed_process_all_dirty (self, - allow_add_to_no_auto_default, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - FALSE, - NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE); + NMSettingsStorage *cur_storage; + NMSettingsStorage *shadowed_storage; + NMSettingsStorage *shadowed_storage_unowned = NULL; + NMSettingsStorage *drop_storages[2] = {}; + gs_free_error GError *local = NULL; + SettConnEntry * sett_conn_entry; + const char * cur_shadowed_storage_filename; + const char * new_shadowed_storage_filename = NULL; + gboolean cur_shadowed_owned; + const char * uuid; + gboolean tombstone_in_memory = FALSE; + gboolean tombstone_on_disk = FALSE; + int i; + + g_return_if_fail(NM_IS_SETTINGS(self)); + g_return_if_fail(NM_IS_SETTINGS_CONNECTION(sett_conn)); + g_return_if_fail(nm_settings_has_connection(self, sett_conn)); + + cur_storage = nm_settings_connection_get_storage(sett_conn); + + nm_assert(NM_IS_SETTINGS_STORAGE(cur_storage)); + + uuid = nm_settings_storage_get_uuid(cur_storage); + nm_assert(nm_utils_is_uuid(uuid)); + + sett_conn_entry = _sett_conn_entries_get(self, uuid); + + g_return_if_fail(sett_conn_entry); + nm_assert(sett_conn_entry->sett_conn == sett_conn); + g_return_if_fail(sett_conn_entry->storage == cur_storage); + + if (NMS_IS_KEYFILE_STORAGE(cur_storage)) { + NMSKeyfileStorage *s = NMS_KEYFILE_STORAGE(cur_storage); + + if (NM_IN_SET(s->storage_type, NMS_KEYFILE_STORAGE_TYPE_RUN, NMS_KEYFILE_STORAGE_TYPE_ETC)) + drop_storages[0] = cur_storage; + else + tombstone_on_disk = TRUE; + } else + drop_storages[0] = cur_storage; + + cur_shadowed_storage_filename = + nm_settings_storage_get_shadowed_storage(cur_storage, &cur_shadowed_owned); + + shadowed_storage = _sett_conn_entry_find_shadowed_storage(sett_conn_entry, + cur_shadowed_storage_filename, + cur_storage); + if (shadowed_storage) { + if (!cur_shadowed_owned) + shadowed_storage_unowned = g_steal_pointer(&shadowed_storage); + } + drop_storages[1] = shadowed_storage; + + for (i = 0; i < (int) G_N_ELEMENTS(drop_storages); i++) { + NMSettingsStorage *storage; + StorageData * sd; + + storage = drop_storages[i]; + if (!storage) + continue; + + if (!nm_settings_plugin_delete_connection(nm_settings_storage_get_plugin(storage), + storage, + &local)) { + _LOGT("delete-connection: failed to delete storage " NM_SETTINGS_STORAGE_PRINT_FMT + ": %s", + NM_SETTINGS_STORAGE_PRINT_ARG(storage), + local->message); + g_clear_error(&local); + /* there is no aborting back form this. We must get rid of the connection and + * cannot do better than log a message. Proceed, but remember to write tombstones. */ + if (nm_settings_storage_is_keyfile_run(cur_storage)) + tombstone_in_memory = TRUE; + else + tombstone_on_disk = TRUE; + sett_conn_entry = _sett_conn_entries_get(self, uuid); + } else + sett_conn_entry = _connection_changed_track(self, storage, NULL, FALSE); + + c_list_for_each_entry (sd, &sett_conn_entry->sd_lst_head, sd_lst) { + if (NM_IN_SET(sd->storage, drop_storages[0], drop_storages[1])) + continue; + if (!_storage_data_is_alive(sd)) + continue; + if (nm_settings_storage_is_meta_data(sd->storage)) + continue; + + if (sd->storage == shadowed_storage_unowned) { + /* this only happens if we leak a profile on disk after NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED. + * We need to write a tombstone and remember the shadowed-storage. */ + tombstone_in_memory = TRUE; + new_shadowed_storage_filename = + nm_settings_storage_get_filename(shadowed_storage_unowned); + continue; + } + + /* we have still conflicting storages. We need to hide them with tombstones. */ + if (nm_settings_storage_is_keyfile_run(sd->storage)) { + tombstone_in_memory = TRUE; + continue; + } + tombstone_on_disk = TRUE; + } + } + + _set_nmmeta_tombstone(self, + uuid, + tombstone_on_disk, + tombstone_in_memory, + new_shadowed_storage_filename); + + _connection_changed_process_all_dirty(self, + allow_add_to_no_auto_default, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + FALSE, + NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE); } /*****************************************************************************/ static void -send_agent_owned_secrets (NMSettings *self, - NMSettingsConnection *sett_conn, - NMAuthSubject *subject) +send_agent_owned_secrets(NMSettings *self, NMSettingsConnection *sett_conn, NMAuthSubject *subject) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - gs_unref_object NMConnection *for_agent = NULL; - - /* Dupe the connection so we can clear out non-agent-owned secrets, - * as agent-owned secrets are the only ones we send back to be saved. - * Only send secrets to agents of the same UID that called update too. - */ - for_agent = nm_simple_connection_new_clone (nm_settings_connection_get_connection (sett_conn)); - _nm_connection_clear_secrets_by_secret_flags (for_agent, - NM_SETTING_SECRET_FLAG_AGENT_OWNED); - nm_agent_manager_save_secrets (priv->agent_mgr, - nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn)), - for_agent, - subject); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + gs_unref_object NMConnection *for_agent = NULL; + + /* Dupe the connection so we can clear out non-agent-owned secrets, + * as agent-owned secrets are the only ones we send back to be saved. + * Only send secrets to agents of the same UID that called update too. + */ + for_agent = nm_simple_connection_new_clone(nm_settings_connection_get_connection(sett_conn)); + _nm_connection_clear_secrets_by_secret_flags(for_agent, NM_SETTING_SECRET_FLAG_AGENT_OWNED); + nm_agent_manager_save_secrets(priv->agent_mgr, + nm_dbus_object_get_path(NM_DBUS_OBJECT(sett_conn)), + for_agent, + subject); } static void -pk_add_cb (NMAuthChain *chain, - GDBusMethodInvocation *context, - gpointer user_data) +pk_add_cb(NMAuthChain *chain, GDBusMethodInvocation *context, gpointer user_data) { - NMSettings *self = NM_SETTINGS (user_data); - NMAuthCallResult result; - gs_free_error GError *error = NULL; - NMConnection *connection = NULL; - gs_unref_object NMSettingsConnection *added = NULL; - NMSettingsAddCallback callback; - gpointer callback_data; - NMAuthSubject *subject; - const char *perm; - - nm_assert (G_IS_DBUS_METHOD_INVOCATION (context)); - - c_list_unlink (nm_auth_chain_parent_lst_list (chain)); - - perm = nm_auth_chain_get_data (chain, "perm"); - nm_assert (perm); - - result = nm_auth_chain_get_result (chain, perm); - - if (result != NM_AUTH_CALL_RESULT_YES) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - NM_UTILS_ERROR_MSG_INSUFF_PRIV); - } else { - /* Authorized */ - connection = nm_auth_chain_get_data (chain, "connection"); - nm_assert (NM_IS_CONNECTION (connection)); - - nm_settings_add_connection (self, - connection, - GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "persist-mode")), - GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "add-reason")), - GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "sett-flags")), - &added, - &error); - - /* The callback may remove the connection from the settings manager (e.g. - * because it's found to be incompatible with the device on AddAndActivate). - * But we need to keep it alive for a bit longer, precisely to check wehther - * it's still known to the setting manager. */ - nm_g_object_ref (added); - } - - callback = nm_auth_chain_get_data (chain, "callback"); - callback_data = nm_auth_chain_get_data (chain, "callback-data"); - subject = nm_auth_chain_get_data (chain, "subject"); - - callback (self, added, error, context, subject, callback_data); - - /* Send agent-owned secrets to the agents */ - if ( added - && nm_settings_has_connection (self, added)) - send_agent_owned_secrets (self, added, subject); + NMSettings * self = NM_SETTINGS(user_data); + NMAuthCallResult result; + gs_free_error GError *error = NULL; + NMConnection * connection = NULL; + gs_unref_object NMSettingsConnection *added = NULL; + NMSettingsAddCallback callback; + gpointer callback_data; + NMAuthSubject * subject; + const char * perm; + + nm_assert(G_IS_DBUS_METHOD_INVOCATION(context)); + + c_list_unlink(nm_auth_chain_parent_lst_list(chain)); + + perm = nm_auth_chain_get_data(chain, "perm"); + nm_assert(perm); + + result = nm_auth_chain_get_result(chain, perm); + + if (result != NM_AUTH_CALL_RESULT_YES) { + error = g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + NM_UTILS_ERROR_MSG_INSUFF_PRIV); + } else { + /* Authorized */ + connection = nm_auth_chain_get_data(chain, "connection"); + nm_assert(NM_IS_CONNECTION(connection)); + + nm_settings_add_connection(self, + connection, + GPOINTER_TO_UINT(nm_auth_chain_get_data(chain, "persist-mode")), + GPOINTER_TO_UINT(nm_auth_chain_get_data(chain, "add-reason")), + GPOINTER_TO_UINT(nm_auth_chain_get_data(chain, "sett-flags")), + &added, + &error); + + /* The callback may remove the connection from the settings manager (e.g. + * because it's found to be incompatible with the device on AddAndActivate). + * But we need to keep it alive for a bit longer, precisely to check wehther + * it's still known to the setting manager. */ + nm_g_object_ref(added); + } + + callback = nm_auth_chain_get_data(chain, "callback"); + callback_data = nm_auth_chain_get_data(chain, "callback-data"); + subject = nm_auth_chain_get_data(chain, "subject"); + + callback(self, added, error, context, subject, callback_data); + + /* Send agent-owned secrets to the agents */ + if (added && nm_settings_has_connection(self, added)) + send_agent_owned_secrets(self, added, subject); } void -nm_settings_add_connection_dbus (NMSettings *self, - NMConnection *connection, - NMSettingsConnectionPersistMode persist_mode, - NMSettingsConnectionAddReason add_reason, - NMSettingsConnectionIntFlags sett_flags, - NMAuthSubject *subject, - GDBusMethodInvocation *context, - NMSettingsAddCallback callback, - gpointer user_data) +nm_settings_add_connection_dbus(NMSettings * self, + NMConnection * connection, + NMSettingsConnectionPersistMode persist_mode, + NMSettingsConnectionAddReason add_reason, + NMSettingsConnectionIntFlags sett_flags, + NMAuthSubject * subject, + GDBusMethodInvocation * context, + NMSettingsAddCallback callback, + gpointer user_data) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - NMSettingConnection *s_con; - NMAuthChain *chain; - GError *error = NULL, *tmp_error = NULL; - const char *perm; - - g_return_if_fail (NM_IS_CONNECTION (connection)); - g_return_if_fail (NM_IS_AUTH_SUBJECT (subject)); - g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (context)); - - nm_assert (!NM_FLAGS_ANY (sett_flags, ~_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK)); - - /* Connection must be valid, of course */ - if (_nm_connection_verify (connection, &tmp_error) != NM_SETTING_VERIFY_SUCCESS) { - error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "The connection was invalid: %s", - tmp_error->message); - g_error_free (tmp_error); - goto done; - } - - if (!nm_auth_is_subject_in_acl_set_error (connection, - subject, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - &error)) - goto done; - - /* If the caller is the only user in the connection's permissions, then - * we use the 'modify.own' permission instead of 'modify.system'. If the - * request affects more than just the caller, require 'modify.system'. - */ - s_con = nm_connection_get_setting_connection (connection); - nm_assert (s_con); - if (nm_setting_connection_get_num_permissions (s_con) == 1) - perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; - else - perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; - - /* Validate the user request */ - chain = nm_auth_chain_new_subject (subject, context, pk_add_cb, self); - if (!chain) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - NM_UTILS_ERROR_MSG_REQ_AUTH_FAILED); - goto done; - } - - c_list_link_tail (&priv->auth_lst_head, nm_auth_chain_parent_lst_list (chain)); - - nm_auth_chain_set_data (chain, "perm", (gpointer) perm, NULL); - nm_auth_chain_set_data (chain, "connection", g_object_ref (connection), g_object_unref); - nm_auth_chain_set_data (chain, "callback", callback, NULL); - nm_auth_chain_set_data (chain, "callback-data", user_data, NULL); - nm_auth_chain_set_data (chain, "subject", g_object_ref (subject), g_object_unref); - nm_auth_chain_set_data (chain, "persist-mode", GUINT_TO_POINTER (persist_mode), NULL); - nm_auth_chain_set_data (chain, "add-reason", GUINT_TO_POINTER (add_reason), NULL); - nm_auth_chain_set_data (chain, "sett-flags", GUINT_TO_POINTER (sett_flags), NULL); - nm_auth_chain_add_call_unsafe (chain, perm, TRUE); - return; + NMSettingsPrivate * priv = NM_SETTINGS_GET_PRIVATE(self); + NMSettingConnection *s_con; + NMAuthChain * chain; + GError * error = NULL, *tmp_error = NULL; + const char * perm; + + g_return_if_fail(NM_IS_CONNECTION(connection)); + g_return_if_fail(NM_IS_AUTH_SUBJECT(subject)); + g_return_if_fail(G_IS_DBUS_METHOD_INVOCATION(context)); + + nm_assert(!NM_FLAGS_ANY(sett_flags, ~_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK)); + + /* Connection must be valid, of course */ + if (_nm_connection_verify(connection, &tmp_error) != NM_SETTING_VERIFY_SUCCESS) { + error = g_error_new(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "The connection was invalid: %s", + tmp_error->message); + g_error_free(tmp_error); + goto done; + } + + if (!nm_auth_is_subject_in_acl_set_error(connection, + subject, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + &error)) + goto done; + + /* If the caller is the only user in the connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. If the + * request affects more than just the caller, require 'modify.system'. + */ + s_con = nm_connection_get_setting_connection(connection); + nm_assert(s_con); + if (nm_setting_connection_get_num_permissions(s_con) == 1) + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + else + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; + + /* Validate the user request */ + chain = nm_auth_chain_new_subject(subject, context, pk_add_cb, self); + if (!chain) { + error = g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + NM_UTILS_ERROR_MSG_REQ_AUTH_FAILED); + goto done; + } + + c_list_link_tail(&priv->auth_lst_head, nm_auth_chain_parent_lst_list(chain)); + + nm_auth_chain_set_data(chain, "perm", (gpointer) perm, NULL); + nm_auth_chain_set_data(chain, "connection", g_object_ref(connection), g_object_unref); + nm_auth_chain_set_data(chain, "callback", callback, NULL); + nm_auth_chain_set_data(chain, "callback-data", user_data, NULL); + nm_auth_chain_set_data(chain, "subject", g_object_ref(subject), g_object_unref); + nm_auth_chain_set_data(chain, "persist-mode", GUINT_TO_POINTER(persist_mode), NULL); + nm_auth_chain_set_data(chain, "add-reason", GUINT_TO_POINTER(add_reason), NULL); + nm_auth_chain_set_data(chain, "sett-flags", GUINT_TO_POINTER(sett_flags), NULL); + nm_auth_chain_add_call_unsafe(chain, perm, TRUE); + return; done: - nm_assert (error); - callback (self, NULL, error, context, subject, user_data); - g_error_free (error); + nm_assert(error); + callback(self, NULL, error, context, subject, user_data); + g_error_free(error); } static void -settings_add_connection_add_cb (NMSettings *self, - NMSettingsConnection *connection, - GError *error, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - gpointer user_data) +settings_add_connection_add_cb(NMSettings * self, + NMSettingsConnection * connection, + GError * error, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + gpointer user_data) { - gboolean is_add_connection_2 = GPOINTER_TO_INT (user_data); - - if (error) { - g_dbus_method_invocation_return_gerror (context, error); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, NULL, subject, error->message); - return; - } - - if (is_add_connection_2) { - GVariantBuilder builder; - - g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); - g_dbus_method_invocation_return_value (context, - g_variant_new ("(oa{sv})", - nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)), - &builder)); - } else { - g_dbus_method_invocation_return_value (context, - g_variant_new ("(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)))); - } - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, connection, TRUE, NULL, - subject, NULL); + gboolean is_add_connection_2 = GPOINTER_TO_INT(user_data); + + if (error) { + g_dbus_method_invocation_return_gerror(context, error); + nm_audit_log_connection_op(NM_AUDIT_OP_CONN_ADD, + NULL, + FALSE, + NULL, + subject, + error->message); + return; + } + + if (is_add_connection_2) { + GVariantBuilder builder; + + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + g_dbus_method_invocation_return_value( + context, + g_variant_new("(oa{sv})", + nm_dbus_object_get_path(NM_DBUS_OBJECT(connection)), + &builder)); + } else { + g_dbus_method_invocation_return_value( + context, + g_variant_new("(o)", nm_dbus_object_get_path(NM_DBUS_OBJECT(connection)))); + } + nm_audit_log_connection_op(NM_AUDIT_OP_CONN_ADD, connection, TRUE, NULL, subject, NULL); } static void -settings_add_connection_helper (NMSettings *self, - GDBusMethodInvocation *context, - gboolean is_add_connection_2, - GVariant *settings, - NMSettingsAddConnection2Flags flags) +settings_add_connection_helper(NMSettings * self, + GDBusMethodInvocation * context, + gboolean is_add_connection_2, + GVariant * settings, + NMSettingsAddConnection2Flags flags) { - gs_unref_object NMConnection *connection = NULL; - GError *error = NULL; - gs_unref_object NMAuthSubject *subject = NULL; - NMSettingsConnectionPersistMode persist_mode; - - connection = _nm_simple_connection_new_from_dbus (settings, - NM_SETTING_PARSE_FLAGS_STRICT - | NM_SETTING_PARSE_FLAGS_NORMALIZE, - &error); - - if ( !connection - || !nm_connection_verify_secrets (connection, &error)) { - g_dbus_method_invocation_take_error (context, error); - return; - } - - subject = nm_dbus_manager_new_auth_subject_from_context (context); - if (!subject) { - g_dbus_method_invocation_return_error_literal (context, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - NM_UTILS_ERROR_MSG_REQ_UID_UKNOWN); - return; - } - - if (NM_FLAGS_HAS (flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK)) - persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK; - else { - nm_assert (NM_FLAGS_HAS (flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY)); - persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY; - } - - nm_settings_add_connection_dbus (self, - connection, - persist_mode, - NM_FLAGS_HAS (flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT) - ? NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT - : NM_SETTINGS_CONNECTION_ADD_REASON_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - subject, - context, - settings_add_connection_add_cb, - GINT_TO_POINTER (!!is_add_connection_2)); + gs_unref_object NMConnection *connection = NULL; + GError * error = NULL; + gs_unref_object NMAuthSubject * subject = NULL; + NMSettingsConnectionPersistMode persist_mode; + + connection = _nm_simple_connection_new_from_dbus(settings, + NM_SETTING_PARSE_FLAGS_STRICT + | NM_SETTING_PARSE_FLAGS_NORMALIZE, + &error); + + if (!connection || !nm_connection_verify_secrets(connection, &error)) { + g_dbus_method_invocation_take_error(context, error); + return; + } + + subject = nm_dbus_manager_new_auth_subject_from_context(context); + if (!subject) { + g_dbus_method_invocation_return_error_literal(context, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + NM_UTILS_ERROR_MSG_REQ_UID_UKNOWN); + return; + } + + if (NM_FLAGS_HAS(flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK)) + persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK; + else { + nm_assert(NM_FLAGS_HAS(flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY)); + persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY; + } + + nm_settings_add_connection_dbus( + self, + connection, + persist_mode, + NM_FLAGS_HAS(flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT) + ? NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT + : NM_SETTINGS_CONNECTION_ADD_REASON_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + subject, + context, + settings_add_connection_add_cb, + GINT_TO_POINTER(!!is_add_connection_2)); } static void -impl_settings_add_connection (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_add_connection(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettings *self = NM_SETTINGS (obj); - gs_unref_variant GVariant *settings = NULL; - - g_variant_get (parameters, "(@a{sa{sv}})", &settings); - settings_add_connection_helper (self, invocation, FALSE, settings, NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK); + NMSettings * self = NM_SETTINGS(obj); + gs_unref_variant GVariant *settings = NULL; + + g_variant_get(parameters, "(@a{sa{sv}})", &settings); + settings_add_connection_helper(self, + invocation, + FALSE, + settings, + NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK); } static void -impl_settings_add_connection_unsaved (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_add_connection_unsaved(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettings *self = NM_SETTINGS (obj); - gs_unref_variant GVariant *settings = NULL; - - g_variant_get (parameters, "(@a{sa{sv}})", &settings); - settings_add_connection_helper (self, invocation, FALSE, settings, NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY); + NMSettings * self = NM_SETTINGS(obj); + gs_unref_variant GVariant *settings = NULL; + + g_variant_get(parameters, "(@a{sa{sv}})", &settings); + settings_add_connection_helper(self, + invocation, + FALSE, + settings, + NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY); } static void -impl_settings_add_connection2 (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_add_connection2(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettings *self = NM_SETTINGS (obj); - gs_unref_variant GVariant *settings = NULL; - gs_unref_variant GVariant *args = NULL; - NMSettingsAddConnection2Flags flags; - const char *args_name; - GVariantIter iter; - guint32 flags_u; - - g_variant_get (parameters, "(@a{sa{sv}}u@a{sv})", &settings, &flags_u, &args); - - if (NM_FLAGS_ANY (flags_u, ~((guint32) ( NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK - | NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY - | NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT)))) { - g_dbus_method_invocation_take_error (invocation, - g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_ARGUMENTS, - "Unknown flags")); - return; - } - - flags = flags_u; - - if (!NM_FLAGS_ANY (flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK - | NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY)) { - g_dbus_method_invocation_take_error (invocation, - g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_ARGUMENTS, - "Requires either to-disk (0x1) or in-memory (0x2) flags")); - return; - } - - if (NM_FLAGS_ALL (flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK - | NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY)) { - g_dbus_method_invocation_take_error (invocation, - g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_ARGUMENTS, - "Cannot set to-disk (0x1) and in-memory (0x2) flags together")); - return; - } - - nm_assert (g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}"))); - - g_variant_iter_init (&iter, args); - while (g_variant_iter_next (&iter, "{&sv}", &args_name, NULL)) { - g_dbus_method_invocation_take_error (invocation, - g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_ARGUMENTS, - "Unsupported argument '%s'", args_name)); - return; - } - - settings_add_connection_helper (self, invocation, TRUE, settings, flags); + NMSettings * self = NM_SETTINGS(obj); + gs_unref_variant GVariant *settings = NULL; + gs_unref_variant GVariant * args = NULL; + NMSettingsAddConnection2Flags flags; + const char * args_name; + GVariantIter iter; + guint32 flags_u; + + g_variant_get(parameters, "(@a{sa{sv}}u@a{sv})", &settings, &flags_u, &args); + + if (NM_FLAGS_ANY(flags_u, + ~((guint32)(NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK + | NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY + | NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT)))) { + g_dbus_method_invocation_take_error(invocation, + g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_ARGUMENTS, + "Unknown flags")); + return; + } + + flags = flags_u; + + if (!NM_FLAGS_ANY(flags, + NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK + | NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY)) { + g_dbus_method_invocation_take_error( + invocation, + g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_ARGUMENTS, + "Requires either to-disk (0x1) or in-memory (0x2) flags")); + return; + } + + if (NM_FLAGS_ALL(flags, + NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK + | NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY)) { + g_dbus_method_invocation_take_error( + invocation, + g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_ARGUMENTS, + "Cannot set to-disk (0x1) and in-memory (0x2) flags together")); + return; + } + + nm_assert(g_variant_is_of_type(args, G_VARIANT_TYPE("a{sv}"))); + + g_variant_iter_init(&iter, args); + while (g_variant_iter_next(&iter, "{&sv}", &args_name, NULL)) { + g_dbus_method_invocation_take_error(invocation, + g_error_new(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_ARGUMENTS, + "Unsupported argument '%s'", + args_name)); + return; + } + + settings_add_connection_helper(self, invocation, TRUE, settings, flags); } /*****************************************************************************/ static void -impl_settings_load_connections (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *dbus_connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_load_connections(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * dbus_connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettings *self = NM_SETTINGS (obj); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - gs_unref_ptrarray GPtrArray *failures = NULL; - gs_free const char **filenames = NULL; - gs_free char *op_result_str = NULL; - - g_variant_get (parameters, "(^a&s)", &filenames); - - /* The permission is already enforced by the D-Bus daemon, but we ensure - * that the caller is still alive so that clients are forced to wait and - * we'll be able to switch to polkit without breaking behavior. - */ - if (!nm_dbus_manager_ensure_uid (nm_dbus_object_get_manager (obj), - invocation, - G_MAXULONG, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED)) - return; - - if ( filenames - && filenames[0]) { - NMSettingsPluginConnectionLoadEntry *entries; - gsize n_entries; - gsize i; - GSList *iter; - - entries = nm_settings_plugin_create_connection_load_entries (filenames, &n_entries); - - for (iter = priv->plugins; iter; iter = iter->next) { - NMSettingsPlugin *plugin = iter->data; - - nm_settings_plugin_load_connections (plugin, - entries, - n_entries, - _plugin_connections_reload_cb, - self); - } - - for (i = 0; i < n_entries; i++) { - NMSettingsPluginConnectionLoadEntry *entry = &entries[i]; - - if (!entry->handled) { - _LOGW ("load: no settings plugin could load \"%s\"", entry->filename); - nm_assert (!entry->error); - } else if (entry->error) { - _LOGW ("load: failure to load \"%s\": %s", entry->filename, entry->error->message); - g_clear_error (&entry->error); - } else - continue; - - if (!failures) - failures = g_ptr_array_new (); - g_ptr_array_add (failures, (char *) entry->filename); - } - - nm_clear_g_free (&entries); - - _connection_changed_process_all_dirty (self, - TRUE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - TRUE, - NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS - | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS); - - for (iter = priv->plugins; iter; iter = iter->next) - nm_settings_plugin_load_connections_done (iter->data); - } - - if (failures) - g_ptr_array_add (failures, NULL); - - nm_audit_log_connection_op (NM_AUDIT_OP_CONNS_LOAD, - NULL, - !failures, - (op_result_str = g_strjoinv (",", (char **) filenames)), - invocation, - NULL); - - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(b^as)", - (gboolean) (!failures), - failures - ? (const char **) failures->pdata - : NM_PTRARRAY_EMPTY (const char *))); + NMSettings * self = NM_SETTINGS(obj); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + gs_unref_ptrarray GPtrArray *failures = NULL; + gs_free const char ** filenames = NULL; + gs_free char * op_result_str = NULL; + + g_variant_get(parameters, "(^a&s)", &filenames); + + /* The permission is already enforced by the D-Bus daemon, but we ensure + * that the caller is still alive so that clients are forced to wait and + * we'll be able to switch to polkit without breaking behavior. + */ + if (!nm_dbus_manager_ensure_uid(nm_dbus_object_get_manager(obj), + invocation, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) + return; + + if (filenames && filenames[0]) { + NMSettingsPluginConnectionLoadEntry *entries; + gsize n_entries; + gsize i; + GSList * iter; + + entries = nm_settings_plugin_create_connection_load_entries(filenames, &n_entries); + + for (iter = priv->plugins; iter; iter = iter->next) { + NMSettingsPlugin *plugin = iter->data; + + nm_settings_plugin_load_connections(plugin, + entries, + n_entries, + _plugin_connections_reload_cb, + self); + } + + for (i = 0; i < n_entries; i++) { + NMSettingsPluginConnectionLoadEntry *entry = &entries[i]; + + if (!entry->handled) { + _LOGW("load: no settings plugin could load \"%s\"", entry->filename); + nm_assert(!entry->error); + } else if (entry->error) { + _LOGW("load: failure to load \"%s\": %s", entry->filename, entry->error->message); + g_clear_error(&entry->error); + } else + continue; + + if (!failures) + failures = g_ptr_array_new(); + g_ptr_array_add(failures, (char *) entry->filename); + } + + nm_clear_g_free(&entries); + + _connection_changed_process_all_dirty( + self, + TRUE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + TRUE, + NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS); + + for (iter = priv->plugins; iter; iter = iter->next) + nm_settings_plugin_load_connections_done(iter->data); + } + + if (failures) + g_ptr_array_add(failures, NULL); + + nm_audit_log_connection_op(NM_AUDIT_OP_CONNS_LOAD, + NULL, + !failures, + (op_result_str = g_strjoinv(",", (char **) filenames)), + invocation, + NULL); + + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(b^as)", + (gboolean)(!failures), + failures + ? (const char **) failures->pdata + : NM_PTRARRAY_EMPTY(const char *))); } static void -impl_settings_reload_connections (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_reload_connections(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettings *self = NM_SETTINGS (obj); + NMSettings *self = NM_SETTINGS(obj); - /* The permission is already enforced by the D-Bus daemon, but we ensure - * that the caller is still alive so that clients are forced to wait and - * we'll be able to switch to polkit without breaking behavior. - */ - if (!nm_dbus_manager_ensure_uid (nm_dbus_object_get_manager (obj), - invocation, - G_MAXULONG, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED)) - return; + /* The permission is already enforced by the D-Bus daemon, but we ensure + * that the caller is still alive so that clients are forced to wait and + * we'll be able to switch to polkit without breaking behavior. + */ + if (!nm_dbus_manager_ensure_uid(nm_dbus_object_get_manager(obj), + invocation, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) + return; - _plugin_connections_reload (self); + _plugin_connections_reload(self); - nm_audit_log_connection_op (NM_AUDIT_OP_CONNS_RELOAD, NULL, TRUE, NULL, invocation, NULL); + nm_audit_log_connection_op(NM_AUDIT_OP_CONNS_RELOAD, NULL, TRUE, NULL, invocation, NULL); - /* We MUST return %TRUE here, otherwise older libnm versions might misbehave. */ - g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", TRUE)); + /* We MUST return %TRUE here, otherwise older libnm versions might misbehave. */ + g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", TRUE)); } /*****************************************************************************/ static void -_clear_connections_cached_list (NMSettingsPrivate *priv) +_clear_connections_cached_list(NMSettingsPrivate *priv) { - if (!priv->connections_cached_list) - return; + if (!priv->connections_cached_list) + return; - nm_assert (priv->connections_len == NM_PTRARRAY_LEN (priv->connections_cached_list)); + nm_assert(priv->connections_len == NM_PTRARRAY_LEN(priv->connections_cached_list)); #if NM_MORE_ASSERTS - /* set the pointer to a bogus value. This makes it more apparent - * if somebody has a reference to the cached list and still uses - * it. That is a bug, this code just tries to make it blow up - * more eagerly. */ - memset (priv->connections_cached_list, - 0x43, - sizeof (NMSettingsConnection *) * (priv->connections_len + 1)); + /* set the pointer to a bogus value. This makes it more apparent + * if somebody has a reference to the cached list and still uses + * it. That is a bug, this code just tries to make it blow up + * more eagerly. */ + memset(priv->connections_cached_list, + 0x43, + sizeof(NMSettingsConnection *) * (priv->connections_len + 1)); #endif - nm_clear_g_free (&priv->connections_cached_list); + nm_clear_g_free(&priv->connections_cached_list); } static void -impl_settings_list_connections (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *dbus_connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_list_connections(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * dbus_connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettings *self = NM_SETTINGS (obj); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - gs_free const char **strv = NULL; - - strv = nm_dbus_utils_get_paths_for_clist (&priv->connections_lst_head, - priv->connections_len, - G_STRUCT_OFFSET (NMSettingsConnection, _connections_lst), - TRUE); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(^ao)", strv)); + NMSettings * self = NM_SETTINGS(obj); + NMSettingsPrivate * priv = NM_SETTINGS_GET_PRIVATE(self); + gs_free const char **strv = NULL; + + strv = + nm_dbus_utils_get_paths_for_clist(&priv->connections_lst_head, + priv->connections_len, + G_STRUCT_OFFSET(NMSettingsConnection, _connections_lst), + TRUE); + g_dbus_method_invocation_return_value(invocation, g_variant_new("(^ao)", strv)); } NMSettingsConnection * -nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid) +nm_settings_get_connection_by_uuid(NMSettings *self, const char *uuid) { - g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); - g_return_val_if_fail (uuid != NULL, NULL); + g_return_val_if_fail(NM_IS_SETTINGS(self), NULL); + g_return_val_if_fail(uuid != NULL, NULL); - return _sett_conn_entry_get_conn (_sett_conn_entries_get (self, uuid)); + return _sett_conn_entry_get_conn(_sett_conn_entries_get(self, uuid)); } const char * -nm_settings_get_dbus_path_for_uuid (NMSettings *self, - const char *uuid) +nm_settings_get_dbus_path_for_uuid(NMSettings *self, const char *uuid) { - NMSettingsConnection *sett_conn; + NMSettingsConnection *sett_conn; - sett_conn = nm_settings_get_connection_by_uuid (self, uuid); + sett_conn = nm_settings_get_connection_by_uuid(self, uuid); - if (!sett_conn) - return NULL; + if (!sett_conn) + return NULL; - return nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn)); + return nm_dbus_object_get_path(NM_DBUS_OBJECT(sett_conn)); } static void -impl_settings_get_connection_by_uuid (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *dbus_connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_get_connection_by_uuid(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * dbus_connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettings *self = NM_SETTINGS (obj); - NMSettingsConnection *sett_conn; - gs_unref_object NMAuthSubject *subject = NULL; - GError *error = NULL; - const char *uuid; - - g_variant_get (parameters, "(&s)", &uuid); - - sett_conn = nm_settings_get_connection_by_uuid (self, uuid); - if (!sett_conn) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "No connection with the UUID was found."); - goto error; - } - - subject = nm_dbus_manager_new_auth_subject_from_context (invocation); - if (!subject) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - NM_UTILS_ERROR_MSG_REQ_UID_UKNOWN); - goto error; - } - - if (!nm_auth_is_subject_in_acl_set_error (nm_settings_connection_get_connection (sett_conn), - subject, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - &error)) - goto error; - - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn)))); - return; + NMSettings * self = NM_SETTINGS(obj); + NMSettingsConnection *sett_conn; + gs_unref_object NMAuthSubject *subject = NULL; + GError * error = NULL; + const char * uuid; + + g_variant_get(parameters, "(&s)", &uuid); + + sett_conn = nm_settings_get_connection_by_uuid(self, uuid); + if (!sett_conn) { + error = g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "No connection with the UUID was found."); + goto error; + } + + subject = nm_dbus_manager_new_auth_subject_from_context(invocation); + if (!subject) { + error = g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + NM_UTILS_ERROR_MSG_REQ_UID_UKNOWN); + goto error; + } + + if (!nm_auth_is_subject_in_acl_set_error(nm_settings_connection_get_connection(sett_conn), + subject, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + &error)) + goto error; + + g_dbus_method_invocation_return_value( + invocation, + g_variant_new("(o)", nm_dbus_object_get_path(NM_DBUS_OBJECT(sett_conn)))); + return; error: - g_dbus_method_invocation_take_error (invocation, error); + g_dbus_method_invocation_take_error(invocation, error); } /** @@ -2992,36 +3003,36 @@ error: * The returned list is cached internally, only valid until the next * NMSettings operation. */ -NMSettingsConnection *const* -nm_settings_get_connections (NMSettings *self, guint *out_len) +NMSettingsConnection *const * +nm_settings_get_connections(NMSettings *self, guint *out_len) { - NMSettingsPrivate *priv; - NMSettingsConnection **v; - NMSettingsConnection *con; - guint i; + NMSettingsPrivate * priv; + NMSettingsConnection **v; + NMSettingsConnection * con; + guint i; - g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS(self), NULL); - priv = NM_SETTINGS_GET_PRIVATE (self); + priv = NM_SETTINGS_GET_PRIVATE(self); - nm_assert (priv->connections_len == c_list_length (&priv->connections_lst_head)); + nm_assert(priv->connections_len == c_list_length(&priv->connections_lst_head)); - if (G_UNLIKELY (!priv->connections_cached_list)) { - v = g_new (NMSettingsConnection *, priv->connections_len + 1); + if (G_UNLIKELY(!priv->connections_cached_list)) { + v = g_new(NMSettingsConnection *, priv->connections_len + 1); - i = 0; - c_list_for_each_entry (con, &priv->connections_lst_head, _connections_lst) { - nm_assert (i < priv->connections_len); - v[i++] = con; - } - nm_assert (i == priv->connections_len); - v[i] = NULL; + i = 0; + c_list_for_each_entry (con, &priv->connections_lst_head, _connections_lst) { + nm_assert(i < priv->connections_len); + v[i++] = con; + } + nm_assert(i == priv->connections_len); + v[i] = NULL; - priv->connections_cached_list = v; - } + priv->connections_cached_list = v; + } - NM_SET_OUT (out_len, priv->connections_len); - return priv->connections_cached_list; + NM_SET_OUT(out_len, priv->connections_len); + return priv->connections_cached_list; } /** @@ -3042,1139 +3053,1100 @@ nm_settings_get_connections (NMSettings *self, guint *out_len) * the contained values do not need to be unrefed. */ NMSettingsConnection ** -nm_settings_get_connections_clone (NMSettings *self, - guint *out_len, - NMSettingsConnectionFilterFunc func, - gpointer func_data, - GCompareDataFunc sort_compare_func, - gpointer sort_data) +nm_settings_get_connections_clone(NMSettings * self, + guint * out_len, + NMSettingsConnectionFilterFunc func, + gpointer func_data, + GCompareDataFunc sort_compare_func, + gpointer sort_data) { - NMSettingsConnection *const*list_cached; - NMSettingsConnection **list; - guint len, i, j; + NMSettingsConnection *const *list_cached; + NMSettingsConnection ** list; + guint len, i, j; - g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); + g_return_val_if_fail(NM_IS_SETTINGS(self), NULL); - list_cached = nm_settings_get_connections (self, &len); + list_cached = nm_settings_get_connections(self, &len); #if NM_MORE_ASSERTS - nm_assert (list_cached); - for (i = 0; i < len; i++) - nm_assert (NM_IS_SETTINGS_CONNECTION (list_cached[i])); - nm_assert (!list_cached[i]); + nm_assert(list_cached); + for (i = 0; i < len; i++) + nm_assert(NM_IS_SETTINGS_CONNECTION(list_cached[i])); + nm_assert(!list_cached[i]); #endif - list = g_new (NMSettingsConnection *, ((gsize) len + 1)); - if (func) { - for (i = 0, j = 0; i < len; i++) { - if (func (self, list_cached[i], func_data)) - list[j++] = list_cached[i]; - } - list[j] = NULL; - len = j; - } else - memcpy (list, list_cached, sizeof (list[0]) * ((gsize) len + 1)); - - if ( len > 1 - && sort_compare_func) { - g_qsort_with_data (list, len, sizeof (NMSettingsConnection *), - sort_compare_func, sort_data); - } - NM_SET_OUT (out_len, len); - return list; + list = g_new(NMSettingsConnection *, ((gsize) len + 1)); + if (func) { + for (i = 0, j = 0; i < len; i++) { + if (func(self, list_cached[i], func_data)) + list[j++] = list_cached[i]; + } + list[j] = NULL; + len = j; + } else + memcpy(list, list_cached, sizeof(list[0]) * ((gsize) len + 1)); + + if (len > 1 && sort_compare_func) { + g_qsort_with_data(list, len, sizeof(NMSettingsConnection *), sort_compare_func, sort_data); + } + NM_SET_OUT(out_len, len); + return list; } NMSettingsConnection * -nm_settings_get_connection_by_path (NMSettings *self, const char *path) +nm_settings_get_connection_by_path(NMSettings *self, const char *path) { - NMSettingsPrivate *priv; - NMSettingsConnection *connection; + NMSettingsPrivate * priv; + NMSettingsConnection *connection; - g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); - g_return_val_if_fail (path, NULL); + g_return_val_if_fail(NM_IS_SETTINGS(self), NULL); + g_return_val_if_fail(path, NULL); - priv = NM_SETTINGS_GET_PRIVATE (self); + priv = NM_SETTINGS_GET_PRIVATE(self); - connection = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), - path); - if ( !connection - || !NM_IS_SETTINGS_CONNECTION (connection)) - return NULL; + connection = + nm_dbus_manager_lookup_object(nm_dbus_object_get_manager(NM_DBUS_OBJECT(self)), path); + if (!connection || !NM_IS_SETTINGS_CONNECTION(connection)) + return NULL; - nm_assert (c_list_contains (&priv->connections_lst_head, &connection->_connections_lst)); - return connection; + nm_assert(c_list_contains(&priv->connections_lst_head, &connection->_connections_lst)); + return connection; } gboolean -nm_settings_has_connection (NMSettings *self, NMSettingsConnection *connection) +nm_settings_has_connection(NMSettings *self, NMSettingsConnection *connection) { - gboolean has; + gboolean has; - g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS(self), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(connection), FALSE); - has = !c_list_is_empty (&connection->_connections_lst); + has = !c_list_is_empty(&connection->_connections_lst); - nm_assert (has == nm_c_list_contains_entry (&NM_SETTINGS_GET_PRIVATE (self)->connections_lst_head, - connection, - _connections_lst)); - nm_assert (({ - NMSettingsConnection *candidate = NULL; - const char *path; + nm_assert(has + == nm_c_list_contains_entry(&NM_SETTINGS_GET_PRIVATE(self)->connections_lst_head, + connection, + _connections_lst)); + nm_assert(({ + NMSettingsConnection *candidate = NULL; + const char * path; - path = nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)); - if (path) - candidate = nm_settings_get_connection_by_path (self, path); + path = nm_dbus_object_get_path(NM_DBUS_OBJECT(connection)); + if (path) + candidate = nm_settings_get_connection_by_path(self, path); - (has == (connection == candidate)); - })); + (has == (connection == candidate)); + })); - return has; + return has; } /*****************************************************************************/ static void -add_plugin (NMSettings *self, - NMSettingsPlugin *plugin, - const char *pname, - const char *path) +add_plugin(NMSettings *self, NMSettingsPlugin *plugin, const char *pname, const char *path) { - NMSettingsPrivate *priv; + NMSettingsPrivate *priv; - nm_assert (NM_IS_SETTINGS (self)); - nm_assert (NM_IS_SETTINGS_PLUGIN (plugin)); + nm_assert(NM_IS_SETTINGS(self)); + nm_assert(NM_IS_SETTINGS_PLUGIN(plugin)); - nm_assert (pname); - nm_assert (nm_streq0 (pname, nm_settings_plugin_get_plugin_name (plugin))); + nm_assert(pname); + nm_assert(nm_streq0(pname, nm_settings_plugin_get_plugin_name(plugin))); - priv = NM_SETTINGS_GET_PRIVATE (self); + priv = NM_SETTINGS_GET_PRIVATE(self); - nm_assert (!g_slist_find (priv->plugins, plugin)); + nm_assert(!g_slist_find(priv->plugins, plugin)); - priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin)); + priv->plugins = g_slist_append(priv->plugins, g_object_ref(plugin)); - nm_shutdown_wait_obj_register_object_full (plugin, - g_strdup_printf ("%s-settings-plugin", pname), - TRUE); + nm_shutdown_wait_obj_register_object_full(plugin, + g_strdup_printf("%s-settings-plugin", pname), + TRUE); - _LOGI ("Loaded settings plugin: %s (%s%s%s)", - pname, - NM_PRINT_FMT_QUOTED (path, "\"", path, "\"", "internal")); + _LOGI("Loaded settings plugin: %s (%s%s%s)", + pname, + NM_PRINT_FMT_QUOTED(path, "\"", path, "\"", "internal")); } static gboolean -add_plugin_load_file (NMSettings *self, const char *pname, GError **error) +add_plugin_load_file(NMSettings *self, const char *pname, GError **error) { - gs_free char *full_name = NULL; - gs_free char *path = NULL; - gs_unref_object NMSettingsPlugin *plugin = NULL; - GModule *module; - NMSettingsPluginFactoryFunc factory_func; - struct stat st; - int errsv; - - full_name = g_strdup_printf ("nm-settings-plugin-%s", pname); - path = g_module_build_path (NMPLUGINDIR, full_name); - - if (stat (path, &st) != 0) { - errsv = errno; - _LOGW ("could not load plugin '%s' from file '%s': %s", pname, path, nm_strerror_native (errsv)); - return TRUE; - } - if (!S_ISREG (st.st_mode)) { - _LOGW ("could not load plugin '%s' from file '%s': not a file", pname, path); - return TRUE; - } - if (st.st_uid != 0) { - _LOGW ("could not load plugin '%s' from file '%s': file must be owned by root", pname, path); - return TRUE; - } - if (st.st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) { - _LOGW ("could not load plugin '%s' from file '%s': invalid file permissions", pname, path); - return TRUE; - } - - module = g_module_open (path, G_MODULE_BIND_LOCAL); - if (!module) { - _LOGW ("could not load plugin '%s' from file '%s': %s", - pname, path, g_module_error ()); - return TRUE; - } - - /* errors after this point are fatal, because we loaded the shared library already. */ - - if (!g_module_symbol (module, "nm_settings_plugin_factory", (gpointer) (&factory_func))) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Could not find plugin '%s' factory function.", - pname); - g_module_close (module); - return FALSE; - } - - /* after accessing the plugin we cannot unload it anymore, because the glib - * types cannot be properly unregistered. */ - g_module_make_resident (module); - - plugin = (*factory_func) (); - if (!NM_IS_SETTINGS_PLUGIN (plugin)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "plugin '%s' returned invalid settings plugin", - pname); - return FALSE; - } - - add_plugin (self, NM_SETTINGS_PLUGIN (plugin), pname, path); - return TRUE; + gs_free char * full_name = NULL; + gs_free char * path = NULL; + gs_unref_object NMSettingsPlugin *plugin = NULL; + GModule * module; + NMSettingsPluginFactoryFunc factory_func; + struct stat st; + int errsv; + + full_name = g_strdup_printf("nm-settings-plugin-%s", pname); + path = g_module_build_path(NMPLUGINDIR, full_name); + + if (stat(path, &st) != 0) { + errsv = errno; + _LOGW("could not load plugin '%s' from file '%s': %s", + pname, + path, + nm_strerror_native(errsv)); + return TRUE; + } + if (!S_ISREG(st.st_mode)) { + _LOGW("could not load plugin '%s' from file '%s': not a file", pname, path); + return TRUE; + } + if (st.st_uid != 0) { + _LOGW("could not load plugin '%s' from file '%s': file must be owned by root", pname, path); + return TRUE; + } + if (st.st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) { + _LOGW("could not load plugin '%s' from file '%s': invalid file permissions", pname, path); + return TRUE; + } + + module = g_module_open(path, G_MODULE_BIND_LOCAL); + if (!module) { + _LOGW("could not load plugin '%s' from file '%s': %s", pname, path, g_module_error()); + return TRUE; + } + + /* errors after this point are fatal, because we loaded the shared library already. */ + + if (!g_module_symbol(module, "nm_settings_plugin_factory", (gpointer)(&factory_func))) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Could not find plugin '%s' factory function.", + pname); + g_module_close(module); + return FALSE; + } + + /* after accessing the plugin we cannot unload it anymore, because the glib + * types cannot be properly unregistered. */ + g_module_make_resident(module); + + plugin = (*factory_func)(); + if (!NM_IS_SETTINGS_PLUGIN(plugin)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "plugin '%s' returned invalid settings plugin", + pname); + return FALSE; + } + + add_plugin(self, NM_SETTINGS_PLUGIN(plugin), pname, path); + return TRUE; } static void -add_plugin_keyfile (NMSettings *self) +add_plugin_keyfile(NMSettings *self) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); - if (priv->keyfile_plugin) - return; - priv->keyfile_plugin = nms_keyfile_plugin_new (); - add_plugin (self, NM_SETTINGS_PLUGIN (priv->keyfile_plugin), "keyfile", NULL); + if (priv->keyfile_plugin) + return; + priv->keyfile_plugin = nms_keyfile_plugin_new(); + add_plugin(self, NM_SETTINGS_PLUGIN(priv->keyfile_plugin), "keyfile", NULL); } static gboolean -load_plugins (NMSettings *self, const char *const*plugins, GError **error) +load_plugins(NMSettings *self, const char *const *plugins, GError **error) { - const char *const*iter; - gboolean success = TRUE; - - for (iter = plugins; iter && *iter; iter++) { - const char *pname = *iter; - - if (!*pname || strchr (pname, '/')) { - _LOGW ("ignore invalid plugin \"%s\"", pname); - continue; - } - - if (NM_IN_STRSET (pname, "ifcfg-suse", "ifnet", "ibft", "no-ibft")) { - _LOGW ("skipping deprecated plugin %s", pname); - continue; - } - - /* keyfile plugin is built-in now */ - if (nm_streq (pname, "keyfile")) { - add_plugin_keyfile (self); - continue; - } - - if (nm_utils_strv_find_first ((char **) plugins, - iter - plugins, - pname) >= 0) { - /* the plugin is already mentioned in the list previously. - * Don't load a duplicate. */ - continue; - } - - success = add_plugin_load_file (self, pname, error); - if (!success) - break; - } - - /* If keyfile plugin was not among configured plugins, add it as the last one */ - if (success) - add_plugin_keyfile (self); - - return success; + const char *const *iter; + gboolean success = TRUE; + + for (iter = plugins; iter && *iter; iter++) { + const char *pname = *iter; + + if (!*pname || strchr(pname, '/')) { + _LOGW("ignore invalid plugin \"%s\"", pname); + continue; + } + + if (NM_IN_STRSET(pname, "ifcfg-suse", "ifnet", "ibft", "no-ibft")) { + _LOGW("skipping deprecated plugin %s", pname); + continue; + } + + /* keyfile plugin is built-in now */ + if (nm_streq(pname, "keyfile")) { + add_plugin_keyfile(self); + continue; + } + + if (nm_utils_strv_find_first((char **) plugins, iter - plugins, pname) >= 0) { + /* the plugin is already mentioned in the list previously. + * Don't load a duplicate. */ + continue; + } + + success = add_plugin_load_file(self, pname, error); + if (!success) + break; + } + + /* If keyfile plugin was not among configured plugins, add it as the last one */ + if (success) + add_plugin_keyfile(self); + + return success; } /*****************************************************************************/ static void -pk_hostname_cb (NMAuthChain *chain, - GDBusMethodInvocation *context, - gpointer user_data) +pk_hostname_cb(NMAuthChain *chain, GDBusMethodInvocation *context, gpointer user_data) { - NMSettings *self = NM_SETTINGS (user_data); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - NMAuthCallResult result; - GError *error = NULL; - const char *hostname; - - nm_assert (G_IS_DBUS_METHOD_INVOCATION (context)); - - c_list_unlink (nm_auth_chain_parent_lst_list (chain)); - - result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME); - hostname = nm_auth_chain_get_data (chain, "hostname"); - - /* If our NMSettingsConnection is already gone, do nothing */ - if (result != NM_AUTH_CALL_RESULT_YES) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - NM_UTILS_ERROR_MSG_INSUFF_PRIV); - } else { - if (!nm_hostname_manager_write_hostname (priv->hostname_manager, hostname)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_FAILED, - "Saving the hostname failed."); - } - } - - nm_audit_log_control_op (NM_AUDIT_OP_HOSTNAME_SAVE, - hostname, - !error, - nm_auth_chain_get_subject (chain), - error ? error->message : NULL); - - if (error) - g_dbus_method_invocation_take_error (context, error); - else - g_dbus_method_invocation_return_value (context, NULL); + NMSettings * self = NM_SETTINGS(user_data); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + NMAuthCallResult result; + GError * error = NULL; + const char * hostname; + + nm_assert(G_IS_DBUS_METHOD_INVOCATION(context)); + + c_list_unlink(nm_auth_chain_parent_lst_list(chain)); + + result = nm_auth_chain_get_result(chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME); + hostname = nm_auth_chain_get_data(chain, "hostname"); + + /* If our NMSettingsConnection is already gone, do nothing */ + if (result != NM_AUTH_CALL_RESULT_YES) { + error = g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + NM_UTILS_ERROR_MSG_INSUFF_PRIV); + } else { + if (!nm_hostname_manager_write_hostname(priv->hostname_manager, hostname)) { + error = g_error_new_literal(NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Saving the hostname failed."); + } + } + + nm_audit_log_control_op(NM_AUDIT_OP_HOSTNAME_SAVE, + hostname, + !error, + nm_auth_chain_get_subject(chain), + error ? error->message : NULL); + + if (error) + g_dbus_method_invocation_take_error(context, error); + else + g_dbus_method_invocation_return_value(context, NULL); } static void -impl_settings_save_hostname (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_save_hostname(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMSettings *self = NM_SETTINGS (obj); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - NMAuthChain *chain; - const char *hostname; - const char *error_reason; - int error_code; - - g_variant_get (parameters, "(&s)", &hostname); - - /* Minimal validation of the hostname */ - if (!nm_hostname_manager_validate_hostname (hostname)) { - error_code = NM_SETTINGS_ERROR_INVALID_HOSTNAME; - error_reason = "The hostname was too long or contained invalid characters"; - goto err; - } - - chain = nm_auth_chain_new_context (invocation, pk_hostname_cb, self); - if (!chain) { - error_code = NM_SETTINGS_ERROR_PERMISSION_DENIED; - error_reason = NM_UTILS_ERROR_MSG_REQ_AUTH_FAILED; - goto err; - } - - c_list_link_tail (&priv->auth_lst_head, nm_auth_chain_parent_lst_list (chain)); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, TRUE); - nm_auth_chain_set_data (chain, "hostname", g_strdup (hostname), g_free); - return; + NMSettings * self = NM_SETTINGS(obj); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + NMAuthChain * chain; + const char * hostname; + const char * error_reason; + int error_code; + + g_variant_get(parameters, "(&s)", &hostname); + + /* Minimal validation of the hostname */ + if (!nm_hostname_manager_validate_hostname(hostname)) { + error_code = NM_SETTINGS_ERROR_INVALID_HOSTNAME; + error_reason = "The hostname was too long or contained invalid characters"; + goto err; + } + + chain = nm_auth_chain_new_context(invocation, pk_hostname_cb, self); + if (!chain) { + error_code = NM_SETTINGS_ERROR_PERMISSION_DENIED; + error_reason = NM_UTILS_ERROR_MSG_REQ_AUTH_FAILED; + goto err; + } + + c_list_link_tail(&priv->auth_lst_head, nm_auth_chain_parent_lst_list(chain)); + nm_auth_chain_add_call(chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, TRUE); + nm_auth_chain_set_data(chain, "hostname", g_strdup(hostname), g_free); + return; err: - nm_audit_log_control_op (NM_AUDIT_OP_HOSTNAME_SAVE, - hostname, - FALSE, - invocation, - error_reason); - g_dbus_method_invocation_return_error_literal (invocation, - NM_SETTINGS_ERROR, - error_code, - error_reason); + nm_audit_log_control_op(NM_AUDIT_OP_HOSTNAME_SAVE, hostname, FALSE, invocation, error_reason); + g_dbus_method_invocation_return_error_literal(invocation, + NM_SETTINGS_ERROR, + error_code, + error_reason); } /*****************************************************************************/ static void -_hostname_changed_cb (NMHostnameManager *hostname_manager, - GParamSpec *pspec, - gpointer user_data) +_hostname_changed_cb(NMHostnameManager *hostname_manager, GParamSpec *pspec, gpointer user_data) { - _notify (user_data, PROP_HOSTNAME); + _notify(user_data, PROP_HOSTNAME); } /*****************************************************************************/ static gboolean -have_connection_for_device (NMSettings *self, NMDevice *device) +have_connection_for_device(NMSettings *self, NMDevice *device) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - NMSettingsConnection *sett_conn; + NMSettingsPrivate * priv = NM_SETTINGS_GET_PRIVATE(self); + NMSettingsConnection *sett_conn; - g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS(self), FALSE); - /* Find a wired connection matching for the device, if any */ - c_list_for_each_entry (sett_conn, &priv->connections_lst_head, _connections_lst) { - NMConnection *connection = nm_settings_connection_get_connection (sett_conn); + /* Find a wired connection matching for the device, if any */ + c_list_for_each_entry (sett_conn, &priv->connections_lst_head, _connections_lst) { + NMConnection *connection = nm_settings_connection_get_connection(sett_conn); - if (!nm_device_check_connection_compatible (device, connection, NULL)) - continue; + if (!nm_device_check_connection_compatible(device, connection, NULL)) + continue; - if (nm_settings_connection_default_wired_get_device (sett_conn)) - continue; + if (nm_settings_connection_default_wired_get_device(sett_conn)) + continue; - if (NM_FLAGS_ANY (nm_settings_connection_get_flags (sett_conn), - NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE - | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) - continue; + if (NM_FLAGS_ANY(nm_settings_connection_get_flags(sett_conn), + NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE + | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)) + continue; - return TRUE; - } + return TRUE; + } - /* See if there's a known non-NetworkManager configuration for the device */ - if (nm_device_spec_match_list (device, priv->unrecognized_specs)) - return TRUE; + /* See if there's a known non-NetworkManager configuration for the device */ + if (nm_device_spec_match_list(device, priv->unrecognized_specs)) + return TRUE; - return FALSE; + return FALSE; } static void -default_wired_clear_tag (NMSettings *self, - NMDevice *device, - NMSettingsConnection *sett_conn, - gboolean add_to_no_auto_default) +default_wired_clear_tag(NMSettings * self, + NMDevice * device, + NMSettingsConnection *sett_conn, + gboolean add_to_no_auto_default) { - nm_assert (NM_IS_SETTINGS (self)); - nm_assert (NM_IS_DEVICE (device)); - nm_assert (NM_IS_SETTINGS_CONNECTION (sett_conn)); - nm_assert (device == nm_settings_connection_default_wired_get_device (sett_conn)); - nm_assert (sett_conn == g_object_get_qdata (G_OBJECT (device), _default_wired_connection_quark ())); + nm_assert(NM_IS_SETTINGS(self)); + nm_assert(NM_IS_DEVICE(device)); + nm_assert(NM_IS_SETTINGS_CONNECTION(sett_conn)); + nm_assert(device == nm_settings_connection_default_wired_get_device(sett_conn)); + nm_assert(sett_conn == g_object_get_qdata(G_OBJECT(device), _default_wired_connection_quark())); - _LOGT ("auto-default: forget association between %s (%s) and device %s (%s)", - nm_settings_connection_get_uuid (sett_conn), - nm_settings_connection_get_id (sett_conn), - nm_device_get_iface (device), - add_to_no_auto_default ? "persisted" : "temporary"); + _LOGT("auto-default: forget association between %s (%s) and device %s (%s)", + nm_settings_connection_get_uuid(sett_conn), + nm_settings_connection_get_id(sett_conn), + nm_device_get_iface(device), + add_to_no_auto_default ? "persisted" : "temporary"); - nm_settings_connection_default_wired_set_device (sett_conn, NULL); + nm_settings_connection_default_wired_set_device(sett_conn, NULL); - g_object_set_qdata (G_OBJECT (device), _default_wired_connection_quark (), NULL); + g_object_set_qdata(G_OBJECT(device), _default_wired_connection_quark(), NULL); - if (add_to_no_auto_default) - nm_config_set_no_auto_default_for_device (NM_SETTINGS_GET_PRIVATE (self)->config, device); + if (add_to_no_auto_default) + nm_config_set_no_auto_default_for_device(NM_SETTINGS_GET_PRIVATE(self)->config, device); } static void -device_realized (NMDevice *device, GParamSpec *pspec, NMSettings *self) +device_realized(NMDevice *device, GParamSpec *pspec, NMSettings *self) { - gs_unref_object NMConnection *connection = NULL; - NMSettingsPrivate *priv; - NMSettingsConnection *added; - GError *error = NULL; - - if (!nm_device_is_real (device)) - return; - - g_signal_handlers_disconnect_by_func (device, - G_CALLBACK (device_realized), - self); - - priv = NM_SETTINGS_GET_PRIVATE (self); - - /* If the device isn't managed or it already has a default wired connection, - * ignore it. - */ - if ( !NM_DEVICE_GET_CLASS (device)->new_default_connection - || !nm_device_get_managed (device, FALSE) - || g_object_get_qdata (G_OBJECT (device), _default_wired_connection_blocked_quark ())) - return; - - /* we only check once whether to create the auto-default connection. If we reach this point, - * we mark the creation of the default-wired-connection as blocked. */ - g_object_set_qdata (G_OBJECT (device), _default_wired_connection_blocked_quark (), device); - - if (nm_config_get_no_auto_default_for_device (priv->config, device)) { - _LOGT ("auto-default: cannot create auto-default connection for device %s: disabled by \"no-auto-default\"", - nm_device_get_iface (device)); - return; - } - - if (have_connection_for_device (self, device)) { - _LOGT ("auto-default: cannot create auto-default connection for device %s: already has a profile", - nm_device_get_iface (device)); - return; - } - - connection = nm_device_new_default_connection (device); - if (!connection) { - _LOGT ("auto-default: cannot create auto-default connection for device %s", - nm_device_get_iface (device)); - return; - } - - _LOGT ("auto-default: creating in-memory connection %s (%s) for device %s", - nm_connection_get_uuid (connection), - nm_connection_get_id (connection), - nm_device_get_iface (device)); - - nm_settings_add_connection (self, - connection, - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, - NM_SETTINGS_CONNECTION_ADD_REASON_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, - &added, - &error); - if (!added) { - if (!g_error_matches (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_UUID_EXISTS)) { - _LOGW ("(%s) couldn't create default wired connection: %s", - nm_device_get_iface (device), - error->message); - } - g_clear_error (&error); - return; - } - - nm_settings_connection_default_wired_set_device (added, device); - - g_object_set_qdata (G_OBJECT (device), _default_wired_connection_quark (), added); - - _LOGI ("(%s): created default wired connection '%s'", - nm_device_get_iface (device), - nm_settings_connection_get_id (added)); + gs_unref_object NMConnection *connection = NULL; + NMSettingsPrivate * priv; + NMSettingsConnection * added; + GError * error = NULL; + + if (!nm_device_is_real(device)) + return; + + g_signal_handlers_disconnect_by_func(device, G_CALLBACK(device_realized), self); + + priv = NM_SETTINGS_GET_PRIVATE(self); + + /* If the device isn't managed or it already has a default wired connection, + * ignore it. + */ + if (!NM_DEVICE_GET_CLASS(device)->new_default_connection + || !nm_device_get_managed(device, FALSE) + || g_object_get_qdata(G_OBJECT(device), _default_wired_connection_blocked_quark())) + return; + + /* we only check once whether to create the auto-default connection. If we reach this point, + * we mark the creation of the default-wired-connection as blocked. */ + g_object_set_qdata(G_OBJECT(device), _default_wired_connection_blocked_quark(), device); + + if (nm_config_get_no_auto_default_for_device(priv->config, device)) { + _LOGT("auto-default: cannot create auto-default connection for device %s: disabled by " + "\"no-auto-default\"", + nm_device_get_iface(device)); + return; + } + + if (have_connection_for_device(self, device)) { + _LOGT("auto-default: cannot create auto-default connection for device %s: already has a " + "profile", + nm_device_get_iface(device)); + return; + } + + connection = nm_device_new_default_connection(device); + if (!connection) { + _LOGT("auto-default: cannot create auto-default connection for device %s", + nm_device_get_iface(device)); + return; + } + + _LOGT("auto-default: creating in-memory connection %s (%s) for device %s", + nm_connection_get_uuid(connection), + nm_connection_get_id(connection), + nm_device_get_iface(device)); + + nm_settings_add_connection(self, + connection, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, + NM_SETTINGS_CONNECTION_ADD_REASON_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, + &added, + &error); + if (!added) { + if (!g_error_matches(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_UUID_EXISTS)) { + _LOGW("(%s) couldn't create default wired connection: %s", + nm_device_get_iface(device), + error->message); + } + g_clear_error(&error); + return; + } + + nm_settings_connection_default_wired_set_device(added, device); + + g_object_set_qdata(G_OBJECT(device), _default_wired_connection_quark(), added); + + _LOGI("(%s): created default wired connection '%s'", + nm_device_get_iface(device), + nm_settings_connection_get_id(added)); } void -nm_settings_device_added (NMSettings *self, NMDevice *device) +nm_settings_device_added(NMSettings *self, NMDevice *device) { - if (nm_device_is_real (device)) - device_realized (device, NULL, self); - else { - /* FIXME(shutdown): we need to disconnect this signal handler during - * shutdown. */ - g_signal_connect_after (device, "notify::" NM_DEVICE_REAL, - G_CALLBACK (device_realized), - self); - } + if (nm_device_is_real(device)) + device_realized(device, NULL, self); + else { + /* FIXME(shutdown): we need to disconnect this signal handler during + * shutdown. */ + g_signal_connect_after(device, + "notify::" NM_DEVICE_REAL, + G_CALLBACK(device_realized), + self); + } } void -nm_settings_device_removed (NMSettings *self, NMDevice *device, gboolean quitting) +nm_settings_device_removed(NMSettings *self, NMDevice *device, gboolean quitting) { - NMSettingsConnection *connection; - - g_signal_handlers_disconnect_by_func (device, - G_CALLBACK (device_realized), - self); - - connection = g_object_get_qdata (G_OBJECT (device), _default_wired_connection_quark ()); - if (connection) { - default_wired_clear_tag (self, device, connection, FALSE); - - /* Don't delete the default wired connection on shutdown, so that it - * remains up and can be assumed if NM starts again. - */ - if (quitting == FALSE) - nm_settings_connection_delete (connection, TRUE); - } + NMSettingsConnection *connection; + + g_signal_handlers_disconnect_by_func(device, G_CALLBACK(device_realized), self); + + connection = g_object_get_qdata(G_OBJECT(device), _default_wired_connection_quark()); + if (connection) { + default_wired_clear_tag(self, device, connection, FALSE); + + /* Don't delete the default wired connection on shutdown, so that it + * remains up and can be assumed if NM starts again. + */ + if (quitting == FALSE) + nm_settings_connection_delete(connection, TRUE); + } } /*****************************************************************************/ static void -session_monitor_changed_cb (NMSessionMonitor *session_monitor, - NMSettings *self) +session_monitor_changed_cb(NMSessionMonitor *session_monitor, NMSettings *self) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - NMSettingsConnection *const*list; - guint i, len; - guint generation; + NMSettingsPrivate * priv = NM_SETTINGS_GET_PRIVATE(self); + NMSettingsConnection *const *list; + guint i, len; + guint generation; again: - list = nm_settings_get_connections (self, &len); - generation = priv->connections_generation; - for (i = 0; i < len; i++) { - gboolean is_visible; - - is_visible = nm_settings_connection_check_visibility (list[i], - session_monitor); - nm_settings_connection_set_flags (list[i], - NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE, - is_visible); - if (generation != priv->connections_generation) { - /* the cached list was invalidated. Start again. - * - * Note that nm_settings_connection_recheck_visibility() will do nothing - * if the visibility didn't change (including emitting no signals, - * and not invalidating the list). - * - * Hence, for this to be an endless loop, the settings would have - * to constantly change the visibility flag and also invalidate the list. */ - goto again; - } - } + list = nm_settings_get_connections(self, &len); + generation = priv->connections_generation; + for (i = 0; i < len; i++) { + gboolean is_visible; + + is_visible = nm_settings_connection_check_visibility(list[i], session_monitor); + nm_settings_connection_set_flags(list[i], + NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE, + is_visible); + if (generation != priv->connections_generation) { + /* the cached list was invalidated. Start again. + * + * Note that nm_settings_connection_recheck_visibility() will do nothing + * if the visibility didn't change (including emitting no signals, + * and not invalidating the list). + * + * Hence, for this to be an endless loop, the settings would have + * to constantly change the visibility flag and also invalidate the list. */ + goto again; + } + } } /*****************************************************************************/ -G_GNUC_PRINTF (4, 5) +G_GNUC_PRINTF(4, 5) static void -_kf_db_log_fcn (NMKeyFileDB *kf_db, - int syslog_level, - gpointer user_data, - const char *fmt, - ...) +_kf_db_log_fcn(NMKeyFileDB *kf_db, int syslog_level, gpointer user_data, const char *fmt, ...) { - NMSettings *self = user_data; - NMLogLevel level = nm_log_level_from_syslog (syslog_level); - - if (_NMLOG_ENABLED (level)) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - gs_free char *msg = NULL; - va_list ap; - const char *prefix; - - va_start (ap, fmt); - msg = g_strdup_vprintf (fmt, ap); - va_end (ap); - - if (priv->kf_db_timestamps == kf_db) - prefix = "timestamps"; - else if (priv->kf_db_seen_bssids == kf_db) - prefix = "seen-bssids"; - else { - nm_assert_not_reached (); - prefix = "???"; - } - - _NMLOG (level, "[%s-keyfile]: %s", prefix, msg); - } + NMSettings *self = user_data; + NMLogLevel level = nm_log_level_from_syslog(syslog_level); + + if (_NMLOG_ENABLED(level)) { + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + gs_free char * msg = NULL; + va_list ap; + const char * prefix; + + va_start(ap, fmt); + msg = g_strdup_vprintf(fmt, ap); + va_end(ap); + + if (priv->kf_db_timestamps == kf_db) + prefix = "timestamps"; + else if (priv->kf_db_seen_bssids == kf_db) + prefix = "seen-bssids"; + else { + nm_assert_not_reached(); + prefix = "???"; + } + + _NMLOG(level, "[%s-keyfile]: %s", prefix, msg); + } } static gboolean -_kf_db_got_dirty_flush (NMSettings *self, - gboolean is_timestamps) +_kf_db_got_dirty_flush(NMSettings *self, gboolean is_timestamps) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - const char *prefix; - NMKeyFileDB *kf_db; - - if (is_timestamps) { - prefix = "timestamps"; - kf_db = priv->kf_db_timestamps; - priv->kf_db_flush_idle_id_timestamps = 0; - } else { - prefix = "seen-bssids"; - kf_db = priv->kf_db_seen_bssids; - priv->kf_db_flush_idle_id_seen_bssids = 0; - } - - if (nm_key_file_db_is_dirty (kf_db)) - nm_key_file_db_to_file (kf_db, FALSE); - else { - _LOGT ("[%s-keyfile]: skip saving changes to \"%s\"", - prefix, - nm_key_file_db_get_filename (kf_db)); - } - - return G_SOURCE_REMOVE; + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + const char * prefix; + NMKeyFileDB * kf_db; + + if (is_timestamps) { + prefix = "timestamps"; + kf_db = priv->kf_db_timestamps; + priv->kf_db_flush_idle_id_timestamps = 0; + } else { + prefix = "seen-bssids"; + kf_db = priv->kf_db_seen_bssids; + priv->kf_db_flush_idle_id_seen_bssids = 0; + } + + if (nm_key_file_db_is_dirty(kf_db)) + nm_key_file_db_to_file(kf_db, FALSE); + else { + _LOGT("[%s-keyfile]: skip saving changes to \"%s\"", + prefix, + nm_key_file_db_get_filename(kf_db)); + } + + return G_SOURCE_REMOVE; } static gboolean -_kf_db_got_dirty_flush_timestamps_cb (gpointer user_data) +_kf_db_got_dirty_flush_timestamps_cb(gpointer user_data) { - return _kf_db_got_dirty_flush (user_data, - TRUE); + return _kf_db_got_dirty_flush(user_data, TRUE); } static gboolean -_kf_db_got_dirty_flush_seen_bssids_cb (gpointer user_data) +_kf_db_got_dirty_flush_seen_bssids_cb(gpointer user_data) { - return _kf_db_got_dirty_flush (user_data, - FALSE); + return _kf_db_got_dirty_flush(user_data, FALSE); } static void -_kf_db_got_dirty_fcn (NMKeyFileDB *kf_db, - gpointer user_data) +_kf_db_got_dirty_fcn(NMKeyFileDB *kf_db, gpointer user_data) { - NMSettings *self = user_data; - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GSourceFunc idle_func; - guint *p_id; - const char *prefix; - - if (priv->kf_db_timestamps == kf_db) { - prefix = "timestamps"; - p_id = &priv->kf_db_flush_idle_id_timestamps; - idle_func = _kf_db_got_dirty_flush_timestamps_cb; - } else if (priv->kf_db_seen_bssids == kf_db) { - prefix = "seen-bssids"; - p_id = &priv->kf_db_flush_idle_id_seen_bssids; - idle_func = _kf_db_got_dirty_flush_seen_bssids_cb; - } else { - nm_assert_not_reached (); - return; - } - - if (*p_id != 0) - return; - _LOGT ("[%s-keyfile]: schedule flushing changes to disk", prefix); - *p_id = g_idle_add_full (G_PRIORITY_LOW, idle_func, self, NULL); + NMSettings * self = user_data; + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + GSourceFunc idle_func; + guint * p_id; + const char * prefix; + + if (priv->kf_db_timestamps == kf_db) { + prefix = "timestamps"; + p_id = &priv->kf_db_flush_idle_id_timestamps; + idle_func = _kf_db_got_dirty_flush_timestamps_cb; + } else if (priv->kf_db_seen_bssids == kf_db) { + prefix = "seen-bssids"; + p_id = &priv->kf_db_flush_idle_id_seen_bssids; + idle_func = _kf_db_got_dirty_flush_seen_bssids_cb; + } else { + nm_assert_not_reached(); + return; + } + + if (*p_id != 0) + return; + _LOGT("[%s-keyfile]: schedule flushing changes to disk", prefix); + *p_id = g_idle_add_full(G_PRIORITY_LOW, idle_func, self, NULL); } void -nm_settings_kf_db_write (NMSettings *self) +nm_settings_kf_db_write(NMSettings *self) { - NMSettingsPrivate *priv; + NMSettingsPrivate *priv; - g_return_if_fail (NM_IS_SETTINGS (self)); + g_return_if_fail(NM_IS_SETTINGS(self)); - priv = NM_SETTINGS_GET_PRIVATE (self); - if (priv->kf_db_timestamps) - nm_key_file_db_to_file (priv->kf_db_timestamps, TRUE); - if (priv->kf_db_seen_bssids) - nm_key_file_db_to_file (priv->kf_db_seen_bssids, TRUE); + priv = NM_SETTINGS_GET_PRIVATE(self); + if (priv->kf_db_timestamps) + nm_key_file_db_to_file(priv->kf_db_timestamps, TRUE); + if (priv->kf_db_seen_bssids) + nm_key_file_db_to_file(priv->kf_db_seen_bssids, TRUE); } /*****************************************************************************/ gboolean -nm_settings_start (NMSettings *self, GError **error) +nm_settings_start(NMSettings *self, GError **error) { - NMSettingsPrivate *priv; - gs_strfreev char **plugins = NULL; - GSList *iter; - - priv = NM_SETTINGS_GET_PRIVATE (self); - - nm_assert (!priv->started); - - priv->startup_complete_start_timestamp_msec = nm_utils_get_monotonic_timestamp_msec (); - - priv->hostname_manager = g_object_ref (nm_hostname_manager_get ()); - - priv->kf_db_timestamps = nm_key_file_db_new (NMSTATEDIR "/timestamps", - "timestamps", - _kf_db_log_fcn, - _kf_db_got_dirty_fcn, - self); - priv->kf_db_seen_bssids = nm_key_file_db_new (NMSTATEDIR "/seen-bssids", - "seen-bssids", - _kf_db_log_fcn, - _kf_db_got_dirty_fcn, - self); - nm_key_file_db_start (priv->kf_db_timestamps); - nm_key_file_db_start (priv->kf_db_seen_bssids); - - /* Load the plugins; fail if a plugin is not found. */ - plugins = nm_config_data_get_plugins (nm_config_get_data_orig (priv->config), TRUE); - - if (!load_plugins (self, (const char *const*) plugins, error)) - return FALSE; - - for (iter = priv->plugins; iter; iter = iter->next) { - NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); - - g_signal_connect (plugin, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED, - G_CALLBACK (_plugin_unmanaged_specs_changed), self); - g_signal_connect (plugin, NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED, - G_CALLBACK (_plugin_unrecognized_specs_changed), self); - } - - _plugin_unmanaged_specs_changed (NULL, self); - _plugin_unrecognized_specs_changed (NULL, self); - - _plugin_connections_reload (self); - - g_signal_connect (priv->hostname_manager, - "notify::"NM_HOSTNAME_MANAGER_HOSTNAME, - G_CALLBACK (_hostname_changed_cb), - self); - if (nm_hostname_manager_get_hostname (priv->hostname_manager)) - _notify (self, PROP_HOSTNAME); - - priv->started = TRUE; - _startup_complete_check (self, 0); - - /* FIXME(shutdown): we also need a nm_settings_stop() during shutdown. - * - * In particular, we need to remove all in-memory keyfiles from /run that are nm-generated. - * alternatively, the nm-generated flag must also be persisted and loaded to /run. */ - - return TRUE; + NMSettingsPrivate *priv; + gs_strfreev char **plugins = NULL; + GSList * iter; + + priv = NM_SETTINGS_GET_PRIVATE(self); + + nm_assert(!priv->started); + + priv->startup_complete_start_timestamp_msec = nm_utils_get_monotonic_timestamp_msec(); + + priv->hostname_manager = g_object_ref(nm_hostname_manager_get()); + + priv->kf_db_timestamps = nm_key_file_db_new(NMSTATEDIR "/timestamps", + "timestamps", + _kf_db_log_fcn, + _kf_db_got_dirty_fcn, + self); + priv->kf_db_seen_bssids = nm_key_file_db_new(NMSTATEDIR "/seen-bssids", + "seen-bssids", + _kf_db_log_fcn, + _kf_db_got_dirty_fcn, + self); + nm_key_file_db_start(priv->kf_db_timestamps); + nm_key_file_db_start(priv->kf_db_seen_bssids); + + /* Load the plugins; fail if a plugin is not found. */ + plugins = nm_config_data_get_plugins(nm_config_get_data_orig(priv->config), TRUE); + + if (!load_plugins(self, (const char *const *) plugins, error)) + return FALSE; + + for (iter = priv->plugins; iter; iter = iter->next) { + NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN(iter->data); + + g_signal_connect(plugin, + NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED, + G_CALLBACK(_plugin_unmanaged_specs_changed), + self); + g_signal_connect(plugin, + NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED, + G_CALLBACK(_plugin_unrecognized_specs_changed), + self); + } + + _plugin_unmanaged_specs_changed(NULL, self); + _plugin_unrecognized_specs_changed(NULL, self); + + _plugin_connections_reload(self); + + g_signal_connect(priv->hostname_manager, + "notify::" NM_HOSTNAME_MANAGER_HOSTNAME, + G_CALLBACK(_hostname_changed_cb), + self); + if (nm_hostname_manager_get_hostname(priv->hostname_manager)) + _notify(self, PROP_HOSTNAME); + + priv->started = TRUE; + _startup_complete_check(self, 0); + + /* FIXME(shutdown): we also need a nm_settings_stop() during shutdown. + * + * In particular, we need to remove all in-memory keyfiles from /run that are nm-generated. + * alternatively, the nm-generated flag must also be persisted and loaded to /run. */ + + return TRUE; } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMSettings *self = NM_SETTINGS (object); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - const char **strv; - - switch (prop_id) { - case PROP_UNMANAGED_SPECS: - g_value_take_boxed (value, - _nm_utils_slist_to_strv (nm_settings_get_unmanaged_specs (self), - TRUE)); - break; - case PROP_HOSTNAME: - g_value_set_string (value, - priv->hostname_manager - ? nm_hostname_manager_get_hostname (priv->hostname_manager) - : NULL); - break; - case PROP_CAN_MODIFY: - g_value_set_boolean (value, TRUE); - break; - case PROP_CONNECTIONS: - strv = nm_dbus_utils_get_paths_for_clist (&priv->connections_lst_head, - priv->connections_len, - G_STRUCT_OFFSET (NMSettingsConnection, _connections_lst), - TRUE); - g_value_take_boxed (value, nm_utils_strv_make_deep_copied (strv)); - break; - case PROP_STARTUP_COMPLETE: - g_value_set_boolean (value, !nm_settings_get_startup_complete_blocked_reason (self, FALSE)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMSettings * self = NM_SETTINGS(object); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + const char ** strv; + + switch (prop_id) { + case PROP_UNMANAGED_SPECS: + g_value_take_boxed(value, + _nm_utils_slist_to_strv(nm_settings_get_unmanaged_specs(self), TRUE)); + break; + case PROP_HOSTNAME: + g_value_set_string(value, + priv->hostname_manager + ? nm_hostname_manager_get_hostname(priv->hostname_manager) + : NULL); + break; + case PROP_CAN_MODIFY: + g_value_set_boolean(value, TRUE); + break; + case PROP_CONNECTIONS: + strv = nm_dbus_utils_get_paths_for_clist( + &priv->connections_lst_head, + priv->connections_len, + G_STRUCT_OFFSET(NMSettingsConnection, _connections_lst), + TRUE); + g_value_take_boxed(value, nm_utils_strv_make_deep_copied(strv)); + break; + case PROP_STARTUP_COMPLETE: + g_value_set_boolean(value, !nm_settings_get_startup_complete_blocked_reason(self, FALSE)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMSettings *self = NM_SETTINGS (object); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_MANAGER: - /* construct-only */ - priv->manager = g_value_get_pointer (value); - nm_assert (NM_IS_MANAGER (priv->manager)); - g_object_add_weak_pointer (G_OBJECT (priv->manager), (gpointer *) &priv->manager); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMSettings * self = NM_SETTINGS(object); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_MANAGER: + /* construct-only */ + priv->manager = g_value_get_pointer(value); + nm_assert(NM_IS_MANAGER(priv->manager)); + g_object_add_weak_pointer(G_OBJECT(priv->manager), (gpointer *) &priv->manager); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_settings_init (NMSettings *self) +nm_settings_init(NMSettings *self) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); - c_list_init (&priv->auth_lst_head); - c_list_init (&priv->connections_lst_head); - c_list_init (&priv->startup_complete_scd_lst_head); + c_list_init(&priv->auth_lst_head); + c_list_init(&priv->connections_lst_head); + c_list_init(&priv->startup_complete_scd_lst_head); - c_list_init (&priv->sce_dirty_lst_head); - priv->sce_idx = g_hash_table_new_full (nm_pstr_hash, nm_pstr_equal, - NULL, (GDestroyNotify) _sett_conn_entry_free); + c_list_init(&priv->sce_dirty_lst_head); + priv->sce_idx = g_hash_table_new_full(nm_pstr_hash, + nm_pstr_equal, + NULL, + (GDestroyNotify) _sett_conn_entry_free); - priv->config = g_object_ref (nm_config_get ()); + priv->config = g_object_ref(nm_config_get()); - priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); + priv->agent_mgr = g_object_ref(nm_agent_manager_get()); - priv->platform = g_object_ref (NM_PLATFORM_GET); + priv->platform = g_object_ref(NM_PLATFORM_GET); - priv->session_monitor = g_object_ref (nm_session_monitor_get ()); - g_signal_connect (priv->session_monitor, - NM_SESSION_MONITOR_CHANGED, - G_CALLBACK (session_monitor_changed_cb), - self); + priv->session_monitor = g_object_ref(nm_session_monitor_get()); + g_signal_connect(priv->session_monitor, + NM_SESSION_MONITOR_CHANGED, + G_CALLBACK(session_monitor_changed_cb), + self); } NMSettings * -nm_settings_new (NMManager *manager) +nm_settings_new(NMManager *manager) { - nm_assert (NM_IS_MANAGER (manager)); + nm_assert(NM_IS_MANAGER(manager)); - return g_object_new (NM_TYPE_SETTINGS, - NM_SETTINGS_MANAGER, manager, - NULL); + return g_object_new(NM_TYPE_SETTINGS, NM_SETTINGS_MANAGER, manager, NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMSettings *self = NM_SETTINGS (object); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - CList *iter; - - nm_assert (c_list_is_empty (&priv->sce_dirty_lst_head)); - nm_assert (g_hash_table_size (priv->sce_idx) == 0); - - nm_clear_g_source (&priv->startup_complete_timeout_id); - nm_clear_pointer (&priv->startup_complete_idx, g_hash_table_destroy); - nm_assert (c_list_is_empty (&priv->startup_complete_scd_lst_head)); - - while ((iter = c_list_first (&priv->auth_lst_head))) - nm_auth_chain_destroy (nm_auth_chain_parent_lst_entry (iter)); - - if (priv->hostname_manager) { - g_signal_handlers_disconnect_by_func (priv->hostname_manager, - G_CALLBACK (_hostname_changed_cb), - self); - g_clear_object (&priv->hostname_manager); - } - - if (priv->session_monitor) { - g_signal_handlers_disconnect_by_func (priv->session_monitor, - G_CALLBACK (session_monitor_changed_cb), - self); - g_clear_object (&priv->session_monitor); - } - - G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object); + NMSettings * self = NM_SETTINGS(object); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + CList * iter; + + nm_assert(c_list_is_empty(&priv->sce_dirty_lst_head)); + nm_assert(g_hash_table_size(priv->sce_idx) == 0); + + nm_clear_g_source(&priv->startup_complete_timeout_id); + nm_clear_pointer(&priv->startup_complete_idx, g_hash_table_destroy); + nm_assert(c_list_is_empty(&priv->startup_complete_scd_lst_head)); + + while ((iter = c_list_first(&priv->auth_lst_head))) + nm_auth_chain_destroy(nm_auth_chain_parent_lst_entry(iter)); + + if (priv->hostname_manager) { + g_signal_handlers_disconnect_by_func(priv->hostname_manager, + G_CALLBACK(_hostname_changed_cb), + self); + g_clear_object(&priv->hostname_manager); + } + + if (priv->session_monitor) { + g_signal_handlers_disconnect_by_func(priv->session_monitor, + G_CALLBACK(session_monitor_changed_cb), + self); + g_clear_object(&priv->session_monitor); + } + + G_OBJECT_CLASS(nm_settings_parent_class)->dispose(object); } static void -finalize (GObject *object) +finalize(GObject *object) { - NMSettings *self = NM_SETTINGS (object); - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GSList *iter; + NMSettings * self = NM_SETTINGS(object); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); + GSList * iter; - _clear_connections_cached_list (priv); + _clear_connections_cached_list(priv); - nm_assert (c_list_is_empty (&priv->connections_lst_head)); + nm_assert(c_list_is_empty(&priv->connections_lst_head)); - nm_assert (c_list_is_empty (&priv->sce_dirty_lst_head)); - nm_assert (g_hash_table_size (priv->sce_idx) == 0); + nm_assert(c_list_is_empty(&priv->sce_dirty_lst_head)); + nm_assert(g_hash_table_size(priv->sce_idx) == 0); - nm_clear_pointer (&priv->sce_idx, g_hash_table_destroy); + nm_clear_pointer(&priv->sce_idx, g_hash_table_destroy); - g_slist_free_full (priv->unmanaged_specs, g_free); - g_slist_free_full (priv->unrecognized_specs, g_free); + g_slist_free_full(priv->unmanaged_specs, g_free); + g_slist_free_full(priv->unrecognized_specs, g_free); - while ((iter = priv->plugins)) { - gs_unref_object NMSettingsPlugin *plugin = iter->data; + while ((iter = priv->plugins)) { + gs_unref_object NMSettingsPlugin *plugin = iter->data; - priv->plugins = g_slist_delete_link (priv->plugins, iter); - g_signal_handlers_disconnect_by_data (plugin, self); - } + priv->plugins = g_slist_delete_link(priv->plugins, iter); + g_signal_handlers_disconnect_by_data(plugin, self); + } - g_clear_object (&priv->keyfile_plugin); + g_clear_object(&priv->keyfile_plugin); - g_clear_object (&priv->agent_mgr); + g_clear_object(&priv->agent_mgr); - nm_clear_g_source (&priv->kf_db_flush_idle_id_timestamps); - nm_clear_g_source (&priv->kf_db_flush_idle_id_seen_bssids); - nm_key_file_db_to_file (priv->kf_db_timestamps, FALSE); - nm_key_file_db_to_file (priv->kf_db_seen_bssids, FALSE); - nm_key_file_db_destroy (priv->kf_db_timestamps); - nm_key_file_db_destroy (priv->kf_db_seen_bssids); + nm_clear_g_source(&priv->kf_db_flush_idle_id_timestamps); + nm_clear_g_source(&priv->kf_db_flush_idle_id_seen_bssids); + nm_key_file_db_to_file(priv->kf_db_timestamps, FALSE); + nm_key_file_db_to_file(priv->kf_db_seen_bssids, FALSE); + nm_key_file_db_destroy(priv->kf_db_timestamps); + nm_key_file_db_destroy(priv->kf_db_seen_bssids); - G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_settings_parent_class)->finalize(object); - g_clear_object (&priv->config); + g_clear_object(&priv->config); - g_clear_object (&priv->platform); + g_clear_object(&priv->platform); - if (priv->manager) { - g_object_remove_weak_pointer (G_OBJECT (priv->manager), (gpointer *) &priv->manager); - priv->manager = NULL; - } + if (priv->manager) { + g_object_remove_weak_pointer(G_OBJECT(priv->manager), (gpointer *) &priv->manager); + priv->manager = NULL; + } } -static const GDBusSignalInfo signal_info_new_connection = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( - "NewConnection", - .args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("connection", "o"), - ), -); +static const GDBusSignalInfo signal_info_new_connection = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT( + "NewConnection", + .args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("connection", "o"), ), ); -static const GDBusSignalInfo signal_info_connection_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( - "ConnectionRemoved", - .args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("connection", "o"), - ), -); +static const GDBusSignalInfo signal_info_connection_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT( + "ConnectionRemoved", + .args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("connection", "o"), ), ); static const NMDBusInterfaceInfoExtended interface_info_settings = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_SETTINGS, - .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "ListConnections", - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("connections", "ao"), - ), - ), - .handle = impl_settings_list_connections, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "GetConnectionByUuid", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("uuid", "s"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("connection", "o"), - ), - ), - .handle = impl_settings_get_connection_by_uuid, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "AddConnection", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("path", "o"), - ), - ), - .handle = impl_settings_add_connection, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "AddConnectionUnsaved", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("path", "o"), - ), - ), - .handle = impl_settings_add_connection_unsaved, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "AddConnection2", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("settings", "a{sa{sv}}"), - NM_DEFINE_GDBUS_ARG_INFO ("flags", "u"), - NM_DEFINE_GDBUS_ARG_INFO ("args", "a{sv}"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("path", "o"), - NM_DEFINE_GDBUS_ARG_INFO ("result", "a{sv}"), - ), - ), - .handle = impl_settings_add_connection2, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "LoadConnections", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("filenames", "as"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("status", "b"), - NM_DEFINE_GDBUS_ARG_INFO ("failures", "as"), - ), - ), - .handle = impl_settings_load_connections, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "ReloadConnections", - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("status", "b"), - ), - ), - .handle = impl_settings_reload_connections, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "SaveHostname", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("hostname", "s"), - ), - ), - .handle = impl_settings_save_hostname, - ), - ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - &signal_info_new_connection, - &signal_info_connection_removed, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Connections", "ao", NM_SETTINGS_CONNECTIONS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Hostname", "s", NM_SETTINGS_HOSTNAME), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("CanModify", "b", NM_SETTINGS_CAN_MODIFY), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_SETTINGS, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "ListConnections", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("connections", "ao"), ), ), + .handle = impl_settings_list_connections, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "GetConnectionByUuid", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("uuid", "s"), ), + .out_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("connection", "o"), ), ), + .handle = impl_settings_get_connection_by_uuid, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "AddConnection", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("connection", "a{sa{sv}}"), ), + .out_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("path", "o"), ), ), + .handle = impl_settings_add_connection, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "AddConnectionUnsaved", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("connection", "a{sa{sv}}"), ), + .out_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("path", "o"), ), ), + .handle = impl_settings_add_connection_unsaved, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "AddConnection2", + .in_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("settings", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO("flags", "u"), + NM_DEFINE_GDBUS_ARG_INFO("args", "a{sv}"), ), + .out_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("path", "o"), + NM_DEFINE_GDBUS_ARG_INFO("result", "a{sv}"), ), ), + .handle = impl_settings_add_connection2, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "LoadConnections", + .in_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("filenames", "as"), ), + .out_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("status", "b"), + NM_DEFINE_GDBUS_ARG_INFO("failures", "as"), ), ), + .handle = impl_settings_load_connections, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT("ReloadConnections", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("status", "b"), ), ), + .handle = impl_settings_reload_connections, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "SaveHostname", + .in_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("hostname", "s"), ), ), + .handle = impl_settings_save_hostname, ), ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, + &signal_info_new_connection, + &signal_info_connection_removed, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Connections", + "ao", + NM_SETTINGS_CONNECTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Hostname", "s", NM_SETTINGS_HOSTNAME), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("CanModify", + "b", + NM_SETTINGS_CAN_MODIFY), ), ), + .legacy_property_changed = TRUE, }; static void -nm_settings_class_init (NMSettingsClass *class) +nm_settings_class_init(NMSettingsClass *class) { - GObjectClass *object_class = G_OBJECT_CLASS (class); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (class); - - dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_STATIC (NM_DBUS_PATH_SETTINGS); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_settings); - - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->dispose = dispose; - object_class->finalize = finalize; - - obj_properties[PROP_MANAGER] = - g_param_spec_pointer (NM_SETTINGS_MANAGER, "", "", - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_WRITABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_UNMANAGED_SPECS] = - g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_HOSTNAME] = - g_param_spec_string (NM_SETTINGS_HOSTNAME, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_CAN_MODIFY] = - g_param_spec_boolean (NM_SETTINGS_CAN_MODIFY, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_CONNECTIONS] = - g_param_spec_boxed (NM_SETTINGS_CONNECTIONS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_STARTUP_COMPLETE] = - g_param_spec_boolean (NM_SETTINGS_STARTUP_COMPLETE, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - signals[CONNECTION_ADDED] = - g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_ADDED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION); - - signals[CONNECTION_UPDATED] = - g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - NULL, - G_TYPE_NONE, 2, NM_TYPE_SETTINGS_CONNECTION, G_TYPE_UINT); - - signals[CONNECTION_REMOVED] = - g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION); - - signals[CONNECTION_FLAGS_CHANGED] = - g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_FLAGS_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION); + GObjectClass * object_class = G_OBJECT_CLASS(class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(class); + + dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_STATIC(NM_DBUS_PATH_SETTINGS); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_settings); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + obj_properties[PROP_MANAGER] = + g_param_spec_pointer(NM_SETTINGS_MANAGER, + "", + "", + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_UNMANAGED_SPECS] = + g_param_spec_boxed(NM_SETTINGS_UNMANAGED_SPECS, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_HOSTNAME] = g_param_spec_string(NM_SETTINGS_HOSTNAME, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_CAN_MODIFY] = + g_param_spec_boolean(NM_SETTINGS_CAN_MODIFY, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_CONNECTIONS] = + g_param_spec_boxed(NM_SETTINGS_CONNECTIONS, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_STARTUP_COMPLETE] = + g_param_spec_boolean(NM_SETTINGS_STARTUP_COMPLETE, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + signals[CONNECTION_ADDED] = g_signal_new(NM_SETTINGS_SIGNAL_CONNECTION_ADDED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + NM_TYPE_SETTINGS_CONNECTION); + + signals[CONNECTION_UPDATED] = g_signal_new(NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + NM_TYPE_SETTINGS_CONNECTION, + G_TYPE_UINT); + + signals[CONNECTION_REMOVED] = g_signal_new(NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + NM_TYPE_SETTINGS_CONNECTION); + + signals[CONNECTION_FLAGS_CHANGED] = g_signal_new(NM_SETTINGS_SIGNAL_CONNECTION_FLAGS_CHANGED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + NM_TYPE_SETTINGS_CONNECTION); } diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 35c62ff7..3740f277 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Søren Sandmann * Dan Williams @@ -14,12 +14,14 @@ #include "nm-settings-connection.h" -#define NM_TYPE_SETTINGS (nm_settings_get_type ()) -#define NM_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS, NMSettings)) -#define NM_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS, NMSettingsClass)) -#define NM_IS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS)) -#define NM_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS)) -#define NM_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS, NMSettingsClass)) +#define NM_TYPE_SETTINGS (nm_settings_get_type()) +#define NM_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTINGS, NMSettings)) +#define NM_SETTINGS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTINGS, NMSettingsClass)) +#define NM_IS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTINGS)) +#define NM_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTINGS)) +#define NM_SETTINGS_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTINGS, NMSettingsClass)) #define NM_SETTINGS_UNMANAGED_SPECS "unmanaged-specs" #define NM_SETTINGS_HOSTNAME "hostname" @@ -28,10 +30,10 @@ #define NM_SETTINGS_STARTUP_COMPLETE "startup-complete" #define NM_SETTINGS_MANAGER "manager" -#define NM_SETTINGS_SIGNAL_CONNECTION_ADDED "connection-added" -#define NM_SETTINGS_SIGNAL_CONNECTION_UPDATED "connection-updated" -#define NM_SETTINGS_SIGNAL_CONNECTION_REMOVED "connection-removed" -#define NM_SETTINGS_SIGNAL_CONNECTION_FLAGS_CHANGED "connection-flags-changed" +#define NM_SETTINGS_SIGNAL_CONNECTION_ADDED "connection-added" +#define NM_SETTINGS_SIGNAL_CONNECTION_UPDATED "connection-updated" +#define NM_SETTINGS_SIGNAL_CONNECTION_REMOVED "connection-removed" +#define NM_SETTINGS_SIGNAL_CONNECTION_FLAGS_CHANGED "connection-flags-changed" /** * NMConnectionFilterFunc: @@ -41,91 +43,88 @@ * * Returns: %TRUE to allow the connection, %FALSE to ignore it */ -typedef gboolean (*NMSettingsConnectionFilterFunc) (NMSettings *settings, - NMSettingsConnection *connection, - gpointer func_data); +typedef gboolean (*NMSettingsConnectionFilterFunc)(NMSettings * settings, + NMSettingsConnection *connection, + gpointer func_data); typedef struct _NMSettingsClass NMSettingsClass; -typedef void (*NMSettingsSetHostnameCb) (const char *name, gboolean result, gpointer user_data); +typedef void (*NMSettingsSetHostnameCb)(const char *name, gboolean result, gpointer user_data); -GType nm_settings_get_type (void); +GType nm_settings_get_type(void); -NMSettings *nm_settings_get (void); -#define NM_SETTINGS_GET (nm_settings_get ()) +NMSettings *nm_settings_get(void); +#define NM_SETTINGS_GET (nm_settings_get()) -NMSettings *nm_settings_new (NMManager *manager); +NMSettings *nm_settings_new(NMManager *manager); -gboolean nm_settings_start (NMSettings *self, GError **error); +gboolean nm_settings_start(NMSettings *self, GError **error); -typedef void (*NMSettingsAddCallback) (NMSettings *settings, - NMSettingsConnection *connection, - GError *error, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - gpointer user_data); - -void nm_settings_add_connection_dbus (NMSettings *self, - NMConnection *connection, - NMSettingsConnectionPersistMode persist_mode, - NMSettingsConnectionAddReason add_reason, - NMSettingsConnectionIntFlags sett_flags, - NMAuthSubject *subject, +typedef void (*NMSettingsAddCallback)(NMSettings * settings, + NMSettingsConnection * connection, + GError * error, GDBusMethodInvocation *context, - NMSettingsAddCallback callback, - gpointer user_data); + NMAuthSubject * subject, + gpointer user_data); + +void nm_settings_add_connection_dbus(NMSettings * self, + NMConnection * connection, + NMSettingsConnectionPersistMode persist_mode, + NMSettingsConnectionAddReason add_reason, + NMSettingsConnectionIntFlags sett_flags, + NMAuthSubject * subject, + GDBusMethodInvocation * context, + NMSettingsAddCallback callback, + gpointer user_data); -NMSettingsConnection *const*nm_settings_get_connections (NMSettings *settings, guint *out_len); +NMSettingsConnection *const *nm_settings_get_connections(NMSettings *settings, guint *out_len); -NMSettingsConnection **nm_settings_get_connections_clone (NMSettings *self, - guint *out_len, - NMSettingsConnectionFilterFunc func, - gpointer func_data, - GCompareDataFunc sort_compare_func, - gpointer sort_data); +NMSettingsConnection **nm_settings_get_connections_clone(NMSettings * self, + guint * out_len, + NMSettingsConnectionFilterFunc func, + gpointer func_data, + GCompareDataFunc sort_compare_func, + gpointer sort_data); -gboolean nm_settings_add_connection (NMSettings *settings, - NMConnection *connection, - NMSettingsConnectionPersistMode persist_mode, - NMSettingsConnectionAddReason add_reason, - NMSettingsConnectionIntFlags sett_flags, - NMSettingsConnection **out_sett_conn, - GError **error); +gboolean nm_settings_add_connection(NMSettings * settings, + NMConnection * connection, + NMSettingsConnectionPersistMode persist_mode, + NMSettingsConnectionAddReason add_reason, + NMSettingsConnectionIntFlags sett_flags, + NMSettingsConnection ** out_sett_conn, + GError ** error); -gboolean nm_settings_update_connection (NMSettings *self, - NMSettingsConnection *sett_conn, - NMConnection *new_connection, - NMSettingsConnectionPersistMode persist_mode, - NMSettingsConnectionIntFlags sett_flags, - NMSettingsConnectionIntFlags sett_mask, - NMSettingsConnectionUpdateReason update_reason, - const char *log_context_name, - GError **error); +gboolean nm_settings_update_connection(NMSettings * self, + NMSettingsConnection * sett_conn, + NMConnection * new_connection, + NMSettingsConnectionPersistMode persist_mode, + NMSettingsConnectionIntFlags sett_flags, + NMSettingsConnectionIntFlags sett_mask, + NMSettingsConnectionUpdateReason update_reason, + const char * log_context_name, + GError ** error); -void nm_settings_delete_connection (NMSettings *self, - NMSettingsConnection *sett_conn, - gboolean allow_add_to_no_auto_default); +void nm_settings_delete_connection(NMSettings * self, + NMSettingsConnection *sett_conn, + gboolean allow_add_to_no_auto_default); -NMSettingsConnection *nm_settings_get_connection_by_path (NMSettings *settings, - const char *path); +NMSettingsConnection *nm_settings_get_connection_by_path(NMSettings *settings, const char *path); -NMSettingsConnection *nm_settings_get_connection_by_uuid (NMSettings *settings, - const char *uuid); +NMSettingsConnection *nm_settings_get_connection_by_uuid(NMSettings *settings, const char *uuid); -const char *nm_settings_get_dbus_path_for_uuid (NMSettings *self, - const char *uuid); +const char *nm_settings_get_dbus_path_for_uuid(NMSettings *self, const char *uuid); -gboolean nm_settings_has_connection (NMSettings *self, NMSettingsConnection *connection); +gboolean nm_settings_has_connection(NMSettings *self, NMSettingsConnection *connection); -const GSList *nm_settings_get_unmanaged_specs (NMSettings *self); +const GSList *nm_settings_get_unmanaged_specs(NMSettings *self); -void nm_settings_device_added (NMSettings *self, NMDevice *device); +void nm_settings_device_added(NMSettings *self, NMDevice *device); -void nm_settings_device_removed (NMSettings *self, NMDevice *device, gboolean quitting); +void nm_settings_device_removed(NMSettings *self, NMDevice *device, gboolean quitting); -const char *nm_settings_get_startup_complete_blocked_reason (NMSettings *self, - gboolean force_reload); +const char *nm_settings_get_startup_complete_blocked_reason(NMSettings *self, + gboolean force_reload); -void nm_settings_kf_db_write (NMSettings *settings); +void nm_settings_kf_db_write(NMSettings *settings); -#endif /* __NM_SETTINGS_H__ */ +#endif /* __NM_SETTINGS_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h index 6a01a5ac..b986cc9a 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 - 2013 Red Hat, Inc. */ @@ -6,17 +6,17 @@ #ifndef __COMMON_H__ #define __COMMON_H__ -#define IFCFG_TAG "ifcfg-" -#define KEYS_TAG "keys-" -#define ROUTE_TAG "route-" -#define RULE_TAG "rule-" +#define IFCFG_TAG "ifcfg-" +#define KEYS_TAG "keys-" +#define ROUTE_TAG "route-" +#define RULE_TAG "rule-" #define ROUTE6_TAG "route6-" -#define RULE6_TAG "rule6-" +#define RULE6_TAG "rule6-" -#define BAK_TAG ".bak" -#define TILDE_TAG "~" -#define ORIG_TAG ".orig" -#define REJ_TAG ".rej" +#define BAK_TAG ".bak" +#define TILDE_TAG "~" +#define ORIG_TAG ".orig" +#define REJ_TAG ".rej" #define RPMNEW_TAG ".rpmnew" #define AUGNEW_TAG ".augnew" #define AUGTMP_TAG ".augtmp" @@ -32,8 +32,8 @@ #define TYPE_TEAM "Team" #define TYPE_TEAM_PORT "TeamPort" -#define SECRET_FLAG_AGENT "user" -#define SECRET_FLAG_NOT_SAVED "ask" +#define SECRET_FLAG_AGENT "user" +#define SECRET_FLAG_NOT_SAVED "ask" #define SECRET_FLAG_NOT_REQUIRED "unused" /* DCB key names */ @@ -60,5 +60,4 @@ #define KEY_DCB_PG_STRICT "DCB_PG_STRICT" #define KEY_DCB_PG_UP2TC "DCB_PG_UP2TC" -#endif /* __COMMON_H__ */ - +#endif /* __COMMON_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c index f5c9bb5e..5288f1bc 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Dan Williams * Søren Sandmann @@ -31,1235 +31,1223 @@ #include "nms-ifcfg-rh-reader.h" #include "nms-ifcfg-rh-writer.h" -#define IFCFGRH1_BUS_NAME "com.redhat.ifcfgrh1" -#define IFCFGRH1_OBJECT_PATH "/com/redhat/ifcfgrh1" -#define IFCFGRH1_IFACE1_NAME "com.redhat.ifcfgrh1" -#define IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS "GetIfcfgDetails" +#define IFCFGRH1_BUS_NAME "com.redhat.ifcfgrh1" +#define IFCFGRH1_OBJECT_PATH "/com/redhat/ifcfgrh1" +#define IFCFGRH1_IFACE1_NAME "com.redhat.ifcfgrh1" +#define IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS "GetIfcfgDetails" /*****************************************************************************/ typedef struct { - NMConfig *config; + NMConfig *config; - struct { - GDBusConnection *connection; - GCancellable *cancellable; - gulong signal_id; - guint regist_id; - } dbus; + struct { + GDBusConnection *connection; + GCancellable * cancellable; + gulong signal_id; + guint regist_id; + } dbus; - NMSettUtilStorages storages; + NMSettUtilStorages storages; - GHashTable *unmanaged_specs; - GHashTable *unrecognized_specs; + GHashTable *unmanaged_specs; + GHashTable *unrecognized_specs; } NMSIfcfgRHPluginPrivate; struct _NMSIfcfgRHPlugin { - NMSettingsPlugin parent; - NMSIfcfgRHPluginPrivate _priv; + NMSettingsPlugin parent; + NMSIfcfgRHPluginPrivate _priv; }; struct _NMSIfcfgRHPluginClass { - NMSettingsPluginClass parent; + NMSettingsPluginClass parent; }; -G_DEFINE_TYPE (NMSIfcfgRHPlugin, nms_ifcfg_rh_plugin, NM_TYPE_SETTINGS_PLUGIN) +G_DEFINE_TYPE(NMSIfcfgRHPlugin, nms_ifcfg_rh_plugin, NM_TYPE_SETTINGS_PLUGIN) -#define NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSIfcfgRHPlugin, NMS_IS_IFCFG_RH_PLUGIN, NMSettingsPlugin) +#define NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSIfcfgRHPlugin, NMS_IS_IFCFG_RH_PLUGIN, NMSettingsPlugin) /*****************************************************************************/ -#define _NMLOG_DOMAIN LOGD_SETTINGS -#define _NMLOG(level, ...) \ - G_STMT_START { \ - nm_log ((level), (_NMLOG_DOMAIN), NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - "ifcfg-rh: " \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } G_STMT_END +#define _NMLOG_DOMAIN LOGD_SETTINGS +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + nm_log((level), \ + (_NMLOG_DOMAIN), \ + NULL, \ + NULL, \ + "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + "ifcfg-rh: " _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END /*****************************************************************************/ -static void _unhandled_specs_reset (NMSIfcfgRHPlugin *self); +static void _unhandled_specs_reset(NMSIfcfgRHPlugin *self); -static void _unhandled_specs_merge_storages (NMSIfcfgRHPlugin *self, - NMSettUtilStorages *storages); +static void _unhandled_specs_merge_storages(NMSIfcfgRHPlugin *self, NMSettUtilStorages *storages); /*****************************************************************************/ static void -nm_assert_self (NMSIfcfgRHPlugin *self, gboolean unhandled_specs_consistent) +nm_assert_self(NMSIfcfgRHPlugin *self, gboolean unhandled_specs_consistent) { - nm_assert (NMS_IS_IFCFG_RH_PLUGIN (self)); + nm_assert(NMS_IS_IFCFG_RH_PLUGIN(self)); #if NM_MORE_ASSERTS > 5 - { - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - NMSIfcfgRHStorage *storage; - gsize n_uuid; - gs_unref_hashtable GHashTable *h_unmanaged = NULL; - gs_unref_hashtable GHashTable *h_unrecognized = NULL; + { + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + NMSIfcfgRHStorage * storage; + gsize n_uuid; + gs_unref_hashtable GHashTable *h_unmanaged = NULL; + gs_unref_hashtable GHashTable *h_unrecognized = NULL; - nm_assert (g_hash_table_size (priv->storages.idx_by_filename) == c_list_length (&priv->storages._storage_lst_head)); + nm_assert(g_hash_table_size(priv->storages.idx_by_filename) + == c_list_length(&priv->storages._storage_lst_head)); - h_unmanaged = g_hash_table_new (nm_str_hash, g_str_equal); - h_unrecognized = g_hash_table_new (nm_str_hash, g_str_equal); + h_unmanaged = g_hash_table_new(nm_str_hash, g_str_equal); + h_unrecognized = g_hash_table_new(nm_str_hash, g_str_equal); - n_uuid = 0; + n_uuid = 0; - c_list_for_each_entry (storage, &priv->storages._storage_lst_head, parent._storage_lst) { - const char *uuid; - const char *filename; + c_list_for_each_entry (storage, &priv->storages._storage_lst_head, parent._storage_lst) { + const char *uuid; + const char *filename; - filename = nms_ifcfg_rh_storage_get_filename (storage); + filename = nms_ifcfg_rh_storage_get_filename(storage); - nm_assert (filename && NM_STR_HAS_PREFIX (filename, IFCFG_DIR"/")); + nm_assert(filename && NM_STR_HAS_PREFIX(filename, IFCFG_DIR "/")); - uuid = nms_ifcfg_rh_storage_get_uuid_opt (storage); + uuid = nms_ifcfg_rh_storage_get_uuid_opt(storage); - nm_assert ((!!uuid) + (!!storage->unmanaged_spec) + (!!storage->unrecognized_spec) == 1); + nm_assert((!!uuid) + (!!storage->unmanaged_spec) + (!!storage->unrecognized_spec) == 1); - nm_assert (storage == nm_sett_util_storages_lookup_by_filename (&priv->storages, filename)); + nm_assert(storage + == nm_sett_util_storages_lookup_by_filename(&priv->storages, filename)); - if (uuid) { - NMSettUtilStorageByUuidHead *sbuh; - NMSettUtilStorageByUuidHead *sbuh2; + if (uuid) { + NMSettUtilStorageByUuidHead *sbuh; + NMSettUtilStorageByUuidHead *sbuh2; - if (storage->connection) - nm_assert (nm_streq0 (nm_connection_get_uuid (storage->connection), uuid)); + if (storage->connection) + nm_assert(nm_streq0(nm_connection_get_uuid(storage->connection), uuid)); - if (!g_hash_table_lookup_extended (priv->storages.idx_by_uuid, &uuid, (gpointer *) &sbuh, (gpointer *) &sbuh2)) - nm_assert_not_reached (); + if (!g_hash_table_lookup_extended(priv->storages.idx_by_uuid, + &uuid, + (gpointer *) &sbuh, + (gpointer *) &sbuh2)) + nm_assert_not_reached(); - nm_assert (sbuh); - nm_assert (nm_streq (uuid, sbuh->uuid)); - nm_assert (sbuh == sbuh2); - nm_assert (c_list_contains (&sbuh->_storage_by_uuid_lst_head, &storage->parent._storage_by_uuid_lst)); + nm_assert(sbuh); + nm_assert(nm_streq(uuid, sbuh->uuid)); + nm_assert(sbuh == sbuh2); + nm_assert(c_list_contains(&sbuh->_storage_by_uuid_lst_head, + &storage->parent._storage_by_uuid_lst)); - if (c_list_first (&sbuh->_storage_by_uuid_lst_head) == &storage->parent._storage_by_uuid_lst) - n_uuid++; - } else if (storage->unmanaged_spec) { - nm_assert (strlen (storage->unmanaged_spec) > 0); - g_hash_table_add (h_unmanaged, storage->unmanaged_spec); - } else if (storage->unrecognized_spec) { - nm_assert (strlen (storage->unrecognized_spec) > 0); - g_hash_table_add (h_unrecognized, storage->unrecognized_spec); - } else - nm_assert_not_reached (); + if (c_list_first(&sbuh->_storage_by_uuid_lst_head) + == &storage->parent._storage_by_uuid_lst) + n_uuid++; + } else if (storage->unmanaged_spec) { + nm_assert(strlen(storage->unmanaged_spec) > 0); + g_hash_table_add(h_unmanaged, storage->unmanaged_spec); + } else if (storage->unrecognized_spec) { + nm_assert(strlen(storage->unrecognized_spec) > 0); + g_hash_table_add(h_unrecognized, storage->unrecognized_spec); + } else + nm_assert_not_reached(); - nm_assert (!storage->connection); - } + nm_assert(!storage->connection); + } - nm_assert (g_hash_table_size (priv->storages.idx_by_uuid) == n_uuid); + nm_assert(g_hash_table_size(priv->storages.idx_by_uuid) == n_uuid); - if (unhandled_specs_consistent) { - nm_assert (nm_utils_hashtable_same_keys (h_unmanaged, priv->unmanaged_specs)); - nm_assert (nm_utils_hashtable_same_keys (h_unrecognized, priv->unrecognized_specs)); - } - } + if (unhandled_specs_consistent) { + nm_assert(nm_utils_hashtable_same_keys(h_unmanaged, priv->unmanaged_specs)); + nm_assert(nm_utils_hashtable_same_keys(h_unrecognized, priv->unrecognized_specs)); + } + } #endif } /*****************************************************************************/ static NMSIfcfgRHStorage * -_load_file (NMSIfcfgRHPlugin *self, - const char *filename, - GError **error) +_load_file(NMSIfcfgRHPlugin *self, const char *filename, GError **error) { - gs_unref_object NMConnection *connection = NULL; - gs_free_error GError *load_error = NULL; - gs_free char *unhandled_spec = NULL; - gboolean load_error_ignore; - struct stat st; - - if (stat (filename, &st) != 0) { - int errsv = errno; - - if (error) { - nm_utils_error_set_errno (error, errsv, - "failure to stat file \%s\": %s", - filename); - } else - _LOGT ("load[%s]: failure to stat file: %s", filename, nm_strerror_native (errsv)); - return NULL; - } - - connection = connection_from_file (filename, - &unhandled_spec, - &load_error, - &load_error_ignore); - if (load_error) { - if (error) { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - "failure to read file \"%s\": %s", - filename, load_error->message); - } else { - _NMLOG (load_error_ignore ? LOGL_TRACE : LOGL_WARN, - "load[%s]: failure to read file: %s", filename, load_error->message); - } - return NULL; - } - - if (unhandled_spec) { - const char *unmanaged_spec; - const char *unrecognized_spec; - - if (!nms_ifcfg_rh_utils_parse_unhandled_spec (unhandled_spec, - &unmanaged_spec, - &unrecognized_spec)) { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - "invalid unhandled spec \"%s\"", - unhandled_spec); - nm_assert_not_reached (); - return NULL; - } - return nms_ifcfg_rh_storage_new_unhandled (self, - filename, - unmanaged_spec, - unrecognized_spec); - } - - return nms_ifcfg_rh_storage_new_connection (self, - filename, - g_steal_pointer (&connection), - &st.st_mtim); + gs_unref_object NMConnection *connection = NULL; + gs_free_error GError *load_error = NULL; + gs_free char * unhandled_spec = NULL; + gboolean load_error_ignore; + struct stat st; + + if (stat(filename, &st) != 0) { + int errsv = errno; + + if (error) { + nm_utils_error_set_errno(error, errsv, "failure to stat file \%s\": %s", filename); + } else + _LOGT("load[%s]: failure to stat file: %s", filename, nm_strerror_native(errsv)); + return NULL; + } + + connection = connection_from_file(filename, &unhandled_spec, &load_error, &load_error_ignore); + if (load_error) { + if (error) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + "failure to read file \"%s\": %s", + filename, + load_error->message); + } else { + _NMLOG(load_error_ignore ? LOGL_TRACE : LOGL_WARN, + "load[%s]: failure to read file: %s", + filename, + load_error->message); + } + return NULL; + } + + if (unhandled_spec) { + const char *unmanaged_spec; + const char *unrecognized_spec; + + if (!nms_ifcfg_rh_utils_parse_unhandled_spec(unhandled_spec, + &unmanaged_spec, + &unrecognized_spec)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + "invalid unhandled spec \"%s\"", + unhandled_spec); + nm_assert_not_reached(); + return NULL; + } + return nms_ifcfg_rh_storage_new_unhandled(self, + filename, + unmanaged_spec, + unrecognized_spec); + } + + return nms_ifcfg_rh_storage_new_connection(self, + filename, + g_steal_pointer(&connection), + &st.st_mtim); } static void -_load_dir (NMSIfcfgRHPlugin *self, - NMSettUtilStorages *storages) +_load_dir(NMSIfcfgRHPlugin *self, NMSettUtilStorages *storages) { - gs_unref_hashtable GHashTable *dupl_filenames = NULL; - gs_free_error GError *local = NULL; - const char *f_filename; - GDir *dir; - - dir = g_dir_open (IFCFG_DIR, 0, &local); - if (!dir) { - _LOGT ("Could not read directory '%s': %s", IFCFG_DIR, local->message); - return; - } - - dupl_filenames = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_free); - - while ((f_filename = g_dir_read_name (dir))) { - gs_free char *full_path = NULL; - NMSIfcfgRHStorage *storage; - char *full_filename; - - full_path = g_build_filename (IFCFG_DIR, f_filename, NULL); - full_filename = utils_detect_ifcfg_path (full_path, TRUE); - if (!full_filename) - continue; - - if (!g_hash_table_add (dupl_filenames, full_filename)) - continue; - - nm_assert (!nm_sett_util_storages_lookup_by_filename (storages, full_filename)); - - storage = _load_file (self, - full_filename, - NULL); - if (storage) - nm_sett_util_storages_add_take (storages, storage); - } - g_dir_close (dir); + gs_unref_hashtable GHashTable *dupl_filenames = NULL; + gs_free_error GError *local = NULL; + const char * f_filename; + GDir * dir; + + dir = g_dir_open(IFCFG_DIR, 0, &local); + if (!dir) { + _LOGT("Could not read directory '%s': %s", IFCFG_DIR, local->message); + return; + } + + dupl_filenames = g_hash_table_new_full(nm_str_hash, g_str_equal, NULL, g_free); + + while ((f_filename = g_dir_read_name(dir))) { + gs_free char * full_path = NULL; + NMSIfcfgRHStorage *storage; + char * full_filename; + + full_path = g_build_filename(IFCFG_DIR, f_filename, NULL); + full_filename = utils_detect_ifcfg_path(full_path, TRUE); + if (!full_filename) + continue; + + if (!g_hash_table_add(dupl_filenames, full_filename)) + continue; + + nm_assert(!nm_sett_util_storages_lookup_by_filename(storages, full_filename)); + + storage = _load_file(self, full_filename, NULL); + if (storage) + nm_sett_util_storages_add_take(storages, storage); + } + g_dir_close(dir); } static void -_storages_consolidate (NMSIfcfgRHPlugin *self, - NMSettUtilStorages *storages_new, - gboolean replace_all, - GHashTable *storages_replaced, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data) +_storages_consolidate(NMSIfcfgRHPlugin * self, + NMSettUtilStorages * storages_new, + gboolean replace_all, + GHashTable * storages_replaced, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data) { - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - CList lst_conn_info_deleted = C_LIST_INIT (lst_conn_info_deleted); - gs_unref_ptrarray GPtrArray *storages_modified = NULL; - CList storages_deleted; - NMSIfcfgRHStorage *storage_safe; - NMSIfcfgRHStorage *storage_new; - NMSIfcfgRHStorage *storage_old; - NMSIfcfgRHStorage *storage; - guint i; - - /* when we reload all files, we must signal add/update/modify of profiles one-by-one. - * NMSettings then goes ahead and emits further signals and a lot of things happen. - * - * So, first, emit an update of the unmanaged/unrecognized specs that contains *all* - * the unmanaged/unrecognized devices from before and after. Since both unmanaged/unrecognized - * specs have the meaning of "not doing something", it makes sense that we temporarily - * disable that action for the sum of before and after. */ - _unhandled_specs_merge_storages (self, storages_new); - - storages_modified = g_ptr_array_new_with_free_func (g_object_unref); - c_list_init (&storages_deleted); - - c_list_for_each_entry (storage_old, &priv->storages._storage_lst_head, parent._storage_lst) - storage_old->dirty = TRUE; - - c_list_for_each_entry_safe (storage_new, storage_safe, &storages_new->_storage_lst_head, parent._storage_lst) { - storage_old = nm_sett_util_storages_lookup_by_filename (&priv->storages, nms_ifcfg_rh_storage_get_filename (storage_new)); - - nm_sett_util_storages_steal (storages_new, storage_new); - - if ( !storage_old - || !nms_ifcfg_rh_storage_equal_type (storage_new, storage_old)) { - if (storage_old) { - nm_sett_util_storages_steal (&priv->storages, storage_old); - if (nms_ifcfg_rh_storage_get_uuid_opt (storage_old)) - c_list_link_tail (&storages_deleted, &storage_old->parent._storage_lst); - else - nms_ifcfg_rh_storage_destroy (storage_old); - } - storage_new->dirty = FALSE; - nm_sett_util_storages_add_take (&priv->storages, storage_new); - g_ptr_array_add (storages_modified, g_object_ref (storage_new)); - continue; - } - - storage_old->dirty = FALSE; - nms_ifcfg_rh_storage_copy_content (storage_old, storage_new); - nms_ifcfg_rh_storage_destroy (storage_new); - g_ptr_array_add (storages_modified, g_object_ref (storage_old)); - } - - c_list_for_each_entry_safe (storage_old, storage_safe, &priv->storages._storage_lst_head, parent._storage_lst) { - if (!storage_old->dirty) - continue; - if ( replace_all - || ( storages_replaced - && g_hash_table_contains (storages_replaced, storage_old))) { - nm_sett_util_storages_steal (&priv->storages, storage_old); - if (nms_ifcfg_rh_storage_get_uuid_opt (storage_old)) - c_list_link_tail (&storages_deleted, &storage_old->parent._storage_lst); - else - nms_ifcfg_rh_storage_destroy (storage_old); - } - } - - /* raise events. */ - - for (i = 0; i < storages_modified->len; i++) { - storage = storages_modified->pdata[i]; - storage->dirty = TRUE; - } - - for (i = 0; i < storages_modified->len; i++) { - gs_unref_object NMConnection *connection = NULL; - storage = storages_modified->pdata[i]; - - if (!storage->dirty) { - /* the entry is no longer dirty. In the meantime we already emited - * another signal for it. */ - continue; - } - storage->dirty = FALSE; - if (storage != nm_sett_util_storages_lookup_by_filename (&priv->storages, nms_ifcfg_rh_storage_get_filename (storage))) { - /* hm? The profile was deleted in the meantime? That is only possible - * if the signal handler called again into the plugin. In any case, the event - * was already emitted. Skip. */ - continue; - } - - connection = nms_ifcfg_rh_storage_steal_connection (storage); - if (!connection) { - nm_assert (!nms_ifcfg_rh_storage_get_uuid_opt (storage)); - continue; - } - - nm_assert (NM_IS_CONNECTION (connection)); - nm_assert (nms_ifcfg_rh_storage_get_uuid_opt (storage)); - callback (NM_SETTINGS_PLUGIN (self), - NM_SETTINGS_STORAGE (storage), - connection, - user_data); - } - - while ((storage = c_list_first_entry (&storages_deleted, NMSIfcfgRHStorage, parent._storage_lst))) { - c_list_unlink (&storage->parent._storage_lst); - callback (NM_SETTINGS_PLUGIN (self), - NM_SETTINGS_STORAGE (storage), - NULL, - user_data); - nms_ifcfg_rh_storage_destroy (storage); - } + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + CList lst_conn_info_deleted = C_LIST_INIT(lst_conn_info_deleted); + gs_unref_ptrarray GPtrArray *storages_modified = NULL; + CList storages_deleted; + NMSIfcfgRHStorage * storage_safe; + NMSIfcfgRHStorage * storage_new; + NMSIfcfgRHStorage * storage_old; + NMSIfcfgRHStorage * storage; + guint i; + + /* when we reload all files, we must signal add/update/modify of profiles one-by-one. + * NMSettings then goes ahead and emits further signals and a lot of things happen. + * + * So, first, emit an update of the unmanaged/unrecognized specs that contains *all* + * the unmanaged/unrecognized devices from before and after. Since both unmanaged/unrecognized + * specs have the meaning of "not doing something", it makes sense that we temporarily + * disable that action for the sum of before and after. */ + _unhandled_specs_merge_storages(self, storages_new); + + storages_modified = g_ptr_array_new_with_free_func(g_object_unref); + c_list_init(&storages_deleted); + + c_list_for_each_entry (storage_old, &priv->storages._storage_lst_head, parent._storage_lst) + storage_old->dirty = TRUE; + + c_list_for_each_entry_safe (storage_new, + storage_safe, + &storages_new->_storage_lst_head, + parent._storage_lst) { + storage_old = nm_sett_util_storages_lookup_by_filename( + &priv->storages, + nms_ifcfg_rh_storage_get_filename(storage_new)); + + nm_sett_util_storages_steal(storages_new, storage_new); + + if (!storage_old || !nms_ifcfg_rh_storage_equal_type(storage_new, storage_old)) { + if (storage_old) { + nm_sett_util_storages_steal(&priv->storages, storage_old); + if (nms_ifcfg_rh_storage_get_uuid_opt(storage_old)) + c_list_link_tail(&storages_deleted, &storage_old->parent._storage_lst); + else + nms_ifcfg_rh_storage_destroy(storage_old); + } + storage_new->dirty = FALSE; + nm_sett_util_storages_add_take(&priv->storages, storage_new); + g_ptr_array_add(storages_modified, g_object_ref(storage_new)); + continue; + } + + storage_old->dirty = FALSE; + nms_ifcfg_rh_storage_copy_content(storage_old, storage_new); + nms_ifcfg_rh_storage_destroy(storage_new); + g_ptr_array_add(storages_modified, g_object_ref(storage_old)); + } + + c_list_for_each_entry_safe (storage_old, + storage_safe, + &priv->storages._storage_lst_head, + parent._storage_lst) { + if (!storage_old->dirty) + continue; + if (replace_all + || (storages_replaced && g_hash_table_contains(storages_replaced, storage_old))) { + nm_sett_util_storages_steal(&priv->storages, storage_old); + if (nms_ifcfg_rh_storage_get_uuid_opt(storage_old)) + c_list_link_tail(&storages_deleted, &storage_old->parent._storage_lst); + else + nms_ifcfg_rh_storage_destroy(storage_old); + } + } + + /* raise events. */ + + for (i = 0; i < storages_modified->len; i++) { + storage = storages_modified->pdata[i]; + storage->dirty = TRUE; + } + + for (i = 0; i < storages_modified->len; i++) { + gs_unref_object NMConnection *connection = NULL; + storage = storages_modified->pdata[i]; + + if (!storage->dirty) { + /* the entry is no longer dirty. In the meantime we already emitted + * another signal for it. */ + continue; + } + storage->dirty = FALSE; + if (storage + != nm_sett_util_storages_lookup_by_filename( + &priv->storages, + nms_ifcfg_rh_storage_get_filename(storage))) { + /* hm? The profile was deleted in the meantime? That is only possible + * if the signal handler called again into the plugin. In any case, the event + * was already emitted. Skip. */ + continue; + } + + connection = nms_ifcfg_rh_storage_steal_connection(storage); + if (!connection) { + nm_assert(!nms_ifcfg_rh_storage_get_uuid_opt(storage)); + continue; + } + + nm_assert(NM_IS_CONNECTION(connection)); + nm_assert(nms_ifcfg_rh_storage_get_uuid_opt(storage)); + callback(NM_SETTINGS_PLUGIN(self), NM_SETTINGS_STORAGE(storage), connection, user_data); + } + + while ( + (storage = c_list_first_entry(&storages_deleted, NMSIfcfgRHStorage, parent._storage_lst))) { + c_list_unlink(&storage->parent._storage_lst); + callback(NM_SETTINGS_PLUGIN(self), NM_SETTINGS_STORAGE(storage), NULL, user_data); + nms_ifcfg_rh_storage_destroy(storage); + } } /*****************************************************************************/ static void -load_connections (NMSettingsPlugin *plugin, - NMSettingsPluginConnectionLoadEntry *entries, - gsize n_entries, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data) +load_connections(NMSettingsPlugin * plugin, + NMSettingsPluginConnectionLoadEntry * entries, + gsize n_entries, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data) { - NMSIfcfgRHPlugin *self = NMS_IFCFG_RH_PLUGIN (plugin); - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - nm_auto_clear_sett_util_storages NMSettUtilStorages storages_new = NM_SETT_UTIL_STORAGES_INIT (storages_new, nms_ifcfg_rh_storage_destroy); - gs_unref_hashtable GHashTable *dupl_filenames = NULL; - gs_unref_hashtable GHashTable *storages_replaced = NULL; - gs_unref_hashtable GHashTable *loaded_uuids = NULL; - const char *loaded_uuid; - GHashTableIter h_iter; - gsize i; - - if (n_entries == 0) - return; - - dupl_filenames = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); - - loaded_uuids = g_hash_table_new (nm_str_hash, g_str_equal); - - storages_replaced = g_hash_table_new_full (nm_direct_hash, NULL, g_object_unref, NULL); - - for (i = 0; i < n_entries; i++) { - NMSettingsPluginConnectionLoadEntry *const entry = &entries[i]; - gs_free_error GError *local = NULL; - const char *full_filename; - const char *uuid; - gs_free char *full_filename_keep = NULL; - NMSettingsPluginConnectionLoadEntry *dupl_content_entry; - gs_unref_object NMSIfcfgRHStorage *storage = NULL; - - if (entry->handled) - continue; - - if (entry->filename[0] != '/') - continue; - - full_filename_keep = utils_detect_ifcfg_path (entry->filename, FALSE); - - if (!full_filename_keep) { - if (nm_utils_file_is_in_path (entry->filename, IFCFG_DIR)) { - nm_utils_error_set (&entry->error, - NM_UTILS_ERROR_UNKNOWN, - ("path is not a valid name for an ifcfg-rh file")); - entry->handled = TRUE; - } - continue; - } - - if ((dupl_content_entry = g_hash_table_lookup (dupl_filenames, full_filename_keep))) { - /* we already visited this file. */ - entry->handled = dupl_content_entry->handled; - if (dupl_content_entry->error) { - g_set_error_literal (&entry->error, - dupl_content_entry->error->domain, - dupl_content_entry->error->code, - dupl_content_entry->error->message); - } - continue; - } - - entry->handled = TRUE; - - full_filename = full_filename_keep; - if (!g_hash_table_insert (dupl_filenames, g_steal_pointer (&full_filename_keep), entry)) - nm_assert_not_reached (); - - storage = _load_file (self, - full_filename, - &local); - if (!storage) { - if (nm_utils_file_stat (full_filename, NULL) == -ENOENT) { - NMSIfcfgRHStorage *storage2; - - /* the file does not exist. We take that as indication to unload the file - * that was previously loaded... */ - storage2 = nm_sett_util_storages_lookup_by_filename (&priv->storages, full_filename); - if (storage2) - g_hash_table_add (storages_replaced, g_object_ref (storage2)); - continue; - } - g_propagate_error (&entry->error, g_steal_pointer (&local)); - continue; - } - - uuid = nms_ifcfg_rh_storage_get_uuid_opt (storage); - if (uuid) - g_hash_table_add (loaded_uuids, (char *) uuid); - - nm_sett_util_storages_add_take (&storages_new, g_steal_pointer (&storage)); - } - - /* now we visit all UUIDs that are about to change... */ - g_hash_table_iter_init (&h_iter, loaded_uuids); - while (g_hash_table_iter_next (&h_iter, (gpointer *) &loaded_uuid, NULL)) { - NMSIfcfgRHStorage *storage; - NMSettUtilStorageByUuidHead *sbuh; - - sbuh = nm_sett_util_storages_lookup_by_uuid (&priv->storages, loaded_uuid); - if (!sbuh) - continue; - - c_list_for_each_entry (storage, &sbuh->_storage_by_uuid_lst_head, parent._storage_by_uuid_lst) { - const char *full_filename = nms_ifcfg_rh_storage_get_filename (storage); - gs_unref_object NMSIfcfgRHStorage *storage_new = NULL; - gs_free_error GError *local = NULL; - - if (g_hash_table_contains (dupl_filenames, full_filename)) { - /* already re-loaded. */ - continue; - } - - /* @storage has a UUID that was just loaded from disk, but we have an entry in cache. - * Reload that file too despite not being told to do so. The reason is to get - * the latest file timestamp so that we get the priorities right. */ - - storage_new = _load_file (self, - full_filename, - &local); - if ( storage_new - && !nm_streq0 (loaded_uuid, nms_ifcfg_rh_storage_get_uuid_opt (storage_new))) { - /* the file now references a different UUID. We are not told to reload - * that file, so this means the existing storage (with the previous - * filename and UUID tuple) is no longer valid. */ - g_clear_object (&storage_new); - } - - g_hash_table_add (storages_replaced, g_object_ref (storage)); - if (storage_new) - nm_sett_util_storages_add_take (&storages_new, g_steal_pointer (&storage_new)); - } - } - - nm_clear_pointer (&loaded_uuids, g_hash_table_destroy); - nm_clear_pointer (&dupl_filenames, g_hash_table_destroy); - - _storages_consolidate (self, - &storages_new, - FALSE, - storages_replaced, - callback, - user_data); + NMSIfcfgRHPlugin * self = NMS_IFCFG_RH_PLUGIN(plugin); + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + nm_auto_clear_sett_util_storages NMSettUtilStorages storages_new = + NM_SETT_UTIL_STORAGES_INIT(storages_new, nms_ifcfg_rh_storage_destroy); + gs_unref_hashtable GHashTable *dupl_filenames = NULL; + gs_unref_hashtable GHashTable *storages_replaced = NULL; + gs_unref_hashtable GHashTable *loaded_uuids = NULL; + const char * loaded_uuid; + GHashTableIter h_iter; + gsize i; + + if (n_entries == 0) + return; + + dupl_filenames = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL); + + loaded_uuids = g_hash_table_new(nm_str_hash, g_str_equal); + + storages_replaced = g_hash_table_new_full(nm_direct_hash, NULL, g_object_unref, NULL); + + for (i = 0; i < n_entries; i++) { + NMSettingsPluginConnectionLoadEntry *const entry = &entries[i]; + gs_free_error GError * local = NULL; + const char * full_filename; + const char * uuid; + gs_free char * full_filename_keep = NULL; + NMSettingsPluginConnectionLoadEntry *dupl_content_entry; + gs_unref_object NMSIfcfgRHStorage *storage = NULL; + + if (entry->handled) + continue; + + if (entry->filename[0] != '/') + continue; + + full_filename_keep = utils_detect_ifcfg_path(entry->filename, FALSE); + + if (!full_filename_keep) { + if (nm_utils_file_is_in_path(entry->filename, IFCFG_DIR)) { + nm_utils_error_set(&entry->error, + NM_UTILS_ERROR_UNKNOWN, + ("path is not a valid name for an ifcfg-rh file")); + entry->handled = TRUE; + } + continue; + } + + if ((dupl_content_entry = g_hash_table_lookup(dupl_filenames, full_filename_keep))) { + /* we already visited this file. */ + entry->handled = dupl_content_entry->handled; + if (dupl_content_entry->error) { + g_set_error_literal(&entry->error, + dupl_content_entry->error->domain, + dupl_content_entry->error->code, + dupl_content_entry->error->message); + } + continue; + } + + entry->handled = TRUE; + + full_filename = full_filename_keep; + if (!g_hash_table_insert(dupl_filenames, g_steal_pointer(&full_filename_keep), entry)) + nm_assert_not_reached(); + + storage = _load_file(self, full_filename, &local); + if (!storage) { + if (nm_utils_file_stat(full_filename, NULL) == -ENOENT) { + NMSIfcfgRHStorage *storage2; + + /* the file does not exist. We take that as indication to unload the file + * that was previously loaded... */ + storage2 = nm_sett_util_storages_lookup_by_filename(&priv->storages, full_filename); + if (storage2) + g_hash_table_add(storages_replaced, g_object_ref(storage2)); + continue; + } + g_propagate_error(&entry->error, g_steal_pointer(&local)); + continue; + } + + uuid = nms_ifcfg_rh_storage_get_uuid_opt(storage); + if (uuid) + g_hash_table_add(loaded_uuids, (char *) uuid); + + nm_sett_util_storages_add_take(&storages_new, g_steal_pointer(&storage)); + } + + /* now we visit all UUIDs that are about to change... */ + g_hash_table_iter_init(&h_iter, loaded_uuids); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &loaded_uuid, NULL)) { + NMSIfcfgRHStorage * storage; + NMSettUtilStorageByUuidHead *sbuh; + + sbuh = nm_sett_util_storages_lookup_by_uuid(&priv->storages, loaded_uuid); + if (!sbuh) + continue; + + c_list_for_each_entry (storage, + &sbuh->_storage_by_uuid_lst_head, + parent._storage_by_uuid_lst) { + const char * full_filename = nms_ifcfg_rh_storage_get_filename(storage); + gs_unref_object NMSIfcfgRHStorage *storage_new = NULL; + gs_free_error GError *local = NULL; + + if (g_hash_table_contains(dupl_filenames, full_filename)) { + /* already re-loaded. */ + continue; + } + + /* @storage has a UUID that was just loaded from disk, but we have an entry in cache. + * Reload that file too despite not being told to do so. The reason is to get + * the latest file timestamp so that we get the priorities right. */ + + storage_new = _load_file(self, full_filename, &local); + if (storage_new + && !nm_streq0(loaded_uuid, nms_ifcfg_rh_storage_get_uuid_opt(storage_new))) { + /* the file now references a different UUID. We are not told to reload + * that file, so this means the existing storage (with the previous + * filename and UUID tuple) is no longer valid. */ + g_clear_object(&storage_new); + } + + g_hash_table_add(storages_replaced, g_object_ref(storage)); + if (storage_new) + nm_sett_util_storages_add_take(&storages_new, g_steal_pointer(&storage_new)); + } + } + + nm_clear_pointer(&loaded_uuids, g_hash_table_destroy); + nm_clear_pointer(&dupl_filenames, g_hash_table_destroy); + + _storages_consolidate(self, &storages_new, FALSE, storages_replaced, callback, user_data); } static void -reload_connections (NMSettingsPlugin *plugin, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data) +reload_connections(NMSettingsPlugin * plugin, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data) { - NMSIfcfgRHPlugin *self = NMS_IFCFG_RH_PLUGIN (plugin); - nm_auto_clear_sett_util_storages NMSettUtilStorages storages_new = NM_SETT_UTIL_STORAGES_INIT (storages_new, nms_ifcfg_rh_storage_destroy); + NMSIfcfgRHPlugin * self = NMS_IFCFG_RH_PLUGIN(plugin); + nm_auto_clear_sett_util_storages NMSettUtilStorages storages_new = + NM_SETT_UTIL_STORAGES_INIT(storages_new, nms_ifcfg_rh_storage_destroy); - nm_assert_self (self, TRUE); + nm_assert_self(self, TRUE); - _load_dir (self, &storages_new); + _load_dir(self, &storages_new); - _storages_consolidate (self, - &storages_new, - TRUE, - NULL, - callback, - user_data); + _storages_consolidate(self, &storages_new, TRUE, NULL, callback, user_data); - nm_assert_self (self, FALSE); + nm_assert_self(self, FALSE); } static void -load_connections_done (NMSettingsPlugin *plugin) +load_connections_done(NMSettingsPlugin *plugin) { - NMSIfcfgRHPlugin *self = NMS_IFCFG_RH_PLUGIN (plugin); - - /* at the beginning of a load, we emit a change signal for unmanaged/unrecognized - * specs that contain the sum of before and after (_unhandled_specs_merge_storages()). - * - * The idea is that while we emit signals about changes to connection, we have - * the sum of all unmanaged/unrecognized devices from before and after. - * - * This if triggered at the end, to reset the specs. */ - _unhandled_specs_reset (self); - - nm_assert_self (self, TRUE); + NMSIfcfgRHPlugin *self = NMS_IFCFG_RH_PLUGIN(plugin); + + /* at the beginning of a load, we emit a change signal for unmanaged/unrecognized + * specs that contain the sum of before and after (_unhandled_specs_merge_storages()). + * + * The idea is that while we emit signals about changes to connection, we have + * the sum of all unmanaged/unrecognized devices from before and after. + * + * This if triggered at the end, to reset the specs. */ + _unhandled_specs_reset(self); + + nm_assert_self(self, TRUE); } /*****************************************************************************/ static gboolean -add_connection (NMSettingsPlugin *plugin, - NMConnection *connection, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error) +add_connection(NMSettingsPlugin * plugin, + NMConnection * connection, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error) { - NMSIfcfgRHPlugin *self = NMS_IFCFG_RH_PLUGIN (plugin); - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - gs_unref_object NMSIfcfgRHStorage *storage = NULL; - gs_unref_object NMConnection *reread = NULL; - gs_free char *full_filename = NULL; - GError *local = NULL; - gboolean reread_same; - struct timespec mtime; - - nm_assert_self (self, TRUE); - nm_assert (NM_IS_CONNECTION (connection)); - nm_assert (out_storage && !*out_storage); - nm_assert (out_connection && !*out_connection); - - if (!nms_ifcfg_rh_writer_write_connection (connection, - IFCFG_DIR, - NULL, - nm_sett_util_allow_filename_cb, - NM_SETT_UTIL_ALLOW_FILENAME_DATA (&priv->storages, NULL), - &full_filename, - &reread, - &reread_same, - &local)) { - _LOGT ("commit: %s (%s): failed to add: %s", - nm_connection_get_uuid (connection), - nm_connection_get_id (connection), - local->message); - g_propagate_error (error, local); - return FALSE; - } - - if ( !reread - || reread_same) - nm_g_object_ref_set (&reread, connection); - - nm_assert (full_filename && full_filename[0] == '/'); - - _LOGT ("commit: %s (%s) added as \"%s\"", - nm_connection_get_uuid (reread), - nm_connection_get_id (reread), - full_filename); - - storage = nms_ifcfg_rh_storage_new_connection (self, - full_filename, - g_steal_pointer (&reread), - nm_sett_util_stat_mtime (full_filename, FALSE, &mtime)); - - nm_sett_util_storages_add_take (&priv->storages, g_object_ref (storage)); - - *out_connection = nms_ifcfg_rh_storage_steal_connection (storage); - *out_storage = NM_SETTINGS_STORAGE (g_steal_pointer (&storage)); - - nm_assert_self (self, TRUE); - - return TRUE; + NMSIfcfgRHPlugin * self = NMS_IFCFG_RH_PLUGIN(plugin); + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + gs_unref_object NMSIfcfgRHStorage *storage = NULL; + gs_unref_object NMConnection *reread = NULL; + gs_free char * full_filename = NULL; + GError * local = NULL; + gboolean reread_same; + struct timespec mtime; + + nm_assert_self(self, TRUE); + nm_assert(NM_IS_CONNECTION(connection)); + nm_assert(out_storage && !*out_storage); + nm_assert(out_connection && !*out_connection); + + if (!nms_ifcfg_rh_writer_write_connection( + connection, + IFCFG_DIR, + NULL, + nm_sett_util_allow_filename_cb, + NM_SETT_UTIL_ALLOW_FILENAME_DATA(&priv->storages, NULL), + &full_filename, + &reread, + &reread_same, + &local)) { + _LOGT("commit: %s (%s): failed to add: %s", + nm_connection_get_uuid(connection), + nm_connection_get_id(connection), + local->message); + g_propagate_error(error, local); + return FALSE; + } + + if (!reread || reread_same) + nm_g_object_ref_set(&reread, connection); + + nm_assert(full_filename && full_filename[0] == '/'); + + _LOGT("commit: %s (%s) added as \"%s\"", + nm_connection_get_uuid(reread), + nm_connection_get_id(reread), + full_filename); + + storage = + nms_ifcfg_rh_storage_new_connection(self, + full_filename, + g_steal_pointer(&reread), + nm_sett_util_stat_mtime(full_filename, FALSE, &mtime)); + + nm_sett_util_storages_add_take(&priv->storages, g_object_ref(storage)); + + *out_connection = nms_ifcfg_rh_storage_steal_connection(storage); + *out_storage = NM_SETTINGS_STORAGE(g_steal_pointer(&storage)); + + nm_assert_self(self, TRUE); + + return TRUE; } static gboolean -update_connection (NMSettingsPlugin *plugin, - NMSettingsStorage *storage_x, - NMConnection *connection, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error) +update_connection(NMSettingsPlugin * plugin, + NMSettingsStorage * storage_x, + NMConnection * connection, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error) { - NMSIfcfgRHPlugin *self = NMS_IFCFG_RH_PLUGIN (plugin); - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - NMSIfcfgRHStorage *storage = NMS_IFCFG_RH_STORAGE (storage_x); - const char *full_filename; - const char *uuid; - GError *local = NULL; - gs_unref_object NMConnection *reread = NULL; - gboolean reread_same; - struct timespec mtime; - - nm_assert_self (self, TRUE); - nm_assert (NM_IS_CONNECTION (connection)); - nm_assert (NMS_IS_IFCFG_RH_STORAGE (storage)); - nm_assert (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS); - nm_assert (!error || !*error); - - uuid = nms_ifcfg_rh_storage_get_uuid_opt (storage); - - nm_assert (uuid && nm_streq0 (uuid, nm_connection_get_uuid (connection))); - - full_filename = nms_ifcfg_rh_storage_get_filename (storage); - - nm_assert (full_filename); - nm_assert (storage == nm_sett_util_storages_lookup_by_filename (&priv->storages, full_filename)); - - if (!nms_ifcfg_rh_writer_write_connection (connection, - IFCFG_DIR, - full_filename, - nm_sett_util_allow_filename_cb, - NM_SETT_UTIL_ALLOW_FILENAME_DATA (&priv->storages, full_filename), - NULL, - &reread, - &reread_same, - &local)) { - _LOGT ("commit: failure to write %s (%s) to \"%s\": %s", - nm_connection_get_uuid (connection), - nm_connection_get_id (connection), - full_filename, - local->message); - g_propagate_error (error, local); - return FALSE; - } - - if ( !reread - || reread_same) - nm_g_object_ref_set (&reread, connection); - - _LOGT ("commit: \"%s\": profile %s (%s) written", - full_filename, - uuid, - nm_connection_get_id (connection)); - - storage->stat_mtime = *nm_sett_util_stat_mtime (full_filename, FALSE, &mtime); - - *out_storage = NM_SETTINGS_STORAGE (g_object_ref (storage)); - *out_connection = g_steal_pointer (&reread); - - nm_assert_self (self, TRUE); - - return TRUE; + NMSIfcfgRHPlugin * self = NMS_IFCFG_RH_PLUGIN(plugin); + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + NMSIfcfgRHStorage * storage = NMS_IFCFG_RH_STORAGE(storage_x); + const char * full_filename; + const char * uuid; + GError * local = NULL; + gs_unref_object NMConnection *reread = NULL; + gboolean reread_same; + struct timespec mtime; + + nm_assert_self(self, TRUE); + nm_assert(NM_IS_CONNECTION(connection)); + nm_assert(NMS_IS_IFCFG_RH_STORAGE(storage)); + nm_assert(_nm_connection_verify(connection, NULL) == NM_SETTING_VERIFY_SUCCESS); + nm_assert(!error || !*error); + + uuid = nms_ifcfg_rh_storage_get_uuid_opt(storage); + + nm_assert(uuid && nm_streq0(uuid, nm_connection_get_uuid(connection))); + + full_filename = nms_ifcfg_rh_storage_get_filename(storage); + + nm_assert(full_filename); + nm_assert(storage == nm_sett_util_storages_lookup_by_filename(&priv->storages, full_filename)); + + if (!nms_ifcfg_rh_writer_write_connection( + connection, + IFCFG_DIR, + full_filename, + nm_sett_util_allow_filename_cb, + NM_SETT_UTIL_ALLOW_FILENAME_DATA(&priv->storages, full_filename), + NULL, + &reread, + &reread_same, + &local)) { + _LOGT("commit: failure to write %s (%s) to \"%s\": %s", + nm_connection_get_uuid(connection), + nm_connection_get_id(connection), + full_filename, + local->message); + g_propagate_error(error, local); + return FALSE; + } + + if (!reread || reread_same) + nm_g_object_ref_set(&reread, connection); + + _LOGT("commit: \"%s\": profile %s (%s) written", + full_filename, + uuid, + nm_connection_get_id(connection)); + + storage->stat_mtime = *nm_sett_util_stat_mtime(full_filename, FALSE, &mtime); + + *out_storage = NM_SETTINGS_STORAGE(g_object_ref(storage)); + *out_connection = g_steal_pointer(&reread); + + nm_assert_self(self, TRUE); + + return TRUE; } static gboolean -delete_connection (NMSettingsPlugin *plugin, - NMSettingsStorage *storage_x, - GError **error) +delete_connection(NMSettingsPlugin *plugin, NMSettingsStorage *storage_x, GError **error) { - NMSIfcfgRHPlugin *self = NMS_IFCFG_RH_PLUGIN (plugin); - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - NMSIfcfgRHStorage *storage = NMS_IFCFG_RH_STORAGE (storage_x); - const char *operation_message; - const char *full_filename; - - nm_assert_self (self, TRUE); - nm_assert (!error || !*error); - nm_assert (NMS_IS_IFCFG_RH_STORAGE (storage)); - - full_filename = nms_ifcfg_rh_storage_get_filename (storage); - nm_assert (full_filename); - - nm_assert (nms_ifcfg_rh_storage_get_uuid_opt (storage)); - - nm_assert (storage == nm_sett_util_storages_lookup_by_filename (&priv->storages, full_filename)); - - { - gs_free char *keyfile = utils_get_keys_path (full_filename); - gs_free char *routefile = utils_get_route_path (full_filename); - gs_free char *route6file = utils_get_route6_path (full_filename); - const char *const files[] = { full_filename, keyfile, routefile, route6file }; - gboolean any_deleted = FALSE; - gboolean any_failure = FALSE; - int i; - - for (i = 0; i < G_N_ELEMENTS (files); i++) { - int errsv; - - if (unlink (files[i]) == 0) { - any_deleted = TRUE; - continue; - } - errsv = errno; - if (errsv == ENOENT) - continue; - - _LOGW ("commit: failure to delete file \"%s\": %s", - files[i], - nm_strerror_native (errsv)); - any_failure = TRUE; - } - if (any_failure) - operation_message = "failed to delete files from disk"; - else if (any_deleted) - operation_message = "deleted from disk"; - else - operation_message = "does not exist on disk"; - } - - _LOGT ("commit: deleted \"%s\", profile %s (%s)", - full_filename, - nms_ifcfg_rh_storage_get_uuid_opt (storage), - operation_message); - - nm_sett_util_storages_steal (&priv->storages, storage); - nms_ifcfg_rh_storage_destroy (storage); - - nm_assert_self (self, TRUE); - - return TRUE; + NMSIfcfgRHPlugin * self = NMS_IFCFG_RH_PLUGIN(plugin); + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + NMSIfcfgRHStorage * storage = NMS_IFCFG_RH_STORAGE(storage_x); + const char * operation_message; + const char * full_filename; + + nm_assert_self(self, TRUE); + nm_assert(!error || !*error); + nm_assert(NMS_IS_IFCFG_RH_STORAGE(storage)); + + full_filename = nms_ifcfg_rh_storage_get_filename(storage); + nm_assert(full_filename); + + nm_assert(nms_ifcfg_rh_storage_get_uuid_opt(storage)); + + nm_assert(storage == nm_sett_util_storages_lookup_by_filename(&priv->storages, full_filename)); + + { + gs_free char * keyfile = utils_get_keys_path(full_filename); + gs_free char * routefile = utils_get_route_path(full_filename); + gs_free char * route6file = utils_get_route6_path(full_filename); + const char *const files[] = {full_filename, keyfile, routefile, route6file}; + gboolean any_deleted = FALSE; + gboolean any_failure = FALSE; + int i; + + for (i = 0; i < G_N_ELEMENTS(files); i++) { + int errsv; + + if (unlink(files[i]) == 0) { + any_deleted = TRUE; + continue; + } + errsv = errno; + if (errsv == ENOENT) + continue; + + _LOGW("commit: failure to delete file \"%s\": %s", files[i], nm_strerror_native(errsv)); + any_failure = TRUE; + } + if (any_failure) + operation_message = "failed to delete files from disk"; + else if (any_deleted) + operation_message = "deleted from disk"; + else + operation_message = "does not exist on disk"; + } + + _LOGT("commit: deleted \"%s\", profile %s (%s)", + full_filename, + nms_ifcfg_rh_storage_get_uuid_opt(storage), + operation_message); + + nm_sett_util_storages_steal(&priv->storages, storage); + nms_ifcfg_rh_storage_destroy(storage); + + nm_assert_self(self, TRUE); + + return TRUE; } /*****************************************************************************/ static void -_unhandled_specs_reset (NMSIfcfgRHPlugin *self) +_unhandled_specs_reset(NMSIfcfgRHPlugin *self) { - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - gs_unref_hashtable GHashTable *unmanaged_specs = NULL; - gs_unref_hashtable GHashTable *unrecognized_specs = NULL; - NMSIfcfgRHStorage *storage; - - unmanaged_specs = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); - unrecognized_specs = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); - - c_list_for_each_entry (storage, &priv->storages._storage_lst_head, parent._storage_lst) { - if (storage->unmanaged_spec) - g_hash_table_add (unmanaged_specs, g_strdup (storage->unmanaged_spec)); - if (storage->unrecognized_spec) - g_hash_table_add (unrecognized_specs, g_strdup (storage->unrecognized_spec)); - } - - if (!nm_utils_hashtable_same_keys (unmanaged_specs, priv->unmanaged_specs)) { - g_hash_table_unref (priv->unmanaged_specs); - priv->unmanaged_specs = g_steal_pointer (&unmanaged_specs); - } - if (!nm_utils_hashtable_same_keys (unrecognized_specs, priv->unrecognized_specs)) { - g_hash_table_unref (priv->unrecognized_specs); - priv->unrecognized_specs = g_steal_pointer (&unrecognized_specs); - } - - if (!unmanaged_specs) - _nm_settings_plugin_emit_signal_unmanaged_specs_changed (NM_SETTINGS_PLUGIN (self)); - if (!unrecognized_specs) - _nm_settings_plugin_emit_signal_unrecognized_specs_changed (NM_SETTINGS_PLUGIN (self)); + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + gs_unref_hashtable GHashTable *unmanaged_specs = NULL; + gs_unref_hashtable GHashTable *unrecognized_specs = NULL; + NMSIfcfgRHStorage * storage; + + unmanaged_specs = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL); + unrecognized_specs = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL); + + c_list_for_each_entry (storage, &priv->storages._storage_lst_head, parent._storage_lst) { + if (storage->unmanaged_spec) + g_hash_table_add(unmanaged_specs, g_strdup(storage->unmanaged_spec)); + if (storage->unrecognized_spec) + g_hash_table_add(unrecognized_specs, g_strdup(storage->unrecognized_spec)); + } + + if (!nm_utils_hashtable_same_keys(unmanaged_specs, priv->unmanaged_specs)) { + g_hash_table_unref(priv->unmanaged_specs); + priv->unmanaged_specs = g_steal_pointer(&unmanaged_specs); + } + if (!nm_utils_hashtable_same_keys(unrecognized_specs, priv->unrecognized_specs)) { + g_hash_table_unref(priv->unrecognized_specs); + priv->unrecognized_specs = g_steal_pointer(&unrecognized_specs); + } + + if (!unmanaged_specs) + _nm_settings_plugin_emit_signal_unmanaged_specs_changed(NM_SETTINGS_PLUGIN(self)); + if (!unrecognized_specs) + _nm_settings_plugin_emit_signal_unrecognized_specs_changed(NM_SETTINGS_PLUGIN(self)); } static void -_unhandled_specs_merge_storages (NMSIfcfgRHPlugin *self, - NMSettUtilStorages *storages) +_unhandled_specs_merge_storages(NMSIfcfgRHPlugin *self, NMSettUtilStorages *storages) { - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - gboolean unmanaged_changed = FALSE; - gboolean unrecognized_changed = FALSE; - NMSIfcfgRHStorage *storage; - - c_list_for_each_entry (storage, &storages->_storage_lst_head, parent._storage_lst) { - if ( storage->unmanaged_spec - && !g_hash_table_contains (priv->unmanaged_specs, storage->unmanaged_spec)) { - unmanaged_changed = TRUE; - g_hash_table_add (priv->unmanaged_specs, g_strdup (storage->unmanaged_spec)); - } - if ( storage->unrecognized_spec - && !g_hash_table_contains (priv->unrecognized_specs, storage->unrecognized_spec)) { - unrecognized_changed = TRUE; - g_hash_table_add (priv->unrecognized_specs, g_strdup (storage->unrecognized_spec)); - } - } - - if (unmanaged_changed) - _nm_settings_plugin_emit_signal_unmanaged_specs_changed (NM_SETTINGS_PLUGIN (self)); - if (unrecognized_changed) - _nm_settings_plugin_emit_signal_unrecognized_specs_changed (NM_SETTINGS_PLUGIN (self)); + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + gboolean unmanaged_changed = FALSE; + gboolean unrecognized_changed = FALSE; + NMSIfcfgRHStorage * storage; + + c_list_for_each_entry (storage, &storages->_storage_lst_head, parent._storage_lst) { + if (storage->unmanaged_spec + && !g_hash_table_contains(priv->unmanaged_specs, storage->unmanaged_spec)) { + unmanaged_changed = TRUE; + g_hash_table_add(priv->unmanaged_specs, g_strdup(storage->unmanaged_spec)); + } + if (storage->unrecognized_spec + && !g_hash_table_contains(priv->unrecognized_specs, storage->unrecognized_spec)) { + unrecognized_changed = TRUE; + g_hash_table_add(priv->unrecognized_specs, g_strdup(storage->unrecognized_spec)); + } + } + + if (unmanaged_changed) + _nm_settings_plugin_emit_signal_unmanaged_specs_changed(NM_SETTINGS_PLUGIN(self)); + if (unrecognized_changed) + _nm_settings_plugin_emit_signal_unrecognized_specs_changed(NM_SETTINGS_PLUGIN(self)); } static GSList * -_unhandled_specs_from_hashtable (GHashTable *hash) +_unhandled_specs_from_hashtable(GHashTable *hash) { - gs_free const char **keys = NULL; - GSList *list = NULL; - guint i, l; - - keys = nm_utils_strdict_get_keys (hash, TRUE, &l); - for (i = l; i > 0; ) { - i--; - list = g_slist_prepend (list, g_strdup (keys[i])); - } - return list; + gs_free const char **keys = NULL; + GSList * list = NULL; + guint i, l; + + keys = nm_utils_strdict_get_keys(hash, TRUE, &l); + for (i = l; i > 0;) { + i--; + list = g_slist_prepend(list, g_strdup(keys[i])); + } + return list; } static GSList * -get_unmanaged_specs (NMSettingsPlugin *plugin) +get_unmanaged_specs(NMSettingsPlugin *plugin) { - return _unhandled_specs_from_hashtable (NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (plugin)->unmanaged_specs); + return _unhandled_specs_from_hashtable( + NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(plugin)->unmanaged_specs); } static GSList * -get_unrecognized_specs (NMSettingsPlugin *plugin) +get_unrecognized_specs(NMSettingsPlugin *plugin) { - return _unhandled_specs_from_hashtable (NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (plugin)->unrecognized_specs); + return _unhandled_specs_from_hashtable( + NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(plugin)->unrecognized_specs); } /*****************************************************************************/ static void -impl_ifcfgrh_get_ifcfg_details (NMSIfcfgRHPlugin *self, - GDBusMethodInvocation *context, - const char *in_ifcfg) +impl_ifcfgrh_get_ifcfg_details(NMSIfcfgRHPlugin * self, + GDBusMethodInvocation *context, + const char * in_ifcfg) { - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - gs_free char *ifcfg_path = NULL; - NMSIfcfgRHStorage *storage; - const char *uuid; - const char *path; - - if (in_ifcfg[0] != '/') { - g_dbus_method_invocation_return_error (context, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "ifcfg path '%s' is not absolute", in_ifcfg); - return; - } - - ifcfg_path = utils_detect_ifcfg_path (in_ifcfg, TRUE); - if (!ifcfg_path) { - g_dbus_method_invocation_return_error (context, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "ifcfg path '%s' is not an ifcfg base file", in_ifcfg); - return; - } - - storage = nm_sett_util_storages_lookup_by_filename (&priv->storages, ifcfg_path); - if (!storage) { - g_dbus_method_invocation_return_error (context, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "ifcfg file '%s' unknown", in_ifcfg); - return; - } - - uuid = nms_ifcfg_rh_storage_get_uuid_opt (storage); - if (!uuid) { - g_dbus_method_invocation_return_error (context, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "ifcfg file '%s' not managed by NetworkManager", in_ifcfg); - return; - } - - /* It is ugly that the ifcfg-rh plugin needs to call back into NMSettings this - * way. - * There are alternatives (like invoking a signal), but they are all significant - * extra code (and performance overhead). So the quick and dirty solution here - * is likely to be simpler than getting this right (also from point of readability!). - */ - path = nm_settings_get_dbus_path_for_uuid (nm_settings_get (), uuid); - - if (!path) { - g_dbus_method_invocation_return_error (context, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_FAILED, - "unable to get the connection D-Bus path"); - return; - } - - g_dbus_method_invocation_return_value (context, - g_variant_new ("(so)", uuid, path)); + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + gs_free char * ifcfg_path = NULL; + NMSIfcfgRHStorage * storage; + const char * uuid; + const char * path; + + if (in_ifcfg[0] != '/') { + g_dbus_method_invocation_return_error(context, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "ifcfg path '%s' is not absolute", + in_ifcfg); + return; + } + + ifcfg_path = utils_detect_ifcfg_path(in_ifcfg, TRUE); + if (!ifcfg_path) { + g_dbus_method_invocation_return_error(context, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "ifcfg path '%s' is not an ifcfg base file", + in_ifcfg); + return; + } + + storage = nm_sett_util_storages_lookup_by_filename(&priv->storages, ifcfg_path); + if (!storage) { + g_dbus_method_invocation_return_error(context, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "ifcfg file '%s' unknown", + in_ifcfg); + return; + } + + uuid = nms_ifcfg_rh_storage_get_uuid_opt(storage); + if (!uuid) { + g_dbus_method_invocation_return_error(context, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "ifcfg file '%s' not managed by NetworkManager", + in_ifcfg); + return; + } + + /* It is ugly that the ifcfg-rh plugin needs to call back into NMSettings this + * way. + * There are alternatives (like invoking a signal), but they are all significant + * extra code (and performance overhead). So the quick and dirty solution here + * is likely to be simpler than getting this right (also from point of readability!). + */ + path = nm_settings_get_dbus_path_for_uuid(nm_settings_get(), uuid); + + if (!path) { + g_dbus_method_invocation_return_error(context, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "unable to get the connection D-Bus path"); + return; + } + + g_dbus_method_invocation_return_value(context, g_variant_new("(so)", uuid, path)); } /*****************************************************************************/ static void -_dbus_clear (NMSIfcfgRHPlugin *self) +_dbus_clear(NMSIfcfgRHPlugin *self) { - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - guint id; + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + guint id; - nm_clear_g_signal_handler (priv->dbus.connection, &priv->dbus.signal_id); + nm_clear_g_signal_handler(priv->dbus.connection, &priv->dbus.signal_id); - nm_clear_g_cancellable (&priv->dbus.cancellable); + nm_clear_g_cancellable(&priv->dbus.cancellable); - if ((id = nm_steal_int (&priv->dbus.regist_id))) { - if (!g_dbus_connection_unregister_object (priv->dbus.connection, id)) - _LOGW ("dbus: unexpected failure to unregister object"); - } + if ((id = nm_steal_int(&priv->dbus.regist_id))) { + if (!g_dbus_connection_unregister_object(priv->dbus.connection, id)) + _LOGW("dbus: unexpected failure to unregister object"); + } - g_clear_object (&priv->dbus.connection); + g_clear_object(&priv->dbus.connection); } static void -_dbus_connection_closed (GDBusConnection *connection, - gboolean remote_peer_vanished, - GError *error, - gpointer user_data) +_dbus_connection_closed(GDBusConnection *connection, + gboolean remote_peer_vanished, + GError * error, + gpointer user_data) { - _LOGW ("dbus: %s bus closed", IFCFGRH1_BUS_NAME); - _dbus_clear (NMS_IFCFG_RH_PLUGIN (user_data)); + _LOGW("dbus: %s bus closed", IFCFGRH1_BUS_NAME); + _dbus_clear(NMS_IFCFG_RH_PLUGIN(user_data)); - /* Retry or recover? */ + /* Retry or recover? */ } static void -_method_call (GDBusConnection *connection, - const char *sender, - const char *object_path, - const char *interface_name, - const char *method_name, - GVariant *parameters, - GDBusMethodInvocation *invocation, - gpointer user_data) +_method_call(GDBusConnection * connection, + const char * sender, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) { - NMSIfcfgRHPlugin *self = NMS_IFCFG_RH_PLUGIN (user_data); - - if (nm_streq (interface_name, IFCFGRH1_IFACE1_NAME)) { - if (nm_streq (method_name, IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS)) { - const char *ifcfg; - - g_variant_get (parameters, "(&s)", &ifcfg); - impl_ifcfgrh_get_ifcfg_details (self, invocation, ifcfg); - return; - } - } - - g_dbus_method_invocation_return_error (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_UNKNOWN_METHOD, - "Unknown method %s", - method_name); + NMSIfcfgRHPlugin *self = NMS_IFCFG_RH_PLUGIN(user_data); + + if (nm_streq(interface_name, IFCFGRH1_IFACE1_NAME)) { + if (nm_streq(method_name, IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS)) { + const char *ifcfg; + + g_variant_get(parameters, "(&s)", &ifcfg); + impl_ifcfgrh_get_ifcfg_details(self, invocation, ifcfg); + return; + } + } + + g_dbus_method_invocation_return_error(invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "Unknown method %s", + method_name); } -static GDBusInterfaceInfo *const interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO ( - IFCFGRH1_IFACE1_NAME, - .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( - NM_DEFINE_GDBUS_METHOD_INFO ( - IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS, - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("ifcfg", "s"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("uuid", "s"), - NM_DEFINE_GDBUS_ARG_INFO ("path", "o"), - ), - ), - ), -); +static GDBusInterfaceInfo *const interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO( + IFCFGRH1_IFACE1_NAME, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS( + NM_DEFINE_GDBUS_METHOD_INFO( + IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS, + .in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("ifcfg", "s"), ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("uuid", "s"), + NM_DEFINE_GDBUS_ARG_INFO("path", "o"), ), ), ), ); static void -_dbus_request_name_done (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +_dbus_request_name_done(GObject *source_object, GAsyncResult *res, gpointer user_data) { - GDBusConnection *connection = G_DBUS_CONNECTION (source_object); - NMSIfcfgRHPlugin *self; - NMSIfcfgRHPluginPrivate *priv; - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *ret = NULL; - guint32 result; - - ret = g_dbus_connection_call_finish (connection, res, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = NMS_IFCFG_RH_PLUGIN (user_data); - priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - - g_clear_object (&priv->dbus.cancellable); - - if (!ret) { - _LOGW ("dbus: couldn't acquire D-Bus service: %s", error->message); - _dbus_clear (self); - return; - } - - g_variant_get (ret, "(u)", &result); - - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - _LOGW ("dbus: couldn't acquire ifcfgrh1 D-Bus service (already taken)"); - _dbus_clear (self); - return; - } - - { - static const GDBusInterfaceVTable interface_vtable = { - .method_call = _method_call, - }; - - priv->dbus.regist_id = g_dbus_connection_register_object (connection, - IFCFGRH1_OBJECT_PATH, - interface_info, - NM_UNCONST_PTR (GDBusInterfaceVTable, &interface_vtable), - self, - NULL, - &error); - if (!priv->dbus.regist_id) { - _LOGW ("dbus: couldn't register D-Bus service: %s", error->message); - _dbus_clear (self); - return; - } - } - - _LOGD ("dbus: acquired D-Bus service %s and exported %s object", - IFCFGRH1_BUS_NAME, - IFCFGRH1_OBJECT_PATH); + GDBusConnection * connection = G_DBUS_CONNECTION(source_object); + NMSIfcfgRHPlugin * self; + NMSIfcfgRHPluginPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *ret = NULL; + guint32 result; + + ret = g_dbus_connection_call_finish(connection, res, &error); + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = NMS_IFCFG_RH_PLUGIN(user_data); + priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + + g_clear_object(&priv->dbus.cancellable); + + if (!ret) { + _LOGW("dbus: couldn't acquire D-Bus service: %s", error->message); + _dbus_clear(self); + return; + } + + g_variant_get(ret, "(u)", &result); + + if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + _LOGW("dbus: couldn't acquire ifcfgrh1 D-Bus service (already taken)"); + _dbus_clear(self); + return; + } + + { + static const GDBusInterfaceVTable interface_vtable = { + .method_call = _method_call, + }; + + priv->dbus.regist_id = g_dbus_connection_register_object( + connection, + IFCFGRH1_OBJECT_PATH, + interface_info, + NM_UNCONST_PTR(GDBusInterfaceVTable, &interface_vtable), + self, + NULL, + &error); + if (!priv->dbus.regist_id) { + _LOGW("dbus: couldn't register D-Bus service: %s", error->message); + _dbus_clear(self); + return; + } + } + + _LOGD("dbus: acquired D-Bus service %s and exported %s object", + IFCFGRH1_BUS_NAME, + IFCFGRH1_OBJECT_PATH); } static void -_dbus_create_done (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +_dbus_create_done(GObject *source_object, GAsyncResult *res, gpointer user_data) { - NMSIfcfgRHPlugin *self; - NMSIfcfgRHPluginPrivate *priv; - gs_free_error GError *error = NULL; - GDBusConnection *connection; - - connection = g_dbus_connection_new_for_address_finish (res, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = NMS_IFCFG_RH_PLUGIN (user_data); - priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - - g_clear_object (&priv->dbus.cancellable); - - if (!connection) { - _LOGW ("dbus: couldn't initialize system bus: %s", error->message); - return; - } - - priv->dbus.connection = connection; - priv->dbus.cancellable = g_cancellable_new (); - - priv->dbus.signal_id = g_signal_connect (priv->dbus.connection, - "closed", - G_CALLBACK (_dbus_connection_closed), - self); - - g_dbus_connection_call (priv->dbus.connection, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - "RequestName", - g_variant_new ("(su)", - IFCFGRH1_BUS_NAME, - DBUS_NAME_FLAG_DO_NOT_QUEUE), - G_VARIANT_TYPE ("(u)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - priv->dbus.cancellable, - _dbus_request_name_done, - self); + NMSIfcfgRHPlugin * self; + NMSIfcfgRHPluginPrivate *priv; + gs_free_error GError *error = NULL; + GDBusConnection * connection; + + connection = g_dbus_connection_new_for_address_finish(res, &error); + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = NMS_IFCFG_RH_PLUGIN(user_data); + priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + + g_clear_object(&priv->dbus.cancellable); + + if (!connection) { + _LOGW("dbus: couldn't initialize system bus: %s", error->message); + return; + } + + priv->dbus.connection = connection; + priv->dbus.cancellable = g_cancellable_new(); + + priv->dbus.signal_id = g_signal_connect(priv->dbus.connection, + "closed", + G_CALLBACK(_dbus_connection_closed), + self); + + g_dbus_connection_call(priv->dbus.connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "RequestName", + g_variant_new("(su)", IFCFGRH1_BUS_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE), + G_VARIANT_TYPE("(u)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->dbus.cancellable, + _dbus_request_name_done, + self); } static void -_dbus_setup (NMSIfcfgRHPlugin *self) +_dbus_setup(NMSIfcfgRHPlugin *self) { - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - gs_free char *address = NULL; - gs_free_error GError *error = NULL; - - _dbus_clear (self); - - if (!NM_MAIN_DBUS_CONNECTION_GET) { - _LOGW ("dbus: don't use D-Bus for %s service", IFCFGRH1_BUS_NAME); - return; - } - - /* We use a separate D-Bus connection so that org.freedesktop.NetworkManager and com.redhat.ifcfgrh1 - * are exported by different connections. */ - address = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - if (address == NULL) { - _LOGW ("dbus: failed getting address for system bus: %s", error->message); - return; - } - - priv->dbus.cancellable = g_cancellable_new (); - - g_dbus_connection_new_for_address (address, - G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT - | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, - NULL, - priv->dbus.cancellable, - _dbus_create_done, - self); + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + gs_free char * address = NULL; + gs_free_error GError *error = NULL; + + _dbus_clear(self); + + if (!NM_MAIN_DBUS_CONNECTION_GET) { + _LOGW("dbus: don't use D-Bus for %s service", IFCFGRH1_BUS_NAME); + return; + } + + /* We use a separate D-Bus connection so that org.freedesktop.NetworkManager and com.redhat.ifcfgrh1 + * are exported by different connections. */ + address = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (address == NULL) { + _LOGW("dbus: failed getting address for system bus: %s", error->message); + return; + } + + priv->dbus.cancellable = g_cancellable_new(); + + g_dbus_connection_new_for_address(address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT + | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, + NULL, + priv->dbus.cancellable, + _dbus_create_done, + self); } static void -config_changed_cb (NMConfig *config, - NMConfigData *config_data, - NMConfigChangeFlags changes, - NMConfigData *old_data, - NMSIfcfgRHPlugin *self) +config_changed_cb(NMConfig * config, + NMConfigData * config_data, + NMConfigChangeFlags changes, + NMConfigData * old_data, + NMSIfcfgRHPlugin * self) { - NMSIfcfgRHPluginPrivate *priv; - - /* If the dbus connection for some reason is borked the D-Bus service - * won't be offered. - * - * On SIGHUP and SIGUSR1 try to re-connect to D-Bus. So in the unlikely - * event that the D-Bus connection is broken, that allows for recovery - * without need for restarting NetworkManager. */ - if (!NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_CAUSE_SIGHUP - | NM_CONFIG_CHANGE_CAUSE_SIGUSR1)) - return; - - priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); - if ( !priv->dbus.connection - && !priv->dbus.cancellable) - _dbus_setup (self); + NMSIfcfgRHPluginPrivate *priv; + + /* If the dbus connection for some reason is borked the D-Bus service + * won't be offered. + * + * On SIGHUP and SIGUSR1 try to re-connect to D-Bus. So in the unlikely + * event that the D-Bus connection is broken, that allows for recovery + * without need for restarting NetworkManager. */ + if (!NM_FLAGS_ANY(changes, NM_CONFIG_CHANGE_CAUSE_SIGHUP | NM_CONFIG_CHANGE_CAUSE_SIGUSR1)) + return; + + priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); + if (!priv->dbus.connection && !priv->dbus.cancellable) + _dbus_setup(self); } /*****************************************************************************/ static void -nms_ifcfg_rh_plugin_init (NMSIfcfgRHPlugin *self) +nms_ifcfg_rh_plugin_init(NMSIfcfgRHPlugin *self) { - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); - priv->config = g_object_ref (nm_config_get ()); + priv->config = g_object_ref(nm_config_get()); - priv->unmanaged_specs = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); - priv->unrecognized_specs = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); + priv->unmanaged_specs = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL); + priv->unrecognized_specs = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL); - priv->storages = (NMSettUtilStorages) NM_SETT_UTIL_STORAGES_INIT (priv->storages, nms_ifcfg_rh_storage_destroy); + priv->storages = (NMSettUtilStorages) NM_SETT_UTIL_STORAGES_INIT(priv->storages, + nms_ifcfg_rh_storage_destroy); } static void -constructed (GObject *object) +constructed(GObject *object) { - NMSIfcfgRHPlugin *self = NMS_IFCFG_RH_PLUGIN (object); - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); + NMSIfcfgRHPlugin * self = NMS_IFCFG_RH_PLUGIN(object); + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); - G_OBJECT_CLASS (nms_ifcfg_rh_plugin_parent_class)->constructed (object); + G_OBJECT_CLASS(nms_ifcfg_rh_plugin_parent_class)->constructed(object); - g_signal_connect (priv->config, - NM_CONFIG_SIGNAL_CONFIG_CHANGED, - G_CALLBACK (config_changed_cb), - self); + g_signal_connect(priv->config, + NM_CONFIG_SIGNAL_CONFIG_CHANGED, + G_CALLBACK(config_changed_cb), + self); - _dbus_setup (self); + _dbus_setup(self); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMSIfcfgRHPlugin *self = NMS_IFCFG_RH_PLUGIN (object); - NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE (self); + NMSIfcfgRHPlugin * self = NMS_IFCFG_RH_PLUGIN(object); + NMSIfcfgRHPluginPrivate *priv = NMS_IFCFG_RH_PLUGIN_GET_PRIVATE(self); - if (priv->config) - g_signal_handlers_disconnect_by_func (priv->config, config_changed_cb, self); + if (priv->config) + g_signal_handlers_disconnect_by_func(priv->config, config_changed_cb, self); - /* FIXME(shutdown) we need a stop method so that we can unregistering the D-Bus service - * when NMSettings is shutting down, and not when the instance gets destroyed. */ - _dbus_clear (self); + /* FIXME(shutdown) we need a stop method so that we can unregistering the D-Bus service + * when NMSettings is shutting down, and not when the instance gets destroyed. */ + _dbus_clear(self); - nm_sett_util_storages_clear (&priv->storages); + nm_sett_util_storages_clear(&priv->storages); - g_clear_object (&priv->config); + g_clear_object(&priv->config); - G_OBJECT_CLASS (nms_ifcfg_rh_plugin_parent_class)->dispose (object); + G_OBJECT_CLASS(nms_ifcfg_rh_plugin_parent_class)->dispose(object); - nm_clear_pointer (&priv->unmanaged_specs, g_hash_table_destroy); - nm_clear_pointer (&priv->unrecognized_specs, g_hash_table_destroy); + nm_clear_pointer(&priv->unmanaged_specs, g_hash_table_destroy); + nm_clear_pointer(&priv->unrecognized_specs, g_hash_table_destroy); } static void -nms_ifcfg_rh_plugin_class_init (NMSIfcfgRHPluginClass *klass) +nms_ifcfg_rh_plugin_class_init(NMSIfcfgRHPluginClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMSettingsPluginClass *plugin_class = NM_SETTINGS_PLUGIN_CLASS (klass); - - object_class->constructed = constructed; - object_class->dispose = dispose; - - plugin_class->plugin_name = "ifcfg-rh"; - plugin_class->get_unmanaged_specs = get_unmanaged_specs; - plugin_class->get_unrecognized_specs = get_unrecognized_specs; - plugin_class->reload_connections = reload_connections; - plugin_class->load_connections = load_connections; - plugin_class->load_connections_done = load_connections_done; - plugin_class->add_connection = add_connection; - plugin_class->update_connection = update_connection; - plugin_class->delete_connection = delete_connection; + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingsPluginClass *plugin_class = NM_SETTINGS_PLUGIN_CLASS(klass); + + object_class->constructed = constructed; + object_class->dispose = dispose; + + plugin_class->plugin_name = "ifcfg-rh"; + plugin_class->get_unmanaged_specs = get_unmanaged_specs; + plugin_class->get_unrecognized_specs = get_unrecognized_specs; + plugin_class->reload_connections = reload_connections; + plugin_class->load_connections = load_connections; + plugin_class->load_connections_done = load_connections_done; + plugin_class->add_connection = add_connection; + plugin_class->update_connection = update_connection; + plugin_class->delete_connection = delete_connection; } /*****************************************************************************/ G_MODULE_EXPORT NMSettingsPlugin * -nm_settings_plugin_factory (void) + nm_settings_plugin_factory(void) { - return g_object_new (NMS_TYPE_IFCFG_RH_PLUGIN, NULL); + return g_object_new(NMS_TYPE_IFCFG_RH_PLUGIN, NULL); } diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h index 14cadac6..ff713cf3 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Dan Williams * Søren Sandmann @@ -8,16 +8,20 @@ #ifndef __NMS_IFCFG_RH_PLUGIN_H__ #define __NMS_IFCFG_RH_PLUGIN_H__ -#define NMS_TYPE_IFCFG_RH_PLUGIN (nms_ifcfg_rh_plugin_get_type ()) -#define NMS_IFCFG_RH_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMS_TYPE_IFCFG_RH_PLUGIN, NMSIfcfgRHPlugin)) -#define NMS_IFCFG_RH_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMS_TYPE_IFCFG_RH_PLUGIN, NMSIfcfgRHPluginClass)) -#define NMS_IS_IFCFG_RH_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMS_TYPE_IFCFG_RH_PLUGIN)) -#define NMS_IS_IFCFG_RH_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMS_TYPE_IFCFG_RH_PLUGIN)) -#define NMS_IFCFG_RH_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMS_TYPE_IFCFG_RH_PLUGIN, NMSIfcfgRHPluginClass)) +#define NMS_TYPE_IFCFG_RH_PLUGIN (nms_ifcfg_rh_plugin_get_type()) +#define NMS_IFCFG_RH_PLUGIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NMS_TYPE_IFCFG_RH_PLUGIN, NMSIfcfgRHPlugin)) +#define NMS_IFCFG_RH_PLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NMS_TYPE_IFCFG_RH_PLUGIN, NMSIfcfgRHPluginClass)) +#define NMS_IS_IFCFG_RH_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMS_TYPE_IFCFG_RH_PLUGIN)) +#define NMS_IS_IFCFG_RH_PLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NMS_TYPE_IFCFG_RH_PLUGIN)) +#define NMS_IFCFG_RH_PLUGIN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NMS_TYPE_IFCFG_RH_PLUGIN, NMSIfcfgRHPluginClass)) -typedef struct _NMSIfcfgRHPlugin NMSIfcfgRHPlugin; +typedef struct _NMSIfcfgRHPlugin NMSIfcfgRHPlugin; typedef struct _NMSIfcfgRHPluginClass NMSIfcfgRHPluginClass; -GType nms_ifcfg_rh_plugin_get_type (void); +GType nms_ifcfg_rh_plugin_get_type(void); #endif /* __NMS_IFCFG_RH_PLUGIN_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 1a9df92c..5a021a8c 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 - 2017 Red Hat, Inc. */ @@ -52,801 +52,836 @@ #define _NMLOG_DOMAIN LOGD_SETTINGS #define _NMLOG_PREFIX_NAME "ifcfg-rh" -#define _NMLOG(level, ...) \ - G_STMT_START { \ - nm_log ((level), (_NMLOG_DOMAIN), NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME": " \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } G_STMT_END - -#define PARSE_WARNING(...) _LOGW ("%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), " " _NM_UTILS_MACRO_REST(__VA_ARGS__)) +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + nm_log((level), \ + (_NMLOG_DOMAIN), \ + NULL, \ + NULL, \ + "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME ": " _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END + +#define PARSE_WARNING(...) \ + _LOGW("%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), " " _NM_UTILS_MACRO_REST(__VA_ARGS__)) /*****************************************************************************/ static char * -get_full_file_path (const char *ifcfg_path, const char *file_path) +get_full_file_path(const char *ifcfg_path, const char *file_path) { - const char *base = file_path; - gs_free char *dirname = NULL; - char *p; + const char * base = file_path; + gs_free char *dirname = NULL; + char * p; - g_return_val_if_fail (ifcfg_path != NULL, NULL); - g_return_val_if_fail (file_path != NULL, NULL); + g_return_val_if_fail(ifcfg_path != NULL, NULL); + g_return_val_if_fail(file_path != NULL, NULL); - if (file_path[0] == '/') - return g_strdup (file_path); + if (file_path[0] == '/') + return g_strdup(file_path); - p = strrchr (file_path, '/'); - if (p) - base = p + 1; + p = strrchr(file_path, '/'); + if (p) + base = p + 1; - dirname = g_path_get_dirname (ifcfg_path); - return g_build_path ("/", dirname, base, NULL); + dirname = g_path_get_dirname(ifcfg_path); + return g_build_path("/", dirname, base, NULL); } /*****************************************************************************/ static NMSettingSecretFlags -_secret_read_ifcfg_flags (shvarFile *ifcfg, const char *flags_key) +_secret_read_ifcfg_flags(shvarFile *ifcfg, const char *flags_key) { - NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; - gs_free char *val_free = NULL; - const char *val; - - nm_assert (flags_key); - nm_assert (g_str_has_suffix (flags_key, "_FLAGS")); - - val = svGetValueStr (ifcfg, flags_key, &val_free); - if (val) { - if (strstr (val, SECRET_FLAG_AGENT)) - flags |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; - if (strstr (val, SECRET_FLAG_NOT_SAVED)) - flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED; - if (strstr (val, SECRET_FLAG_NOT_REQUIRED)) - flags |= NM_SETTING_SECRET_FLAG_NOT_REQUIRED; - } - return flags; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + gs_free char * val_free = NULL; + const char * val; + + nm_assert(flags_key); + nm_assert(g_str_has_suffix(flags_key, "_FLAGS")); + + val = svGetValueStr(ifcfg, flags_key, &val_free); + if (val) { + if (strstr(val, SECRET_FLAG_AGENT)) + flags |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; + if (strstr(val, SECRET_FLAG_NOT_SAVED)) + flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED; + if (strstr(val, SECRET_FLAG_NOT_REQUIRED)) + flags |= NM_SETTING_SECRET_FLAG_NOT_REQUIRED; + } + return flags; } static void -_secret_read_ifcfg (shvarFile *ifcfg, - shvarFile *keys_ifcfg, - const char *name, - char **value, - NMSettingSecretFlags *flags) +_secret_read_ifcfg(shvarFile * ifcfg, + shvarFile * keys_ifcfg, + const char * name, + char ** value, + NMSettingSecretFlags *flags) { - char flags_key[250]; + char flags_key[250]; - nm_sprintf_buf (flags_key, "%s_FLAGS", name); + nm_sprintf_buf(flags_key, "%s_FLAGS", name); - *flags = _secret_read_ifcfg_flags (ifcfg, flags_key); + *flags = _secret_read_ifcfg_flags(ifcfg, flags_key); - if (*flags != NM_SETTING_SECRET_FLAG_NONE) - *value = NULL; - else { - *value = svGetValue_cp (ifcfg, name); - if (!*value && keys_ifcfg) - *value = svGetValue_cp (keys_ifcfg, name); - } + if (*flags != NM_SETTING_SECRET_FLAG_NONE) + *value = NULL; + else { + *value = svGetValue_cp(ifcfg, name); + if (!*value && keys_ifcfg) + *value = svGetValue_cp(keys_ifcfg, name); + } } static void -_secret_set_from_ifcfg (gpointer setting, - shvarFile *ifcfg, - shvarFile *keys_ifcfg, - const char *ifcfg_key, - const char *property_name) +_secret_set_from_ifcfg(gpointer setting, + shvarFile * ifcfg, + shvarFile * keys_ifcfg, + const char *ifcfg_key, + const char *property_name) { - nm_auto_free_secret char *secret = NULL; - NMSettingSecretFlags flags; - char flags_key[250]; + nm_auto_free_secret char *secret = NULL; + NMSettingSecretFlags flags; + char flags_key[250]; - nm_assert (NM_IS_SETTING (setting)); + nm_assert(NM_IS_SETTING(setting)); - _secret_read_ifcfg (ifcfg, keys_ifcfg, ifcfg_key, &secret, &flags); + _secret_read_ifcfg(ifcfg, keys_ifcfg, ifcfg_key, &secret, &flags); - g_object_set (setting, - property_name, - secret, - nm_sprintf_buf (flags_key, "%s-flags", property_name), - flags, - NULL); + g_object_set(setting, + property_name, + secret, + nm_sprintf_buf(flags_key, "%s-flags", property_name), + flags, + NULL); } static gboolean -_secret_password_raw_to_bytes (const char *ifcfg_key, - const char *password_raw, - GBytes **out_bytes, - GError **error) +_secret_password_raw_to_bytes(const char *ifcfg_key, + const char *password_raw, + GBytes ** out_bytes, + GError ** error) { - nm_auto_free_secret_buf NMSecretBuf *secret = NULL; - gsize len; - - if (!password_raw) { - NM_SET_OUT (out_bytes, NULL); - return TRUE; - } - - if (password_raw[0] == '0' && password_raw[1] == 'x') - password_raw += 2; - - secret = nm_secret_buf_new (strlen (password_raw) / 2 + 3); - if (!nm_utils_hexstr2bin_full (password_raw, FALSE, FALSE, ":", 0, secret->bin, secret->len, &len)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid hex password in %s", - ifcfg_key); - return FALSE; - } - - NM_SET_OUT (out_bytes, nm_secret_buf_to_gbytes_take (g_steal_pointer (&secret), len)); - return TRUE; + nm_auto_free_secret_buf NMSecretBuf *secret = NULL; + gsize len; + + if (!password_raw) { + NM_SET_OUT(out_bytes, NULL); + return TRUE; + } + + if (password_raw[0] == '0' && password_raw[1] == 'x') + password_raw += 2; + + secret = nm_secret_buf_new(strlen(password_raw) / 2 + 3); + if (!nm_utils_hexstr2bin_full(password_raw, + FALSE, + FALSE, + FALSE, + ":", + 0, + secret->bin, + secret->len, + &len)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid hex password in %s", + ifcfg_key); + return FALSE; + } + + NM_SET_OUT(out_bytes, nm_secret_buf_to_gbytes_take(g_steal_pointer(&secret), len)); + return TRUE; } /*****************************************************************************/ static GBytes * -_cert_get_cert_bytes (const char *ifcfg_path, - const char *value, - GError **error) +_cert_get_cert_bytes(const char *ifcfg_path, const char *value, GError **error) { - gs_free char *path = NULL; - - if (NM_STR_HAS_PREFIX (value, "pkcs11:")) - return _nm_setting_802_1x_cert_value_to_bytes (NM_SETTING_802_1X_CK_SCHEME_PKCS11, (guint8 *) value, -1, error); - - path = get_full_file_path (ifcfg_path, value); - return _nm_setting_802_1x_cert_value_to_bytes (NM_SETTING_802_1X_CK_SCHEME_PATH, (guint8 *) path, -1, error); + gs_free char *path = NULL; + + if (NM_STR_HAS_PREFIX(value, "pkcs11:")) + return _nm_setting_802_1x_cert_value_to_bytes(NM_SETTING_802_1X_CK_SCHEME_PKCS11, + (guint8 *) value, + -1, + error); + + path = get_full_file_path(ifcfg_path, value); + return _nm_setting_802_1x_cert_value_to_bytes(NM_SETTING_802_1X_CK_SCHEME_PATH, + (guint8 *) path, + -1, + error); } static gboolean -_cert_get_cert (shvarFile *ifcfg, - const char *ifcfg_key, - GBytes **out_cert, - NMSetting8021xCKScheme *out_scheme, - GError **error) +_cert_get_cert(shvarFile * ifcfg, + const char * ifcfg_key, + GBytes ** out_cert, + NMSetting8021xCKScheme *out_scheme, + GError ** error) { - nm_auto_free_secret char *val_free = NULL; - const char *val; - gs_unref_bytes GBytes *cert = NULL; - GError *local = NULL; - NMSetting8021xCKScheme scheme; - - val = svGetValueStr (ifcfg, ifcfg_key, &val_free); - if (!val) { - NM_SET_OUT (out_cert, NULL); - NM_SET_OUT (out_scheme, NM_SETTING_802_1X_CK_SCHEME_UNKNOWN); - return TRUE; - } - - cert = _cert_get_cert_bytes (svFileGetName (ifcfg), val, &local); - if (!cert) - goto err; - - scheme = _nm_setting_802_1x_cert_get_scheme (cert, &local); - if (scheme == NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) - goto err; - - NM_SET_OUT (out_cert, g_steal_pointer (&cert)); - NM_SET_OUT (out_scheme, scheme); - return TRUE; + nm_auto_free_secret char *val_free = NULL; + const char * val; + gs_unref_bytes GBytes *cert = NULL; + GError * local = NULL; + NMSetting8021xCKScheme scheme; + + val = svGetValueStr(ifcfg, ifcfg_key, &val_free); + if (!val) { + NM_SET_OUT(out_cert, NULL); + NM_SET_OUT(out_scheme, NM_SETTING_802_1X_CK_SCHEME_UNKNOWN); + return TRUE; + } + + cert = _cert_get_cert_bytes(svFileGetName(ifcfg), val, &local); + if (!cert) + goto err; + + scheme = _nm_setting_802_1x_cert_get_scheme(cert, &local); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) + goto err; + + NM_SET_OUT(out_cert, g_steal_pointer(&cert)); + NM_SET_OUT(out_scheme, scheme); + return TRUE; err: - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "invalid certificate %s: %s", - ifcfg_key, - local->message); - g_error_free (local); - return FALSE; + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid certificate %s: %s", + ifcfg_key, + local->message); + g_error_free(local); + return FALSE; } static gboolean -_cert_set_from_ifcfg (gpointer setting, - shvarFile *ifcfg, - const char *ifcfg_key, - const char *property_name, - GBytes **out_cert, - GError **error) +_cert_set_from_ifcfg(gpointer setting, + shvarFile * ifcfg, + const char *ifcfg_key, + const char *property_name, + GBytes ** out_cert, + GError ** error) { - gs_unref_bytes GBytes *cert = NULL; + gs_unref_bytes GBytes *cert = NULL; - if (!_cert_get_cert (ifcfg, - ifcfg_key, - &cert, - NULL, - error)) - return FALSE; + if (!_cert_get_cert(ifcfg, ifcfg_key, &cert, NULL, error)) + return FALSE; - g_object_set (setting, property_name, cert, NULL); + g_object_set(setting, property_name, cert, NULL); - NM_SET_OUT (out_cert, g_steal_pointer (&cert)); - return TRUE; + NM_SET_OUT(out_cert, g_steal_pointer(&cert)); + return TRUE; } /*****************************************************************************/ static void -check_if_bond_slave (shvarFile *ifcfg, - NMSettingConnection *s_con) +check_if_bond_slave(shvarFile *ifcfg, NMSettingConnection *s_con) { - gs_free char *value = NULL; - const char *v; - const char *master; - - v = svGetValueStr (ifcfg, "MASTER_UUID", &value); - if (!v) - v = svGetValueStr (ifcfg, "MASTER", &value); - - if (v) { - master = nm_setting_connection_get_master (s_con); - if (master) { - PARSE_WARNING ("Already configured as slave of %s. Ignoring MASTER{_UUID}=\"%s\"", - master, v); - return; - } - - g_object_set (s_con, - NM_SETTING_CONNECTION_MASTER, v, - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, - NULL); - } - - /* We should be checking for SLAVE=yes as well, but NM used to not set that, - * so for backward-compatibility, we don't check. - */ + gs_free char *value = NULL; + const char * v; + const char * master; + + v = svGetValueStr(ifcfg, "MASTER_UUID", &value); + if (!v) + v = svGetValueStr(ifcfg, "MASTER", &value); + + if (v) { + master = nm_setting_connection_get_master(s_con); + if (master) { + PARSE_WARNING("Already configured as slave of %s. Ignoring MASTER{_UUID}=\"%s\"", + master, + v); + return; + } + + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + v, + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BOND_SETTING_NAME, + NULL); + } + + /* We should be checking for SLAVE=yes as well, but NM used to not set that, + * so for backward-compatibility, we don't check. + */ } static void -check_if_team_slave (shvarFile *ifcfg, - NMSettingConnection *s_con) +check_if_team_slave(shvarFile *ifcfg, NMSettingConnection *s_con) { - gs_free char *value = NULL; - const char *v; - const char *master; - - v = svGetValueStr (ifcfg, "TEAM_MASTER_UUID", &value); - if (!v) - v = svGetValueStr (ifcfg, "TEAM_MASTER", &value); - if (!v) - return; - - master = nm_setting_connection_get_master (s_con); - if (master) { - PARSE_WARNING ("Already configured as slave of %s. Ignoring TEAM_MASTER{_UUID}=\"%s\"", - master, v); - return; - } - - g_object_set (s_con, - NM_SETTING_CONNECTION_MASTER, v, - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, - NULL); + gs_free char *value = NULL; + const char * v; + const char * master; + + v = svGetValueStr(ifcfg, "TEAM_MASTER_UUID", &value); + if (!v) + v = svGetValueStr(ifcfg, "TEAM_MASTER", &value); + if (!v) + return; + + master = nm_setting_connection_get_master(s_con); + if (master) { + PARSE_WARNING("Already configured as slave of %s. Ignoring TEAM_MASTER{_UUID}=\"%s\"", + master, + v); + return; + } + + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + v, + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_TEAM_SETTING_NAME, + NULL); } static char * -make_connection_name (shvarFile *ifcfg, - const char *ifcfg_name, - const char *suggested, - const char *prefix) +make_connection_name(shvarFile * ifcfg, + const char *ifcfg_name, + const char *suggested, + const char *prefix) { - char *full_name = NULL, *name; - - /* If the ifcfg file already has a NAME, always use that */ - name = svGetValueStr_cp (ifcfg, "NAME"); - if (name) - return name; - - /* Otherwise construct a new NAME */ - if (!prefix) - prefix = "System"; - - /* For cosmetic reasons, if the suggested name is the same as - * the ifcfg files name, don't use it. Mainly for wifi so that - * the SSID is shown in the connection ID instead of just "wlan0". - */ - if (suggested && strcmp (ifcfg_name, suggested)) - full_name = g_strdup_printf ("%s %s (%s)", prefix, suggested, ifcfg_name); - else - full_name = g_strdup_printf ("%s %s", prefix, ifcfg_name); - - return full_name; + char *full_name = NULL, *name; + + /* If the ifcfg file already has a NAME, always use that */ + name = svGetValueStr_cp(ifcfg, "NAME"); + if (name) + return name; + + /* Otherwise, construct a new NAME */ + if (!prefix) + prefix = "System"; + + /* For cosmetic reasons, if the suggested name is the same as + * the ifcfg files name, don't use it. Mainly for wifi so that + * the SSID is shown in the connection ID instead of just "wlan0". + */ + if (suggested && strcmp(ifcfg_name, suggested)) + full_name = g_strdup_printf("%s %s (%s)", prefix, suggested, ifcfg_name); + else + full_name = g_strdup_printf("%s %s", prefix, ifcfg_name); + + return full_name; } static NMSetting * -make_connection_setting (const char *file, - shvarFile *ifcfg, - const char *type, - const char *suggested, - const char *prefix) +make_connection_setting(const char *file, + shvarFile * ifcfg, + const char *type, + const char *suggested, + const char *prefix) { - NMSettingConnection *s_con; - NMSettingConnectionLldp lldp; - const char *ifcfg_name = NULL; - gs_free char *new_id = NULL; - const char *uuid; - gs_free char *uuid_free = NULL; - gs_free char *value = NULL; - const char *v; - gs_free char *stable_id = NULL; - const char *const *iter; - int vint64, i_val; - - ifcfg_name = utils_get_ifcfg_name (file, TRUE); - if (!ifcfg_name) - return NULL; - - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - - new_id = make_connection_name (ifcfg, ifcfg_name, suggested, prefix); - g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL); - - /* Try for a UUID key before falling back to hashing the file name */ - uuid = svGetValueStr (ifcfg, "UUID", &uuid_free); - if (!uuid) { - uuid_free = nm_utils_uuid_generate_from_string (svFileGetName (ifcfg), -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); - uuid = uuid_free; - } - - g_object_set (s_con, - NM_SETTING_CONNECTION_TYPE, type, - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_STABLE_ID, svGetValue (ifcfg, "STABLE_ID", &stable_id), - NULL); - - v = svGetValueStr (ifcfg, "DEVICE", &value); - if (v) { - GError *error = NULL; - - /* Only validate for NMU_IFACE_KERNEL, because ifcfg plugin anyway - * doesn't support OVS types. */ - if (nm_utils_ifname_valid (v, NMU_IFACE_KERNEL, &error)) { - g_object_set (s_con, - NM_SETTING_CONNECTION_INTERFACE_NAME, v, - NULL); - } else { - PARSE_WARNING ("invalid DEVICE name '%s': %s", v, error->message); - g_error_free (error); - } - } - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "LLDP", &value); - if (nm_streq0 (v, "rx")) - lldp = NM_SETTING_CONNECTION_LLDP_ENABLE_RX; - else - lldp = svParseBoolean (v, NM_SETTING_CONNECTION_LLDP_DEFAULT); - - /* Missing ONBOOT is treated as "ONBOOT=true" by the old network service */ - g_object_set (s_con, - NM_SETTING_CONNECTION_AUTOCONNECT, - svGetValueBoolean (ifcfg, "ONBOOT", TRUE), - NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, - (int) svGetValueInt64 (ifcfg, "AUTOCONNECT_PRIORITY", 10, - NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN, - NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX, - NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT), - NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, - (int) svGetValueInt64 (ifcfg, "AUTOCONNECT_RETRIES", 10, - -1, G_MAXINT32, -1), - NM_SETTING_CONNECTION_MULTI_CONNECT, - (int) svGetValueInt64 (ifcfg, "MULTI_CONNECT", 10, - G_MININT32, G_MAXINT32, NM_CONNECTION_MULTI_CONNECT_DEFAULT), - NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES, - svGetValueBoolean (ifcfg, "AUTOCONNECT_SLAVES", NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT), - NM_SETTING_CONNECTION_LLDP, lldp, - NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "USERS", &value); - if (v) { - gs_free const char **items = NULL; - - items = nm_utils_strsplit_set (v, " "); - for (iter = items; iter && *iter; iter++) { - if (!nm_setting_connection_add_permission (s_con, "user", *iter, NULL)) - PARSE_WARNING ("invalid USERS item '%s'", *iter); - } - } - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "ZONE", &value); - g_object_set (s_con, NM_SETTING_CONNECTION_ZONE, v, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "SECONDARY_UUIDS", &value); - if (v) { - gs_free const char **items = NULL; - - items = nm_utils_strsplit_set (v, " \t"); - for (iter = items; iter && *iter; iter++) { - if (!nm_setting_connection_add_secondary (s_con, *iter)) - PARSE_WARNING ("secondary connection UUID '%s' already added", *iter); - } - } - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "BRIDGE_UUID", &value); - if (!v) - v = svGetValueStr (ifcfg, "BRIDGE", &value); - if (v) { - const char *old_value; - - if ((old_value = nm_setting_connection_get_master (s_con))) { - PARSE_WARNING ("Already configured as slave of %s. Ignoring BRIDGE=\"%s\"", - old_value, v); - } else { - g_object_set (s_con, NM_SETTING_CONNECTION_MASTER, v, NULL); - g_object_set (s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, - NM_SETTING_BRIDGE_SETTING_NAME, NULL); - } - } - - check_if_bond_slave (ifcfg, s_con); - check_if_team_slave (ifcfg, s_con); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "OVS_PORT_UUID", &value); - if (!v) - v = svGetValueStr (ifcfg, "OVS_PORT", &value); - if (v) { - const char *old_value; - - if ((old_value = nm_setting_connection_get_master (s_con))) { - PARSE_WARNING ("Already configured as slave of %s. Ignoring OVS_PORT=\"%s\"", - old_value, v); - } else { - g_object_set (s_con, NM_SETTING_CONNECTION_MASTER, v, NULL); - g_object_set (s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, - NM_SETTING_OVS_PORT_SETTING_NAME, NULL); - } - } - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "VRF_UUID", &value); - if (!v) - v = svGetValueStr (ifcfg, "VRF", &value); - if (v) { - const char *old_value; - - if ((old_value = nm_setting_connection_get_master (s_con))) { - PARSE_WARNING ("Already configured as slave of %s. Ignoring VRF{_UUID}=\"%s\"", - old_value, v); - } else { - g_object_set (s_con, NM_SETTING_CONNECTION_MASTER, v, NULL); - g_object_set (s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, - NM_SETTING_VRF_SETTING_NAME, NULL); - } - } - - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "GATEWAY_PING_TIMEOUT", &value); - if (v) { - gint64 tmp; - - tmp = _nm_utils_ascii_str_to_int64 (v, 10, 0, G_MAXINT32 - 1, -1); - if (tmp >= 0) { - if (tmp > 600) { - tmp = 600; - PARSE_WARNING ("invalid GATEWAY_PING_TIMEOUT time"); - } - g_object_set (s_con, NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, (guint) tmp, NULL); - } else - PARSE_WARNING ("invalid GATEWAY_PING_TIMEOUT time"); - } - - switch (svGetValueBoolean (ifcfg, "CONNECTION_METERED", -1)) { - case TRUE: - g_object_set (s_con, NM_SETTING_CONNECTION_METERED, NM_METERED_YES, NULL); - break; - case FALSE: - g_object_set (s_con, NM_SETTING_CONNECTION_METERED, NM_METERED_NO, NULL); - break; - } - - vint64 = svGetValueInt64 (ifcfg, "AUTH_RETRIES", 10, -1, G_MAXINT32, -1); - g_object_set (s_con, NM_SETTING_CONNECTION_AUTH_RETRIES, (int) vint64, NULL); - - nm_clear_g_free (&value); - v = svGetValue (ifcfg, "DEVTIMEOUT", &value); - if (v) { - v = nm_str_skip_leading_spaces (v); - vint64 = _nm_utils_ascii_str_to_int64 (v, 10, 0, ((gint64) G_MAXINT32) / 1000, -1); - if (vint64 != -1) - vint64 *= 1000; - else if (v[0] != '\0') { - char *endptr; - double d; - - d = nm_g_ascii_strtod (v, &endptr); - endptr = nm_str_skip_leading_spaces (endptr); - if ( errno == 0 - && endptr[0] == '\0' - && d >= 0.0) { - d *= 1000.0; - - /* We round. Yes, this is not correct to round IEEE 754 floats in general, - * but sufficient for our case where we know that NetworkManager wrote the - * setting with up to 3 digits for the milliseconds. */ - d += 0.5; - if ( d >= 0.0 - && d <= (double) G_MAXINT32) - vint64 = (gint64) d; - } - } - if (vint64 == -1) - PARSE_WARNING ("invalid DEVTIMEOUT setting"); - else - g_object_set (s_con, NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, (int) vint64, NULL); - } - - nm_clear_g_free (&value); - v = svGetValue (ifcfg, "MUD_URL", &value); - if (v) - g_object_set (s_con, NM_SETTING_CONNECTION_MUD_URL, v, NULL); - - i_val = NM_SETTING_CONNECTION_MDNS_DEFAULT; - if (!svGetValueEnum (ifcfg, "MDNS", - nm_setting_connection_mdns_get_type (), - &i_val, NULL)) - PARSE_WARNING ("invalid MDNS setting"); - g_object_set (s_con, NM_SETTING_CONNECTION_MDNS, i_val, NULL); - - i_val = NM_SETTING_CONNECTION_LLMNR_DEFAULT; - if (!svGetValueEnum (ifcfg, "LLMNR", - nm_setting_connection_llmnr_get_type (), - &i_val, NULL)) - PARSE_WARNING ("invalid LLMNR setting"); - g_object_set (s_con, NM_SETTING_CONNECTION_LLMNR, i_val, NULL); - - return NM_SETTING (s_con); + NMSettingConnection * s_con; + NMSettingConnectionLldp lldp; + const char * ifcfg_name = NULL; + gs_free char * new_id = NULL; + const char * uuid; + gs_free char * uuid_free = NULL; + gs_free char * value = NULL; + const char * v; + gs_free char * stable_id = NULL; + const char *const * iter; + int vint64, i_val; + + ifcfg_name = utils_get_ifcfg_name(file, TRUE); + if (!ifcfg_name) + return NULL; + + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + + new_id = make_connection_name(ifcfg, ifcfg_name, suggested, prefix); + g_object_set(s_con, NM_SETTING_CONNECTION_ID, new_id, NULL); + + /* Try for a UUID key before falling back to hashing the file name */ + uuid = svGetValueStr(ifcfg, "UUID", &uuid_free); + if (!uuid) { + uuid_free = nm_utils_uuid_generate_from_string(svFileGetName(ifcfg), + -1, + NM_UTILS_UUID_TYPE_LEGACY, + NULL); + uuid = uuid_free; + } + + g_object_set(s_con, + NM_SETTING_CONNECTION_TYPE, + type, + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_STABLE_ID, + svGetValue(ifcfg, "STABLE_ID", &stable_id), + NULL); + + v = svGetValueStr(ifcfg, "DEVICE", &value); + if (v) { + GError *error = NULL; + + /* Only validate for NMU_IFACE_KERNEL, because ifcfg plugin anyway + * doesn't support OVS types. */ + if (nm_utils_ifname_valid(v, NMU_IFACE_KERNEL, &error)) { + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, v, NULL); + } else { + PARSE_WARNING("invalid DEVICE name '%s': %s", v, error->message); + g_error_free(error); + } + } + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "LLDP", &value); + if (nm_streq0(v, "rx")) + lldp = NM_SETTING_CONNECTION_LLDP_ENABLE_RX; + else + lldp = svParseBoolean(v, NM_SETTING_CONNECTION_LLDP_DEFAULT); + + /* Missing ONBOOT is treated as "ONBOOT=true" by the old network service */ + g_object_set(s_con, + NM_SETTING_CONNECTION_AUTOCONNECT, + svGetValueBoolean(ifcfg, "ONBOOT", TRUE), + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, + (int) svGetValueInt64(ifcfg, + "AUTOCONNECT_PRIORITY", + 10, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT), + NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, + (int) svGetValueInt64(ifcfg, "AUTOCONNECT_RETRIES", 10, -1, G_MAXINT32, -1), + NM_SETTING_CONNECTION_MULTI_CONNECT, + (int) svGetValueInt64(ifcfg, + "MULTI_CONNECT", + 10, + G_MININT32, + G_MAXINT32, + NM_CONNECTION_MULTI_CONNECT_DEFAULT), + NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES, + svGetValueBoolean(ifcfg, + "AUTOCONNECT_SLAVES", + NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT), + NM_SETTING_CONNECTION_LLDP, + lldp, + NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "USERS", &value); + if (v) { + gs_free const char **items = NULL; + + items = nm_utils_strsplit_set(v, " "); + for (iter = items; iter && *iter; iter++) { + if (!nm_setting_connection_add_permission(s_con, "user", *iter, NULL)) + PARSE_WARNING("invalid USERS item '%s'", *iter); + } + } + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "ZONE", &value); + g_object_set(s_con, NM_SETTING_CONNECTION_ZONE, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "SECONDARY_UUIDS", &value); + if (v) { + gs_free const char **items = NULL; + + items = nm_utils_strsplit_set(v, " \t"); + for (iter = items; iter && *iter; iter++) { + if (!nm_setting_connection_add_secondary(s_con, *iter)) + PARSE_WARNING("secondary connection UUID '%s' already added", *iter); + } + } + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "BRIDGE_UUID", &value); + if (!v) + v = svGetValueStr(ifcfg, "BRIDGE", &value); + if (v) { + const char *old_value; + + if ((old_value = nm_setting_connection_get_master(s_con))) { + PARSE_WARNING("Already configured as slave of %s. Ignoring BRIDGE=\"%s\"", + old_value, + v); + } else { + g_object_set(s_con, NM_SETTING_CONNECTION_MASTER, v, NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BRIDGE_SETTING_NAME, + NULL); + } + } + + check_if_bond_slave(ifcfg, s_con); + check_if_team_slave(ifcfg, s_con); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "OVS_PORT_UUID", &value); + if (!v) + v = svGetValueStr(ifcfg, "OVS_PORT", &value); + if (v) { + const char *old_value; + + if ((old_value = nm_setting_connection_get_master(s_con))) { + PARSE_WARNING("Already configured as slave of %s. Ignoring OVS_PORT=\"%s\"", + old_value, + v); + } else { + g_object_set(s_con, NM_SETTING_CONNECTION_MASTER, v, NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_OVS_PORT_SETTING_NAME, + NULL); + } + } + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "VRF_UUID", &value); + if (!v) + v = svGetValueStr(ifcfg, "VRF", &value); + if (v) { + const char *old_value; + + if ((old_value = nm_setting_connection_get_master(s_con))) { + PARSE_WARNING("Already configured as slave of %s. Ignoring VRF{_UUID}=\"%s\"", + old_value, + v); + } else { + g_object_set(s_con, NM_SETTING_CONNECTION_MASTER, v, NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_VRF_SETTING_NAME, + NULL); + } + } + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "GATEWAY_PING_TIMEOUT", &value); + if (v) { + gint64 tmp; + + tmp = _nm_utils_ascii_str_to_int64(v, 10, 0, G_MAXINT32 - 1, -1); + if (tmp >= 0) { + if (tmp > 600) { + tmp = 600; + PARSE_WARNING("invalid GATEWAY_PING_TIMEOUT time"); + } + g_object_set(s_con, NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, (guint) tmp, NULL); + } else + PARSE_WARNING("invalid GATEWAY_PING_TIMEOUT time"); + } + + switch (svGetValueBoolean(ifcfg, "CONNECTION_METERED", -1)) { + case TRUE: + g_object_set(s_con, NM_SETTING_CONNECTION_METERED, NM_METERED_YES, NULL); + break; + case FALSE: + g_object_set(s_con, NM_SETTING_CONNECTION_METERED, NM_METERED_NO, NULL); + break; + } + + vint64 = svGetValueInt64(ifcfg, "AUTH_RETRIES", 10, -1, G_MAXINT32, -1); + g_object_set(s_con, NM_SETTING_CONNECTION_AUTH_RETRIES, (int) vint64, NULL); + + nm_clear_g_free(&value); + v = svGetValue(ifcfg, "DEVTIMEOUT", &value); + if (v) { + v = nm_str_skip_leading_spaces(v); + vint64 = _nm_utils_ascii_str_to_int64(v, 10, 0, ((gint64) G_MAXINT32) / 1000, -1); + if (vint64 != -1) + vint64 *= 1000; + else if (v[0] != '\0') { + char * endptr; + double d; + + d = nm_g_ascii_strtod(v, &endptr); + endptr = nm_str_skip_leading_spaces(endptr); + if (errno == 0 && endptr[0] == '\0' && d >= 0.0) { + d *= 1000.0; + + /* We round. Yes, this is not correct to round IEEE 754 floats in general, + * but sufficient for our case where we know that NetworkManager wrote the + * setting with up to 3 digits for the milliseconds. */ + d += 0.5; + if (d >= 0.0 && d <= (double) G_MAXINT32) + vint64 = (gint64) d; + } + } + if (vint64 == -1) + PARSE_WARNING("invalid DEVTIMEOUT setting"); + else + g_object_set(s_con, NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, (int) vint64, NULL); + } + + nm_clear_g_free(&value); + v = svGetValue(ifcfg, "MUD_URL", &value); + if (v) + g_object_set(s_con, NM_SETTING_CONNECTION_MUD_URL, v, NULL); + + i_val = NM_SETTING_CONNECTION_MDNS_DEFAULT; + if (!svGetValueEnum(ifcfg, "MDNS", nm_setting_connection_mdns_get_type(), &i_val, NULL)) + PARSE_WARNING("invalid MDNS setting"); + g_object_set(s_con, NM_SETTING_CONNECTION_MDNS, i_val, NULL); + + i_val = NM_SETTING_CONNECTION_LLMNR_DEFAULT; + if (!svGetValueEnum(ifcfg, "LLMNR", nm_setting_connection_llmnr_get_type(), &i_val, NULL)) + PARSE_WARNING("invalid LLMNR setting"); + g_object_set(s_con, NM_SETTING_CONNECTION_LLMNR, i_val, NULL); + + return NM_SETTING(s_con); } static gboolean -read_ip4_address (shvarFile *ifcfg, - const char *tag, - gboolean *out_has_key, - guint32 *out_addr, - GError **error) +read_ip4_address(shvarFile * ifcfg, + const char *tag, + gboolean * out_has_key, + guint32 * out_addr, + GError ** error) { - gs_free char *value_to_free = NULL; - const char *value; - in_addr_t a; - - nm_assert (ifcfg); - nm_assert (tag); - nm_assert (!error || !*error); - - value = svGetValueStr (ifcfg, tag, &value_to_free); - if (!value) { - NM_SET_OUT (out_has_key, FALSE); - NM_SET_OUT (out_addr, 0); - return TRUE; - } - - if (inet_pton (AF_INET, value, &a) != 1) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid %s IP4 address '%s'", tag, value); - return FALSE; - } - - NM_SET_OUT (out_has_key, TRUE); - NM_SET_OUT (out_addr, a); - return TRUE; + gs_free char *value_to_free = NULL; + const char * value; + in_addr_t a; + + nm_assert(ifcfg); + nm_assert(tag); + nm_assert(!error || !*error); + + value = svGetValueStr(ifcfg, tag, &value_to_free); + if (!value) { + NM_SET_OUT(out_has_key, FALSE); + NM_SET_OUT(out_addr, 0); + return TRUE; + } + + if (inet_pton(AF_INET, value, &a) != 1) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid %s IP4 address '%s'", + tag, + value); + return FALSE; + } + + NM_SET_OUT(out_has_key, TRUE); + NM_SET_OUT(out_addr, a); + return TRUE; } static gboolean -is_any_ip4_address_defined (shvarFile *ifcfg, int *idx) +is_any_ip4_address_defined(shvarFile *ifcfg, int *idx) { - int i, ignore, *ret_idx; - - ret_idx = idx ?: &ignore; - - for (i = -1; i <= 2; i++) { - gs_free char *value = NULL; - char tag[256]; - - if (svGetValueStr (ifcfg, numbered_tag (tag, "IPADDR", i), &value)) { - *ret_idx = i; - return TRUE; - } - - if (svGetValueStr (ifcfg, numbered_tag (tag, "PREFIX", i), &value)) { - *ret_idx = i; - return TRUE; - } - - if (svGetValueStr (ifcfg, numbered_tag (tag, "NETMASK", i), &value)) { - *ret_idx = i; - return TRUE; - } - } - return FALSE; + int i, ignore, *ret_idx; + + ret_idx = idx ?: &ignore; + + for (i = -1; i <= 2; i++) { + gs_free char *value = NULL; + char tag[256]; + + if (svGetValueStr(ifcfg, numbered_tag(tag, "IPADDR", i), &value)) { + *ret_idx = i; + return TRUE; + } + + if (svGetValueStr(ifcfg, numbered_tag(tag, "PREFIX", i), &value)) { + *ret_idx = i; + return TRUE; + } + + if (svGetValueStr(ifcfg, numbered_tag(tag, "NETMASK", i), &value)) { + *ret_idx = i; + return TRUE; + } + } + return FALSE; } /* Returns TRUE on missing address or valid address */ static gboolean -read_full_ip4_address (shvarFile *ifcfg, - gint32 which, - NMIPAddress *base_addr, - NMIPAddress **out_address, - char **out_gateway, - GError **error) +read_full_ip4_address(shvarFile * ifcfg, + gint32 which, + NMIPAddress * base_addr, + NMIPAddress **out_address, + char ** out_gateway, + GError ** error) { - char tag[256]; - char prefix_tag[256]; - guint32 ipaddr; - gs_free char *value = NULL; - const char *v; - int prefix = 0; - gboolean has_key; - guint32 a; - char inet_buf[NM_UTILS_INET_ADDRSTRLEN]; - - g_return_val_if_fail (which >= -1, FALSE); - g_return_val_if_fail (ifcfg != NULL, FALSE); - g_return_val_if_fail (out_address != NULL, FALSE); - g_return_val_if_fail (*out_address == NULL, FALSE); - g_return_val_if_fail (!error || !*error, FALSE); - - /* IP address */ - if (!read_ip4_address (ifcfg, - numbered_tag (tag, "IPADDR", which), - &has_key, &ipaddr, error)) - return FALSE; - if (!has_key) { - if (!base_addr) - return TRUE; - nm_ip_address_get_address_binary (base_addr, &ipaddr); - } - - /* Gateway */ - if (out_gateway && !*out_gateway) { - if (!read_ip4_address (ifcfg, - numbered_tag (tag, "GATEWAY", which), - &has_key, &a, error)) - return FALSE; - if (has_key) - *out_gateway = nm_utils_inet4_ntop_dup (a); - } - - /* Prefix */ - numbered_tag (prefix_tag, "PREFIX", which); - v = svGetValueStr (ifcfg, prefix_tag, &value); - if (v) { - prefix = _nm_utils_ascii_str_to_int64 (v, 10, 0, 32, -1); - if (prefix < 0) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid IP4 prefix '%s'", v); - return FALSE; - } - } else { - /* Fall back to NETMASK if no PREFIX was specified */ - if (!read_ip4_address (ifcfg, - numbered_tag (tag, "NETMASK", which), - &has_key, &a, error)) - return FALSE; - if (has_key) - prefix = nm_utils_ip4_netmask_to_prefix (a); - else { - if (base_addr) - prefix = nm_ip_address_get_prefix (base_addr); - else { - /* Try to autodetermine the prefix for the address' class */ - prefix = _nm_utils_ip4_get_default_prefix (ipaddr); - PARSE_WARNING ("missing %s, assuming %s/%d", prefix_tag, _nm_utils_inet4_ntop (ipaddr, inet_buf), prefix); - } - } - } - - *out_address = nm_ip_address_new_binary (AF_INET, &ipaddr, prefix, error); - if (*out_address) - return TRUE; - - return FALSE; + char tag[256]; + char prefix_tag[256]; + guint32 ipaddr; + gs_free char *value = NULL; + const char * v; + int prefix = 0; + gboolean has_key; + guint32 a; + char inet_buf[NM_UTILS_INET_ADDRSTRLEN]; + + g_return_val_if_fail(which >= -1, FALSE); + g_return_val_if_fail(ifcfg != NULL, FALSE); + g_return_val_if_fail(out_address != NULL, FALSE); + g_return_val_if_fail(*out_address == NULL, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + /* IP address */ + if (!read_ip4_address(ifcfg, numbered_tag(tag, "IPADDR", which), &has_key, &ipaddr, error)) + return FALSE; + if (!has_key) { + if (!base_addr) + return TRUE; + nm_ip_address_get_address_binary(base_addr, &ipaddr); + } + + /* Gateway */ + if (out_gateway && !*out_gateway) { + if (!read_ip4_address(ifcfg, numbered_tag(tag, "GATEWAY", which), &has_key, &a, error)) + return FALSE; + if (has_key) + *out_gateway = nm_utils_inet4_ntop_dup(a); + } + + /* Prefix */ + numbered_tag(prefix_tag, "PREFIX", which); + v = svGetValueStr(ifcfg, prefix_tag, &value); + if (v) { + prefix = _nm_utils_ascii_str_to_int64(v, 10, 0, 32, -1); + if (prefix < 0) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IP4 prefix '%s'", + v); + return FALSE; + } + } else { + /* Fall back to NETMASK if no PREFIX was specified */ + if (!read_ip4_address(ifcfg, numbered_tag(tag, "NETMASK", which), &has_key, &a, error)) + return FALSE; + if (has_key) + prefix = nm_utils_ip4_netmask_to_prefix(a); + else { + if (base_addr) + prefix = nm_ip_address_get_prefix(base_addr); + else { + /* Try to autodetermine the prefix for the address' class */ + prefix = _nm_utils_ip4_get_default_prefix(ipaddr); + PARSE_WARNING("missing %s, assuming %s/%d", + prefix_tag, + _nm_utils_inet4_ntop(ipaddr, inet_buf), + prefix); + } + } + } + + *out_address = nm_ip_address_new_binary(AF_INET, &ipaddr, prefix, error); + if (*out_address) + return TRUE; + + return FALSE; } /*****************************************************************************/ static gboolean -parse_route_line_is_comment (const char *line) +parse_route_line_is_comment(const char *line) { - /* we obtained the line from a legacy route file. Here we skip - * empty lines and comments. - * - * initscripts compares: "$line" =~ '^[[:space:]]*(\#.*)?$' - */ - while (nm_utils_is_separator (line[0])) - line++; - if (NM_IN_SET (line[0], '\0', '#')) - return TRUE; - return FALSE; + /* we obtained the line from a legacy route file. Here we skip + * empty lines and comments. + * + * initscripts compares: "$line" =~ '^[[:space:]]*(\#.*)?$' + */ + while (nm_utils_is_separator(line[0])) + line++; + if (NM_IN_SET(line[0], '\0', '#')) + return TRUE; + return FALSE; } /*****************************************************************************/ typedef enum { - PARSE_LINE_AF_FLAG_FOR_IPV4 = 0x01, - PARSE_LINE_AF_FLAG_FOR_IPV6 = 0x02, + PARSE_LINE_AF_FLAG_FOR_IPV4 = 0x01, + PARSE_LINE_AF_FLAG_FOR_IPV6 = 0x02, } ParseLineAFFlag; typedef struct { - const char *key; + const char *key; - /* the element is not available in this case. */ - ParseLineAFFlag disabled:3; + /* the element is not available in this case. */ + ParseLineAFFlag disabled : 3; - bool disabled_with_options_route:1; + bool disabled_with_options_route : 1; - /* whether the element is to be ignored. Ignord is different from - * "disabled", because we still parse the option, but don't use it. */ - ParseLineAFFlag ignore:3; + /* whether the element is to be ignored. Ignord is different from + * "disabled", because we still parse the option, but don't use it. */ + ParseLineAFFlag ignore : 3; - bool int_base_16:1; + bool int_base_16 : 1; - /* the type, one of PARSE_LINE_TYPE_* */ - char type; + /* the type, one of PARSE_LINE_TYPE_* */ + char type; } ParseLineInfo; typedef struct { - - /* whether the command line option was found, and @v is - * initialized. */ - bool has:1; - - union { - guint8 uint8; - guint32 uint32; - const char *str; - struct { - guint32 uint32; - bool lock:1; - } uint32_with_lock; - struct { - NMIPAddr addr; - guint8 plen; - bool has_plen:1; - } addr; - } v; + /* whether the command line option was found, and @v is + * initialized. */ + bool has : 1; + + union { + guint8 uint8; + guint32 uint32; + const char *str; + struct { + guint32 uint32; + bool lock : 1; + } uint32_with_lock; + struct { + NMIPAddr addr; + guint8 plen; + bool has_plen : 1; + } addr; + } v; } ParseLineData; enum { - /* route attributes */ - PARSE_LINE_ATTR_ROUTE_TYPE, - PARSE_LINE_ATTR_ROUTE_TABLE, - PARSE_LINE_ATTR_ROUTE_SRC, - PARSE_LINE_ATTR_ROUTE_FROM, - PARSE_LINE_ATTR_ROUTE_TOS, - PARSE_LINE_ATTR_ROUTE_SCOPE, - PARSE_LINE_ATTR_ROUTE_ONLINK, - PARSE_LINE_ATTR_ROUTE_WINDOW, - PARSE_LINE_ATTR_ROUTE_CWND, - PARSE_LINE_ATTR_ROUTE_INITCWND, - PARSE_LINE_ATTR_ROUTE_INITRWND, - PARSE_LINE_ATTR_ROUTE_MTU, - - /* iproute2 arguments that only matter when parsing the file. */ - PARSE_LINE_ATTR_ROUTE_TO, - PARSE_LINE_ATTR_ROUTE_VIA, - PARSE_LINE_ATTR_ROUTE_METRIC, - - /* iproute2 parameters that are well known and that we silently ignore. */ - PARSE_LINE_ATTR_ROUTE_DEV, + /* route attributes */ + PARSE_LINE_ATTR_ROUTE_TYPE, + PARSE_LINE_ATTR_ROUTE_TABLE, + PARSE_LINE_ATTR_ROUTE_SRC, + PARSE_LINE_ATTR_ROUTE_FROM, + PARSE_LINE_ATTR_ROUTE_TOS, + PARSE_LINE_ATTR_ROUTE_SCOPE, + PARSE_LINE_ATTR_ROUTE_ONLINK, + PARSE_LINE_ATTR_ROUTE_WINDOW, + PARSE_LINE_ATTR_ROUTE_CWND, + PARSE_LINE_ATTR_ROUTE_INITCWND, + PARSE_LINE_ATTR_ROUTE_INITRWND, + PARSE_LINE_ATTR_ROUTE_MTU, + + /* iproute2 arguments that only matter when parsing the file. */ + PARSE_LINE_ATTR_ROUTE_TO, + PARSE_LINE_ATTR_ROUTE_VIA, + PARSE_LINE_ATTR_ROUTE_METRIC, + + /* iproute2 parameters that are well known and that we silently ignore. */ + PARSE_LINE_ATTR_ROUTE_DEV, }; -#define PARSE_LINE_TYPE_UINT8 '8' -#define PARSE_LINE_TYPE_UINT32 'u' -#define PARSE_LINE_TYPE_UINT32_WITH_LOCK 'l' -#define PARSE_LINE_TYPE_ADDR 'a' -#define PARSE_LINE_TYPE_ADDR_WITH_PREFIX 'p' -#define PARSE_LINE_TYPE_IFNAME 'i' -#define PARSE_LINE_TYPE_FLAG 'f' -#define PARSE_LINE_TYPE_ROUTE_SCOPE 'S' -#define PARSE_LINE_TYPE_STRING 's' +#define PARSE_LINE_TYPE_UINT8 '8' +#define PARSE_LINE_TYPE_UINT32 'u' +#define PARSE_LINE_TYPE_UINT32_WITH_LOCK 'l' +#define PARSE_LINE_TYPE_ADDR 'a' +#define PARSE_LINE_TYPE_ADDR_WITH_PREFIX 'p' +#define PARSE_LINE_TYPE_IFNAME 'i' +#define PARSE_LINE_TYPE_FLAG 'f' +#define PARSE_LINE_TYPE_ROUTE_SCOPE 'S' +#define PARSE_LINE_TYPE_STRING 's' /** * parse_route_line: @@ -871,5469 +906,5685 @@ enum { * and @out_route. */ static int -parse_route_line (const char *line, - int addr_family, - NMIPRoute *options_route, - NMIPRoute **out_route, - GError **error) +parse_route_line(const char *line, + int addr_family, + NMIPRoute * options_route, + NMIPRoute **out_route, + GError ** error) { - static const ParseLineInfo parse_infos[] = { - [PARSE_LINE_ATTR_ROUTE_TYPE] = { .key = NM_IP_ROUTE_ATTRIBUTE_TYPE, - .type = PARSE_LINE_TYPE_STRING, }, - [PARSE_LINE_ATTR_ROUTE_TABLE] = { .key = NM_IP_ROUTE_ATTRIBUTE_TABLE, - .type = PARSE_LINE_TYPE_UINT32, }, - [PARSE_LINE_ATTR_ROUTE_SRC] = { .key = NM_IP_ROUTE_ATTRIBUTE_SRC, - .type = PARSE_LINE_TYPE_ADDR, }, - [PARSE_LINE_ATTR_ROUTE_FROM] = { .key = NM_IP_ROUTE_ATTRIBUTE_FROM, - .type = PARSE_LINE_TYPE_ADDR_WITH_PREFIX, - .disabled = PARSE_LINE_AF_FLAG_FOR_IPV4, }, - [PARSE_LINE_ATTR_ROUTE_TOS] = { .key = NM_IP_ROUTE_ATTRIBUTE_TOS, - .type = PARSE_LINE_TYPE_UINT8, - .int_base_16 = TRUE, - .ignore = PARSE_LINE_AF_FLAG_FOR_IPV6, }, - [PARSE_LINE_ATTR_ROUTE_SCOPE] = { .key = NM_IP_ROUTE_ATTRIBUTE_SCOPE, - .type = PARSE_LINE_TYPE_ROUTE_SCOPE, - .ignore = PARSE_LINE_AF_FLAG_FOR_IPV6, }, - [PARSE_LINE_ATTR_ROUTE_ONLINK] = { .key = NM_IP_ROUTE_ATTRIBUTE_ONLINK, - .type = PARSE_LINE_TYPE_FLAG, }, - [PARSE_LINE_ATTR_ROUTE_WINDOW] = { .key = NM_IP_ROUTE_ATTRIBUTE_WINDOW, - .type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, }, - [PARSE_LINE_ATTR_ROUTE_CWND] = { .key = NM_IP_ROUTE_ATTRIBUTE_CWND, - .type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, }, - [PARSE_LINE_ATTR_ROUTE_INITCWND] = { .key = NM_IP_ROUTE_ATTRIBUTE_INITCWND, - .type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, }, - [PARSE_LINE_ATTR_ROUTE_INITRWND] = { .key = NM_IP_ROUTE_ATTRIBUTE_INITRWND, - .type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, }, - [PARSE_LINE_ATTR_ROUTE_MTU] = { .key = NM_IP_ROUTE_ATTRIBUTE_MTU, - .type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, }, - - [PARSE_LINE_ATTR_ROUTE_TO] = { .key = "to", - .type = PARSE_LINE_TYPE_ADDR_WITH_PREFIX, - .disabled_with_options_route = TRUE, }, - [PARSE_LINE_ATTR_ROUTE_VIA] = { .key = "via", - .type = PARSE_LINE_TYPE_ADDR, - .disabled_with_options_route = TRUE, }, - [PARSE_LINE_ATTR_ROUTE_METRIC] = { .key = "metric", - .type = PARSE_LINE_TYPE_UINT32, - .disabled_with_options_route = TRUE, }, - - [PARSE_LINE_ATTR_ROUTE_DEV] = { .key = "dev", - .type = PARSE_LINE_TYPE_IFNAME, - .ignore = PARSE_LINE_AF_FLAG_FOR_IPV4 | PARSE_LINE_AF_FLAG_FOR_IPV6, - .disabled_with_options_route = TRUE, }, - }; - nm_auto_unref_ip_route NMIPRoute *route = NULL; - gs_free const char **words_free = NULL; - const char *const*words; - const char *s; - gsize i_words; - guint i; - char buf1[256]; - char buf2[256]; - ParseLineData parse_datas[G_N_ELEMENTS (parse_infos)] = { }; - const ParseLineAFFlag af_flag = (addr_family == AF_INET) - ? PARSE_LINE_AF_FLAG_FOR_IPV4 - : PARSE_LINE_AF_FLAG_FOR_IPV6; - - nm_assert (line); - nm_assert_addr_family (addr_family); - nm_assert (!options_route || nm_ip_route_get_family (options_route) == addr_family); - - /* initscripts read the legacy route file line-by-line and - * use it as `ip route add $line`, thus doing split+glob. - * Splitting on IFS (which we consider '') - * and globbing (which we obviously don't do). - * - * I think it's a mess, because it doesn't support escaping or - * quoting. In fact, it can only encode benign values. - * - * We also use the same form for the numbered OPTIONS - * variable. I think it's bad not to support any form of - * escaping. But do that for now. - * - * Maybe later we want to support some form of quotation here. - * Which of course, would be incompatible with initscripts. - */ - words_free = nm_utils_strsplit_set (line, " \t\n"); - - words = words_free ?: NM_PTRARRAY_EMPTY (const char *); - - for (i_words = 0; words[i_words]; ) { - const gsize i_words0 = i_words; - const char *const w = words[i_words0]; - const ParseLineInfo *p_info; - ParseLineData *p_data; - gboolean unqualified_addr = FALSE; - - for (i = 0; i < G_N_ELEMENTS (parse_infos); i++) { - p_info = &parse_infos[i]; - p_data = &parse_datas[i]; - - if ( (p_info->disabled & af_flag) - || (p_info->disabled_with_options_route && options_route)) - continue; - - if (!nm_streq (w, p_info->key)) - continue; - - if (p_data->has) { - /* iproute2 for most arguments allows specifying them multiple times. - * Let's not do that. */ - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Duplicate option \"%s\"", w); - return -EINVAL; - } - - p_data->has = TRUE; - switch (p_info->type) { - case PARSE_LINE_TYPE_UINT8: - i_words++; - goto parse_line_type_uint8; - case PARSE_LINE_TYPE_UINT32: - i_words++; - goto parse_line_type_uint32; - case PARSE_LINE_TYPE_UINT32_WITH_LOCK: - i_words++; - goto parse_line_type_uint32_with_lock; - case PARSE_LINE_TYPE_ADDR: - i_words++; - goto parse_line_type_addr; - case PARSE_LINE_TYPE_ADDR_WITH_PREFIX: - i_words++; - goto parse_line_type_addr_with_prefix; - case PARSE_LINE_TYPE_IFNAME: - i_words++; - goto parse_line_type_ifname; - case PARSE_LINE_TYPE_FLAG: - i_words++; - goto next; - case PARSE_LINE_TYPE_ROUTE_SCOPE: - i_words++; - goto parse_line_type_route_scope; - default: - nm_assert_not_reached (); - } - } - - p_info = &parse_infos[PARSE_LINE_ATTR_ROUTE_TYPE]; - p_data = &parse_datas[PARSE_LINE_ATTR_ROUTE_TYPE]; - if ( !p_data->has - && NM_IN_STRSET (w, - "local", - "unicast", - "broadcast" - "multicast", - "throw", - "unreachable", - "prohibit", - "blackhole", - "nat")) { - p_data->has = TRUE; - goto parse_line_type_string; - } - - /* "to" is also accepted unqualified... (once) */ - p_info = &parse_infos[PARSE_LINE_ATTR_ROUTE_TO]; - p_data = &parse_datas[PARSE_LINE_ATTR_ROUTE_TO]; - if ( !p_data->has - && !(p_info->disabled & af_flag) - && !(p_info->disabled_with_options_route && options_route)) { - unqualified_addr = TRUE; - p_data->has = TRUE; - goto parse_line_type_addr; - } - - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Unrecognized argument (\"to\" is duplicate or \"%s\" is garbage)", w); - return -EINVAL; + static const ParseLineInfo parse_infos[] = { + [PARSE_LINE_ATTR_ROUTE_TYPE] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_TYPE, + .type = PARSE_LINE_TYPE_STRING, + }, + [PARSE_LINE_ATTR_ROUTE_TABLE] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_TABLE, + .type = PARSE_LINE_TYPE_UINT32, + }, + [PARSE_LINE_ATTR_ROUTE_SRC] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_SRC, + .type = PARSE_LINE_TYPE_ADDR, + }, + [PARSE_LINE_ATTR_ROUTE_FROM] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_FROM, + .type = PARSE_LINE_TYPE_ADDR_WITH_PREFIX, + .disabled = PARSE_LINE_AF_FLAG_FOR_IPV4, + }, + [PARSE_LINE_ATTR_ROUTE_TOS] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_TOS, + .type = PARSE_LINE_TYPE_UINT8, + .int_base_16 = TRUE, + .ignore = PARSE_LINE_AF_FLAG_FOR_IPV6, + }, + [PARSE_LINE_ATTR_ROUTE_SCOPE] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_SCOPE, + .type = PARSE_LINE_TYPE_ROUTE_SCOPE, + .ignore = PARSE_LINE_AF_FLAG_FOR_IPV6, + }, + [PARSE_LINE_ATTR_ROUTE_ONLINK] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_ONLINK, + .type = PARSE_LINE_TYPE_FLAG, + }, + [PARSE_LINE_ATTR_ROUTE_WINDOW] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_WINDOW, + .type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, + }, + [PARSE_LINE_ATTR_ROUTE_CWND] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_CWND, + .type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, + }, + [PARSE_LINE_ATTR_ROUTE_INITCWND] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_INITCWND, + .type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, + }, + [PARSE_LINE_ATTR_ROUTE_INITRWND] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_INITRWND, + .type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, + }, + [PARSE_LINE_ATTR_ROUTE_MTU] = + { + .key = NM_IP_ROUTE_ATTRIBUTE_MTU, + .type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, + }, + + [PARSE_LINE_ATTR_ROUTE_TO] = + { + .key = "to", + .type = PARSE_LINE_TYPE_ADDR_WITH_PREFIX, + .disabled_with_options_route = TRUE, + }, + [PARSE_LINE_ATTR_ROUTE_VIA] = + { + .key = "via", + .type = PARSE_LINE_TYPE_ADDR, + .disabled_with_options_route = TRUE, + }, + [PARSE_LINE_ATTR_ROUTE_METRIC] = + { + .key = "metric", + .type = PARSE_LINE_TYPE_UINT32, + .disabled_with_options_route = TRUE, + }, + + [PARSE_LINE_ATTR_ROUTE_DEV] = + { + .key = "dev", + .type = PARSE_LINE_TYPE_IFNAME, + .ignore = PARSE_LINE_AF_FLAG_FOR_IPV4 | PARSE_LINE_AF_FLAG_FOR_IPV6, + .disabled_with_options_route = TRUE, + }, + }; + nm_auto_unref_ip_route NMIPRoute *route = NULL; + gs_free const char ** words_free = NULL; + const char *const * words; + const char * s; + gsize i_words; + guint i; + char buf1[256]; + char buf2[256]; + ParseLineData parse_datas[G_N_ELEMENTS(parse_infos)] = {}; + const ParseLineAFFlag af_flag = + (addr_family == AF_INET) ? PARSE_LINE_AF_FLAG_FOR_IPV4 : PARSE_LINE_AF_FLAG_FOR_IPV6; + + nm_assert(line); + nm_assert_addr_family(addr_family); + nm_assert(!options_route || nm_ip_route_get_family(options_route) == addr_family); + + /* initscripts read the legacy route file line-by-line and + * use it as `ip route add $line`, thus doing split+glob. + * Splitting on IFS (which we consider '') + * and globbing (which we obviously don't do). + * + * I think it's a mess, because it doesn't support escaping or + * quoting. In fact, it can only encode benign values. + * + * We also use the same form for the numbered OPTIONS + * variable. I think it's bad not to support any form of + * escaping. But do that for now. + * + * Maybe later we want to support some form of quotation here. + * Which of course, would be incompatible with initscripts. + */ + words_free = nm_utils_strsplit_set(line, " \t\n"); + + words = words_free ?: NM_PTRARRAY_EMPTY(const char *); + + for (i_words = 0; words[i_words];) { + const gsize i_words0 = i_words; + const char *const w = words[i_words0]; + const ParseLineInfo *p_info; + ParseLineData * p_data; + gboolean unqualified_addr = FALSE; + + for (i = 0; i < G_N_ELEMENTS(parse_infos); i++) { + p_info = &parse_infos[i]; + p_data = &parse_datas[i]; + + if ((p_info->disabled & af_flag) + || (p_info->disabled_with_options_route && options_route)) + continue; + + if (!nm_streq(w, p_info->key)) + continue; + + if (p_data->has) { + /* iproute2 for most arguments allows specifying them multiple times. + * Let's not do that. */ + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Duplicate option \"%s\"", + w); + return -EINVAL; + } + + p_data->has = TRUE; + switch (p_info->type) { + case PARSE_LINE_TYPE_UINT8: + i_words++; + goto parse_line_type_uint8; + case PARSE_LINE_TYPE_UINT32: + i_words++; + goto parse_line_type_uint32; + case PARSE_LINE_TYPE_UINT32_WITH_LOCK: + i_words++; + goto parse_line_type_uint32_with_lock; + case PARSE_LINE_TYPE_ADDR: + i_words++; + goto parse_line_type_addr; + case PARSE_LINE_TYPE_ADDR_WITH_PREFIX: + i_words++; + goto parse_line_type_addr_with_prefix; + case PARSE_LINE_TYPE_IFNAME: + i_words++; + goto parse_line_type_ifname; + case PARSE_LINE_TYPE_FLAG: + i_words++; + goto next; + case PARSE_LINE_TYPE_ROUTE_SCOPE: + i_words++; + goto parse_line_type_route_scope; + default: + nm_assert_not_reached(); + } + } + + p_info = &parse_infos[PARSE_LINE_ATTR_ROUTE_TYPE]; + p_data = &parse_datas[PARSE_LINE_ATTR_ROUTE_TYPE]; + if (!p_data->has + && NM_IN_STRSET(w, + "local", + "unicast", + "broadcast" + "multicast", + "throw", + "unreachable", + "prohibit", + "blackhole", + "nat")) { + p_data->has = TRUE; + goto parse_line_type_string; + } + + /* "to" is also accepted unqualified... (once) */ + p_info = &parse_infos[PARSE_LINE_ATTR_ROUTE_TO]; + p_data = &parse_datas[PARSE_LINE_ATTR_ROUTE_TO]; + if (!p_data->has && !(p_info->disabled & af_flag) + && !(p_info->disabled_with_options_route && options_route)) { + unqualified_addr = TRUE; + p_data->has = TRUE; + goto parse_line_type_addr; + } + + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Unrecognized argument (\"to\" is duplicate or \"%s\" is garbage)", + w); + return -EINVAL; parse_line_type_route_scope: - s = words[i_words]; - if (!s) - goto err_word_missing_argument; - if (nm_streq (s, "global")) - p_data->v.uint8 = RT_SCOPE_UNIVERSE; - else if (nm_streq (s, "nowhere")) - p_data->v.uint8 = RT_SCOPE_NOWHERE; - else if (nm_streq (s, "host")) - p_data->v.uint8 = RT_SCOPE_HOST; - else if (nm_streq (s, "link")) - p_data->v.uint8 = RT_SCOPE_LINK; - else if (nm_streq (s, "site")) - p_data->v.uint8 = RT_SCOPE_SITE; - else { - p_data->v.uint8 = _nm_utils_ascii_str_to_int64 (s, - 0, - 0, - G_MAXUINT8, - 0);; - if (errno) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Argument for \"%s\" is not a valid number", w); - return -EINVAL; - } - } - i_words++; - goto next; + s = words[i_words]; + if (!s) + goto err_word_missing_argument; + if (nm_streq(s, "global")) + p_data->v.uint8 = RT_SCOPE_UNIVERSE; + else if (nm_streq(s, "nowhere")) + p_data->v.uint8 = RT_SCOPE_NOWHERE; + else if (nm_streq(s, "host")) + p_data->v.uint8 = RT_SCOPE_HOST; + else if (nm_streq(s, "link")) + p_data->v.uint8 = RT_SCOPE_LINK; + else if (nm_streq(s, "site")) + p_data->v.uint8 = RT_SCOPE_SITE; + else { + p_data->v.uint8 = _nm_utils_ascii_str_to_int64(s, 0, 0, G_MAXUINT8, 0); + if (errno) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Argument for \"%s\" is not a valid number", + w); + return -EINVAL; + } + } + i_words++; + goto next; parse_line_type_uint8: - s = words[i_words]; - if (!s) - goto err_word_missing_argument; - p_data->v.uint8 = _nm_utils_ascii_str_to_int64 (s, - p_info->int_base_16 ? 16 : 10, - 0, - G_MAXUINT8, - 0);; - if (errno) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Argument for \"%s\" is not a valid number", w); - return -EINVAL; - } - i_words++; - goto next; + s = words[i_words]; + if (!s) + goto err_word_missing_argument; + p_data->v.uint8 = + _nm_utils_ascii_str_to_int64(s, p_info->int_base_16 ? 16 : 10, 0, G_MAXUINT8, 0); + if (errno) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Argument for \"%s\" is not a valid number", + w); + return -EINVAL; + } + i_words++; + goto next; parse_line_type_uint32: parse_line_type_uint32_with_lock: - s = words[i_words]; - if (!s) - goto err_word_missing_argument; - if (p_info->type == PARSE_LINE_TYPE_UINT32_WITH_LOCK) { - if (nm_streq (s, "lock")) { - s = words[++i_words]; - if (!s) - goto err_word_missing_argument; - p_data->v.uint32_with_lock.lock = TRUE; - } else - p_data->v.uint32_with_lock.lock = FALSE; - p_data->v.uint32_with_lock.uint32 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXUINT32, 0);; - } else { - p_data->v.uint32 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXUINT32, 0); - } - if (errno) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Argument for \"%s\" is not a valid number", w); - return -EINVAL; - } - i_words++; - goto next; + s = words[i_words]; + if (!s) + goto err_word_missing_argument; + if (p_info->type == PARSE_LINE_TYPE_UINT32_WITH_LOCK) { + if (nm_streq(s, "lock")) { + s = words[++i_words]; + if (!s) + goto err_word_missing_argument; + p_data->v.uint32_with_lock.lock = TRUE; + } else + p_data->v.uint32_with_lock.lock = FALSE; + p_data->v.uint32_with_lock.uint32 = + _nm_utils_ascii_str_to_int64(s, 10, 0, G_MAXUINT32, 0); + } else { + p_data->v.uint32 = _nm_utils_ascii_str_to_int64(s, 10, 0, G_MAXUINT32, 0); + } + if (errno) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Argument for \"%s\" is not a valid number", + w); + return -EINVAL; + } + i_words++; + goto next; parse_line_type_ifname: - s = words[i_words]; - if (!s) - goto err_word_missing_argument; - i_words++; - goto next; + s = words[i_words]; + if (!s) + goto err_word_missing_argument; + i_words++; + goto next; parse_line_type_addr: parse_line_type_addr_with_prefix: - s = words[i_words]; - if (!s) - goto err_word_missing_argument; - { - int prefix = -1; - - if (p_info->type == PARSE_LINE_TYPE_ADDR) { - if (!nm_utils_parse_inaddr_bin (addr_family, - s, - NULL, - &p_data->v.addr.addr)) { - if ( p_info == &parse_infos[PARSE_LINE_ATTR_ROUTE_VIA] - && nm_streq (s, "(null)")) { - /* Due to a bug, would older versions of NM write "via (null)" - * (rh#1452648). Workaround that, and accept it.*/ - memset (&p_data->v.addr.addr, 0, sizeof (p_data->v.addr.addr)); - } else { - if (unqualified_addr) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Unrecognized argument (inet prefix is expected rather then \"%s\")", w); - return -EINVAL; - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Argument for \"%s\" is not a valid IPv%c address", w, - addr_family == AF_INET ? '4' : '6'); - } - return -EINVAL; - } - } - } else { - nm_assert (p_info->type == PARSE_LINE_TYPE_ADDR_WITH_PREFIX); - if ( p_info == &parse_infos[PARSE_LINE_ATTR_ROUTE_TO] - && nm_streq (s, "default")) { - memset (&p_data->v.addr.addr, 0, sizeof (p_data->v.addr.addr)); - prefix = 0; - } else if (!nm_utils_parse_inaddr_prefix_bin (addr_family, - s, - NULL, - &p_data->v.addr.addr, - &prefix)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Argument for \"%s\" is not ADDR/PREFIX format", w); - return -EINVAL; - } - } - if (prefix == -1) - p_data->v.addr.has_plen = FALSE; - else { - p_data->v.addr.has_plen = TRUE; - p_data->v.addr.plen = prefix; - } - } - i_words++; - goto next; + s = words[i_words]; + if (!s) + goto err_word_missing_argument; + { + int prefix = -1; + + if (p_info->type == PARSE_LINE_TYPE_ADDR) { + if (!nm_utils_parse_inaddr_bin(addr_family, s, NULL, &p_data->v.addr.addr)) { + if (p_info == &parse_infos[PARSE_LINE_ATTR_ROUTE_VIA] + && nm_streq(s, "(null)")) { + /* Due to a bug, would older versions of NM write "via (null)" + * (rh#1452648). Workaround that, and accept it.*/ + memset(&p_data->v.addr.addr, 0, sizeof(p_data->v.addr.addr)); + } else { + if (unqualified_addr) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Unrecognized argument (inet prefix is expected rather " + "then \"%s\")", + w); + return -EINVAL; + } else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Argument for \"%s\" is not a valid IPv%c address", + w, + addr_family == AF_INET ? '4' : '6'); + } + return -EINVAL; + } + } + } else { + nm_assert(p_info->type == PARSE_LINE_TYPE_ADDR_WITH_PREFIX); + if (p_info == &parse_infos[PARSE_LINE_ATTR_ROUTE_TO] && nm_streq(s, "default")) { + memset(&p_data->v.addr.addr, 0, sizeof(p_data->v.addr.addr)); + prefix = 0; + } else if (!nm_utils_parse_inaddr_prefix_bin(addr_family, + s, + NULL, + &p_data->v.addr.addr, + &prefix)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Argument for \"%s\" is not ADDR/PREFIX format", + w); + return -EINVAL; + } + } + if (prefix == -1) + p_data->v.addr.has_plen = FALSE; + else { + p_data->v.addr.has_plen = TRUE; + p_data->v.addr.plen = prefix; + } + } + i_words++; + goto next; parse_line_type_string: - s = words[i_words]; - if (!s) - goto err_word_missing_argument; + s = words[i_words]; + if (!s) + goto err_word_missing_argument; - p_data->v.str = s; - i_words++; - goto next; + p_data->v.str = s; + i_words++; + goto next; err_word_missing_argument: - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing argument for \"%s\"", w); - return -EINVAL; -next: - ; - } - - if (options_route) { - route = options_route; - nm_ip_route_ref (route); - } else { - ParseLineData *data_to = &parse_datas[PARSE_LINE_ATTR_ROUTE_TO]; - ParseLineData *data_via = &parse_datas[PARSE_LINE_ATTR_ROUTE_VIA]; - ParseLineData *data_metric = &parse_datas[PARSE_LINE_ATTR_ROUTE_METRIC]; - guint prefix; - - if (!data_to->has) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing destination prefix"); - return -EINVAL; - } - - prefix = data_to->v.addr.has_plen - ? data_to->v.addr.plen - : (addr_family == AF_INET ? 32 : 128); - - route = nm_ip_route_new_binary (addr_family, - &data_to->v.addr.addr, - prefix, - data_via->has ? &data_via->v.addr.addr : NULL, - data_metric->has ? (gint64) data_metric->v.uint32 : (gint64) -1, - error); - data_to->has = FALSE; - data_via->has = FALSE; - data_metric->has = FALSE; - if (!route) - return -EINVAL; - } - - for (i = 0; i < G_N_ELEMENTS (parse_infos); i++) { - const ParseLineInfo *p_info = &parse_infos[i]; - ParseLineData *p_data = &parse_datas[i]; - - if (!p_data->has) - continue; - - if ( (p_info->ignore & af_flag) - || (p_info->disabled & af_flag) - || (p_info->disabled_with_options_route && options_route)) - continue; - - switch (p_info->type) { - case PARSE_LINE_TYPE_UINT8: - case PARSE_LINE_TYPE_ROUTE_SCOPE: - nm_ip_route_set_attribute (route, - p_info->key, - g_variant_new_byte (p_data->v.uint8)); - break; - case PARSE_LINE_TYPE_UINT32: - nm_ip_route_set_attribute (route, - p_info->key, - g_variant_new_uint32 (p_data->v.uint32)); - break; - case PARSE_LINE_TYPE_UINT32_WITH_LOCK: - if (p_data->v.uint32_with_lock.lock) { - nm_ip_route_set_attribute (route, - nm_sprintf_buf (buf1, "lock-%s", p_info->key), - g_variant_new_boolean (TRUE)); - } - nm_ip_route_set_attribute (route, - p_info->key, - g_variant_new_uint32 (p_data->v.uint32_with_lock.uint32)); - break; - case PARSE_LINE_TYPE_ADDR: - case PARSE_LINE_TYPE_ADDR_WITH_PREFIX: - nm_ip_route_set_attribute (route, - p_info->key, - g_variant_new_printf ("%s%s", - inet_ntop (addr_family, &p_data->v.addr.addr, buf1, sizeof (buf1)), - p_data->v.addr.has_plen - ? nm_sprintf_buf (buf2, "/%u", (unsigned) p_data->v.addr.plen) - : "")); - break; - case PARSE_LINE_TYPE_FLAG: - /* NOTE: the flag (for "onlink") only allows to explicitly set "TRUE". - * There is no way to express an explicit "FALSE" setting - * of this attribute, hence, the file format cannot encode - * that configuration. */ - nm_ip_route_set_attribute (route, - p_info->key, - g_variant_new_boolean (TRUE)); - break; - case PARSE_LINE_TYPE_STRING: - nm_ip_route_set_attribute (route, - p_info->key, - g_variant_new_string (p_data->v.str)); - break; - default: - nm_assert_not_reached (); - break; - } - } - - nm_assert (_nm_ip_route_attribute_validate_all (route, NULL)); - - NM_SET_OUT (out_route, g_steal_pointer (&route)); - return 0; + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing argument for \"%s\"", + w); + return -EINVAL; +next:; + } + + if (options_route) { + route = options_route; + nm_ip_route_ref(route); + } else { + ParseLineData *data_to = &parse_datas[PARSE_LINE_ATTR_ROUTE_TO]; + ParseLineData *data_via = &parse_datas[PARSE_LINE_ATTR_ROUTE_VIA]; + ParseLineData *data_metric = &parse_datas[PARSE_LINE_ATTR_ROUTE_METRIC]; + guint prefix; + + if (!data_to->has) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing destination prefix"); + return -EINVAL; + } + + prefix = + data_to->v.addr.has_plen ? data_to->v.addr.plen : (addr_family == AF_INET ? 32 : 128); + + route = + nm_ip_route_new_binary(addr_family, + &data_to->v.addr.addr, + prefix, + data_via->has ? &data_via->v.addr.addr : NULL, + data_metric->has ? (gint64) data_metric->v.uint32 : (gint64) -1, + error); + data_to->has = FALSE; + data_via->has = FALSE; + data_metric->has = FALSE; + if (!route) + return -EINVAL; + } + + for (i = 0; i < G_N_ELEMENTS(parse_infos); i++) { + const ParseLineInfo *p_info = &parse_infos[i]; + ParseLineData * p_data = &parse_datas[i]; + + if (!p_data->has) + continue; + + if ((p_info->ignore & af_flag) || (p_info->disabled & af_flag) + || (p_info->disabled_with_options_route && options_route)) + continue; + + switch (p_info->type) { + case PARSE_LINE_TYPE_UINT8: + case PARSE_LINE_TYPE_ROUTE_SCOPE: + nm_ip_route_set_attribute(route, p_info->key, g_variant_new_byte(p_data->v.uint8)); + break; + case PARSE_LINE_TYPE_UINT32: + nm_ip_route_set_attribute(route, p_info->key, g_variant_new_uint32(p_data->v.uint32)); + break; + case PARSE_LINE_TYPE_UINT32_WITH_LOCK: + if (p_data->v.uint32_with_lock.lock) { + nm_ip_route_set_attribute(route, + nm_sprintf_buf(buf1, "lock-%s", p_info->key), + g_variant_new_boolean(TRUE)); + } + nm_ip_route_set_attribute(route, + p_info->key, + g_variant_new_uint32(p_data->v.uint32_with_lock.uint32)); + break; + case PARSE_LINE_TYPE_ADDR: + case PARSE_LINE_TYPE_ADDR_WITH_PREFIX: + nm_ip_route_set_attribute( + route, + p_info->key, + g_variant_new_printf( + "%s%s", + inet_ntop(addr_family, &p_data->v.addr.addr, buf1, sizeof(buf1)), + p_data->v.addr.has_plen + ? nm_sprintf_buf(buf2, "/%u", (unsigned) p_data->v.addr.plen) + : "")); + break; + case PARSE_LINE_TYPE_FLAG: + /* NOTE: the flag (for "onlink") only allows to explicitly set "TRUE". + * There is no way to express an explicit "FALSE" setting + * of this attribute, hence, the file format cannot encode + * that configuration. */ + nm_ip_route_set_attribute(route, p_info->key, g_variant_new_boolean(TRUE)); + break; + case PARSE_LINE_TYPE_STRING: + nm_ip_route_set_attribute(route, p_info->key, g_variant_new_string(p_data->v.str)); + break; + default: + nm_assert_not_reached(); + break; + } + } + + nm_assert(_nm_ip_route_attribute_validate_all(route, NULL)); + + NM_SET_OUT(out_route, g_steal_pointer(&route)); + return 0; } /* Returns TRUE on missing route or valid route */ static gboolean -read_one_ip4_route (shvarFile *ifcfg, - guint32 which, - NMIPRoute **out_route, - GError **error) +read_one_ip4_route(shvarFile *ifcfg, guint32 which, NMIPRoute **out_route, GError **error) { - char tag[256]; - char netmask_tag[256]; - guint32 dest; - guint32 next_hop; - guint32 netmask; - gboolean has_key; - const char *v; - gs_free char *value = NULL; - gint64 prefix, metric; - char inet_buf[NM_UTILS_INET_ADDRSTRLEN]; - - g_return_val_if_fail (ifcfg != NULL, FALSE); - g_return_val_if_fail (out_route && !*out_route, FALSE); - g_return_val_if_fail (!error || !*error, FALSE); - - /* Destination */ - if (!read_ip4_address (ifcfg, - numbered_tag (tag, "ADDRESS", which), - &has_key, &dest, error)) - return FALSE; - if (!has_key) { - /* missing route = success */ - *out_route = NULL; - return TRUE; - } - - /* Next hop */ - if (!read_ip4_address (ifcfg, - numbered_tag (tag, "GATEWAY", which), - NULL, &next_hop, error)) - return FALSE; - /* We don't make distinction between missing GATEWAY IP and 0.0.0.0 */ - - /* Prefix */ - if (!read_ip4_address (ifcfg, - numbered_tag (netmask_tag, "NETMASK", which), - &has_key, &netmask, error)) - return FALSE; - if (has_key) { - prefix = nm_utils_ip4_netmask_to_prefix (netmask); - if (netmask != _nm_utils_ip4_prefix_to_netmask (prefix)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid IP4 netmask '%s' \"%s\"", netmask_tag, _nm_utils_inet4_ntop (netmask, inet_buf)); - return FALSE; - } - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing IP4 route element '%s'", netmask_tag); - return FALSE; - } - - /* Metric */ - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, numbered_tag (tag, "METRIC", which), &value); - if (v) { - metric = _nm_utils_ascii_str_to_int64 (v, 10, 0, G_MAXUINT32, -1); - if (metric < 0) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid IP4 route metric '%s'", v); - return FALSE; - } - } else - metric = -1; - - *out_route = nm_ip_route_new_binary (AF_INET, &dest, prefix, &next_hop, metric, error); - if (!*out_route) - return FALSE; - - /* Options */ - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, numbered_tag (tag, "OPTIONS", which), &value); - if (v) { - if (parse_route_line (v, AF_INET, *out_route, NULL, error) < 0) { - nm_clear_pointer (out_route, nm_ip_route_unref); - return FALSE; - } - } - - return TRUE; + char tag[256]; + char netmask_tag[256]; + guint32 dest; + guint32 next_hop; + guint32 netmask; + gboolean has_key; + const char * v; + gs_free char *value = NULL; + gint64 prefix, metric; + char inet_buf[NM_UTILS_INET_ADDRSTRLEN]; + + g_return_val_if_fail(ifcfg != NULL, FALSE); + g_return_val_if_fail(out_route && !*out_route, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + /* Destination */ + if (!read_ip4_address(ifcfg, numbered_tag(tag, "ADDRESS", which), &has_key, &dest, error)) + return FALSE; + if (!has_key) { + /* missing route = success */ + *out_route = NULL; + return TRUE; + } + + /* Next hop */ + if (!read_ip4_address(ifcfg, numbered_tag(tag, "GATEWAY", which), NULL, &next_hop, error)) + return FALSE; + /* We don't make distinction between missing GATEWAY IP and 0.0.0.0 */ + + /* Prefix */ + if (!read_ip4_address(ifcfg, + numbered_tag(netmask_tag, "NETMASK", which), + &has_key, + &netmask, + error)) + return FALSE; + if (has_key) { + prefix = nm_utils_ip4_netmask_to_prefix(netmask); + if (netmask != _nm_utils_ip4_prefix_to_netmask(prefix)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IP4 netmask '%s' \"%s\"", + netmask_tag, + _nm_utils_inet4_ntop(netmask, inet_buf)); + return FALSE; + } + } else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IP4 route element '%s'", + netmask_tag); + return FALSE; + } + + /* Metric */ + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, numbered_tag(tag, "METRIC", which), &value); + if (v) { + metric = _nm_utils_ascii_str_to_int64(v, 10, 0, G_MAXUINT32, -1); + if (metric < 0) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IP4 route metric '%s'", + v); + return FALSE; + } + } else + metric = -1; + + *out_route = nm_ip_route_new_binary(AF_INET, &dest, prefix, &next_hop, metric, error); + if (!*out_route) + return FALSE; + + /* Options */ + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, numbered_tag(tag, "OPTIONS", which), &value); + if (v) { + if (parse_route_line(v, AF_INET, *out_route, NULL, error) < 0) { + nm_clear_pointer(out_route, nm_ip_route_unref); + return FALSE; + } + } + + return TRUE; } static gboolean -read_route_file_parse (int addr_family, - const char *filename, - const char *contents, - gsize len, - NMSettingIPConfig *s_ip, - GError **error) +read_route_file_parse(int addr_family, + const char * filename, + const char * contents, + gsize len, + NMSettingIPConfig *s_ip, + GError ** error) { - gsize line_num; - - nm_assert (filename); - nm_assert (addr_family == nm_setting_ip_config_get_addr_family (s_ip)); - nm_assert (!error || !*error); - - if (len <= 0) - return TRUE; /* missing/empty = success */ - - line_num = 0; - while (TRUE) { - nm_auto_unref_ip_route NMIPRoute *route = NULL; - gs_free_error GError *local = NULL; - const char *line = contents; - char *eol; - int e; - - eol = strchr (contents, '\n'); - if (eol) { - eol[0] = '\0'; - contents = &eol[1]; - } - - line_num++; - - if (parse_route_line_is_comment (line)) - goto next; - - e = parse_route_line (line, addr_family, NULL, &route, &local); - - if (e < 0) { - if (e == -ERANGE) - PARSE_WARNING ("ignoring manual default route: '%s' (%s)", line, filename); - else { - /* we accept all unrecognized lines, because otherwise we would reject the - * entire connection. */ - PARSE_WARNING ("ignoring invalid route at \"%s\" (%s:%lu): %s", line, filename, (long unsigned) line_num, local->message); - } - goto next; - } - - if (!nm_setting_ip_config_add_route (s_ip, route)) - PARSE_WARNING ("duplicate IPv%c route", addr_family == AF_INET ? '4' : '6'); + gsize line_num; + + nm_assert(filename); + nm_assert(addr_family == nm_setting_ip_config_get_addr_family(s_ip)); + nm_assert(!error || !*error); + + if (len <= 0) + return TRUE; /* missing/empty = success */ + + line_num = 0; + while (TRUE) { + nm_auto_unref_ip_route NMIPRoute *route = NULL; + gs_free_error GError *local = NULL; + const char * line = contents; + char * eol; + int e; + + eol = strchr(contents, '\n'); + if (eol) { + eol[0] = '\0'; + contents = &eol[1]; + } + + line_num++; + + if (parse_route_line_is_comment(line)) + goto next; + + e = parse_route_line(line, addr_family, NULL, &route, &local); + + if (e < 0) { + if (e == -ERANGE) + PARSE_WARNING("ignoring manual default route: '%s' (%s)", line, filename); + else { + /* we accept all unrecognized lines, because otherwise we would reject the + * entire connection. */ + PARSE_WARNING("ignoring invalid route at \"%s\" (%s:%lu): %s", + line, + filename, + (long unsigned) line_num, + local->message); + } + goto next; + } + + if (!nm_setting_ip_config_add_route(s_ip, route)) + PARSE_WARNING("duplicate IPv%c route", addr_family == AF_INET ? '4' : '6'); next: - if (!eol) - return TRUE; + if (!eol) + return TRUE; - /* restore original content. */ - eol[0] = '\n'; - } + /* restore original content. */ + eol[0] = '\n'; + } } static gboolean -read_route_file (int addr_family, - const char *filename, - NMSettingIPConfig *s_ip, - GError **error) +read_route_file(int addr_family, const char *filename, NMSettingIPConfig *s_ip, GError **error) { - gs_free char *contents = NULL; - gsize len; + gs_free char *contents = NULL; + gsize len; - nm_assert (filename); - nm_assert (addr_family == nm_setting_ip_config_get_addr_family (s_ip)); - nm_assert (!error || !*error); + nm_assert(filename); + nm_assert(addr_family == nm_setting_ip_config_get_addr_family(s_ip)); + nm_assert(!error || !*error); - if (!g_file_get_contents (filename, &contents, &len, NULL)) - return TRUE; /* missing/empty = success */ + if (!g_file_get_contents(filename, &contents, &len, NULL)) + return TRUE; /* missing/empty = success */ - return read_route_file_parse (addr_family, filename, contents, len, s_ip, error); + return read_route_file_parse(addr_family, filename, contents, len, s_ip, error); } static void -parse_dns_options (NMSettingIPConfig *ip_config, const char *value) +parse_dns_options(NMSettingIPConfig *ip_config, const char *value) { - gs_free const char **options = NULL; - const char *const *item; + gs_free const char **options = NULL; + const char *const * item; - g_return_if_fail (ip_config); + g_return_if_fail(ip_config); - if (!value) - return; + if (!value) + return; - if (!nm_setting_ip_config_has_dns_options (ip_config)) - nm_setting_ip_config_clear_dns_options (ip_config, TRUE); + if (!nm_setting_ip_config_has_dns_options(ip_config)) + nm_setting_ip_config_clear_dns_options(ip_config, TRUE); - options = nm_utils_strsplit_set (value, " "); - if (options) { - for (item = options; *item; item++) { - if (!nm_setting_ip_config_add_dns_option (ip_config, *item)) - PARSE_WARNING ("can't add DNS option '%s'", *item); - } - } + options = nm_utils_strsplit_set(value, " "); + if (options) { + for (item = options; *item; item++) { + if (!nm_setting_ip_config_add_dns_option(ip_config, *item)) + PARSE_WARNING("can't add DNS option '%s'", *item); + } + } } static gboolean -parse_full_ip6_address (shvarFile *ifcfg, - const char *addr_str, - int i, - NMIPAddress **out_address, - GError **error) +parse_full_ip6_address(shvarFile * ifcfg, + const char * addr_str, + int i, + NMIPAddress **out_address, + GError ** error) { - NMIPAddress *addr; - NMIPAddr addr_bin; - int prefix; - - nm_assert (addr_str); - nm_assert (out_address && !*out_address); - nm_assert (!error || !*error); - - if (!nm_utils_parse_inaddr_prefix_bin (AF_INET6, - addr_str, - NULL, - &addr_bin, - &prefix)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid IP6 address '%s'", addr_str); - return FALSE; - } - - if (prefix < 0) - prefix = 64; - - addr = nm_ip_address_new_binary (AF_INET6, &addr_bin, prefix, error); - if (!addr) - return FALSE; - - *out_address = addr; - return TRUE; + NMIPAddress *addr; + NMIPAddr addr_bin; + int prefix; + + nm_assert(addr_str); + nm_assert(out_address && !*out_address); + nm_assert(!error || !*error); + + if (!nm_utils_parse_inaddr_prefix_bin(AF_INET6, addr_str, NULL, &addr_bin, &prefix)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IP6 address '%s'", + addr_str); + return FALSE; + } + + if (prefix < 0) + prefix = 64; + + addr = nm_ip_address_new_binary(AF_INET6, &addr_bin, prefix, error); + if (!addr) + return FALSE; + + *out_address = addr; + return TRUE; } static NMSetting * -make_user_setting (shvarFile *ifcfg) +make_user_setting(shvarFile *ifcfg) { - gboolean has_user_data = FALSE; - gs_unref_object NMSettingUser *s_user = NULL; - gs_unref_hashtable GHashTable *keys = NULL; - GHashTableIter iter; - const char *key; - nm_auto_free_gstring GString *str = NULL; - - keys = svGetKeys (ifcfg, SV_KEY_TYPE_USER); - if (!keys) - return NULL; - - g_hash_table_iter_init (&iter, keys); - while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) { - const char *value; - gs_free char *value_to_free = NULL; - - value = svGetValue (ifcfg, key, &value_to_free); - - if (!value) - continue; - - if (!str) - str = g_string_sized_new (100); - else - g_string_set_size (str, 0); - - if (!nms_ifcfg_rh_utils_user_key_decode (key + NM_STRLEN ("NM_USER_"), str)) - continue; - - if (!s_user) - s_user = NM_SETTING_USER (nm_setting_user_new ()); - - if (nm_setting_user_set_data (s_user, str->str, - value, NULL)) - has_user_data = TRUE; - } - - return has_user_data - ? NM_SETTING (g_steal_pointer (&s_user)) - : NULL; -} + gboolean has_user_data = FALSE; + gs_unref_object NMSettingUser *s_user = NULL; + gs_unref_hashtable GHashTable *keys = NULL; + GHashTableIter iter; + const char * key; + nm_auto_free_gstring GString *str = NULL; + + keys = svGetKeys(ifcfg, SV_KEY_TYPE_USER); + if (!keys) + return NULL; + g_hash_table_iter_init(&iter, keys); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, NULL)) { + const char * value; + gs_free char *value_to_free = NULL; + + value = svGetValue(ifcfg, key, &value_to_free); + + if (!value) + continue; + + if (!str) + str = g_string_sized_new(100); + else + g_string_set_size(str, 0); + + if (!nms_ifcfg_rh_utils_user_key_decode(key + NM_STRLEN("NM_USER_"), str)) + continue; + + if (!s_user) + s_user = NM_SETTING_USER(nm_setting_user_new()); + + if (nm_setting_user_set_data(s_user, str->str, value, NULL)) + has_user_data = TRUE; + } + + return has_user_data ? NM_SETTING(g_steal_pointer(&s_user)) : NULL; +} static void -make_match_setting_prop (const char *v, - NMSettingMatch **s_match, - void (*add_fcn) (NMSettingMatch *s_match, const char *value)) +make_match_setting_prop(const char * v, + NMSettingMatch **s_match, + void (*add_fcn)(NMSettingMatch *s_match, const char *value)) { - gs_free const char **strv = NULL; - gsize i; - - strv = nm_utils_escaped_tokens_split (v, NM_ASCII_SPACES); - if (strv) { - for (i = 0; strv[i]; i++) { - if (!(*s_match)) - *s_match = NM_SETTING_MATCH (nm_setting_match_new ()); - add_fcn (*s_match, strv[i]); - } - } + gs_free const char **strv = NULL; + gsize i; + + strv = nm_utils_escaped_tokens_split(v, NM_ASCII_SPACES); + if (strv) { + for (i = 0; strv[i]; i++) { + if (!(*s_match)) + *s_match = NM_SETTING_MATCH(nm_setting_match_new()); + add_fcn(*s_match, strv[i]); + } + } } static NMSetting * -make_match_setting (shvarFile *ifcfg) +make_match_setting(shvarFile *ifcfg) { - NMSettingMatch *s_match = NULL; - gs_free char *value_ifn = NULL; - gs_free char *value_kcl = NULL; - gs_free char *value_d = NULL; - gs_free char *value_p = NULL; - const char *v; - - v = svGetValueStr (ifcfg, "MATCH_INTERFACE_NAME", &value_ifn); - make_match_setting_prop (v, &s_match, nm_setting_match_add_interface_name); - v = svGetValueStr (ifcfg, "MATCH_KERNEL_COMMAND_LINE", &value_kcl); - make_match_setting_prop (v, &s_match, nm_setting_match_add_kernel_command_line); - v = svGetValueStr (ifcfg, "MATCH_DRIVER", &value_d); - make_match_setting_prop (v, &s_match, nm_setting_match_add_driver); - v = svGetValueStr (ifcfg, "MATCH_PATH", &value_p); - make_match_setting_prop (v, &s_match, nm_setting_match_add_path); - - return NM_SETTING (s_match); + NMSettingMatch *s_match = NULL; + gs_free char * value_ifn = NULL; + gs_free char * value_kcl = NULL; + gs_free char * value_d = NULL; + gs_free char * value_p = NULL; + const char * v; + + v = svGetValueStr(ifcfg, "MATCH_INTERFACE_NAME", &value_ifn); + make_match_setting_prop(v, &s_match, nm_setting_match_add_interface_name); + v = svGetValueStr(ifcfg, "MATCH_KERNEL_COMMAND_LINE", &value_kcl); + make_match_setting_prop(v, &s_match, nm_setting_match_add_kernel_command_line); + v = svGetValueStr(ifcfg, "MATCH_DRIVER", &value_d); + make_match_setting_prop(v, &s_match, nm_setting_match_add_driver); + v = svGetValueStr(ifcfg, "MATCH_PATH", &value_p); + make_match_setting_prop(v, &s_match, nm_setting_match_add_path); + + return NM_SETTING(s_match); } static NMSetting * -make_proxy_setting (shvarFile *ifcfg) +make_proxy_setting(shvarFile *ifcfg) { - NMSettingProxy *s_proxy = NULL; - gs_free char *value = NULL; - const char *v; - NMSettingProxyMethod method; - - v = svGetValueStr (ifcfg, "PROXY_METHOD", &value); - if (!v) - return NULL; - - if (!g_ascii_strcasecmp (v, "auto")) - method = NM_SETTING_PROXY_METHOD_AUTO; - else - method = NM_SETTING_PROXY_METHOD_NONE; - - s_proxy = (NMSettingProxy *) nm_setting_proxy_new (); - - switch (method) { - case NM_SETTING_PROXY_METHOD_AUTO: - g_object_set (s_proxy, - NM_SETTING_PROXY_METHOD, (int) NM_SETTING_PROXY_METHOD_AUTO, - NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "PAC_URL", &value); - if (v) - g_object_set (s_proxy, NM_SETTING_PROXY_PAC_URL, v, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "PAC_SCRIPT", &value); - if (v) - g_object_set (s_proxy, NM_SETTING_PROXY_PAC_SCRIPT, v, NULL); - - break; - case NM_SETTING_PROXY_METHOD_NONE: - g_object_set (s_proxy, - NM_SETTING_PROXY_METHOD, (int) NM_SETTING_PROXY_METHOD_NONE, - NULL); - break; - } - - if (svGetValueBoolean (ifcfg, "BROWSER_ONLY", FALSE)) - g_object_set (s_proxy, NM_SETTING_PROXY_BROWSER_ONLY, TRUE, NULL); - - return NM_SETTING (s_proxy); + NMSettingProxy * s_proxy = NULL; + gs_free char * value = NULL; + const char * v; + NMSettingProxyMethod method; + + v = svGetValueStr(ifcfg, "PROXY_METHOD", &value); + if (!v) + return NULL; + + if (!g_ascii_strcasecmp(v, "auto")) + method = NM_SETTING_PROXY_METHOD_AUTO; + else + method = NM_SETTING_PROXY_METHOD_NONE; + + s_proxy = (NMSettingProxy *) nm_setting_proxy_new(); + + switch (method) { + case NM_SETTING_PROXY_METHOD_AUTO: + g_object_set(s_proxy, NM_SETTING_PROXY_METHOD, (int) NM_SETTING_PROXY_METHOD_AUTO, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "PAC_URL", &value); + if (v) + g_object_set(s_proxy, NM_SETTING_PROXY_PAC_URL, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "PAC_SCRIPT", &value); + if (v) + g_object_set(s_proxy, NM_SETTING_PROXY_PAC_SCRIPT, v, NULL); + + break; + case NM_SETTING_PROXY_METHOD_NONE: + g_object_set(s_proxy, NM_SETTING_PROXY_METHOD, (int) NM_SETTING_PROXY_METHOD_NONE, NULL); + break; + } + + if (svGetValueBoolean(ifcfg, "BROWSER_ONLY", FALSE)) + g_object_set(s_proxy, NM_SETTING_PROXY_BROWSER_ONLY, TRUE, NULL); + + return NM_SETTING(s_proxy); } static NMSetting * -make_ip4_setting (shvarFile *ifcfg, - shvarFile *network_ifcfg, - gboolean routes_read, - gboolean *out_has_defroute, - GError **error) +make_ip4_setting(shvarFile *ifcfg, + shvarFile *network_ifcfg, + gboolean routes_read, + gboolean * out_has_defroute, + GError ** error) { - gs_unref_object NMSettingIPConfig *s_ip4 = NULL; - gs_free char *route_path = NULL; - gs_free char *value = NULL; - const char *v; - char *method; - gs_free char *dns_options_free = NULL; - const char *dns_options = NULL; - gs_free char *gateway = NULL; - int i; - guint32 a; - gboolean has_key; - gboolean never_default; - gint64 i64; - int priority; - const char *const *item; - guint32 route_table; - - nm_assert (out_has_defroute && !*out_has_defroute); - - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - - /* First check if DEFROUTE is set for this device; DEFROUTE has the - * opposite meaning from never-default. The default if DEFROUTE is not - * specified is DEFROUTE=yes which means that this connection can be used - * as a default route - */ - i = svGetValueBoolean (ifcfg, "DEFROUTE", -1); - if (i == -1) - never_default = FALSE; - else { - never_default = !i; - *out_has_defroute = TRUE; - } - - /* Then check if GATEWAYDEV; it's global and overrides DEFROUTE */ - if (network_ifcfg) { - gs_free char *gatewaydev_value = NULL; - const char *gatewaydev; - - /* Get the connection ifcfg device name and the global gateway device */ - v = svGetValueStr (ifcfg, "DEVICE", &value); - gatewaydev = svGetValueStr (network_ifcfg, "GATEWAYDEV", &gatewaydev_value); - dns_options = svGetValue (network_ifcfg, "RES_OPTIONS", &dns_options_free); - - /* If there was a global gateway device specified, then only connections - * for that device can be the default connection. - */ - if (gatewaydev && v) - never_default = !!strcmp (v, gatewaydev); - - nm_clear_g_free (&value); - } - - v = svGetValueStr (ifcfg, "BOOTPROTO", &value); - - if (!v || !*v || !g_ascii_strcasecmp (v, "none")) { - if (is_any_ip4_address_defined (ifcfg, NULL)) - method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; - else - method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; - } else if (!g_ascii_strcasecmp (v, "bootp") || !g_ascii_strcasecmp (v, "dhcp")) { - method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; - } else if (!g_ascii_strcasecmp (v, "static")) { - if (is_any_ip4_address_defined (ifcfg, NULL)) - method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; - else - method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; - } else if (!g_ascii_strcasecmp (v, "autoip")) { - method = NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL; - } else if (!g_ascii_strcasecmp (v, "shared")) { - method = NM_SETTING_IP4_CONFIG_METHOD_SHARED; - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Unknown BOOTPROTO '%s'", v); - return NULL; - } - - /* the route table (policy routing) is ignored if we don't handle routes. */ - route_table = svGetValueInt64 (ifcfg, "IPV4_ROUTE_TABLE", 10, - 0, G_MAXUINT32, 0); - if ( route_table != 0 - && !routes_read) { - PARSE_WARNING ("'rule-' or 'rule6-' files are present; Policy routing (IPV4_ROUTE_TABLE) is ignored"); - route_table = 0; - } - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, method, - NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, !svGetValueBoolean (ifcfg, "PEERDNS", TRUE), - NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, !svGetValueBoolean (ifcfg, "PEERROUTES", TRUE), - NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, - NM_SETTING_IP_CONFIG_MAY_FAIL, !svGetValueBoolean (ifcfg, "IPV4_FAILURE_FATAL", FALSE), - NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV4_ROUTE_METRIC", 10, - -1, G_MAXUINT32, -1), - NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) route_table, - NULL); - - if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) - return NM_SETTING (g_steal_pointer (&s_ip4)); - - /* Handle DHCP settings */ - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DHCP_HOSTNAME", &value); - if (v) - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, v, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DHCP_FQDN", &value); - if (v) { - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, NULL, - NM_SETTING_IP4_CONFIG_DHCP_FQDN, v, - NULL); - } - - i64 = svGetValueInt64 (ifcfg, "DHCP_HOSTNAME_FLAGS", 10, 0, G_MAXUINT32, -1); - if (i64 > -1) { - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, - (guint) i64, - NULL); - } - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, svGetValueBoolean (ifcfg, "DHCP_SEND_HOSTNAME", TRUE), - NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, (int) svGetValueInt64 (ifcfg, "IPV4_DHCP_TIMEOUT", 10, 0, G_MAXINT32, 0), - NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DHCP_CLIENT_ID", &value); - if (v) - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, v, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DHCP_IAID", &value); - if (v) - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_IAID, v, NULL); - - /* Read static IP addresses. - * Read them even for AUTO method - in this case the addresses are - * added to the automatic ones. Note that this is not currently supported by - * the legacy 'network' service (ifup-eth). - */ - for (i = -1;; i++) { - NMIPAddress *addr = NULL; - - /* gateway will only be set if still unset. Hence, we don't leak gateway - * here by calling read_full_ip4_address() repeatedly */ - if (!read_full_ip4_address (ifcfg, i, NULL, &addr, &gateway, error)) - return NULL; - - if (!addr) { - /* The first mandatory variable is 2-indexed (IPADDR2) - * Variables IPADDR, IPADDR0 and IPADDR1 are optional */ - if (i > 1) - break; - continue; - } - - if (!nm_setting_ip_config_add_address (s_ip4, addr)) - PARSE_WARNING ("duplicate IP4 address"); - nm_ip_address_unref (addr); - } - - /* Gateway */ - if (!gateway) { - if (network_ifcfg) { - gboolean read_success; - - read_success = read_ip4_address (network_ifcfg, "GATEWAY", &has_key, &a, error); - if (!read_success) - return NULL; - if (has_key) { - if (nm_setting_ip_config_get_num_addresses (s_ip4) == 0) { - gs_free char *f = g_path_get_basename (svFileGetName (ifcfg)); - PARSE_WARNING ("ignoring GATEWAY (/etc/sysconfig/network) for %s " - "because the connection has no static addresses", f); - } else - gateway = nm_utils_inet4_ntop_dup (a); - } - } - } - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL); - - if (gateway && never_default) - PARSE_WARNING ("GATEWAY will be ignored when DEFROUTE is disabled"); - - /* We used to skip saving a lot of unused properties for the ipv4 shared method. - * We want now to persist them but... unfortunately loading DNS or DOMAIN options - * would cause a fail in the ipv4 verify() function. As we don't want any regression - * in the unlikely event that someone has a working ifcfg file for an IPv4 shared ip - * connection with a crafted "DNS" entry... don't load it. So we will avoid failing - * the connection) */ - if (!nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { - /* DNS servers - * Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting()) - */ - for (i = 1; i <= 10; i++) { - char tag[256]; - - numbered_tag (tag, "DNS", i); - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, tag, &value); - if (v) { - if (nm_utils_ipaddr_is_valid (AF_INET, v)) { - if (!nm_setting_ip_config_add_dns (s_ip4, v)) - PARSE_WARNING ("duplicate DNS server %s", tag); - } else if (nm_utils_ipaddr_is_valid (AF_INET6, v)) { - /* Ignore IPv6 addresses */ - } else { - PARSE_WARNING ("invalid DNS server address %s", v); - return NULL; - } - } - } - - /* DNS searches */ - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DOMAIN", &value); - if (v) { - gs_free const char **searches = NULL; - - searches = nm_utils_strsplit_set (v, " "); - if (searches) { - for (item = searches; *item; item++) { - if (!nm_setting_ip_config_add_dns_search (s_ip4, *item)) - PARSE_WARNING ("duplicate DNS domain '%s'", *item); - } - } - } - } - - /* DNS options */ - nm_clear_g_free (&value); - parse_dns_options (s_ip4, svGetValue (ifcfg, "RES_OPTIONS", &value)); - parse_dns_options (s_ip4, dns_options); - - /* DNS priority */ - priority = svGetValueInt64 (ifcfg, "IPV4_DNS_PRIORITY", 10, G_MININT32, G_MAXINT32, 0); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_DNS_PRIORITY, - priority, - NULL); - - /* Static routes - route- file */ - route_path = utils_get_route_path (svFileGetName (ifcfg)); - - if (routes_read) { - gs_free char *contents = NULL; - gsize len; - - if (!g_file_get_contents (route_path, &contents, &len, NULL)) - len = 0; - - if (utils_has_route_file_new_syntax_content (contents, len)) { - nm_auto_shvar_file_close shvarFile *route_ifcfg = NULL; - - /* Parse route file in new syntax */ - route_ifcfg = svFile_new (route_path, -1, contents); - for (i = 0;; i++) { - nm_auto_unref_ip_route NMIPRoute *route = NULL; - - if (!read_one_ip4_route (route_ifcfg, i, &route, error)) - return NULL; - - if (!route) - break; - - if (!nm_setting_ip_config_add_route (s_ip4, route)) - PARSE_WARNING ("duplicate IP4 route"); - } - } else { - if (!read_route_file_parse (AF_INET, route_path, contents, len, s_ip4, error)) - return NULL; - } - } - - /* Legacy value NM used for a while but is incorrect (rh #459370) */ - if ( !nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) - && !nm_setting_ip_config_get_num_dns_searches (s_ip4)) { - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "SEARCH", &value); - if (v) { - gs_free const char **searches = NULL; - - searches = nm_utils_strsplit_set (v, " "); - if (searches) { - for (item = searches; *item; item++) { - if (!nm_setting_ip_config_add_dns_search (s_ip4, *item)) - PARSE_WARNING ("duplicate DNS search '%s'", *item); - } - } - } - } - - i64 = svGetValueInt64 (ifcfg, "ACD_TIMEOUT", 10, -1, NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, -2); - if (i64 == -2) { - i64 = svGetValueInt64 (ifcfg, "ARPING_WAIT", 10, -1, - NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX / 1000, -1); - if (i64 > 0) - i64 *= 1000; - } - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DAD_TIMEOUT, (int) i64, NULL); - - return NM_SETTING (g_steal_pointer (&s_ip4)); + gs_unref_object NMSettingIPConfig *s_ip4 = NULL; + gs_free char * route_path = NULL; + gs_free char * value = NULL; + const char * v; + char * method; + gs_free char * dns_options_free = NULL; + const char * dns_options = NULL; + gs_free char * gateway = NULL; + int i; + guint32 a; + gboolean has_key; + gboolean never_default; + gint64 i64; + int priority; + const char *const * item; + guint32 route_table; + + nm_assert(out_has_defroute && !*out_has_defroute); + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + + /* First check if DEFROUTE is set for this device; DEFROUTE has the + * opposite meaning from never-default. The default if DEFROUTE is not + * specified is DEFROUTE=yes which means that this connection can be used + * as a default route + */ + i = svGetValueBoolean(ifcfg, "DEFROUTE", -1); + if (i == -1) + never_default = FALSE; + else { + never_default = !i; + *out_has_defroute = TRUE; + } + + /* Then check if GATEWAYDEV; it's global and overrides DEFROUTE */ + if (network_ifcfg) { + gs_free char *gatewaydev_value = NULL; + const char * gatewaydev; + + /* Get the connection ifcfg device name and the global gateway device */ + v = svGetValueStr(ifcfg, "DEVICE", &value); + gatewaydev = svGetValueStr(network_ifcfg, "GATEWAYDEV", &gatewaydev_value); + dns_options = svGetValue(network_ifcfg, "RES_OPTIONS", &dns_options_free); + + /* If there was a global gateway device specified, then only connections + * for that device can be the default connection. + */ + if (gatewaydev && v) + never_default = !!strcmp(v, gatewaydev); + + nm_clear_g_free(&value); + } + + v = svGetValueStr(ifcfg, "BOOTPROTO", &value); + + if (!v || !*v || !g_ascii_strcasecmp(v, "none")) { + if (is_any_ip4_address_defined(ifcfg, NULL)) + method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; + else + method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + } else if (!g_ascii_strcasecmp(v, "bootp") || !g_ascii_strcasecmp(v, "dhcp")) { + method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + } else if (!g_ascii_strcasecmp(v, "static")) { + if (is_any_ip4_address_defined(ifcfg, NULL)) + method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; + else + method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + } else if (!g_ascii_strcasecmp(v, "autoip")) { + method = NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL; + } else if (!g_ascii_strcasecmp(v, "shared")) { + method = NM_SETTING_IP4_CONFIG_METHOD_SHARED; + } else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Unknown BOOTPROTO '%s'", + v); + return NULL; + } + + /* the route table (policy routing) is ignored if we don't handle routes. */ + route_table = svGetValueInt64(ifcfg, "IPV4_ROUTE_TABLE", 10, 0, G_MAXUINT32, 0); + if (route_table != 0 && !routes_read) { + PARSE_WARNING( + "'rule-' or 'rule6-' files are present; Policy routing (IPV4_ROUTE_TABLE) is ignored"); + route_table = 0; + } + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + method, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, + !svGetValueBoolean(ifcfg, "PEERDNS", TRUE), + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, + !svGetValueBoolean(ifcfg, "PEERROUTES", TRUE), + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, + never_default, + NM_SETTING_IP_CONFIG_MAY_FAIL, + !svGetValueBoolean(ifcfg, "IPV4_FAILURE_FATAL", FALSE), + NM_SETTING_IP_CONFIG_ROUTE_METRIC, + svGetValueInt64(ifcfg, "IPV4_ROUTE_METRIC", 10, -1, G_MAXUINT32, -1), + NM_SETTING_IP_CONFIG_ROUTE_TABLE, + (guint) route_table, + NULL); + + if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) + return NM_SETTING(g_steal_pointer(&s_ip4)); + + /* Handle DHCP settings */ + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DHCP_HOSTNAME", &value); + if (v) + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DHCP_FQDN", &value); + if (v) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, + NULL, + NM_SETTING_IP4_CONFIG_DHCP_FQDN, + v, + NULL); + } + + i64 = svGetValueInt64(ifcfg, "DHCP_HOSTNAME_FLAGS", 10, 0, G_MAXUINT32, -1); + if (i64 > -1) { + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, (guint) i64, NULL); + } + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, + svGetValueBoolean(ifcfg, "DHCP_SEND_HOSTNAME", TRUE), + NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, + (int) svGetValueInt64(ifcfg, "IPV4_DHCP_TIMEOUT", 10, 0, G_MAXINT32, 0), + NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DHCP_CLIENT_ID", &value); + if (v) + g_object_set(s_ip4, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DHCP_VENDOR_CLASS_IDENTIFIER", &value); + if (v) + g_object_set(s_ip4, NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DHCP_IAID", &value); + if (v) + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_DHCP_IAID, v, NULL); + + /* Read static IP addresses. + * Read them even for AUTO method - in this case the addresses are + * added to the automatic ones. Note that this is not currently supported by + * the legacy 'network' service (ifup-eth). + */ + for (i = -1;; i++) { + NMIPAddress *addr = NULL; + + /* gateway will only be set if still unset. Hence, we don't leak gateway + * here by calling read_full_ip4_address() repeatedly */ + if (!read_full_ip4_address(ifcfg, i, NULL, &addr, &gateway, error)) + return NULL; + + if (!addr) { + /* The first mandatory variable is 2-indexed (IPADDR2) + * Variables IPADDR, IPADDR0 and IPADDR1 are optional */ + if (i > 1) + break; + continue; + } + + if (!nm_setting_ip_config_add_address(s_ip4, addr)) + PARSE_WARNING("duplicate IP4 address"); + nm_ip_address_unref(addr); + } + + /* Gateway */ + if (!gateway) { + if (network_ifcfg) { + gboolean read_success; + + read_success = read_ip4_address(network_ifcfg, "GATEWAY", &has_key, &a, error); + if (!read_success) + return NULL; + if (has_key) { + if (nm_setting_ip_config_get_num_addresses(s_ip4) == 0) { + gs_free char *f = g_path_get_basename(svFileGetName(ifcfg)); + PARSE_WARNING("ignoring GATEWAY (/etc/sysconfig/network) for %s " + "because the connection has no static addresses", + f); + } else + gateway = nm_utils_inet4_ntop_dup(a); + } + } + } + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL); + + if (gateway && never_default) + PARSE_WARNING("GATEWAY will be ignored when DEFROUTE is disabled"); + + /* We used to skip saving a lot of unused properties for the ipv4 shared method. + * We want now to persist them but... unfortunately loading DNS or DOMAIN options + * would cause a fail in the ipv4 verify() function. As we don't want any regression + * in the unlikely event that someone has a working ifcfg file for an IPv4 shared ip + * connection with a crafted "DNS" entry... don't load it. So we will avoid failing + * the connection) */ + if (!nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { + /* DNS servers + * Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting()) + */ + for (i = 1; i <= 10; i++) { + char tag[256]; + + numbered_tag(tag, "DNS", i); + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, tag, &value); + if (v) { + if (nm_utils_ipaddr_is_valid(AF_INET, v)) { + if (!nm_setting_ip_config_add_dns(s_ip4, v)) + PARSE_WARNING("duplicate DNS server %s", tag); + } else if (nm_utils_ipaddr_is_valid(AF_INET6, v)) { + /* Ignore IPv6 addresses */ + } else { + PARSE_WARNING("invalid DNS server address %s", v); + return NULL; + } + } + } + + /* DNS searches */ + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DOMAIN", &value); + if (v) { + gs_free const char **searches = NULL; + + searches = nm_utils_strsplit_set(v, " "); + if (searches) { + for (item = searches; *item; item++) { + if (!nm_setting_ip_config_add_dns_search(s_ip4, *item)) + PARSE_WARNING("duplicate DNS domain '%s'", *item); + } + } + } + } + + /* DNS options */ + nm_clear_g_free(&value); + parse_dns_options(s_ip4, svGetValue(ifcfg, "RES_OPTIONS", &value)); + parse_dns_options(s_ip4, dns_options); + + /* DNS priority */ + priority = svGetValueInt64(ifcfg, "IPV4_DNS_PRIORITY", 10, G_MININT32, G_MAXINT32, 0); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_DNS_PRIORITY, priority, NULL); + + /* Static routes - route- file */ + route_path = utils_get_route_path(svFileGetName(ifcfg)); + + if (routes_read) { + gs_free char *contents = NULL; + gsize len; + + if (!g_file_get_contents(route_path, &contents, &len, NULL)) + len = 0; + + if (utils_has_route_file_new_syntax_content(contents, len)) { + nm_auto_shvar_file_close shvarFile *route_ifcfg = NULL; + + /* Parse route file in new syntax */ + route_ifcfg = svFile_new(route_path, -1, contents); + for (i = 0;; i++) { + nm_auto_unref_ip_route NMIPRoute *route = NULL; + + if (!read_one_ip4_route(route_ifcfg, i, &route, error)) + return NULL; + + if (!route) + break; + + if (!nm_setting_ip_config_add_route(s_ip4, route)) + PARSE_WARNING("duplicate IP4 route"); + } + } else { + if (!read_route_file_parse(AF_INET, route_path, contents, len, s_ip4, error)) + return NULL; + } + } + + /* Legacy value NM used for a while but is incorrect (rh #459370) */ + if (!nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) + && !nm_setting_ip_config_get_num_dns_searches(s_ip4)) { + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "SEARCH", &value); + if (v) { + gs_free const char **searches = NULL; + + searches = nm_utils_strsplit_set(v, " "); + if (searches) { + for (item = searches; *item; item++) { + if (!nm_setting_ip_config_add_dns_search(s_ip4, *item)) + PARSE_WARNING("duplicate DNS search '%s'", *item); + } + } + } + } + + i64 = svGetValueInt64(ifcfg, "ACD_TIMEOUT", 10, -1, NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, -2); + if (i64 == -2) { + i64 = svGetValueInt64(ifcfg, + "ARPING_WAIT", + 10, + -1, + NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX / 1000, + -1); + if (i64 > 0) + i64 *= 1000; + } + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_DAD_TIMEOUT, (int) i64, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DHCP_REJECT_SERVERS", &value); + if (v) { + gs_free const char **strv = NULL; + + strv = nm_utils_escaped_tokens_split(v, NM_ASCII_SPACES); + if (strv) { + for (item = strv; *item; item++) + nm_setting_ip_config_add_dhcp_reject_server(s_ip4, *item); + } + } + + return NM_SETTING(g_steal_pointer(&s_ip4)); } static void -read_aliases (NMSettingIPConfig *s_ip4, gboolean read_defroute, const char *filename) +read_aliases(NMSettingIPConfig *s_ip4, gboolean read_defroute, const char *filename) { - GDir *dir; - gs_free char *dirname = NULL; - gs_free char *base = NULL; - NMIPAddress *base_addr = NULL; - GError *err = NULL; - - g_return_if_fail (s_ip4 != NULL); - g_return_if_fail (filename != NULL); - - if (nm_setting_ip_config_get_num_addresses (s_ip4) > 0) - base_addr = nm_setting_ip_config_get_address (s_ip4, 0); - - dirname = g_path_get_dirname (filename); - nm_assert (dirname != NULL); - base = g_path_get_basename (filename); - nm_assert (base != NULL); - - dir = g_dir_open (dirname, 0, &err); - if (dir) { - const char *item; - NMIPAddress *addr; - gboolean ok; - - while ((item = g_dir_read_name (dir))) { - nm_auto_shvar_file_close shvarFile *parsed = NULL; - gs_free char *gateway = NULL; - gs_free char *device_value = NULL; - gs_free char *full_path = NULL; - const char *device; - const char *p; - - if (!utils_is_ifcfg_alias_file (item, base)) - continue; - - full_path = g_build_filename (dirname, item, NULL); - - p = strchr (item, ':'); - g_assert (p != NULL); /* we know this is true from utils_is_ifcfg_alias_file() */ - for (p++; *p; p++) { - if (!g_ascii_isalnum (*p) && *p != '_') - break; - } - if (*p) { - PARSE_WARNING ("ignoring alias file '%s' with invalid name", full_path); - continue; - } - - parsed = svOpenFile (full_path, &err); - if (!parsed) { - PARSE_WARNING ("couldn't parse alias file '%s': %s", full_path, err->message); - g_clear_error (&err); - continue; - } - - device = svGetValueStr (parsed, "DEVICE", &device_value); - if (!device) { - PARSE_WARNING ("alias file '%s' has no DEVICE", full_path); - continue; - } - /* We know that item starts with IFCFG_TAG from utils_is_ifcfg_alias_file() */ - if (strcmp (device, item + strlen (IFCFG_TAG)) != 0) { - PARSE_WARNING ("alias file '%s' has invalid DEVICE (%s) for filename", - full_path, device); - continue; - } - - addr = NULL; - ok = read_full_ip4_address (parsed, -1, base_addr, &addr, - read_defroute ? &gateway : NULL, - &err); - if (ok) { - nm_ip_address_set_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL, g_variant_new_string (device)); - if (!nm_setting_ip_config_add_address (s_ip4, addr)) - PARSE_WARNING ("duplicate IP4 address in alias file %s", item); - if (nm_streq0 (nm_setting_ip_config_get_method (s_ip4), NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); - if (read_defroute) { - int i; - - if (gateway) { - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL); - read_defroute = FALSE; - } - i = svGetValueBoolean (parsed, "DEFROUTE", -1); - if (i != -1) { - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_NEVER_DEFAULT, (gboolean) !i, - NULL); - read_defroute = FALSE; - } - } - } else { - PARSE_WARNING ("error reading IP4 address from alias file '%s': %s", - full_path, err ? err->message : "no address"); - g_clear_error (&err); - } - nm_ip_address_unref (addr); - } - - g_dir_close (dir); - } else { - PARSE_WARNING ("can not read directory '%s': %s", dirname, err->message); - g_error_free (err); - } + GDir * dir; + gs_free char *dirname = NULL; + gs_free char *base = NULL; + NMIPAddress * base_addr = NULL; + GError * err = NULL; + + g_return_if_fail(s_ip4 != NULL); + g_return_if_fail(filename != NULL); + + if (nm_setting_ip_config_get_num_addresses(s_ip4) > 0) + base_addr = nm_setting_ip_config_get_address(s_ip4, 0); + + dirname = g_path_get_dirname(filename); + nm_assert(dirname != NULL); + base = g_path_get_basename(filename); + nm_assert(base != NULL); + + dir = g_dir_open(dirname, 0, &err); + if (dir) { + const char * item; + NMIPAddress *addr; + gboolean ok; + + while ((item = g_dir_read_name(dir))) { + nm_auto_shvar_file_close shvarFile *parsed = NULL; + gs_free char * gateway = NULL; + gs_free char * device_value = NULL; + gs_free char * full_path = NULL; + const char * device; + const char * p; + + if (!utils_is_ifcfg_alias_file(item, base)) + continue; + + full_path = g_build_filename(dirname, item, NULL); + + p = strchr(item, ':'); + g_assert(p != NULL); /* we know this is true from utils_is_ifcfg_alias_file() */ + for (p++; *p; p++) { + if (!g_ascii_isalnum(*p) && *p != '_') + break; + } + if (*p) { + PARSE_WARNING("ignoring alias file '%s' with invalid name", full_path); + continue; + } + + parsed = svOpenFile(full_path, &err); + if (!parsed) { + PARSE_WARNING("couldn't parse alias file '%s': %s", full_path, err->message); + g_clear_error(&err); + continue; + } + + device = svGetValueStr(parsed, "DEVICE", &device_value); + if (!device) { + PARSE_WARNING("alias file '%s' has no DEVICE", full_path); + continue; + } + /* We know that item starts with IFCFG_TAG from utils_is_ifcfg_alias_file() */ + if (strcmp(device, item + strlen(IFCFG_TAG)) != 0) { + PARSE_WARNING("alias file '%s' has invalid DEVICE (%s) for filename", + full_path, + device); + continue; + } + + addr = NULL; + ok = read_full_ip4_address(parsed, + -1, + base_addr, + &addr, + read_defroute ? &gateway : NULL, + &err); + if (ok) { + nm_ip_address_set_attribute(addr, + NM_IP_ADDRESS_ATTRIBUTE_LABEL, + g_variant_new_string(device)); + if (!nm_setting_ip_config_add_address(s_ip4, addr)) + PARSE_WARNING("duplicate IP4 address in alias file %s", item); + if (nm_streq0(nm_setting_ip_config_get_method(s_ip4), + NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + if (read_defroute) { + int i; + + if (gateway) { + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL); + read_defroute = FALSE; + } + i = svGetValueBoolean(parsed, "DEFROUTE", -1); + if (i != -1) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, + (gboolean) !i, + NULL); + read_defroute = FALSE; + } + } + } else { + PARSE_WARNING("error reading IP4 address from alias file '%s': %s", + full_path, + err ? err->message : "no address"); + g_clear_error(&err); + } + nm_ip_address_unref(addr); + } + + g_dir_close(dir); + } else { + PARSE_WARNING("can not read directory '%s': %s", dirname, err->message); + g_error_free(err); + } } static NMSetting * -make_ip6_setting (shvarFile *ifcfg, - shvarFile *network_ifcfg, - gboolean routes_read, - GError **error) +make_ip6_setting(shvarFile *ifcfg, shvarFile *network_ifcfg, gboolean routes_read, GError **error) { - gs_unref_object NMSettingIPConfig *s_ip6 = NULL; - const char *v; - gs_free char *value = NULL; - gboolean ipv6init; - gboolean ipv6forwarding; - gboolean disabled; - gboolean dhcp6 = FALSE; - char *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; - const char *ipv6addr, *ipv6addr_secondaries; - gs_free char *ipv6addr_to_free = NULL; - gs_free char *ipv6addr_secondaries_to_free = NULL; - gs_free const char **list = NULL; - const char *const *iter; - guint32 i; - gint64 i64; - int i_val; - GError *local = NULL; - int priority; - gboolean never_default = FALSE; - gboolean ip6_privacy = FALSE, ip6_privacy_prefer_public_ip; - NMSettingIP6ConfigPrivacy ip6_privacy_val; - guint32 route_table; - - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - - /* First check if IPV6_DEFROUTE is set for this device; IPV6_DEFROUTE has the - * opposite meaning from never-default. The default if IPV6_DEFROUTE is not - * specified is IPV6_DEFROUTE=yes which means that this connection can be used - * as a default route - */ - never_default = !svGetValueBoolean (ifcfg, "IPV6_DEFROUTE", TRUE); - - /* Then check if IPV6_DEFAULTGW or IPV6_DEFAULTDEV is specified; - * they are global and override IPV6_DEFROUTE - * When both are set, the device specified in IPV6_DEFAULTGW takes preference. - */ - if (network_ifcfg) { - const char *ipv6_defaultgw, *ipv6_defaultdev; - gs_free char *ipv6_defaultgw_to_free = NULL; - gs_free char *ipv6_defaultdev_to_free = NULL; - const char *default_dev = NULL; - - /* Get the connection ifcfg device name and the global default route device */ - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DEVICE", &value); - ipv6_defaultgw = svGetValueStr (network_ifcfg, "IPV6_DEFAULTGW", &ipv6_defaultgw_to_free); - ipv6_defaultdev = svGetValueStr (network_ifcfg, "IPV6_DEFAULTDEV", &ipv6_defaultdev_to_free); - - if (ipv6_defaultgw) { - default_dev = strchr (ipv6_defaultgw, '%'); - if (default_dev) - default_dev++; - } - if (!default_dev) - default_dev = ipv6_defaultdev; - - /* If there was a global default route device specified, then only connections - * for that device can be the default connection. - */ - if (default_dev && v) - never_default = !!strcmp (v, default_dev); - } - - /* Find out method property */ - /* Is IPV6 enabled? Set method to "ignored", when not enabled */ - disabled = svGetValueBoolean(ifcfg, "IPV6_DISABLED", FALSE); - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IPV6INIT", &value); - ipv6init = svGetValueBoolean (ifcfg, "IPV6INIT", FALSE); - if (!v) { - if (network_ifcfg) - ipv6init = svGetValueBoolean (network_ifcfg, "IPV6INIT", FALSE); - } - - if (disabled) - method = NM_SETTING_IP6_CONFIG_METHOD_DISABLED; - else if (!ipv6init) - method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - else { - ipv6forwarding = svGetValueBoolean (ifcfg, "IPV6FORWARDING", FALSE); - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IPV6_AUTOCONF", &value); - dhcp6 = svGetValueBoolean (ifcfg, "DHCPV6C", FALSE); - - if (!g_strcmp0 (v, "shared")) - method = NM_SETTING_IP6_CONFIG_METHOD_SHARED; - else if (svParseBoolean (v, !ipv6forwarding)) - method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; - else if (dhcp6) - method = NM_SETTING_IP6_CONFIG_METHOD_DHCP; - else { - /* IPV6_AUTOCONF=no and no IPv6 address -> method 'link-local' */ - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IPV6ADDR", &value); - if (!v) { - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IPV6ADDR_SECONDARIES", &value); - } - - if (!v) - method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; - } - } - /* TODO - handle other methods */ - - /* Read IPv6 Privacy Extensions configuration */ - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IPV6_PRIVACY", &value); - if (v) { - ip6_privacy = svParseBoolean (v, FALSE); - if (!ip6_privacy) - ip6_privacy = (g_strcmp0 (v, "rfc4941") == 0) || - (g_strcmp0 (v, "rfc3041") == 0); - } - ip6_privacy_prefer_public_ip = svGetValueBoolean (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", FALSE); - ip6_privacy_val = v ? - (ip6_privacy ? - (ip6_privacy_prefer_public_ip ? NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR : NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR) : - NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED) : - NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; - - /* the route table (policy routing) is ignored if we don't handle routes. */ - route_table = svGetValueInt64 (ifcfg, "IPV6_ROUTE_TABLE", 10, - 0, G_MAXUINT32, 0); - if ( route_table != 0 - && !routes_read) { - PARSE_WARNING ("'rule-' or 'rule6-' files are present; Policy routing (IPV6_ROUTE_TABLE) is ignored"); - route_table = 0; - } - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, method, - NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, !svGetValueBoolean (ifcfg, "IPV6_PEERDNS", TRUE), - NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, !svGetValueBoolean (ifcfg, "IPV6_PEERROUTES", TRUE), - NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, - NM_SETTING_IP_CONFIG_MAY_FAIL, !svGetValueBoolean (ifcfg, "IPV6_FAILURE_FATAL", FALSE), - NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV6_ROUTE_METRIC", 10, - -1, G_MAXUINT32, -1), - NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) route_table, - NM_SETTING_IP6_CONFIG_IP6_PRIVACY, ip6_privacy_val, - NULL); - - /* Don't bother to read IP, DNS and routes when IPv6 is disabled */ - if (NM_IN_STRSET (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) - return NM_SETTING (g_steal_pointer (&s_ip6)); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DHCPV6_DUID", &value); - if (v) - g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_DHCP_DUID, v, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DHCPV6_IAID", &value); - if (v) - g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_IAID, v, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DHCPV6_HOSTNAME", &value); - /* Use DHCP_HOSTNAME as fallback if it is in FQDN format and ipv6.method is - * auto or dhcp: this is required to support old ifcfg files - */ - if (!v && ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) - || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP))) { - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DHCP_HOSTNAME", &value); - if (v && !strchr (v, '.')) - v = NULL; - } - if (v) - g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, v, NULL); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, svGetValueBoolean (ifcfg, "DHCPV6_SEND_HOSTNAME", TRUE), - NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, (int) svGetValueInt64 (ifcfg, "IPV6_DHCP_TIMEOUT", 10, 0, G_MAXINT32, 0), - NM_SETTING_IP6_CONFIG_RA_TIMEOUT, (int) svGetValueInt64 (ifcfg, "IPV6_RA_TIMEOUT", 10, 0, G_MAXINT32, 0), - NULL); - - i64 = svGetValueInt64 (ifcfg, "DHCPV6_HOSTNAME_FLAGS", 10, 0, G_MAXUINT32, -1); - if (i64 > -1) { - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, - (guint) i64, - NULL); - } - - /* Read static IP addresses. - * Read them even for AUTO and DHCP methods - in this case the addresses are - * added to the automatic ones. Note that this is not currently supported by - * the legacy 'network' service (ifup-eth). - */ - ipv6addr = svGetValueStr (ifcfg, "IPV6ADDR", &ipv6addr_to_free); - ipv6addr_secondaries = svGetValueStr (ifcfg, "IPV6ADDR_SECONDARIES", &ipv6addr_secondaries_to_free); - - nm_clear_g_free (&value); - value = g_strjoin (ipv6addr && ipv6addr_secondaries ? " " : NULL, - ipv6addr ?: "", - ipv6addr_secondaries ?: "", - NULL); - - list = nm_utils_strsplit_set (value, " "); - for (iter = list, i = 0; iter && *iter; iter++, i++) { - NMIPAddress *addr = NULL; - - if (!parse_full_ip6_address (ifcfg, *iter, i, &addr, error)) - return NULL; - - if (!nm_setting_ip_config_add_address (s_ip6, addr)) - PARSE_WARNING ("duplicate IP6 address"); - nm_ip_address_unref (addr); - } - - /* Gateway */ - if (nm_setting_ip_config_get_num_addresses (s_ip6)) { - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IPV6_DEFAULTGW", &value); - if (!v) { - /* If no gateway in the ifcfg, try global /etc/sysconfig/network instead */ - if (network_ifcfg) { - nm_clear_g_free (&value); - v = svGetValueStr (network_ifcfg, "IPV6_DEFAULTGW", &value); - } - } - if (v) { - char *ptr; - if ((ptr = strchr (v, '%')) != NULL) - *ptr = '\0'; /* remove %interface prefix if present */ - if (!nm_utils_ipaddr_is_valid (AF_INET6, v)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid IP6 address '%s'", v); - return NULL; - } - - g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, v, NULL); - } - } - - i_val = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64; - if (!svGetValueEnum (ifcfg, "IPV6_ADDR_GEN_MODE", - nm_setting_ip6_config_addr_gen_mode_get_type (), - &i_val, &local)) { - PARSE_WARNING ("%s", local->message); - g_clear_error (&local); - } - g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, i_val, NULL); - - /* IPv6 tokenized interface identifier */ - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IPV6_TOKEN", &value); - if (v) - g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, v, NULL); - - /* DNS servers - * Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting()) - */ - for (i = 1; i <= 10; i++) { - char tag[256]; - - numbered_tag (tag, "DNS", i); - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, tag, &value); - if (!v) { - /* all done */ - break; - } - - if (nm_utils_ipaddr_is_valid (AF_INET6, v)) { - if (!nm_setting_ip_config_add_dns (s_ip6, v)) - PARSE_WARNING ("duplicate DNS server %s", tag); - } else if (nm_utils_ipaddr_is_valid (AF_INET, v)) { - /* Ignore IPv4 addresses */ - } else { - PARSE_WARNING ("invalid DNS server address %s", v); - return NULL; - } - } - - if (!routes_read) { - /* NOP */ - } else { - gs_free char *route6_path = NULL; - - /* Read static routes from route6- file */ - route6_path = utils_get_route6_path (svFileGetName (ifcfg)); - if (!read_route_file (AF_INET6, route6_path, s_ip6, error)) - return NULL; - } - - /* DNS searches */ - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IPV6_DOMAIN", &value); - if (v) { - gs_free const char **searches = NULL; - - searches = nm_utils_strsplit_set (v, " "); - if (searches) { - for (iter = searches; *iter; iter++) { - if (!nm_setting_ip_config_add_dns_search (s_ip6, *iter)) - PARSE_WARNING ("duplicate DNS domain '%s'", *iter); - } - } - } - - /* DNS options */ - nm_clear_g_free (&value); - parse_dns_options (s_ip6, svGetValue (ifcfg, "IPV6_RES_OPTIONS", &value)); - - /* DNS priority */ - priority = svGetValueInt64 (ifcfg, "IPV6_DNS_PRIORITY", 10, G_MININT32, G_MAXINT32, 0); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_DNS_PRIORITY, - priority, - NULL); - - return NM_SETTING (g_steal_pointer (&s_ip6)); + gs_unref_object NMSettingIPConfig *s_ip6 = NULL; + const char * v; + gs_free char * value = NULL; + gboolean ipv6init; + gboolean ipv6forwarding; + gboolean disabled; + gboolean dhcp6 = FALSE; + char * method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + const char * ipv6addr, *ipv6addr_secondaries; + gs_free char * ipv6addr_to_free = NULL; + gs_free char * ipv6addr_secondaries_to_free = NULL; + gs_free const char ** list = NULL; + const char *const * iter; + guint32 i; + gint64 i64; + int i_val; + GError * local = NULL; + int priority; + gboolean never_default = FALSE; + gboolean ip6_privacy = FALSE, ip6_privacy_prefer_public_ip; + NMSettingIP6ConfigPrivacy ip6_privacy_val; + guint32 route_table; + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + + /* First check if IPV6_DEFROUTE is set for this device; IPV6_DEFROUTE has the + * opposite meaning from never-default. The default if IPV6_DEFROUTE is not + * specified is IPV6_DEFROUTE=yes which means that this connection can be used + * as a default route + */ + never_default = !svGetValueBoolean(ifcfg, "IPV6_DEFROUTE", TRUE); + + /* Then check if IPV6_DEFAULTGW or IPV6_DEFAULTDEV is specified; + * they are global and override IPV6_DEFROUTE + * When both are set, the device specified in IPV6_DEFAULTGW takes preference. + */ + if (network_ifcfg) { + const char * ipv6_defaultgw, *ipv6_defaultdev; + gs_free char *ipv6_defaultgw_to_free = NULL; + gs_free char *ipv6_defaultdev_to_free = NULL; + const char * default_dev = NULL; + + /* Get the connection ifcfg device name and the global default route device */ + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DEVICE", &value); + ipv6_defaultgw = svGetValueStr(network_ifcfg, "IPV6_DEFAULTGW", &ipv6_defaultgw_to_free); + ipv6_defaultdev = svGetValueStr(network_ifcfg, "IPV6_DEFAULTDEV", &ipv6_defaultdev_to_free); + + if (ipv6_defaultgw) { + default_dev = strchr(ipv6_defaultgw, '%'); + if (default_dev) + default_dev++; + } + if (!default_dev) + default_dev = ipv6_defaultdev; + + /* If there was a global default route device specified, then only connections + * for that device can be the default connection. + */ + if (default_dev && v) + never_default = !!strcmp(v, default_dev); + } + + /* Find out method property */ + /* Is IPV6 enabled? Set method to "ignored", when not enabled */ + disabled = svGetValueBoolean(ifcfg, "IPV6_DISABLED", FALSE); + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IPV6INIT", &value); + ipv6init = svGetValueBoolean(ifcfg, "IPV6INIT", FALSE); + if (!v) { + if (network_ifcfg) + ipv6init = svGetValueBoolean(network_ifcfg, "IPV6INIT", FALSE); + } + + if (disabled) + method = NM_SETTING_IP6_CONFIG_METHOD_DISABLED; + else if (!ipv6init) + method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE; + else { + ipv6forwarding = svGetValueBoolean(ifcfg, "IPV6FORWARDING", FALSE); + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IPV6_AUTOCONF", &value); + dhcp6 = svGetValueBoolean(ifcfg, "DHCPV6C", FALSE); + + if (!g_strcmp0(v, "shared")) + method = NM_SETTING_IP6_CONFIG_METHOD_SHARED; + else if (svParseBoolean(v, !ipv6forwarding)) + method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; + else if (dhcp6) + method = NM_SETTING_IP6_CONFIG_METHOD_DHCP; + else { + /* IPV6_AUTOCONF=no and no IPv6 address -> method 'link-local' */ + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IPV6ADDR", &value); + if (!v) { + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IPV6ADDR_SECONDARIES", &value); + } + + if (!v) + method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; + } + } + /* TODO - handle other methods */ + + /* Read IPv6 Privacy Extensions configuration */ + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IPV6_PRIVACY", &value); + if (v) { + ip6_privacy = svParseBoolean(v, FALSE); + if (!ip6_privacy) + ip6_privacy = (g_strcmp0(v, "rfc4941") == 0) || (g_strcmp0(v, "rfc3041") == 0); + } + ip6_privacy_prefer_public_ip = svGetValueBoolean(ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", FALSE); + ip6_privacy_val = v ? (ip6_privacy ? (ip6_privacy_prefer_public_ip + ? NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR + : NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR) + : NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED) + : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; + + /* the route table (policy routing) is ignored if we don't handle routes. */ + route_table = svGetValueInt64(ifcfg, "IPV6_ROUTE_TABLE", 10, 0, G_MAXUINT32, 0); + if (route_table != 0 && !routes_read) { + PARSE_WARNING( + "'rule-' or 'rule6-' files are present; Policy routing (IPV6_ROUTE_TABLE) is ignored"); + route_table = 0; + } + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + method, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, + !svGetValueBoolean(ifcfg, "IPV6_PEERDNS", TRUE), + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, + !svGetValueBoolean(ifcfg, "IPV6_PEERROUTES", TRUE), + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, + never_default, + NM_SETTING_IP_CONFIG_MAY_FAIL, + !svGetValueBoolean(ifcfg, "IPV6_FAILURE_FATAL", FALSE), + NM_SETTING_IP_CONFIG_ROUTE_METRIC, + svGetValueInt64(ifcfg, "IPV6_ROUTE_METRIC", 10, -1, G_MAXUINT32, -1), + NM_SETTING_IP_CONFIG_ROUTE_TABLE, + (guint) route_table, + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, + ip6_privacy_val, + NULL); + + /* Don't bother to read IP, DNS and routes when IPv6 is disabled */ + if (NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) + return NM_SETTING(g_steal_pointer(&s_ip6)); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DHCPV6_DUID", &value); + if (v) + g_object_set(s_ip6, NM_SETTING_IP6_CONFIG_DHCP_DUID, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DHCPV6_IAID", &value); + if (v) + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_DHCP_IAID, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DHCPV6_HOSTNAME", &value); + /* Use DHCP_HOSTNAME as fallback if it is in FQDN format and ipv6.method is + * auto or dhcp: this is required to support old ifcfg files + */ + if (!v + && (!strcmp(method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) + || !strcmp(method, NM_SETTING_IP6_CONFIG_METHOD_DHCP))) { + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DHCP_HOSTNAME", &value); + if (v && !strchr(v, '.')) + v = NULL; + } + if (v) + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, v, NULL); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, + svGetValueBoolean(ifcfg, "DHCPV6_SEND_HOSTNAME", TRUE), + NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, + (int) svGetValueInt64(ifcfg, "IPV6_DHCP_TIMEOUT", 10, 0, G_MAXINT32, 0), + NM_SETTING_IP6_CONFIG_RA_TIMEOUT, + (int) svGetValueInt64(ifcfg, "IPV6_RA_TIMEOUT", 10, 0, G_MAXINT32, 0), + NULL); + + i64 = svGetValueInt64(ifcfg, "DHCPV6_HOSTNAME_FLAGS", 10, 0, G_MAXUINT32, -1); + if (i64 > -1) { + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, (guint) i64, NULL); + } + + /* Read static IP addresses. + * Read them even for AUTO and DHCP methods - in this case the addresses are + * added to the automatic ones. Note that this is not currently supported by + * the legacy 'network' service (ifup-eth). + */ + ipv6addr = svGetValueStr(ifcfg, "IPV6ADDR", &ipv6addr_to_free); + ipv6addr_secondaries = + svGetValueStr(ifcfg, "IPV6ADDR_SECONDARIES", &ipv6addr_secondaries_to_free); + + nm_clear_g_free(&value); + value = g_strjoin(ipv6addr && ipv6addr_secondaries ? " " : NULL, + ipv6addr ?: "", + ipv6addr_secondaries ?: "", + NULL); + + list = nm_utils_strsplit_set(value, " "); + for (iter = list, i = 0; iter && *iter; iter++, i++) { + NMIPAddress *addr = NULL; + + if (!parse_full_ip6_address(ifcfg, *iter, i, &addr, error)) + return NULL; + + if (!nm_setting_ip_config_add_address(s_ip6, addr)) + PARSE_WARNING("duplicate IP6 address"); + nm_ip_address_unref(addr); + } + + /* Gateway */ + if (nm_setting_ip_config_get_num_addresses(s_ip6)) { + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IPV6_DEFAULTGW", &value); + if (!v) { + /* If no gateway in the ifcfg, try global /etc/sysconfig/network instead */ + if (network_ifcfg) { + nm_clear_g_free(&value); + v = svGetValueStr(network_ifcfg, "IPV6_DEFAULTGW", &value); + } + } + if (v) { + char *ptr; + if ((ptr = strchr(v, '%')) != NULL) + *ptr = '\0'; /* remove %interface prefix if present */ + if (!nm_utils_ipaddr_is_valid(AF_INET6, v)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IP6 address '%s'", + v); + return NULL; + } + + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, v, NULL); + } + } + + i_val = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64; + if (!svGetValueEnum(ifcfg, + "IPV6_ADDR_GEN_MODE", + nm_setting_ip6_config_addr_gen_mode_get_type(), + &i_val, + &local)) { + PARSE_WARNING("%s", local->message); + g_clear_error(&local); + } + g_object_set(s_ip6, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, i_val, NULL); + + /* IPv6 tokenized interface identifier */ + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IPV6_TOKEN", &value); + if (v) + g_object_set(s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, v, NULL); + + /* DNS servers + * Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting()) + */ + for (i = 1; i <= 10; i++) { + char tag[256]; + + numbered_tag(tag, "DNS", i); + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, tag, &value); + if (!v) { + /* all done */ + break; + } + + if (nm_utils_ipaddr_is_valid(AF_INET6, v)) { + if (!nm_setting_ip_config_add_dns(s_ip6, v)) + PARSE_WARNING("duplicate DNS server %s", tag); + } else if (nm_utils_ipaddr_is_valid(AF_INET, v)) { + /* Ignore IPv4 addresses */ + } else { + PARSE_WARNING("invalid DNS server address %s", v); + return NULL; + } + } + + if (!routes_read) { + /* NOP */ + } else { + gs_free char *route6_path = NULL; + + /* Read static routes from route6- file */ + route6_path = utils_get_route6_path(svFileGetName(ifcfg)); + if (!read_route_file(AF_INET6, route6_path, s_ip6, error)) + return NULL; + } + + /* DNS searches */ + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IPV6_DOMAIN", &value); + if (v) { + gs_free const char **searches = NULL; + + searches = nm_utils_strsplit_set(v, " "); + if (searches) { + for (iter = searches; *iter; iter++) { + if (!nm_setting_ip_config_add_dns_search(s_ip6, *iter)) + PARSE_WARNING("duplicate DNS domain '%s'", *iter); + } + } + } + + /* DNS options */ + nm_clear_g_free(&value); + parse_dns_options(s_ip6, svGetValue(ifcfg, "IPV6_RES_OPTIONS", &value)); + + /* DNS priority */ + priority = svGetValueInt64(ifcfg, "IPV6_DNS_PRIORITY", 10, G_MININT32, G_MAXINT32, 0); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_DNS_PRIORITY, priority, NULL); + + return NM_SETTING(g_steal_pointer(&s_ip6)); } static NMSetting * -make_sriov_setting (shvarFile *ifcfg) +make_sriov_setting(shvarFile *ifcfg) { - gs_unref_hashtable GHashTable *keys = NULL; - gs_unref_ptrarray GPtrArray *vfs = NULL; - int autoprobe_drivers; - NMSettingSriov *s_sriov; - gint64 total_vfs; - - - total_vfs = svGetValueInt64 (ifcfg, "SRIOV_TOTAL_VFS", 10, 0, G_MAXUINT32, -1); - - autoprobe_drivers = svGetValueInt64 (ifcfg, - "SRIOV_AUTOPROBE_DRIVERS", - 10, - NM_TERNARY_DEFAULT, - NM_TERNARY_TRUE, - -2); - - keys = svGetKeys (ifcfg, SV_KEY_TYPE_SRIOV_VF); - if (keys) { - GHashTableIter iter; - const char *key; - - g_hash_table_iter_init (&iter, keys); - while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) { - gs_free_error GError *error = NULL; - gs_free char *value_to_free = NULL; - const char *value; - NMSriovVF *vf; - - nm_assert (g_str_has_prefix (key, "SRIOV_VF")); - - value = svGetValue (ifcfg, key, &value_to_free); - if (!value) - continue; - - key += NM_STRLEN ("SRIOV_VF"); - - vf = _nm_utils_sriov_vf_from_strparts (key, value, TRUE, &error); - if (!vf) { - PARSE_WARNING ("ignoring invalid SR-IOV VF '%s %s': %s", - key, value, error->message); - continue; - } - if (!vfs) - vfs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_sriov_vf_unref); - g_ptr_array_add (vfs, vf); - } - } - - /* Create the setting when at least one key is set */ - if ( total_vfs < 0 - && !vfs - && autoprobe_drivers < NM_TERNARY_DEFAULT) - return NULL; - - s_sriov = (NMSettingSriov *) nm_setting_sriov_new (); - - autoprobe_drivers = NM_MAX (autoprobe_drivers, NM_TERNARY_DEFAULT); - total_vfs = NM_MAX (total_vfs, 0); - - g_object_set (s_sriov, - NM_SETTING_SRIOV_TOTAL_VFS, (guint) total_vfs, - NM_SETTING_SRIOV_VFS, vfs, - NM_SETTING_SRIOV_AUTOPROBE_DRIVERS, autoprobe_drivers, - NULL); - - return (NMSetting *) s_sriov; + gs_unref_hashtable GHashTable *keys = NULL; + gs_unref_ptrarray GPtrArray *vfs = NULL; + int autoprobe_drivers; + NMSettingSriov * s_sriov; + gint64 total_vfs; + + total_vfs = svGetValueInt64(ifcfg, "SRIOV_TOTAL_VFS", 10, 0, G_MAXUINT32, -1); + + autoprobe_drivers = svGetValueInt64(ifcfg, + "SRIOV_AUTOPROBE_DRIVERS", + 10, + NM_TERNARY_DEFAULT, + NM_TERNARY_TRUE, + -2); + + keys = svGetKeys(ifcfg, SV_KEY_TYPE_SRIOV_VF); + if (keys) { + GHashTableIter iter; + const char * key; + + g_hash_table_iter_init(&iter, keys); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, NULL)) { + gs_free_error GError *error = NULL; + gs_free char * value_to_free = NULL; + const char * value; + NMSriovVF * vf; + + nm_assert(g_str_has_prefix(key, "SRIOV_VF")); + + value = svGetValue(ifcfg, key, &value_to_free); + if (!value) + continue; + + key += NM_STRLEN("SRIOV_VF"); + + vf = _nm_utils_sriov_vf_from_strparts(key, value, TRUE, &error); + if (!vf) { + PARSE_WARNING("ignoring invalid SR-IOV VF '%s %s': %s", key, value, error->message); + continue; + } + if (!vfs) + vfs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_sriov_vf_unref); + g_ptr_array_add(vfs, vf); + } + } + + /* Create the setting when at least one key is set */ + if (total_vfs < 0 && !vfs && autoprobe_drivers < NM_TERNARY_DEFAULT) + return NULL; + + s_sriov = (NMSettingSriov *) nm_setting_sriov_new(); + + autoprobe_drivers = NM_MAX(autoprobe_drivers, NM_TERNARY_DEFAULT); + total_vfs = NM_MAX(total_vfs, 0); + + g_object_set(s_sriov, + NM_SETTING_SRIOV_TOTAL_VFS, + (guint) total_vfs, + NM_SETTING_SRIOV_VFS, + vfs, + NM_SETTING_SRIOV_AUTOPROBE_DRIVERS, + autoprobe_drivers, + NULL); + + return (NMSetting *) s_sriov; } static NMSetting * -make_tc_setting (shvarFile *ifcfg) +make_tc_setting(shvarFile *ifcfg) { - NMSettingTCConfig *s_tc = NULL; - char tag[256]; - int i; - - s_tc = (NMSettingTCConfig *) nm_setting_tc_config_new (); - - for (i = 1;; i++) { - NMTCQdisc *qdisc = NULL; - gs_free char *value_to_free = NULL; - const char *value = NULL; - GError *local = NULL; - - value = svGetValueStr (ifcfg, numbered_tag (tag, "QDISC", i), &value_to_free); - if (!value) - break; - - qdisc = nm_utils_tc_qdisc_from_str (value, &local); - if (!qdisc) { - PARSE_WARNING ("ignoring bad tc qdisc: '%s': %s", value, local->message); - continue; - } - - if (!nm_setting_tc_config_add_qdisc (s_tc, qdisc)) - PARSE_WARNING ("duplicate tc qdisc"); - - nm_tc_qdisc_unref (qdisc); - } - - for (i = 1;; i++) { - NMTCTfilter *tfilter = NULL; - gs_free char *value_to_free = NULL; - const char *value = NULL; - gs_free_error GError *local = NULL; - - value = svGetValueStr (ifcfg, numbered_tag (tag, "FILTER", i), &value_to_free); - if (!value) - break; - - tfilter = nm_utils_tc_tfilter_from_str (value, &local); - if (!tfilter) { - PARSE_WARNING ("ignoring bad tc filter: '%s': %s", value, local->message); - continue; - } - - if (!nm_setting_tc_config_add_tfilter (s_tc, tfilter)) - PARSE_WARNING ("duplicate tc filter"); - - nm_tc_tfilter_unref (tfilter); - } - - if ( nm_setting_tc_config_get_num_qdiscs (s_tc) > 0 - || nm_setting_tc_config_get_num_tfilters (s_tc) > 0) - return NM_SETTING (s_tc); - - g_object_unref (s_tc); - return NULL; + NMSettingTCConfig *s_tc = NULL; + char tag[256]; + int i; + + s_tc = (NMSettingTCConfig *) nm_setting_tc_config_new(); + + for (i = 1;; i++) { + NMTCQdisc * qdisc = NULL; + gs_free char *value_to_free = NULL; + const char * value = NULL; + GError * local = NULL; + + value = svGetValueStr(ifcfg, numbered_tag(tag, "QDISC", i), &value_to_free); + if (!value) + break; + + qdisc = nm_utils_tc_qdisc_from_str(value, &local); + if (!qdisc) { + PARSE_WARNING("ignoring bad tc qdisc: '%s': %s", value, local->message); + continue; + } + + if (!nm_setting_tc_config_add_qdisc(s_tc, qdisc)) + PARSE_WARNING("duplicate tc qdisc"); + + nm_tc_qdisc_unref(qdisc); + } + + for (i = 1;; i++) { + NMTCTfilter * tfilter = NULL; + gs_free char *value_to_free = NULL; + const char * value = NULL; + gs_free_error GError *local = NULL; + + value = svGetValueStr(ifcfg, numbered_tag(tag, "FILTER", i), &value_to_free); + if (!value) + break; + + tfilter = nm_utils_tc_tfilter_from_str(value, &local); + if (!tfilter) { + PARSE_WARNING("ignoring bad tc filter: '%s': %s", value, local->message); + continue; + } + + if (!nm_setting_tc_config_add_tfilter(s_tc, tfilter)) + PARSE_WARNING("duplicate tc filter"); + + nm_tc_tfilter_unref(tfilter); + } + + if (nm_setting_tc_config_get_num_qdiscs(s_tc) > 0 + || nm_setting_tc_config_get_num_tfilters(s_tc) > 0) + return NM_SETTING(s_tc); + + g_object_unref(s_tc); + return NULL; } typedef struct { - const char *enable_key; - const char *advertise_key; - const char *willing_key; - const char *flags_prop; + const char *enable_key; + const char *advertise_key; + const char *willing_key; + const char *flags_prop; } DcbFlagsProperty; enum { - DCB_APP_FCOE_FLAGS = 0, - DCB_APP_ISCSI_FLAGS = 1, - DCB_APP_FIP_FLAGS = 2, - DCB_PFC_FLAGS = 3, - DCB_PG_FLAGS = 4, + DCB_APP_FCOE_FLAGS = 0, + DCB_APP_ISCSI_FLAGS = 1, + DCB_APP_FIP_FLAGS = 2, + DCB_PFC_FLAGS = 3, + DCB_PG_FLAGS = 4, }; static DcbFlagsProperty dcb_flags_props[] = { - { KEY_DCB_APP_FCOE_ENABLE, KEY_DCB_APP_FCOE_ADVERTISE, KEY_DCB_APP_FCOE_WILLING, NM_SETTING_DCB_APP_FCOE_FLAGS }, - { KEY_DCB_APP_ISCSI_ENABLE, KEY_DCB_APP_ISCSI_ADVERTISE, KEY_DCB_APP_ISCSI_WILLING, NM_SETTING_DCB_APP_ISCSI_FLAGS }, - { KEY_DCB_APP_FIP_ENABLE, KEY_DCB_APP_FIP_ADVERTISE, KEY_DCB_APP_FIP_WILLING, NM_SETTING_DCB_APP_FIP_FLAGS }, - { KEY_DCB_PFC_ENABLE, KEY_DCB_PFC_ADVERTISE, KEY_DCB_PFC_WILLING, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS }, - { KEY_DCB_PG_ENABLE, KEY_DCB_PG_ADVERTISE, KEY_DCB_PG_WILLING, NM_SETTING_DCB_PRIORITY_GROUP_FLAGS }, - { NULL }, + {KEY_DCB_APP_FCOE_ENABLE, + KEY_DCB_APP_FCOE_ADVERTISE, + KEY_DCB_APP_FCOE_WILLING, + NM_SETTING_DCB_APP_FCOE_FLAGS}, + {KEY_DCB_APP_ISCSI_ENABLE, + KEY_DCB_APP_ISCSI_ADVERTISE, + KEY_DCB_APP_ISCSI_WILLING, + NM_SETTING_DCB_APP_ISCSI_FLAGS}, + {KEY_DCB_APP_FIP_ENABLE, + KEY_DCB_APP_FIP_ADVERTISE, + KEY_DCB_APP_FIP_WILLING, + NM_SETTING_DCB_APP_FIP_FLAGS}, + {KEY_DCB_PFC_ENABLE, + KEY_DCB_PFC_ADVERTISE, + KEY_DCB_PFC_WILLING, + NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS}, + {KEY_DCB_PG_ENABLE, + KEY_DCB_PG_ADVERTISE, + KEY_DCB_PG_WILLING, + NM_SETTING_DCB_PRIORITY_GROUP_FLAGS}, + {NULL}, }; static NMSettingDcbFlags -read_dcb_flags (shvarFile *ifcfg, DcbFlagsProperty *property) +read_dcb_flags(shvarFile *ifcfg, DcbFlagsProperty *property) { - NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE; + NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE; - if (svGetValueBoolean (ifcfg, property->enable_key, FALSE)) - flags |= NM_SETTING_DCB_FLAG_ENABLE; - if (svGetValueBoolean (ifcfg, property->advertise_key, FALSE)) - flags |= NM_SETTING_DCB_FLAG_ADVERTISE; - if (svGetValueBoolean (ifcfg, property->willing_key, FALSE)) - flags |= NM_SETTING_DCB_FLAG_WILLING; + if (svGetValueBoolean(ifcfg, property->enable_key, FALSE)) + flags |= NM_SETTING_DCB_FLAG_ENABLE; + if (svGetValueBoolean(ifcfg, property->advertise_key, FALSE)) + flags |= NM_SETTING_DCB_FLAG_ADVERTISE; + if (svGetValueBoolean(ifcfg, property->willing_key, FALSE)) + flags |= NM_SETTING_DCB_FLAG_WILLING; - return flags; + return flags; } static gboolean -read_dcb_app (shvarFile *ifcfg, - NMSettingDcb *s_dcb, - const char *app, - DcbFlagsProperty *flags_prop, - const char *priority_prop, - GError **error) +read_dcb_app(shvarFile * ifcfg, + NMSettingDcb * s_dcb, + const char * app, + DcbFlagsProperty *flags_prop, + const char * priority_prop, + GError ** error) { - NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE; - gs_free char *value = NULL; - const char *v; - gboolean success = TRUE; - int priority = -1; - char key[255]; - - flags = read_dcb_flags (ifcfg, flags_prop); - - /* Priority */ - nm_sprintf_buf (key, "DCB_APP_%s_PRIORITY", app); - v = svGetValueStr (ifcfg, key, &value); - if (v) { - priority = _nm_utils_ascii_str_to_int64 (v, 0, 0, 7, -1); - if (priority < 0) { - success = FALSE; - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid %s value '%s' (expected 0 - 7)", - key, v); - } - - if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) - PARSE_WARNING ("ignoring DCB %s priority; app not enabled", app); - } - - if (success) { - g_object_set (G_OBJECT (s_dcb), - flags_prop->flags_prop, flags, - priority_prop, (guint) priority, - NULL); - } - - return success; + NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE; + gs_free char * value = NULL; + const char * v; + gboolean success = TRUE; + int priority = -1; + char key[255]; + + flags = read_dcb_flags(ifcfg, flags_prop); + + /* Priority */ + nm_sprintf_buf(key, "DCB_APP_%s_PRIORITY", app); + v = svGetValueStr(ifcfg, key, &value); + if (v) { + priority = _nm_utils_ascii_str_to_int64(v, 0, 0, 7, -1); + if (priority < 0) { + success = FALSE; + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid %s value '%s' (expected 0 - 7)", + key, + v); + } + + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) + PARSE_WARNING("ignoring DCB %s priority; app not enabled", app); + } + + if (success) { + g_object_set(G_OBJECT(s_dcb), + flags_prop->flags_prop, + flags, + priority_prop, + (guint) priority, + NULL); + } + + return success; } -typedef void (*DcbSetBoolFunc) (NMSettingDcb *, guint, gboolean); +typedef void (*DcbSetBoolFunc)(NMSettingDcb *, guint, gboolean); static gboolean -read_dcb_bool_array (shvarFile *ifcfg, - NMSettingDcb *s_dcb, - NMSettingDcbFlags flags, - const char *prop, - const char *desc, - DcbSetBoolFunc set_func, - GError **error) +read_dcb_bool_array(shvarFile * ifcfg, + NMSettingDcb * s_dcb, + NMSettingDcbFlags flags, + const char * prop, + const char * desc, + DcbSetBoolFunc set_func, + GError ** error) { - gs_free char *value = NULL; - const char *v; - guint i; - - v = svGetValueStr (ifcfg, prop, &value); - if (!v) - return TRUE; - - if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) { - PARSE_WARNING ("ignoring %s; %s is not enabled", prop, desc); - return TRUE; - } - - if (strlen (v) != 8) { - PARSE_WARNING ("%s value '%s' must be 8 characters long", prop, v); - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "boolean array must be 8 characters"); - return FALSE; - } - - /* All characters must be either 0 or 1 */ - for (i = 0; i < 8; i++) { - if (v[i] != '0' && v[i] != '1') { - PARSE_WARNING ("invalid %s value '%s': not all 0s and 1s", prop, v); - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "invalid boolean digit"); - return FALSE; - } - set_func (s_dcb, i, (v[i] == '1')); - } - return TRUE; + gs_free char *value = NULL; + const char * v; + guint i; + + v = svGetValueStr(ifcfg, prop, &value); + if (!v) + return TRUE; + + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) { + PARSE_WARNING("ignoring %s; %s is not enabled", prop, desc); + return TRUE; + } + + if (strlen(v) != 8) { + PARSE_WARNING("%s value '%s' must be 8 characters long", prop, v); + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "boolean array must be 8 characters"); + return FALSE; + } + + /* All characters must be either 0 or 1 */ + for (i = 0; i < 8; i++) { + if (v[i] != '0' && v[i] != '1') { + PARSE_WARNING("invalid %s value '%s': not all 0s and 1s", prop, v); + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid boolean digit"); + return FALSE; + } + set_func(s_dcb, i, (v[i] == '1')); + } + return TRUE; } -typedef void (*DcbSetUintFunc) (NMSettingDcb *, guint, guint); +typedef void (*DcbSetUintFunc)(NMSettingDcb *, guint, guint); static gboolean -read_dcb_uint_array (shvarFile *ifcfg, - NMSettingDcb *s_dcb, - NMSettingDcbFlags flags, - const char *prop, - const char *desc, - gboolean f_allowed, - DcbSetUintFunc set_func, - GError **error) +read_dcb_uint_array(shvarFile * ifcfg, + NMSettingDcb * s_dcb, + NMSettingDcbFlags flags, + const char * prop, + const char * desc, + gboolean f_allowed, + DcbSetUintFunc set_func, + GError ** error) { - gs_free char *val = NULL; - guint i; - - val = svGetValueStr_cp (ifcfg, prop); - if (!val) - return TRUE; - - if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) { - PARSE_WARNING ("ignoring %s; %s is not enabled", prop, desc); - return TRUE; - } - - if (strlen (val) != 8) { - PARSE_WARNING ("%s value '%s' must be 8 characters long", prop, val); - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "uint array must be 8 characters"); - return FALSE; - } - - /* All characters must be either 0 - 7 or (optionally) f */ - for (i = 0; i < 8; i++) { - if (val[i] >= '0' && val[i] <= '7') - set_func (s_dcb, i, val[i] - '0'); - else if (f_allowed && (val[i] == 'f' || val[i] == 'F')) - set_func (s_dcb, i, 15); - else { - PARSE_WARNING ("invalid %s value '%s': not 0 - 7%s", - prop, val, f_allowed ? " or 'f'" : ""); - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "invalid uint digit"); - return FALSE; - } - } - - return TRUE; + gs_free char *val = NULL; + guint i; + + val = svGetValueStr_cp(ifcfg, prop); + if (!val) + return TRUE; + + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) { + PARSE_WARNING("ignoring %s; %s is not enabled", prop, desc); + return TRUE; + } + + if (strlen(val) != 8) { + PARSE_WARNING("%s value '%s' must be 8 characters long", prop, val); + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "uint array must be 8 characters"); + return FALSE; + } + + /* All characters must be either 0 - 7 or (optionally) f */ + for (i = 0; i < 8; i++) { + if (val[i] >= '0' && val[i] <= '7') + set_func(s_dcb, i, val[i] - '0'); + else if (f_allowed && (val[i] == 'f' || val[i] == 'F')) + set_func(s_dcb, i, 15); + else { + PARSE_WARNING("invalid %s value '%s': not 0 - 7%s", + prop, + val, + f_allowed ? " or 'f'" : ""); + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid uint digit"); + return FALSE; + } + } + + return TRUE; } static gboolean -read_dcb_percent_array (shvarFile *ifcfg, - NMSettingDcb *s_dcb, - NMSettingDcbFlags flags, - const char *prop, - const char *desc, - gboolean sum_pct, - DcbSetUintFunc set_func, - GError **error) +read_dcb_percent_array(shvarFile * ifcfg, + NMSettingDcb * s_dcb, + NMSettingDcbFlags flags, + const char * prop, + const char * desc, + gboolean sum_pct, + DcbSetUintFunc set_func, + GError ** error) { - gs_free char *val = NULL; - gs_free const char **split = NULL; - const char *const *iter; - guint i, sum = 0; - - val = svGetValueStr_cp (ifcfg, prop); - if (!val) - return TRUE; - - if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) { - PARSE_WARNING ("ignoring %s; %s is not enabled", prop, desc); - return TRUE; - } - - split = nm_utils_strsplit_set (val, ","); - if (NM_PTRARRAY_LEN (split) != 8) { - PARSE_WARNING ("invalid %s percentage list value '%s'", prop, val); - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "percent array must be 8 elements"); - return FALSE; - } - - for (iter = split, i = 0; iter && *iter; iter++, i++) { - int tmp; - - tmp = _nm_utils_ascii_str_to_int64 (*iter, 0, 0, 100, -1); - if (tmp < 0) { - PARSE_WARNING ("invalid %s percentage value '%s'", prop, *iter); - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "invalid percent element"); - return FALSE; - } - set_func (s_dcb, i, (guint) tmp); - sum += (guint) tmp; - } - - if (sum_pct && (sum != 100)) { - PARSE_WARNING ("%s percentages do not equal 100%%", prop); - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "invalid percentage sum"); - return FALSE; - } - - return TRUE; + gs_free char * val = NULL; + gs_free const char **split = NULL; + const char *const * iter; + guint i, sum = 0; + + val = svGetValueStr_cp(ifcfg, prop); + if (!val) + return TRUE; + + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) { + PARSE_WARNING("ignoring %s; %s is not enabled", prop, desc); + return TRUE; + } + + split = nm_utils_strsplit_set(val, ","); + if (NM_PTRARRAY_LEN(split) != 8) { + PARSE_WARNING("invalid %s percentage list value '%s'", prop, val); + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "percent array must be 8 elements"); + return FALSE; + } + + for (iter = split, i = 0; iter && *iter; iter++, i++) { + int tmp; + + tmp = _nm_utils_ascii_str_to_int64(*iter, 0, 0, 100, -1); + if (tmp < 0) { + PARSE_WARNING("invalid %s percentage value '%s'", prop, *iter); + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid percent element"); + return FALSE; + } + set_func(s_dcb, i, (guint) tmp); + sum += (guint) tmp; + } + + if (sum_pct && (sum != 100)) { + PARSE_WARNING("%s percentages do not equal 100%%", prop); + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid percentage sum"); + return FALSE; + } + + return TRUE; } static gboolean -make_dcb_setting (shvarFile *ifcfg, - NMSetting **out_setting, - GError **error) +make_dcb_setting(shvarFile *ifcfg, NMSetting **out_setting, GError **error) { - gs_unref_object NMSettingDcb *s_dcb = NULL; - gboolean dcb_on; - NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE; - - g_return_val_if_fail (out_setting != NULL, FALSE); - - dcb_on = !!svGetValueBoolean (ifcfg, "DCB", FALSE); - if (!dcb_on) - return TRUE; - - s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); - - /* FCOE */ - if (!read_dcb_app (ifcfg, s_dcb, "FCOE", - &dcb_flags_props[DCB_APP_FCOE_FLAGS], - NM_SETTING_DCB_APP_FCOE_PRIORITY, - error)) { - return FALSE; - } - if (nm_setting_dcb_get_app_fcoe_flags (s_dcb) & NM_SETTING_DCB_FLAG_ENABLE) { - gs_free char *val = NULL; - - val = svGetValueStr_cp (ifcfg, KEY_DCB_APP_FCOE_MODE); - if (val) { - if (NM_IN_STRSET (val, NM_SETTING_DCB_FCOE_MODE_FABRIC, - NM_SETTING_DCB_FCOE_MODE_VN2VN)) - g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_FCOE_MODE, val, NULL); - else { - PARSE_WARNING ("invalid FCoE mode '%s'", val); - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "invalid FCoE mode"); - return FALSE; - } - } - } - - /* iSCSI */ - if (!read_dcb_app (ifcfg, s_dcb, "ISCSI", - &dcb_flags_props[DCB_APP_ISCSI_FLAGS], - NM_SETTING_DCB_APP_ISCSI_PRIORITY, - error)) { - return FALSE; - } - - /* FIP */ - if (!read_dcb_app (ifcfg, s_dcb, "FIP", - &dcb_flags_props[DCB_APP_FIP_FLAGS], - NM_SETTING_DCB_APP_FIP_PRIORITY, - error)) { - return FALSE; - } - - /* Priority Flow Control */ - flags = read_dcb_flags (ifcfg, &dcb_flags_props[DCB_PFC_FLAGS]); - g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, flags, NULL); - - if (!read_dcb_bool_array (ifcfg, - s_dcb, - flags, - KEY_DCB_PFC_UP, - "PFC", - nm_setting_dcb_set_priority_flow_control, - error)) { - return FALSE; - } - - /* Priority Groups */ - flags = read_dcb_flags (ifcfg, &dcb_flags_props[DCB_PG_FLAGS]); - g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, flags, NULL); - - if (!read_dcb_uint_array (ifcfg, - s_dcb, - flags, - KEY_DCB_PG_ID, - "PGID", - TRUE, - nm_setting_dcb_set_priority_group_id, - error)) { - return FALSE; - } - - /* Group bandwidth */ - if (!read_dcb_percent_array (ifcfg, - s_dcb, - flags, - KEY_DCB_PG_PCT, - "PGPCT", - TRUE, - nm_setting_dcb_set_priority_group_bandwidth, - error)) { - return FALSE; - } - - /* Priority bandwidth */ - if (!read_dcb_percent_array (ifcfg, - s_dcb, - flags, - KEY_DCB_PG_UPPCT, - "UPPCT", - FALSE, - nm_setting_dcb_set_priority_bandwidth, - error)) { - return FALSE; - } - - /* Strict Bandwidth */ - if (!read_dcb_bool_array (ifcfg, - s_dcb, - flags, - KEY_DCB_PG_STRICT, - "STRICT", - nm_setting_dcb_set_priority_strict_bandwidth, - error)) { - return FALSE; - } - - if (!read_dcb_uint_array (ifcfg, - s_dcb, - flags, - KEY_DCB_PG_UP2TC, - "UP2TC", - FALSE, - nm_setting_dcb_set_priority_traffic_class, - error)) { - return FALSE; - } - - *out_setting = NM_SETTING (g_steal_pointer (&s_dcb)); - return TRUE; + gs_unref_object NMSettingDcb *s_dcb = NULL; + gboolean dcb_on; + NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE; + + g_return_val_if_fail(out_setting != NULL, FALSE); + + dcb_on = !!svGetValueBoolean(ifcfg, "DCB", FALSE); + if (!dcb_on) + return TRUE; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new(); + + /* FCOE */ + if (!read_dcb_app(ifcfg, + s_dcb, + "FCOE", + &dcb_flags_props[DCB_APP_FCOE_FLAGS], + NM_SETTING_DCB_APP_FCOE_PRIORITY, + error)) { + return FALSE; + } + if (nm_setting_dcb_get_app_fcoe_flags(s_dcb) & NM_SETTING_DCB_FLAG_ENABLE) { + gs_free char *val = NULL; + + val = svGetValueStr_cp(ifcfg, KEY_DCB_APP_FCOE_MODE); + if (val) { + if (NM_IN_STRSET(val, NM_SETTING_DCB_FCOE_MODE_FABRIC, NM_SETTING_DCB_FCOE_MODE_VN2VN)) + g_object_set(G_OBJECT(s_dcb), NM_SETTING_DCB_APP_FCOE_MODE, val, NULL); + else { + PARSE_WARNING("invalid FCoE mode '%s'", val); + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid FCoE mode"); + return FALSE; + } + } + } + + /* iSCSI */ + if (!read_dcb_app(ifcfg, + s_dcb, + "ISCSI", + &dcb_flags_props[DCB_APP_ISCSI_FLAGS], + NM_SETTING_DCB_APP_ISCSI_PRIORITY, + error)) { + return FALSE; + } + + /* FIP */ + if (!read_dcb_app(ifcfg, + s_dcb, + "FIP", + &dcb_flags_props[DCB_APP_FIP_FLAGS], + NM_SETTING_DCB_APP_FIP_PRIORITY, + error)) { + return FALSE; + } + + /* Priority Flow Control */ + flags = read_dcb_flags(ifcfg, &dcb_flags_props[DCB_PFC_FLAGS]); + g_object_set(G_OBJECT(s_dcb), NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, flags, NULL); + + if (!read_dcb_bool_array(ifcfg, + s_dcb, + flags, + KEY_DCB_PFC_UP, + "PFC", + nm_setting_dcb_set_priority_flow_control, + error)) { + return FALSE; + } + + /* Priority Groups */ + flags = read_dcb_flags(ifcfg, &dcb_flags_props[DCB_PG_FLAGS]); + g_object_set(G_OBJECT(s_dcb), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, flags, NULL); + + if (!read_dcb_uint_array(ifcfg, + s_dcb, + flags, + KEY_DCB_PG_ID, + "PGID", + TRUE, + nm_setting_dcb_set_priority_group_id, + error)) { + return FALSE; + } + + /* Group bandwidth */ + if (!read_dcb_percent_array(ifcfg, + s_dcb, + flags, + KEY_DCB_PG_PCT, + "PGPCT", + TRUE, + nm_setting_dcb_set_priority_group_bandwidth, + error)) { + return FALSE; + } + + /* Priority bandwidth */ + if (!read_dcb_percent_array(ifcfg, + s_dcb, + flags, + KEY_DCB_PG_UPPCT, + "UPPCT", + FALSE, + nm_setting_dcb_set_priority_bandwidth, + error)) { + return FALSE; + } + + /* Strict Bandwidth */ + if (!read_dcb_bool_array(ifcfg, + s_dcb, + flags, + KEY_DCB_PG_STRICT, + "STRICT", + nm_setting_dcb_set_priority_strict_bandwidth, + error)) { + return FALSE; + } + + if (!read_dcb_uint_array(ifcfg, + s_dcb, + flags, + KEY_DCB_PG_UP2TC, + "UP2TC", + FALSE, + nm_setting_dcb_set_priority_traffic_class, + error)) { + return FALSE; + } + + *out_setting = NM_SETTING(g_steal_pointer(&s_dcb)); + return TRUE; } static gboolean -add_one_wep_key (shvarFile *ifcfg, - const char *shvar_key, - guint8 key_idx, - gboolean passphrase, - NMSettingWirelessSecurity *s_wsec, - GError **error) +add_one_wep_key(shvarFile * ifcfg, + const char * shvar_key, + guint8 key_idx, + gboolean passphrase, + NMSettingWirelessSecurity *s_wsec, + GError ** error) { - gs_free char *value_free = NULL; - const char *value; - const char *key = NULL; - - g_return_val_if_fail (ifcfg != NULL, FALSE); - g_return_val_if_fail (shvar_key != NULL, FALSE); - g_return_val_if_fail (key_idx <= 3, FALSE); - g_return_val_if_fail (s_wsec != NULL, FALSE); - - value = svGetValueStr (ifcfg, shvar_key, &value_free); - if (!value) - return TRUE; - - /* Validate keys */ - if (passphrase) { - if (value[0] && strlen (value) < 64) - key = value; - } else { - if (NM_IN_SET (strlen (value), 10, 26)) { - /* Hexadecimal WEP key */ - if (NM_STRCHAR_ANY (value, ch, !g_ascii_isxdigit (ch))) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid hexadecimal WEP key"); - return FALSE; - } - key = value; - } else if ( !strncmp (value, "s:", 2) - && NM_IN_SET (strlen (value), 7, 15)) { - /* ASCII key */ - if (NM_STRCHAR_ANY (value + 2, ch, !g_ascii_isprint (ch))) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid ASCII WEP key"); - return FALSE; - } - - /* Remove 's:' prefix. - * Don't convert to hex string. wpa_supplicant takes 'wep_key0' option over D-Bus as byte array - * and converts it to hex string itself. Even though we convert hex string keys into a bin string - * before passing to wpa_supplicant, this prevents two unnecessary conversions. And mainly, - * ASCII WEP key doesn't change to HEX WEP key in UI, which could confuse users. - */ - key = value + 2; - } - } - - if (!key) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid WEP key length"); - return FALSE; - } - - nm_setting_wireless_security_set_wep_key (s_wsec, key_idx, key); - return TRUE; + gs_free char *value_free = NULL; + const char * value; + const char * key = NULL; + + g_return_val_if_fail(ifcfg != NULL, FALSE); + g_return_val_if_fail(shvar_key != NULL, FALSE); + g_return_val_if_fail(key_idx <= 3, FALSE); + g_return_val_if_fail(s_wsec != NULL, FALSE); + + value = svGetValueStr(ifcfg, shvar_key, &value_free); + if (!value) + return TRUE; + + /* Validate keys */ + if (passphrase) { + if (value[0] && strlen(value) < 64) + key = value; + } else { + if (NM_IN_SET(strlen(value), 10, 26)) { + /* Hexadecimal WEP key */ + if (NM_STRCHAR_ANY(value, ch, !g_ascii_isxdigit(ch))) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid hexadecimal WEP key"); + return FALSE; + } + key = value; + } else if (!strncmp(value, "s:", 2) && NM_IN_SET(strlen(value), 7, 15)) { + /* ASCII key */ + if (NM_STRCHAR_ANY(value + 2, ch, !g_ascii_isprint(ch))) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid ASCII WEP key"); + return FALSE; + } + + /* Remove 's:' prefix. + * Don't convert to hex string. wpa_supplicant takes 'wep_key0' option over D-Bus as byte array + * and converts it to hex string itself. Even though we convert hex string keys into a bin string + * before passing to wpa_supplicant, this prevents two unnecessary conversions. And mainly, + * ASCII WEP key doesn't change to HEX WEP key in UI, which could confuse users. + */ + key = value + 2; + } + } + + if (!key) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid WEP key length"); + return FALSE; + } + + nm_setting_wireless_security_set_wep_key(s_wsec, key_idx, key); + return TRUE; } static gboolean -read_wep_keys (shvarFile *ifcfg, - NMWepKeyType key_type, - guint8 def_idx, - NMSettingWirelessSecurity *s_wsec, - GError **error) +read_wep_keys(shvarFile * ifcfg, + NMWepKeyType key_type, + guint8 def_idx, + NMSettingWirelessSecurity *s_wsec, + GError ** error) { - if (key_type != NM_WEP_KEY_TYPE_PASSPHRASE) { - if (!add_one_wep_key (ifcfg, "KEY1", 0, FALSE, s_wsec, error)) - return FALSE; - if (!add_one_wep_key (ifcfg, "KEY2", 1, FALSE, s_wsec, error)) - return FALSE; - if (!add_one_wep_key (ifcfg, "KEY3", 2, FALSE, s_wsec, error)) - return FALSE; - if (!add_one_wep_key (ifcfg, "KEY4", 3, FALSE, s_wsec, error)) - return FALSE; - if (!add_one_wep_key (ifcfg, "KEY", def_idx, FALSE, s_wsec, error)) - return FALSE; - } - - if (key_type != NM_WEP_KEY_TYPE_KEY) { - if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE1", 0, TRUE, s_wsec, error)) - return FALSE; - if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE2", 1, TRUE, s_wsec, error)) - return FALSE; - if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE3", 2, TRUE, s_wsec, error)) - return FALSE; - if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE4", 3, TRUE, s_wsec, error)) - return FALSE; - } - - return TRUE; + if (key_type != NM_WEP_KEY_TYPE_PASSPHRASE) { + if (!add_one_wep_key(ifcfg, "KEY1", 0, FALSE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key(ifcfg, "KEY2", 1, FALSE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key(ifcfg, "KEY3", 2, FALSE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key(ifcfg, "KEY4", 3, FALSE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key(ifcfg, "KEY", def_idx, FALSE, s_wsec, error)) + return FALSE; + } + + if (key_type != NM_WEP_KEY_TYPE_KEY) { + if (!add_one_wep_key(ifcfg, "KEY_PASSPHRASE1", 0, TRUE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key(ifcfg, "KEY_PASSPHRASE2", 1, TRUE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key(ifcfg, "KEY_PASSPHRASE3", 2, TRUE, s_wsec, error)) + return FALSE; + if (!add_one_wep_key(ifcfg, "KEY_PASSPHRASE4", 3, TRUE, s_wsec, error)) + return FALSE; + } + + return TRUE; } static NMSetting * -make_wep_setting (shvarFile *ifcfg, - const char *file, - GError **error) +make_wep_setting(shvarFile *ifcfg, const char *file, GError **error) { - gs_unref_object NMSettingWirelessSecurity *s_wsec = NULL; - gs_free char *value = NULL; - shvarFile *keys_ifcfg = NULL; - int default_key_idx = 0; - gboolean has_default_key = FALSE; - NMSettingSecretFlags key_flags; - - s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); - g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL); - - value = svGetValueStr_cp (ifcfg, "DEFAULTKEY"); - if (value) { - default_key_idx = _nm_utils_ascii_str_to_int64 (value, 0, 1, 4, 0); - if (default_key_idx == 0) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid default WEP key '%s'", value); - return NULL; - } - has_default_key = TRUE; - default_key_idx--; /* convert to [0...3] */ - g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, (guint) default_key_idx, NULL); - nm_clear_g_free (&value); - } - - /* Read WEP key flags */ - key_flags = _secret_read_ifcfg_flags (ifcfg, "WEP_KEY_FLAGS"); - g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, key_flags, NULL); - - /* Read keys in the ifcfg file if they are system-owned */ - if (key_flags == NM_SETTING_SECRET_FLAG_NONE) { - NMWepKeyType key_type; - const char *v; - gs_free char *to_free = NULL; - - v = svGetValueStr (ifcfg, "KEY_TYPE", &to_free); - if (!v) - key_type = NM_WEP_KEY_TYPE_UNKNOWN; - else if (nm_streq (v, "key")) - key_type = NM_WEP_KEY_TYPE_KEY; - else if (nm_streq (v, "passphrase")) - key_type = NM_WEP_KEY_TYPE_PASSPHRASE; - else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid KEY_TYPE value '%s'", v); - return FALSE; - } - - if (!read_wep_keys (ifcfg, key_type, default_key_idx, s_wsec, error)) - return NULL; - - /* Try to get keys from the "shadow" key file */ - keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); - if (keys_ifcfg) { - if (!read_wep_keys (keys_ifcfg, key_type, default_key_idx, s_wsec, error)) { - svCloseFile (keys_ifcfg); - return NULL; - } - svCloseFile (keys_ifcfg); - g_assert (error == NULL || *error == NULL); - } - - g_object_set (G_OBJECT (s_wsec), - NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, key_type, - NULL); - } - - value = svGetValueStr_cp (ifcfg, "SECURITYMODE"); - if (value) { - gs_free char *lcase = NULL; - - lcase = g_ascii_strdown (value, -1); - nm_clear_g_free (&value); - - if (nm_streq (lcase, "open")) { - g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL); - } else if (nm_streq (lcase, "restricted")) { - g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", NULL); - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid WEP authentication algorithm '%s'", - lcase); - return NULL; - } - } - - /* If no WEP keys were given, and the keys are not agent-owned, and no - * default WEP key index was given, then the connection is unencrypted. - */ - if ( !nm_setting_wireless_security_get_wep_key (s_wsec, 0) - && !nm_setting_wireless_security_get_wep_key (s_wsec, 1) - && !nm_setting_wireless_security_get_wep_key (s_wsec, 2) - && !nm_setting_wireless_security_get_wep_key (s_wsec, 3) - && (has_default_key == FALSE) - && (key_flags == NM_SETTING_SECRET_FLAG_NONE)) { - const char *auth_alg; - - auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); - if (auth_alg && !strcmp (auth_alg, "shared")) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "WEP Shared Key authentication is invalid for " - "unencrypted connections"); - return NULL; - } - - /* Unencrypted */ - return NULL; - } - - return NM_SETTING (g_steal_pointer (&s_wsec)); + gs_unref_object NMSettingWirelessSecurity *s_wsec = NULL; + gs_free char * value = NULL; + shvarFile * keys_ifcfg = NULL; + int default_key_idx = 0; + gboolean has_default_key = FALSE; + NMSettingSecretFlags key_flags; + + s_wsec = NM_SETTING_WIRELESS_SECURITY(nm_setting_wireless_security_new()); + g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL); + + value = svGetValueStr_cp(ifcfg, "DEFAULTKEY"); + if (value) { + default_key_idx = _nm_utils_ascii_str_to_int64(value, 0, 1, 4, 0); + if (default_key_idx == 0) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid default WEP key '%s'", + value); + return NULL; + } + has_default_key = TRUE; + default_key_idx--; /* convert to [0...3] */ + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, + (guint) default_key_idx, + NULL); + nm_clear_g_free(&value); + } + + /* Read WEP key flags */ + key_flags = _secret_read_ifcfg_flags(ifcfg, "WEP_KEY_FLAGS"); + g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, key_flags, NULL); + + /* Read keys in the ifcfg file if they are system-owned */ + if (key_flags == NM_SETTING_SECRET_FLAG_NONE) { + NMWepKeyType key_type; + const char * v; + gs_free char *to_free = NULL; + + v = svGetValueStr(ifcfg, "KEY_TYPE", &to_free); + if (!v) + key_type = NM_WEP_KEY_TYPE_UNKNOWN; + else if (nm_streq(v, "key")) + key_type = NM_WEP_KEY_TYPE_KEY; + else if (nm_streq(v, "passphrase")) + key_type = NM_WEP_KEY_TYPE_PASSPHRASE; + else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid KEY_TYPE value '%s'", + v); + return FALSE; + } + + if (!read_wep_keys(ifcfg, key_type, default_key_idx, s_wsec, error)) + return NULL; + + /* Try to get keys from the "shadow" key file */ + keys_ifcfg = utils_get_keys_ifcfg(file, FALSE); + if (keys_ifcfg) { + if (!read_wep_keys(keys_ifcfg, key_type, default_key_idx, s_wsec, error)) { + svCloseFile(keys_ifcfg); + return NULL; + } + svCloseFile(keys_ifcfg); + g_assert(error == NULL || *error == NULL); + } + + g_object_set(G_OBJECT(s_wsec), NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, key_type, NULL); + } + + value = svGetValueStr_cp(ifcfg, "SECURITYMODE"); + if (value) { + gs_free char *lcase = NULL; + + lcase = g_ascii_strdown(value, -1); + nm_clear_g_free(&value); + + if (nm_streq(lcase, "open")) { + g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL); + } else if (nm_streq(lcase, "restricted")) { + g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", NULL); + } else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid WEP authentication algorithm '%s'", + lcase); + return NULL; + } + } + + /* If no WEP keys were given, and the keys are not agent-owned, and no + * default WEP key index was given, then the connection is unencrypted. + */ + if (!nm_setting_wireless_security_get_wep_key(s_wsec, 0) + && !nm_setting_wireless_security_get_wep_key(s_wsec, 1) + && !nm_setting_wireless_security_get_wep_key(s_wsec, 2) + && !nm_setting_wireless_security_get_wep_key(s_wsec, 3) && (has_default_key == FALSE) + && (key_flags == NM_SETTING_SECRET_FLAG_NONE)) { + const char *auth_alg; + + auth_alg = nm_setting_wireless_security_get_auth_alg(s_wsec); + if (auth_alg && !strcmp(auth_alg, "shared")) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "WEP Shared Key authentication is invalid for " + "unencrypted connections"); + return NULL; + } + + /* Unencrypted */ + return NULL; + } + + return NM_SETTING(g_steal_pointer(&s_wsec)); } static gboolean -fill_wpa_ciphers (shvarFile *ifcfg, - NMSettingWirelessSecurity *wsec, - gboolean group, - gboolean adhoc) +fill_wpa_ciphers(shvarFile *ifcfg, NMSettingWirelessSecurity *wsec, gboolean group, gboolean adhoc) { - gs_free char *value = NULL; - const char *p; - gs_free const char **list = NULL; - const char *const *iter; - int i = 0; - - p = svGetValueStr (ifcfg, group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE", &value); - if (!p) - return TRUE; - - list = nm_utils_strsplit_set (p, " "); - for (iter = list; iter && *iter; iter++, i++) { - if (!strcmp (*iter, "CCMP")) { - if (group) - nm_setting_wireless_security_add_group (wsec, "ccmp"); - else - nm_setting_wireless_security_add_pairwise (wsec, "ccmp"); - } else if (!strcmp (*iter, "TKIP")) { - if (group) - nm_setting_wireless_security_add_group (wsec, "tkip"); - else - nm_setting_wireless_security_add_pairwise (wsec, "tkip"); - } else if (group && !strcmp (*iter, "WEP104")) - nm_setting_wireless_security_add_group (wsec, "wep104"); - else if (group && !strcmp (*iter, "WEP40")) - nm_setting_wireless_security_add_group (wsec, "wep40"); - else { - PARSE_WARNING ("ignoring invalid %s cipher '%s'", - group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE", - *iter); - } - } - - return TRUE; + gs_free char * value = NULL; + const char * p; + gs_free const char **list = NULL; + const char *const * iter; + int i = 0; + + p = svGetValueStr(ifcfg, group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE", &value); + if (!p) + return TRUE; + + list = nm_utils_strsplit_set(p, " "); + for (iter = list; iter && *iter; iter++, i++) { + if (!strcmp(*iter, "CCMP")) { + if (group) + nm_setting_wireless_security_add_group(wsec, "ccmp"); + else + nm_setting_wireless_security_add_pairwise(wsec, "ccmp"); + } else if (!strcmp(*iter, "TKIP")) { + if (group) + nm_setting_wireless_security_add_group(wsec, "tkip"); + else + nm_setting_wireless_security_add_pairwise(wsec, "tkip"); + } else if (group && !strcmp(*iter, "WEP104")) + nm_setting_wireless_security_add_group(wsec, "wep104"); + else if (group && !strcmp(*iter, "WEP40")) + nm_setting_wireless_security_add_group(wsec, "wep40"); + else { + PARSE_WARNING("ignoring invalid %s cipher '%s'", + group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE", + *iter); + } + } + + return TRUE; } #define WPA_PMK_LEN 32 static char * -parse_wpa_psk (shvarFile *ifcfg, - const char *file, - GBytes *ssid, - GError **error) +parse_wpa_psk(shvarFile *ifcfg, const char *file, GBytes *ssid, GError **error) { - shvarFile *keys_ifcfg; - gs_free char *psk = NULL; - size_t plen; - - /* Passphrase must be between 10 and 66 characters in length because WPA - * hex keys are exactly 64 characters (no quoting), and WPA passphrases - * are between 8 and 63 characters (inclusive), plus optional quoting if - * the passphrase contains spaces. - */ - - /* Try to get keys from the "shadow" key file */ - keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); - if (keys_ifcfg) { - psk = svGetValueStr_cp (keys_ifcfg, "WPA_PSK"); - svCloseFile (keys_ifcfg); - } - - /* Fall back to the original ifcfg */ - if (!psk) - psk = svGetValueStr_cp (ifcfg, "WPA_PSK"); - - if (!psk) - return NULL; - - plen = strlen (psk); - - if (plen == 64) { - /* Verify the hex PSK; 64 digits */ - if (!NM_STRCHAR_ALL (psk, ch, g_ascii_isxdigit (ch))) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid WPA_PSK (contains non-hexadecimal characters)"); - return NULL; - } - } else { - if (plen < 8 || plen > 63) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid WPA_PSK (passphrases must be between " - "8 and 63 characters long (inclusive))"); - return NULL; - } - } - - return g_steal_pointer (&psk); + shvarFile * keys_ifcfg; + gs_free char *psk = NULL; + size_t plen; + + /* Passphrase must be between 10 and 66 characters in length because WPA + * hex keys are exactly 64 characters (no quoting), and WPA passphrases + * are between 8 and 63 characters (inclusive), plus optional quoting if + * the passphrase contains spaces. + */ + + /* Try to get keys from the "shadow" key file */ + keys_ifcfg = utils_get_keys_ifcfg(file, FALSE); + if (keys_ifcfg) { + psk = svGetValueStr_cp(keys_ifcfg, "WPA_PSK"); + svCloseFile(keys_ifcfg); + } + + /* Fall back to the original ifcfg */ + if (!psk) + psk = svGetValueStr_cp(ifcfg, "WPA_PSK"); + + if (!psk) + return NULL; + + plen = strlen(psk); + + if (plen == 64) { + /* Verify the hex PSK; 64 digits */ + if (!NM_STRCHAR_ALL(psk, ch, g_ascii_isxdigit(ch))) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid WPA_PSK (contains non-hexadecimal characters)"); + return NULL; + } + } else { + if (plen < 8 || plen > 63) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid WPA_PSK (passphrases must be between " + "8 and 63 characters long (inclusive))"); + return NULL; + } + } + + return g_steal_pointer(&psk); } static gboolean -eap_simple_reader (const char *eap_method, - shvarFile *ifcfg, - shvarFile *keys_ifcfg, - NMSetting8021x *s_8021x, - gboolean phase2, - GError **error) +eap_simple_reader(const char * eap_method, + shvarFile * ifcfg, + shvarFile * keys_ifcfg, + NMSetting8021x *s_8021x, + gboolean phase2, + GError ** error) { - NMSettingSecretFlags flags; - gs_free char *identity_free = NULL; - nm_auto_free_secret char *password_raw_str = NULL; - gs_unref_bytes GBytes *password_raw_bytes = NULL; - - g_object_set (s_8021x, - NM_SETTING_802_1X_IDENTITY, - svGetValueStr (ifcfg, "IEEE_8021X_IDENTITY", &identity_free), - NULL); - - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - "IEEE_8021X_PASSWORD", - NM_SETTING_802_1X_PASSWORD); - - _secret_read_ifcfg (ifcfg, keys_ifcfg, "IEEE_8021X_PASSWORD_RAW", &password_raw_str, &flags); - if (!_secret_password_raw_to_bytes ("IEEE_8021X_PASSWORD_RAW", - password_raw_str, - &password_raw_bytes, - error)) - return FALSE; - - g_object_set (s_8021x, - NM_SETTING_802_1X_PASSWORD_RAW_FLAGS, - flags, - NM_SETTING_802_1X_PASSWORD_RAW, - password_raw_bytes, - NULL); - - return TRUE; + NMSettingSecretFlags flags; + gs_free char * identity_free = NULL; + nm_auto_free_secret char *password_raw_str = NULL; + gs_unref_bytes GBytes *password_raw_bytes = NULL; + + g_object_set(s_8021x, + NM_SETTING_802_1X_IDENTITY, + svGetValueStr(ifcfg, "IEEE_8021X_IDENTITY", &identity_free), + NULL); + + _secret_set_from_ifcfg(s_8021x, + ifcfg, + keys_ifcfg, + "IEEE_8021X_PASSWORD", + NM_SETTING_802_1X_PASSWORD); + + _secret_read_ifcfg(ifcfg, keys_ifcfg, "IEEE_8021X_PASSWORD_RAW", &password_raw_str, &flags); + if (!_secret_password_raw_to_bytes("IEEE_8021X_PASSWORD_RAW", + password_raw_str, + &password_raw_bytes, + error)) + return FALSE; + + g_object_set(s_8021x, + NM_SETTING_802_1X_PASSWORD_RAW_FLAGS, + flags, + NM_SETTING_802_1X_PASSWORD_RAW, + password_raw_bytes, + NULL); + + return TRUE; } static gboolean -eap_tls_reader (const char *eap_method, - shvarFile *ifcfg, - shvarFile *keys_ifcfg, - NMSetting8021x *s_8021x, - gboolean phase2, - GError **error) +eap_tls_reader(const char * eap_method, + shvarFile * ifcfg, + shvarFile * keys_ifcfg, + NMSetting8021x *s_8021x, + gboolean phase2, + GError ** error) { - gs_unref_bytes GBytes *privkey = NULL; - gs_unref_bytes GBytes *client_cert = NULL; - gs_free char *identity_free = NULL; - gs_free char *value_to_free = NULL; - const char *client_cert_var; - const char *client_cert_prop; - NMSetting8021xCKFormat format; - - g_object_set (s_8021x, - NM_SETTING_802_1X_IDENTITY, - svGetValueStr (ifcfg, "IEEE_8021X_IDENTITY", &identity_free), - NULL); - - /* CA certificate */ - if (!_cert_set_from_ifcfg (s_8021x, - ifcfg, - phase2 ? "IEEE_8021X_INNER_CA_CERT" : "IEEE_8021X_CA_CERT", - phase2 ? NM_SETTING_802_1X_PHASE2_CA_CERT : NM_SETTING_802_1X_CA_CERT, - NULL, - error)) - return FALSE; - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - phase2 ? "IEEE_8021X_INNER_CA_CERT_PASSWORD" : "IEEE_8021X_CA_CERT_PASSWORD", - phase2 ? NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD : NM_SETTING_802_1X_CA_CERT_PASSWORD); - - /* Private key */ - if (!_cert_set_from_ifcfg (s_8021x, - ifcfg, - phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY", - phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY : NM_SETTING_802_1X_PRIVATE_KEY, - &privkey, - error)) - return FALSE; - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD" : "IEEE_8021X_PRIVATE_KEY_PASSWORD", - phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); - - /* Client certificate */ - client_cert_var = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT"; - client_cert_prop = phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT : NM_SETTING_802_1X_CLIENT_CERT; - if (!_cert_set_from_ifcfg (s_8021x, - ifcfg, - client_cert_var, - client_cert_prop, - &client_cert, - error)) - return FALSE; - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - phase2 ? "IEEE_8021X_INNER_CLIENT_CERT_PASSWORD" : "IEEE_8021X_CLIENT_CERT_PASSWORD", - phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD : NM_SETTING_802_1X_CLIENT_CERT_PASSWORD); - - /* In the past when the private key and client certificate - * were the same PKCS #12 file we used to write only the - * private key variable. Still support that even if it means - * that we have to look into the file content, which makes - * the connection not self-contained. - */ - if ( !client_cert - && privkey - && !svGetValue (ifcfg, client_cert_var, &value_to_free)) { - if (phase2) - format = nm_setting_802_1x_get_phase2_private_key_format (s_8021x); - else - format = nm_setting_802_1x_get_private_key_format (s_8021x); - - if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) - g_object_set (s_8021x, client_cert_prop, privkey, NULL); - } - - return TRUE; + gs_unref_bytes GBytes *privkey = NULL; + gs_unref_bytes GBytes *client_cert = NULL; + gs_free char * identity_free = NULL; + gs_free char * value_to_free = NULL; + const char * client_cert_var; + const char * client_cert_prop; + NMSetting8021xCKFormat format; + + g_object_set(s_8021x, + NM_SETTING_802_1X_IDENTITY, + svGetValueStr(ifcfg, "IEEE_8021X_IDENTITY", &identity_free), + NULL); + + /* CA certificate */ + if (!_cert_set_from_ifcfg(s_8021x, + ifcfg, + phase2 ? "IEEE_8021X_INNER_CA_CERT" : "IEEE_8021X_CA_CERT", + phase2 ? NM_SETTING_802_1X_PHASE2_CA_CERT : NM_SETTING_802_1X_CA_CERT, + NULL, + error)) + return FALSE; + _secret_set_from_ifcfg( + s_8021x, + ifcfg, + keys_ifcfg, + phase2 ? "IEEE_8021X_INNER_CA_CERT_PASSWORD" : "IEEE_8021X_CA_CERT_PASSWORD", + phase2 ? NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD : NM_SETTING_802_1X_CA_CERT_PASSWORD); + + /* Private key */ + if (!_cert_set_from_ifcfg(s_8021x, + ifcfg, + phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY", + phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY + : NM_SETTING_802_1X_PRIVATE_KEY, + &privkey, + error)) + return FALSE; + _secret_set_from_ifcfg(s_8021x, + ifcfg, + keys_ifcfg, + phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD" + : "IEEE_8021X_PRIVATE_KEY_PASSWORD", + phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD + : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); + + /* Client certificate */ + client_cert_var = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT"; + client_cert_prop = + phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT : NM_SETTING_802_1X_CLIENT_CERT; + if (!_cert_set_from_ifcfg(s_8021x, + ifcfg, + client_cert_var, + client_cert_prop, + &client_cert, + error)) + return FALSE; + _secret_set_from_ifcfg(s_8021x, + ifcfg, + keys_ifcfg, + phase2 ? "IEEE_8021X_INNER_CLIENT_CERT_PASSWORD" + : "IEEE_8021X_CLIENT_CERT_PASSWORD", + phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD + : NM_SETTING_802_1X_CLIENT_CERT_PASSWORD); + + /* In the past when the private key and client certificate + * were the same PKCS #12 file we used to write only the + * private key variable. Still support that even if it means + * that we have to look into the file content, which makes + * the connection not self-contained. + */ + if (!client_cert && privkey && !svGetValue(ifcfg, client_cert_var, &value_to_free)) { + if (phase2) + format = nm_setting_802_1x_get_phase2_private_key_format(s_8021x); + else + format = nm_setting_802_1x_get_private_key_format(s_8021x); + + if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) + g_object_set(s_8021x, client_cert_prop, privkey, NULL); + } + + return TRUE; } static gboolean -parse_8021x_phase2_auth (shvarFile *ifcfg, - shvarFile *keys_ifcfg, - NMSetting8021x *s_8021x, - GError **error) +parse_8021x_phase2_auth(shvarFile * ifcfg, + shvarFile * keys_ifcfg, + NMSetting8021x *s_8021x, + GError ** error) { - gs_free char *inner_auth = NULL; - gs_free char *v_free = NULL; - const char *v; - gs_free const char **list = NULL; - const char *const *iter; - guint num_auth = 0; - guint num_autheap = 0; - - v = svGetValueStr (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", &v_free); - if (!v) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing IEEE_8021X_INNER_AUTH_METHODS"); - return FALSE; - } - - inner_auth = g_ascii_strdown (v, -1); - list = nm_utils_strsplit_set (inner_auth, " "); - for (iter = list; iter && *iter; iter++) { - if (NM_IN_STRSET (*iter, "pap", - "chap", - "mschap", - "mschapv2", - "gtc", - "otp", - "md5")) { - if (num_auth == 0) { - if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) - return FALSE; - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, *iter, NULL); - } - num_auth++; - } else if (nm_streq (*iter, "tls")) { - if (num_auth == 0) { - if (!eap_tls_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) - return FALSE; - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "tls", NULL); - } - num_auth++; - } else if (NM_IN_STRSET (*iter, "eap-md5", - "eap-mschapv2", - "eap-otp", - "eap-gtc")) { - if (num_autheap == 0) { - if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) - return FALSE; - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, (*iter + NM_STRLEN ("eap-")), NULL); - } - num_autheap++; - } else if (nm_streq (*iter, "eap-tls")) { - if (num_autheap == 0) { - if (!eap_tls_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) - return FALSE; - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, "tls", NULL); - } - num_autheap++; - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'", - *iter); - return FALSE; - } - } - - if (num_auth > 1) - PARSE_WARNING ("Discarded extra phase2 authentication methods"); - if (num_auth > 1) - PARSE_WARNING ("Discarded extra phase2 EAP authentication methods"); - - if (!num_auth && !num_autheap) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "No phase2 authentication method found"); - return FALSE; - } - - return TRUE; + gs_free char * inner_auth = NULL; + gs_free char * v_free = NULL; + const char * v; + gs_free const char **list = NULL; + const char *const * iter; + guint num_auth = 0; + guint num_autheap = 0; + + v = svGetValueStr(ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", &v_free); + if (!v) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IEEE_8021X_INNER_AUTH_METHODS"); + return FALSE; + } + + inner_auth = g_ascii_strdown(v, -1); + list = nm_utils_strsplit_set(inner_auth, " "); + for (iter = list; iter && *iter; iter++) { + if (NM_IN_STRSET(*iter, "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5")) { + if (num_auth == 0) { + if (!eap_simple_reader(*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) + return FALSE; + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, *iter, NULL); + } + num_auth++; + } else if (nm_streq(*iter, "tls")) { + if (num_auth == 0) { + if (!eap_tls_reader(*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) + return FALSE; + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "tls", NULL); + } + num_auth++; + } else if (NM_IN_STRSET(*iter, "eap-md5", "eap-mschapv2", "eap-otp", "eap-gtc")) { + if (num_autheap == 0) { + if (!eap_simple_reader(*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) + return FALSE; + g_object_set(s_8021x, + NM_SETTING_802_1X_PHASE2_AUTHEAP, + (*iter + NM_STRLEN("eap-")), + NULL); + } + num_autheap++; + } else if (nm_streq(*iter, "eap-tls")) { + if (num_autheap == 0) { + if (!eap_tls_reader(*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) + return FALSE; + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, "tls", NULL); + } + num_autheap++; + } else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'", + *iter); + return FALSE; + } + } + + if (num_auth > 1) + PARSE_WARNING("Discarded extra phase2 authentication methods"); + if (num_auth > 1) + PARSE_WARNING("Discarded extra phase2 EAP authentication methods"); + + if (!num_auth && !num_autheap) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "No phase2 authentication method found"); + return FALSE; + } + + return TRUE; } static gboolean -eap_peap_reader (const char *eap_method, - shvarFile *ifcfg, - shvarFile *keys_ifcfg, - NMSetting8021x *s_8021x, - gboolean phase2, - GError **error) +eap_peap_reader(const char * eap_method, + shvarFile * ifcfg, + shvarFile * keys_ifcfg, + NMSetting8021x *s_8021x, + gboolean phase2, + GError ** error) { - gs_free char *value = NULL; - const char *v; - - if (!_cert_set_from_ifcfg (s_8021x, - ifcfg, - "IEEE_8021X_CA_CERT", - NM_SETTING_802_1X_CA_CERT, - NULL, - error)) - return FALSE; - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - "IEEE_8021X_CA_CERT_PASSWORD", - NM_SETTING_802_1X_CA_CERT_PASSWORD); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IEEE_8021X_PEAP_VERSION", &value); - if (v) { - if (!strcmp (v, "0")) - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "0", NULL); - else if (!strcmp (v, "1")) - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "1", NULL); - else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Unknown IEEE_8021X_PEAP_VERSION value '%s'", - v); - return FALSE; - } - } - - if (svGetValueBoolean (ifcfg, "IEEE_8021X_PEAP_FORCE_NEW_LABEL", FALSE)) - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1", NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IEEE_8021X_ANON_IDENTITY", &value); - if (v) - g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, v, NULL); - - if (!parse_8021x_phase2_auth (ifcfg, keys_ifcfg, s_8021x, error)) - return FALSE; - - return TRUE; + gs_free char *value = NULL; + const char * v; + + if (!_cert_set_from_ifcfg(s_8021x, + ifcfg, + "IEEE_8021X_CA_CERT", + NM_SETTING_802_1X_CA_CERT, + NULL, + error)) + return FALSE; + _secret_set_from_ifcfg(s_8021x, + ifcfg, + keys_ifcfg, + "IEEE_8021X_CA_CERT_PASSWORD", + NM_SETTING_802_1X_CA_CERT_PASSWORD); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IEEE_8021X_PEAP_VERSION", &value); + if (v) { + if (!strcmp(v, "0")) + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "0", NULL); + else if (!strcmp(v, "1")) + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "1", NULL); + else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Unknown IEEE_8021X_PEAP_VERSION value '%s'", + v); + return FALSE; + } + } + + if (svGetValueBoolean(ifcfg, "IEEE_8021X_PEAP_FORCE_NEW_LABEL", FALSE)) + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1", NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IEEE_8021X_ANON_IDENTITY", &value); + if (v) + g_object_set(s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, v, NULL); + + if (!parse_8021x_phase2_auth(ifcfg, keys_ifcfg, s_8021x, error)) + return FALSE; + + return TRUE; } static gboolean -eap_ttls_reader (const char *eap_method, - shvarFile *ifcfg, - shvarFile *keys_ifcfg, - NMSetting8021x *s_8021x, - gboolean phase2, - GError **error) +eap_ttls_reader(const char * eap_method, + shvarFile * ifcfg, + shvarFile * keys_ifcfg, + NMSetting8021x *s_8021x, + gboolean phase2, + GError ** error) { - gs_free char *value = NULL; - const char *v; - - if (!_cert_set_from_ifcfg (s_8021x, - ifcfg, - "IEEE_8021X_CA_CERT", - NM_SETTING_802_1X_CA_CERT, - NULL, - error)) - return FALSE; - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - "IEEE_8021X_CA_CERT_PASSWORD", - NM_SETTING_802_1X_CA_CERT_PASSWORD); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IEEE_8021X_ANON_IDENTITY", &value); - if (v) - g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, v, NULL); - - if (!parse_8021x_phase2_auth (ifcfg, keys_ifcfg, s_8021x, error)) - return FALSE; - - return TRUE; + gs_free char *value = NULL; + const char * v; + + if (!_cert_set_from_ifcfg(s_8021x, + ifcfg, + "IEEE_8021X_CA_CERT", + NM_SETTING_802_1X_CA_CERT, + NULL, + error)) + return FALSE; + _secret_set_from_ifcfg(s_8021x, + ifcfg, + keys_ifcfg, + "IEEE_8021X_CA_CERT_PASSWORD", + NM_SETTING_802_1X_CA_CERT_PASSWORD); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IEEE_8021X_ANON_IDENTITY", &value); + if (v) + g_object_set(s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, v, NULL); + + if (!parse_8021x_phase2_auth(ifcfg, keys_ifcfg, s_8021x, error)) + return FALSE; + + return TRUE; } static gboolean -eap_fast_reader (const char *eap_method, - shvarFile *ifcfg, - shvarFile *keys_ifcfg, - NMSetting8021x *s_8021x, - gboolean phase2, - GError **error) +eap_fast_reader(const char * eap_method, + shvarFile * ifcfg, + shvarFile * keys_ifcfg, + NMSetting8021x *s_8021x, + gboolean phase2, + GError ** error) { - gs_free char *anon_ident = NULL; - gs_free char *pac_file = NULL; - gs_free char *real_pac_path = NULL; - gs_free char *fast_provisioning = NULL; - const char *const *iter; - const char *pac_prov_str; - gboolean allow_unauth = FALSE, allow_auth = FALSE; - - pac_file = svGetValueStr_cp (ifcfg, "IEEE_8021X_PAC_FILE"); - if (pac_file) { - real_pac_path = get_full_file_path (svFileGetName (ifcfg), pac_file); - g_object_set (s_8021x, NM_SETTING_802_1X_PAC_FILE, real_pac_path, NULL); - } - - fast_provisioning = svGetValueStr_cp (ifcfg, "IEEE_8021X_FAST_PROVISIONING"); - if (fast_provisioning) { - gs_free const char **list = NULL; - - list = nm_utils_strsplit_set (fast_provisioning, " \t"); - for (iter = list; iter && *iter; iter++) { - if (strcmp (*iter, "allow-unauth") == 0) - allow_unauth = TRUE; - else if (strcmp (*iter, "allow-auth") == 0) - allow_auth = TRUE; - else { - PARSE_WARNING ("invalid IEEE_8021X_FAST_PROVISIONING '%s' " - "(space-separated list of these values [allow-auth, allow-unauth] expected)", - *iter); - } - } - } - pac_prov_str = allow_unauth ? (allow_auth ? "3" : "1") : (allow_auth ? "2" : "0"); - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, pac_prov_str, NULL); - - if (!pac_file && !(allow_unauth || allow_auth)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "IEEE_8021X_PAC_FILE not provided and EAP-FAST automatic PAC provisioning disabled"); - return FALSE; - } - - anon_ident = svGetValueStr_cp (ifcfg, "IEEE_8021X_ANON_IDENTITY"); - if (anon_ident) - g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, anon_ident, NULL); - - if (!parse_8021x_phase2_auth (ifcfg, keys_ifcfg, s_8021x, error)) - return FALSE; - - return TRUE; + gs_free char * anon_ident = NULL; + gs_free char * pac_file = NULL; + gs_free char * real_pac_path = NULL; + gs_free char * fast_provisioning = NULL; + const char *const *iter; + const char * pac_prov_str; + gboolean allow_unauth = FALSE, allow_auth = FALSE; + + pac_file = svGetValueStr_cp(ifcfg, "IEEE_8021X_PAC_FILE"); + if (pac_file) { + real_pac_path = get_full_file_path(svFileGetName(ifcfg), pac_file); + g_object_set(s_8021x, NM_SETTING_802_1X_PAC_FILE, real_pac_path, NULL); + } + + fast_provisioning = svGetValueStr_cp(ifcfg, "IEEE_8021X_FAST_PROVISIONING"); + if (fast_provisioning) { + gs_free const char **list = NULL; + + list = nm_utils_strsplit_set(fast_provisioning, " \t"); + for (iter = list; iter && *iter; iter++) { + if (strcmp(*iter, "allow-unauth") == 0) + allow_unauth = TRUE; + else if (strcmp(*iter, "allow-auth") == 0) + allow_auth = TRUE; + else { + PARSE_WARNING( + "invalid IEEE_8021X_FAST_PROVISIONING '%s' " + "(space-separated list of these values [allow-auth, allow-unauth] expected)", + *iter); + } + } + } + pac_prov_str = allow_unauth ? (allow_auth ? "3" : "1") : (allow_auth ? "2" : "0"); + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, pac_prov_str, NULL); + + if (!pac_file && !(allow_unauth || allow_auth)) { + g_set_error( + error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "IEEE_8021X_PAC_FILE not provided and EAP-FAST automatic PAC provisioning disabled"); + return FALSE; + } + + anon_ident = svGetValueStr_cp(ifcfg, "IEEE_8021X_ANON_IDENTITY"); + if (anon_ident) + g_object_set(s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, anon_ident, NULL); + + if (!parse_8021x_phase2_auth(ifcfg, keys_ifcfg, s_8021x, error)) + return FALSE; + + return TRUE; } typedef struct { - const char *method; - gboolean (*reader) (const char *eap_method, - shvarFile *ifcfg, - shvarFile *keys_ifcfg, - NMSetting8021x *s_8021x, - gboolean phase2, - GError **error); - gboolean wifi_phase2_only; + const char *method; + gboolean (*reader)(const char * eap_method, + shvarFile * ifcfg, + shvarFile * keys_ifcfg, + NMSetting8021x *s_8021x, + gboolean phase2, + GError ** error); + gboolean wifi_phase2_only; } EAPReader; -static EAPReader eap_readers[] = { - { "md5", eap_simple_reader, TRUE }, - { "pap", eap_simple_reader, TRUE }, - { "chap", eap_simple_reader, TRUE }, - { "mschap", eap_simple_reader, TRUE }, - { "mschapv2", eap_simple_reader, TRUE }, - { "leap", eap_simple_reader, FALSE }, - { "pwd", eap_simple_reader, FALSE }, - { "tls", eap_tls_reader, FALSE }, - { "peap", eap_peap_reader, FALSE }, - { "ttls", eap_ttls_reader, FALSE }, - { "fast", eap_fast_reader, FALSE }, - { NULL, NULL } -}; +static EAPReader eap_readers[] = {{"md5", eap_simple_reader, TRUE}, + {"pap", eap_simple_reader, TRUE}, + {"chap", eap_simple_reader, TRUE}, + {"mschap", eap_simple_reader, TRUE}, + {"mschapv2", eap_simple_reader, TRUE}, + {"leap", eap_simple_reader, FALSE}, + {"pwd", eap_simple_reader, FALSE}, + {"tls", eap_tls_reader, FALSE}, + {"peap", eap_peap_reader, FALSE}, + {"ttls", eap_ttls_reader, FALSE}, + {"fast", eap_fast_reader, FALSE}, + {NULL, NULL}}; static void -read_8021x_list_value (shvarFile *ifcfg, - const char *ifcfg_var_name, - NMSetting8021x *setting, - const char *prop_name) +read_8021x_list_value(shvarFile * ifcfg, + const char * ifcfg_var_name, + NMSetting8021x *setting, + const char * prop_name) { - gs_free char *value = NULL; - gs_free const char **strv = NULL; - const char *v; + gs_free char * value = NULL; + gs_free const char **strv = NULL; + const char * v; - g_return_if_fail (ifcfg != NULL); - g_return_if_fail (ifcfg_var_name != NULL); - g_return_if_fail (prop_name != NULL); + g_return_if_fail(ifcfg != NULL); + g_return_if_fail(ifcfg_var_name != NULL); + g_return_if_fail(prop_name != NULL); - v = svGetValueStr (ifcfg, ifcfg_var_name, &value); - if (!v) - return; + v = svGetValueStr(ifcfg, ifcfg_var_name, &value); + if (!v) + return; - strv = nm_utils_strsplit_set (v, " \t"); - if (strv) - g_object_set (setting, prop_name, strv, NULL); + strv = nm_utils_strsplit_set(v, " \t"); + if (strv) + g_object_set(setting, prop_name, strv, NULL); } static NMSetting8021x * -fill_8021x (shvarFile *ifcfg, - const char *file, - const char *key_mgmt, - gboolean wifi, - GError **error) +fill_8021x(shvarFile *ifcfg, const char *file, const char *key_mgmt, gboolean wifi, GError **error) { - nm_auto_shvar_file_close shvarFile *keys_ifcfg = NULL; - gs_unref_object NMSetting8021x *s_8021x = NULL; - gs_free char *value = NULL; - const char *v; - gs_free const char **list = NULL; - const char *const *iter; - gint64 timeout; - int i_val; - - v = svGetValueStr (ifcfg, "IEEE_8021X_EAP_METHODS", &value); - if (!v) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing IEEE_8021X_EAP_METHODS for key management '%s'", - key_mgmt); - return NULL; - } - - list = nm_utils_strsplit_set (v, " "); - - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - - /* Read in the lookaside keys_ifcfg file, if present */ - keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); - - /* Validate and handle each EAP method */ - for (iter = list; iter && *iter; iter++) { - EAPReader *eap = &eap_readers[0]; - gboolean found = FALSE; - gs_free char *lower = NULL; - - lower = g_ascii_strdown (*iter, -1); - while (eap->method) { - if (strcmp (eap->method, lower)) - goto next; - - /* Some EAP methods don't provide keying material, thus they - * cannot be used with Wi-Fi unless they are an inner method - * used with TTLS or PEAP or whatever. - */ - if (wifi && eap->wifi_phase2_only) { - PARSE_WARNING ("ignored invalid IEEE_8021X_EAP_METHOD '%s'; not allowed for wifi", - lower); - goto next; - } - - /* Parse EAP method specific options */ - if (!(*eap->reader)(lower, ifcfg, keys_ifcfg, s_8021x, FALSE, error)) - return NULL; - - nm_setting_802_1x_add_eap_method (s_8021x, lower); - found = TRUE; - break; + nm_auto_shvar_file_close shvarFile *keys_ifcfg = NULL; + gs_unref_object NMSetting8021x *s_8021x = NULL; + gs_free char * value = NULL; + const char * v; + gs_free const char ** list = NULL; + const char *const * iter; + gint64 timeout; + int i_val; + + v = svGetValueStr(ifcfg, "IEEE_8021X_EAP_METHODS", &value); + if (!v) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IEEE_8021X_EAP_METHODS for key management '%s'", + key_mgmt); + return NULL; + } + + list = nm_utils_strsplit_set(v, " "); + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + + /* Read in the lookaside keys_ifcfg file, if present */ + keys_ifcfg = utils_get_keys_ifcfg(file, FALSE); + + /* Validate and handle each EAP method */ + for (iter = list; iter && *iter; iter++) { + EAPReader * eap = &eap_readers[0]; + gboolean found = FALSE; + gs_free char *lower = NULL; + + lower = g_ascii_strdown(*iter, -1); + while (eap->method) { + if (strcmp(eap->method, lower)) + goto next; + + /* Some EAP methods don't provide keying material, thus they + * cannot be used with Wi-Fi unless they are an inner method + * used with TTLS or PEAP or whatever. + */ + if (wifi && eap->wifi_phase2_only) { + PARSE_WARNING("ignored invalid IEEE_8021X_EAP_METHOD '%s'; not allowed for wifi", + lower); + goto next; + } + + /* Parse EAP method specific options */ + if (!(*eap->reader)(lower, ifcfg, keys_ifcfg, s_8021x, FALSE, error)) + return NULL; + + nm_setting_802_1x_add_eap_method(s_8021x, lower); + found = TRUE; + break; next: - eap++; - } - - if (!found) - PARSE_WARNING ("ignored unknown IEEE_8021X_EAP_METHOD '%s'", lower); - } - - if (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 0) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "No valid EAP methods found in IEEE_8021X_EAP_METHODS"); - return NULL; - } - - g_object_set (s_8021x, - NM_SETTING_802_1X_SYSTEM_CA_CERTS, - svGetValueBoolean (ifcfg, "IEEE_8021X_SYSTEM_CA_CERTS", FALSE), - NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IEEE_8021X_SUBJECT_MATCH", &value); - g_object_set (s_8021x, NM_SETTING_802_1X_SUBJECT_MATCH, v, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IEEE_8021X_PHASE2_SUBJECT_MATCH", &value); - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH, v, NULL); - - i_val = NM_SETTING_802_1X_AUTH_FLAGS_NONE; - if (!svGetValueEnum (ifcfg, "IEEE_8021X_PHASE1_AUTH_FLAGS", - nm_setting_802_1x_auth_flags_get_type (), - &i_val, error)) - return NULL; - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_AUTH_FLAGS, (guint) i_val, NULL); - - read_8021x_list_value (ifcfg, "IEEE_8021X_ALTSUBJECT_MATCHES", - s_8021x, NM_SETTING_802_1X_ALTSUBJECT_MATCHES); - read_8021x_list_value (ifcfg, "IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES", - s_8021x, NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IEEE_8021X_DOMAIN_SUFFIX_MATCH", &value); - g_object_set (s_8021x, NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH, v, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IEEE_8021X_PHASE2_DOMAIN_SUFFIX_MATCH", &value); - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH, v, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IEEE_8021X_DOMAIN_MATCH", &value); - g_object_set (s_8021x, NM_SETTING_802_1X_DOMAIN_MATCH, v, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IEEE_8021X_PHASE2_DOMAIN_MATCH", &value); - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_DOMAIN_MATCH, v, NULL); - - timeout = svGetValueInt64 (ifcfg, "IEEE_8021X_AUTH_TIMEOUT", 10, 0, G_MAXINT32, 0); - g_object_set (s_8021x, NM_SETTING_802_1X_AUTH_TIMEOUT, (int) timeout, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IEEE_8021X_CA_PATH", &value); - g_object_set (s_8021x, NM_SETTING_802_1X_CA_PATH, v, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "IEEE_8021X_PHASE2_CA_PATH", &value); - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_CA_PATH, v, NULL); - - g_object_set (s_8021x, - NM_SETTING_802_1X_OPTIONAL, - svGetValueBoolean (ifcfg, "IEEE_8021X_OPTIONAL", FALSE), - NULL); - - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - "IEEE_8021X_PIN", - NM_SETTING_802_1X_PIN); - - return g_steal_pointer (&s_8021x); + eap++; + } + + if (!found) + PARSE_WARNING("ignored unknown IEEE_8021X_EAP_METHOD '%s'", lower); + } + + if (nm_setting_802_1x_get_num_eap_methods(s_8021x) == 0) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "No valid EAP methods found in IEEE_8021X_EAP_METHODS"); + return NULL; + } + + g_object_set(s_8021x, + NM_SETTING_802_1X_SYSTEM_CA_CERTS, + svGetValueBoolean(ifcfg, "IEEE_8021X_SYSTEM_CA_CERTS", FALSE), + NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IEEE_8021X_SUBJECT_MATCH", &value); + g_object_set(s_8021x, NM_SETTING_802_1X_SUBJECT_MATCH, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IEEE_8021X_PHASE2_SUBJECT_MATCH", &value); + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH, v, NULL); + + i_val = NM_SETTING_802_1X_AUTH_FLAGS_NONE; + if (!svGetValueEnum(ifcfg, + "IEEE_8021X_PHASE1_AUTH_FLAGS", + nm_setting_802_1x_auth_flags_get_type(), + &i_val, + error)) + return NULL; + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE1_AUTH_FLAGS, (guint) i_val, NULL); + + read_8021x_list_value(ifcfg, + "IEEE_8021X_ALTSUBJECT_MATCHES", + s_8021x, + NM_SETTING_802_1X_ALTSUBJECT_MATCHES); + read_8021x_list_value(ifcfg, + "IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES", + s_8021x, + NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IEEE_8021X_DOMAIN_SUFFIX_MATCH", &value); + g_object_set(s_8021x, NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IEEE_8021X_PHASE2_DOMAIN_SUFFIX_MATCH", &value); + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IEEE_8021X_DOMAIN_MATCH", &value); + g_object_set(s_8021x, NM_SETTING_802_1X_DOMAIN_MATCH, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IEEE_8021X_PHASE2_DOMAIN_MATCH", &value); + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE2_DOMAIN_MATCH, v, NULL); + + timeout = svGetValueInt64(ifcfg, "IEEE_8021X_AUTH_TIMEOUT", 10, 0, G_MAXINT32, 0); + g_object_set(s_8021x, NM_SETTING_802_1X_AUTH_TIMEOUT, (int) timeout, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IEEE_8021X_CA_PATH", &value); + g_object_set(s_8021x, NM_SETTING_802_1X_CA_PATH, v, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "IEEE_8021X_PHASE2_CA_PATH", &value); + g_object_set(s_8021x, NM_SETTING_802_1X_PHASE2_CA_PATH, v, NULL); + + g_object_set(s_8021x, + NM_SETTING_802_1X_OPTIONAL, + svGetValueBoolean(ifcfg, "IEEE_8021X_OPTIONAL", FALSE), + NULL); + + _secret_set_from_ifcfg(s_8021x, ifcfg, keys_ifcfg, "IEEE_8021X_PIN", NM_SETTING_802_1X_PIN); + + return g_steal_pointer(&s_8021x); } static NMSetting * -make_wpa_setting (shvarFile *ifcfg, - const char *file, - GBytes *ssid, - gboolean adhoc, - NMSetting8021x **s_8021x, - GError **error) +make_wpa_setting(shvarFile * ifcfg, + const char * file, + GBytes * ssid, + gboolean adhoc, + NMSetting8021x **s_8021x, + GError ** error) { - gs_unref_object NMSettingWirelessSecurity *wsec = NULL; - gs_free char *value = NULL; - const char *v; - gboolean wpa_psk = FALSE, wpa_sae = FALSE, wpa_owe = FALSE, wpa_eap = FALSE, ieee8021x = FALSE; - int i_val; - GError *local = NULL; - - wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); - - v = svGetValueStr (ifcfg, "KEY_MGMT", &value); - wpa_psk = nm_streq0 (v, "WPA-PSK"); - wpa_sae = nm_streq0 (v, "SAE"); - wpa_owe = nm_streq0 (v, "OWE"); - wpa_eap = nm_streq0 (v, "WPA-EAP"); - ieee8021x = nm_streq0 (v, "IEEE8021X"); - if ( !wpa_psk - && !wpa_sae - && !wpa_owe - && !wpa_eap - && !ieee8021x) - return NULL; /* Not WPA or Dynamic WEP */ - - /* WPS */ - i_val = NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT; - if (!svGetValueEnum (ifcfg, "WPS_METHOD", - nm_setting_wireless_security_wps_method_get_type (), - &i_val, error)) - return NULL; - g_object_set (wsec, - NM_SETTING_WIRELESS_SECURITY_WPS_METHOD, (guint) i_val, - NULL); - - /* Pairwise and Group ciphers (only relevant for WPA/RSN) */ - if (wpa_psk || wpa_sae || wpa_owe || wpa_eap) { - fill_wpa_ciphers (ifcfg, wsec, FALSE, adhoc); - fill_wpa_ciphers (ifcfg, wsec, TRUE, adhoc); - } - - /* WPA and/or RSN */ - if (adhoc) { - /* Ad-Hoc mode only supports RSN proto */ - nm_setting_wireless_security_add_proto (wsec, "rsn"); - } else { - gs_free char *value2 = NULL; - const char *v2; - - v2 = svGetValueStr (ifcfg, "WPA_ALLOW_WPA", &value2); - if (v2 && svParseBoolean (v2, TRUE)) - nm_setting_wireless_security_add_proto (wsec, "wpa"); - - nm_clear_g_free (&value2); - v2 = svGetValueStr (ifcfg, "WPA_ALLOW_WPA2", &value2); - if (v2 && svParseBoolean (v2, TRUE)) - nm_setting_wireless_security_add_proto (wsec, "rsn"); - } - - if (wpa_psk || wpa_sae) { - NMSettingSecretFlags psk_flags; - - psk_flags = _secret_read_ifcfg_flags (ifcfg, "WPA_PSK_FLAGS"); - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, psk_flags, NULL); - - /* Read PSK if it's system-owned */ - if (psk_flags == NM_SETTING_SECRET_FLAG_NONE) { - gs_free char *psk = NULL; - - psk = parse_wpa_psk (ifcfg, file, ssid, &local); - if (psk) - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL); - else if (local) { - g_propagate_error (error, local); - return NULL; - } - } - - if (wpa_psk) - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL); - else { - nm_assert (wpa_sae); - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", NULL); - } - } else { - nm_assert (wpa_eap || ieee8021x || wpa_owe); - - /* Adhoc mode is mutually exclusive with any 802.1x-based authentication */ - if (adhoc) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Ad-Hoc mode cannot be used with KEY_MGMT type '%s'", v); - return NULL; - } - - if (wpa_owe) { - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "owe", NULL); - } else { - *s_8021x = fill_8021x (ifcfg, file, v, TRUE, error); - if (!*s_8021x) - return NULL; - - { - gs_free char *lower = g_ascii_strdown (v, -1); - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, lower, NULL); - } - } - } - - i_val = NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT; - if (!svGetValueEnum (ifcfg, "PMF", - nm_setting_wireless_security_pmf_get_type (), - &i_val, error)) - return NULL; - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PMF, i_val, NULL); - - i_val = NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT; - if (!svGetValueEnum (ifcfg, "FILS", - nm_setting_wireless_security_fils_get_type (), - &i_val, error)) - return NULL; - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_FILS, i_val, NULL); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "SECURITYMODE", &value); - if (NM_IN_STRSET (v, NULL, "open")) - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, v, NULL); - - return (NMSetting *) g_steal_pointer (&wsec); + gs_unref_object NMSettingWirelessSecurity *wsec = NULL; + gs_free char * value = NULL; + const char * v; + gboolean wpa_psk = FALSE, wpa_sae = FALSE, wpa_owe = FALSE, wpa_eap = FALSE, ieee8021x = FALSE; + int i_val; + GError * local = NULL; + + wsec = NM_SETTING_WIRELESS_SECURITY(nm_setting_wireless_security_new()); + + v = svGetValueStr(ifcfg, "KEY_MGMT", &value); + wpa_psk = nm_streq0(v, "WPA-PSK"); + wpa_sae = nm_streq0(v, "SAE"); + wpa_owe = nm_streq0(v, "OWE"); + wpa_eap = nm_streq0(v, "WPA-EAP"); + ieee8021x = nm_streq0(v, "IEEE8021X"); + if (!wpa_psk && !wpa_sae && !wpa_owe && !wpa_eap && !ieee8021x) + return NULL; /* Not WPA or Dynamic WEP */ + + /* WPS */ + i_val = NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT; + if (!svGetValueEnum(ifcfg, + "WPS_METHOD", + nm_setting_wireless_security_wps_method_get_type(), + &i_val, + error)) + return NULL; + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_WPS_METHOD, (guint) i_val, NULL); + + /* Pairwise and Group ciphers (only relevant for WPA/RSN) */ + if (wpa_psk || wpa_sae || wpa_owe || wpa_eap) { + fill_wpa_ciphers(ifcfg, wsec, FALSE, adhoc); + fill_wpa_ciphers(ifcfg, wsec, TRUE, adhoc); + } + + /* WPA and/or RSN */ + if (adhoc) { + /* Ad-Hoc mode only supports RSN proto */ + nm_setting_wireless_security_add_proto(wsec, "rsn"); + } else { + gs_free char *value2 = NULL; + const char * v2; + + v2 = svGetValueStr(ifcfg, "WPA_ALLOW_WPA", &value2); + if (v2 && svParseBoolean(v2, TRUE)) + nm_setting_wireless_security_add_proto(wsec, "wpa"); + + nm_clear_g_free(&value2); + v2 = svGetValueStr(ifcfg, "WPA_ALLOW_WPA2", &value2); + if (v2 && svParseBoolean(v2, TRUE)) + nm_setting_wireless_security_add_proto(wsec, "rsn"); + } + + if (wpa_psk || wpa_sae) { + NMSettingSecretFlags psk_flags; + + psk_flags = _secret_read_ifcfg_flags(ifcfg, "WPA_PSK_FLAGS"); + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, psk_flags, NULL); + + /* Read PSK if it's system-owned */ + if (psk_flags == NM_SETTING_SECRET_FLAG_NONE) { + gs_free char *psk = NULL; + + psk = parse_wpa_psk(ifcfg, file, ssid, &local); + if (psk) + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL); + else if (local) { + g_propagate_error(error, local); + return NULL; + } + } + + if (wpa_psk) + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL); + else { + nm_assert(wpa_sae); + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", NULL); + } + } else { + nm_assert(wpa_eap || ieee8021x || wpa_owe); + + /* Adhoc mode is mutually exclusive with any 802.1x-based authentication */ + if (adhoc) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Ad-Hoc mode cannot be used with KEY_MGMT type '%s'", + v); + return NULL; + } + + if (wpa_owe) { + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "owe", NULL); + } else { + *s_8021x = fill_8021x(ifcfg, file, v, TRUE, error); + if (!*s_8021x) + return NULL; + + { + gs_free char *lower = g_ascii_strdown(v, -1); + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, lower, NULL); + } + } + } + + i_val = NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT; + if (!svGetValueEnum(ifcfg, "PMF", nm_setting_wireless_security_pmf_get_type(), &i_val, error)) + return NULL; + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_PMF, i_val, NULL); + + i_val = NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT; + if (!svGetValueEnum(ifcfg, "FILS", nm_setting_wireless_security_fils_get_type(), &i_val, error)) + return NULL; + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_FILS, i_val, NULL); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "SECURITYMODE", &value); + if (NM_IN_STRSET(v, NULL, "open")) + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, v, NULL); + + return (NMSetting *) g_steal_pointer(&wsec); } static NMSetting * -make_leap_setting (shvarFile *ifcfg, - const char *file, - GError **error) +make_leap_setting(shvarFile *ifcfg, const char *file, GError **error) { - gs_unref_object NMSettingWirelessSecurity *wsec = NULL; - shvarFile *keys_ifcfg; - gs_free char *value = NULL; - NMSettingSecretFlags flags; - - wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); - - value = svGetValueStr_cp (ifcfg, "KEY_MGMT"); - if (!value || strcmp (value, "IEEE8021X")) - return NULL; - nm_clear_g_free (&value); - - value = svGetValueStr_cp (ifcfg, "SECURITYMODE"); - if (!value || g_ascii_strcasecmp (value, "leap")) - return NULL; /* Not LEAP */ - nm_clear_g_free (&value); - - flags = _secret_read_ifcfg_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS"); - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, flags, NULL); - - /* Read LEAP password if it's system-owned */ - if (flags == NM_SETTING_SECRET_FLAG_NONE) { - value = svGetValueStr_cp (ifcfg, "IEEE_8021X_PASSWORD"); - if (!value) { - /* Try to get keys from the "shadow" key file */ - keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); - if (keys_ifcfg) { - value = svGetValueStr_cp (keys_ifcfg, "IEEE_8021X_PASSWORD"); - svCloseFile (keys_ifcfg); - } - } - if (value && strlen (value)) - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, value, NULL); - nm_clear_g_free (&value); - } - - value = svGetValueStr_cp (ifcfg, "IEEE_8021X_IDENTITY"); - if (!value) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing LEAP identity"); - return NULL; - } - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, value, NULL); - nm_clear_g_free (&value); - - g_object_set (wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", - NULL); - - return (NMSetting *) g_steal_pointer (&wsec); + gs_unref_object NMSettingWirelessSecurity *wsec = NULL; + shvarFile * keys_ifcfg; + gs_free char * value = NULL; + NMSettingSecretFlags flags; + + wsec = NM_SETTING_WIRELESS_SECURITY(nm_setting_wireless_security_new()); + + value = svGetValueStr_cp(ifcfg, "KEY_MGMT"); + if (!value || strcmp(value, "IEEE8021X")) + return NULL; + nm_clear_g_free(&value); + + value = svGetValueStr_cp(ifcfg, "SECURITYMODE"); + if (!value || g_ascii_strcasecmp(value, "leap")) + return NULL; /* Not LEAP */ + nm_clear_g_free(&value); + + flags = _secret_read_ifcfg_flags(ifcfg, "IEEE_8021X_PASSWORD_FLAGS"); + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, flags, NULL); + + /* Read LEAP password if it's system-owned */ + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + value = svGetValueStr_cp(ifcfg, "IEEE_8021X_PASSWORD"); + if (!value) { + /* Try to get keys from the "shadow" key file */ + keys_ifcfg = utils_get_keys_ifcfg(file, FALSE); + if (keys_ifcfg) { + value = svGetValueStr_cp(keys_ifcfg, "IEEE_8021X_PASSWORD"); + svCloseFile(keys_ifcfg); + } + } + if (value && strlen(value)) + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, value, NULL); + nm_clear_g_free(&value); + } + + value = svGetValueStr_cp(ifcfg, "IEEE_8021X_IDENTITY"); + if (!value) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing LEAP identity"); + return NULL; + } + g_object_set(wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, value, NULL); + nm_clear_g_free(&value); + + g_object_set(wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "leap", + NULL); + + return (NMSetting *) g_steal_pointer(&wsec); } static NMSetting * -make_wireless_security_setting (shvarFile *ifcfg, - const char *file, - GBytes *ssid, - gboolean adhoc, - NMSetting8021x **s_8021x, - GError **error) +make_wireless_security_setting(shvarFile * ifcfg, + const char * file, + GBytes * ssid, + gboolean adhoc, + NMSetting8021x **s_8021x, + GError ** error) { - NMSetting *wsec; - - g_return_val_if_fail (error && !*error, NULL); - - if (!adhoc) { - wsec = make_leap_setting (ifcfg, file, error); - if (wsec) - return wsec; - else if (*error) - return NULL; - } - - wsec = make_wpa_setting (ifcfg, file, ssid, adhoc, s_8021x, error); - if (wsec) - return wsec; - else if (*error) - return NULL; - - wsec = make_wep_setting (ifcfg, file, error); - if (wsec) - return wsec; - else if (*error) - return NULL; - - return NULL; /* unencrypted */ + NMSetting *wsec; + + g_return_val_if_fail(error && !*error, NULL); + + if (!adhoc) { + wsec = make_leap_setting(ifcfg, file, error); + if (wsec) + return wsec; + else if (*error) + return NULL; + } + + wsec = make_wpa_setting(ifcfg, file, ssid, adhoc, s_8021x, error); + if (wsec) + return wsec; + else if (*error) + return NULL; + + wsec = make_wep_setting(ifcfg, file, error); + if (wsec) + return wsec; + else if (*error) + return NULL; + + return NULL; /* unencrypted */ } static const char ** -transform_hwaddr_blacklist (const char *blacklist) +transform_hwaddr_blacklist(const char *blacklist) { - const char **strv; - gsize i, j; - - strv = nm_utils_strsplit_set (blacklist, " \t"); - if (!strv) - return NULL; - for (i = 0, j = 0; strv[j]; j++) { - const char *s = strv[j]; - - if (!nm_utils_hwaddr_valid (s, ETH_ALEN)) { - PARSE_WARNING ("invalid MAC in HWADDR_BLACKLIST '%s'", s); - continue; - } - strv[i++] = s; - } - strv[i] = NULL; - return strv; + const char **strv; + gsize i, j; + + strv = nm_utils_strsplit_set(blacklist, " \t"); + if (!strv) + return NULL; + for (i = 0, j = 0; strv[j]; j++) { + const char *s = strv[j]; + + if (!nm_utils_hwaddr_valid(s, ETH_ALEN)) { + PARSE_WARNING("invalid MAC in HWADDR_BLACKLIST '%s'", s); + continue; + } + strv[i++] = s; + } + strv[i] = NULL; + return strv; } static NMSetting * -make_wireless_setting (shvarFile *ifcfg, - GError **error) +make_wireless_setting(shvarFile *ifcfg, GError **error) { - NMSettingWireless *s_wireless; - const char *cvalue; - char *value = NULL; - gint64 chan = 0; - NMSettingMacRandomization mac_randomization; - NMSettingWirelessPowersave powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT; - - s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - - value = svGetValueStr_cp (ifcfg, "HWADDR"); - if (value) { - value = g_strstrip (value); - g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, value, NULL); - g_free (value); - } - - value = svGetValueStr_cp (ifcfg, "MACADDR"); - if (value) { - value = g_strstrip (value); - g_object_set (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, value, NULL); - g_free (value); - } - - value = svGetValueStr_cp (ifcfg, "GENERATE_MAC_ADDRESS_MASK"); - g_object_set (s_wireless, NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK, value, NULL); - g_free (value); - - cvalue = svGetValueStr (ifcfg, "HWADDR_BLACKLIST", &value); - if (cvalue) { - gs_free const char **strv = NULL; - - strv = transform_hwaddr_blacklist (cvalue); - g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, strv, NULL); - g_free (value); - } - - value = svGetValueStr_cp (ifcfg, "ESSID"); - if (value) { - gs_unref_bytes GBytes *bytes = NULL; - gsize ssid_len = 0; - gsize value_len = strlen (value); - - if ( value_len > 2 - && (value_len % 2) == 0 - && g_str_has_prefix (value, "0x") - && NM_STRCHAR_ALL (&value[2], ch, g_ascii_isxdigit (ch))) { - /* interpret the value as hex-digits iff value starts - * with "0x" followed by pairs of hex digits */ - bytes = nm_utils_hexstr2bin (&value[2]); - } else - bytes = g_bytes_new (value, value_len); - - ssid_len = g_bytes_get_size (bytes); - if (ssid_len > 32 || ssid_len == 0) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid SSID '%s' (size %zu not between 1 and 32 inclusive)", - value, ssid_len); - g_free (value); - goto error; - } - - g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, bytes, NULL); - g_free (value); - } - - value = svGetValueStr_cp (ifcfg, "MODE"); - if (value) { - char *lcase; - const char *mode = NULL; - - lcase = g_ascii_strdown (value, -1); - g_free (value); - - if (!strcmp (lcase, "ad-hoc")) { - mode = "adhoc"; - } else if (!strcmp (lcase, "ap")) { - mode = "ap"; - } else if (!strcmp (lcase, "managed") || !strcmp (lcase, "auto")) { - mode = "infrastructure"; - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid mode '%s' (not 'Ad-Hoc', 'Ap', 'Managed', or 'Auto')", - lcase); - g_free (lcase); - goto error; - } - g_free (lcase); - - g_object_set (s_wireless, NM_SETTING_WIRELESS_MODE, mode, NULL); - } - - value = svGetValueStr_cp (ifcfg, "BSSID"); - if (value) { - value = g_strstrip (value); - g_object_set (s_wireless, NM_SETTING_WIRELESS_BSSID, value, NULL); - g_free (value); - } - - value = svGetValueStr_cp (ifcfg, "CHANNEL"); - if (value) { - chan = _nm_utils_ascii_str_to_int64 (value, 10, 1, 196, 0); - if (chan == 0) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid wireless channel '%s'", value); - g_free (value); - goto error; - } - g_object_set (s_wireless, NM_SETTING_WIRELESS_CHANNEL, (guint32) chan, NULL); - g_free (value); - } - - value = svGetValueStr_cp (ifcfg, "BAND"); - if (value) { - if (!strcmp (value, "a")) { - if (chan && chan <= 14) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Band '%s' invalid for channel %u", value, (guint32) chan); - g_free (value); - goto error; - } - } else if (!strcmp (value, "bg")) { - if (chan && chan > 14) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Band '%s' invalid for channel %u", value, (guint32) chan); - g_free (value); - goto error; - } - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid wireless band '%s'", value); - g_free (value); - goto error; - } - g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, value, NULL); - g_free (value); - } else if (chan > 0) { - if (chan > 14) - g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "a", NULL); - else - g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "bg", NULL); - } - - value = svGetValueStr_cp (ifcfg, "MTU"); - if (value) { - int mtu; - - mtu = _nm_utils_ascii_str_to_int64 (value, 10, 0, 50000, -1); - if (mtu == -1) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid wireless MTU '%s'", value); - g_free (value); - goto error; - } - g_object_set (s_wireless, NM_SETTING_WIRELESS_MTU, (guint) mtu, NULL); - g_free (value); - } - - g_object_set (s_wireless, - NM_SETTING_WIRELESS_HIDDEN, - svGetValueBoolean (ifcfg, "SSID_HIDDEN", FALSE), - NULL); - - cvalue = svGetValue (ifcfg, "POWERSAVE", &value); - if (cvalue) { - if (!strcmp (cvalue, "default")) - powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT; - else if (!strcmp (cvalue, "ignore")) - powersave = NM_SETTING_WIRELESS_POWERSAVE_IGNORE; - else if (!strcmp (cvalue, "disable") || !strcmp (cvalue, "no")) - powersave = NM_SETTING_WIRELESS_POWERSAVE_DISABLE; - else if (!strcmp (cvalue, "enable") || !strcmp (cvalue, "yes")) - powersave = NM_SETTING_WIRELESS_POWERSAVE_ENABLE; - else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid POWERSAVE value '%s'", cvalue); - g_free (value); - goto error; - } - g_free (value); - } - - g_object_set (s_wireless, - NM_SETTING_WIRELESS_POWERSAVE, - powersave, - NULL); - - cvalue = svGetValue (ifcfg, "MAC_ADDRESS_RANDOMIZATION", &value); - if (cvalue) { - if (strcmp (cvalue, "default") == 0) - mac_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; - else if (strcmp (cvalue, "never") == 0) - mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER; - else if (strcmp (cvalue, "always") == 0) - mac_randomization = NM_SETTING_MAC_RANDOMIZATION_ALWAYS; - else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid MAC_ADDRESS_RANDOMIZATION value '%s'", cvalue); - g_free (value); - goto error; - } - g_free (value); - } else - mac_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; - - g_object_set (s_wireless, - NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, - mac_randomization, - NULL); - - return NM_SETTING (s_wireless); + NMSettingWireless * s_wireless; + const char * cvalue; + char * value = NULL; + gint64 chan = 0; + NMSettingMacRandomization mac_randomization; + NMSettingWirelessPowersave powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT; + NMTernary ternary; + + s_wireless = NM_SETTING_WIRELESS(nm_setting_wireless_new()); + + value = svGetValueStr_cp(ifcfg, "HWADDR"); + if (value) { + value = g_strstrip(value); + g_object_set(s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, value, NULL); + g_free(value); + } + + value = svGetValueStr_cp(ifcfg, "MACADDR"); + if (value) { + value = g_strstrip(value); + g_object_set(s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, value, NULL); + g_free(value); + } + + value = svGetValueStr_cp(ifcfg, "GENERATE_MAC_ADDRESS_MASK"); + g_object_set(s_wireless, NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK, value, NULL); + g_free(value); + + cvalue = svGetValueStr(ifcfg, "HWADDR_BLACKLIST", &value); + if (cvalue) { + gs_free const char **strv = NULL; + + strv = transform_hwaddr_blacklist(cvalue); + g_object_set(s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, strv, NULL); + g_free(value); + } + + value = svGetValueStr_cp(ifcfg, "ESSID"); + if (value) { + gs_unref_bytes GBytes *bytes = NULL; + gsize ssid_len = 0; + gsize value_len = strlen(value); + + if (value_len > 2 && (value_len % 2) == 0 && g_str_has_prefix(value, "0x") + && NM_STRCHAR_ALL(&value[2], ch, g_ascii_isxdigit(ch))) { + /* interpret the value as hex-digits iff value starts + * with "0x" followed by pairs of hex digits */ + bytes = nm_utils_hexstr2bin(&value[2]); + } else + bytes = g_bytes_new(value, value_len); + + ssid_len = g_bytes_get_size(bytes); + if (ssid_len > 32 || ssid_len == 0) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid SSID '%s' (size %zu not between 1 and 32 inclusive)", + value, + ssid_len); + g_free(value); + goto error; + } + + g_object_set(s_wireless, NM_SETTING_WIRELESS_SSID, bytes, NULL); + g_free(value); + } + + value = svGetValueStr_cp(ifcfg, "MODE"); + if (value) { + char * lcase; + const char *mode = NULL; + + lcase = g_ascii_strdown(value, -1); + g_free(value); + + if (!strcmp(lcase, "ad-hoc")) { + mode = "adhoc"; + } else if (!strcmp(lcase, "ap")) { + mode = "ap"; + } else if (!strcmp(lcase, "managed") || !strcmp(lcase, "auto")) { + mode = "infrastructure"; + } else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid mode '%s' (not 'Ad-Hoc', 'Ap', 'Managed', or 'Auto')", + lcase); + g_free(lcase); + goto error; + } + g_free(lcase); + + g_object_set(s_wireless, NM_SETTING_WIRELESS_MODE, mode, NULL); + } + + value = svGetValueStr_cp(ifcfg, "BSSID"); + if (value) { + value = g_strstrip(value); + g_object_set(s_wireless, NM_SETTING_WIRELESS_BSSID, value, NULL); + g_free(value); + } + + value = svGetValueStr_cp(ifcfg, "CHANNEL"); + if (value) { + chan = _nm_utils_ascii_str_to_int64(value, 10, 1, 196, 0); + if (chan == 0) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid wireless channel '%s'", + value); + g_free(value); + goto error; + } + g_object_set(s_wireless, NM_SETTING_WIRELESS_CHANNEL, (guint32) chan, NULL); + g_free(value); + } + + value = svGetValueStr_cp(ifcfg, "BAND"); + if (value) { + if (!strcmp(value, "a")) { + if (chan && chan <= 14) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Band '%s' invalid for channel %u", + value, + (guint32) chan); + g_free(value); + goto error; + } + } else if (!strcmp(value, "bg")) { + if (chan && chan > 14) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Band '%s' invalid for channel %u", + value, + (guint32) chan); + g_free(value); + goto error; + } + } else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid wireless band '%s'", + value); + g_free(value); + goto error; + } + g_object_set(s_wireless, NM_SETTING_WIRELESS_BAND, value, NULL); + g_free(value); + } else if (chan > 0) { + if (chan > 14) + g_object_set(s_wireless, NM_SETTING_WIRELESS_BAND, "a", NULL); + else + g_object_set(s_wireless, NM_SETTING_WIRELESS_BAND, "bg", NULL); + } + + value = svGetValueStr_cp(ifcfg, "MTU"); + if (value) { + int mtu; + + mtu = _nm_utils_ascii_str_to_int64(value, 10, 0, 50000, -1); + if (mtu == -1) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid wireless MTU '%s'", + value); + g_free(value); + goto error; + } + g_object_set(s_wireless, NM_SETTING_WIRELESS_MTU, (guint) mtu, NULL); + g_free(value); + } + + g_object_set(s_wireless, + NM_SETTING_WIRELESS_HIDDEN, + svGetValueBoolean(ifcfg, "SSID_HIDDEN", FALSE), + NULL); + + cvalue = svGetValue(ifcfg, "POWERSAVE", &value); + if (cvalue) { + if (!strcmp(cvalue, "default")) + powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT; + else if (!strcmp(cvalue, "ignore")) + powersave = NM_SETTING_WIRELESS_POWERSAVE_IGNORE; + else if (!strcmp(cvalue, "disable") || !strcmp(cvalue, "no")) + powersave = NM_SETTING_WIRELESS_POWERSAVE_DISABLE; + else if (!strcmp(cvalue, "enable") || !strcmp(cvalue, "yes")) + powersave = NM_SETTING_WIRELESS_POWERSAVE_ENABLE; + else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid POWERSAVE value '%s'", + cvalue); + g_free(value); + goto error; + } + g_free(value); + } + + g_object_set(s_wireless, NM_SETTING_WIRELESS_POWERSAVE, powersave, NULL); + + cvalue = svGetValue(ifcfg, "MAC_ADDRESS_RANDOMIZATION", &value); + if (cvalue) { + if (strcmp(cvalue, "default") == 0) + mac_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; + else if (strcmp(cvalue, "never") == 0) + mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER; + else if (strcmp(cvalue, "always") == 0) + mac_randomization = NM_SETTING_MAC_RANDOMIZATION_ALWAYS; + else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid MAC_ADDRESS_RANDOMIZATION value '%s'", + cvalue); + g_free(value); + goto error; + } + g_free(value); + } else + mac_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT; + + g_object_set(s_wireless, + NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, + mac_randomization, + NULL); + + ternary = svGetValueTernary(ifcfg, "AP_ISOLATION"); + if (ternary != NM_TERNARY_DEFAULT) { + g_object_set(s_wireless, NM_SETTING_WIRELESS_AP_ISOLATION, ternary, NULL); + } + + return NM_SETTING(s_wireless); error: - if (s_wireless) - g_object_unref (s_wireless); - return NULL; + if (s_wireless) + g_object_unref(s_wireless); + return NULL; } static NMConnection * -wireless_connection_from_ifcfg (const char *file, - shvarFile *ifcfg, - GError **error) +wireless_connection_from_ifcfg(const char *file, shvarFile *ifcfg, GError **error) { - NMConnection *connection = NULL; - NMSetting *con_setting = NULL; - NMSetting *wireless_setting = NULL; - NMSetting8021x *s_8021x = NULL; - GBytes *ssid; - NMSetting *security_setting = NULL; - gs_free char *ssid_utf8 = NULL; - const char *mode; - gboolean adhoc = FALSE; - GError *local = NULL; - - g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (ifcfg != NULL, NULL); - g_return_val_if_fail (!error || !*error, NULL); - - connection = nm_simple_connection_new (); - - /* Wireless */ - wireless_setting = make_wireless_setting (ifcfg, error); - if (!wireless_setting) { - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, wireless_setting); - - ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (wireless_setting)); - mode = nm_setting_wireless_get_mode (NM_SETTING_WIRELESS (wireless_setting)); - if (mode && !strcmp (mode, "adhoc")) - adhoc = TRUE; - - /* Wireless security */ - security_setting = make_wireless_security_setting (ifcfg, file, ssid, adhoc, &s_8021x, &local); - if (local) { - g_object_unref (connection); - g_propagate_error (error, local); - return NULL; - } - if (security_setting) { - nm_connection_add_setting (connection, security_setting); - if (s_8021x) - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - } - - if (ssid) - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); - - /* Connection */ - con_setting = make_connection_setting (file, - ifcfg, - NM_SETTING_WIRELESS_SETTING_NAME, - nm_str_not_empty (ssid_utf8) ?: "unmanaged", - NULL); - - if (!con_setting) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Failed to create connection setting"); - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, con_setting); - - return connection; + NMConnection * connection = NULL; + NMSetting * con_setting = NULL; + NMSetting * wireless_setting = NULL; + NMSetting8021x *s_8021x = NULL; + GBytes * ssid; + NMSetting * security_setting = NULL; + gs_free char * ssid_utf8 = NULL; + const char * mode; + gboolean adhoc = FALSE; + GError * local = NULL; + + g_return_val_if_fail(file != NULL, NULL); + g_return_val_if_fail(ifcfg != NULL, NULL); + g_return_val_if_fail(!error || !*error, NULL); + + connection = nm_simple_connection_new(); + + /* Wireless */ + wireless_setting = make_wireless_setting(ifcfg, error); + if (!wireless_setting) { + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, wireless_setting); + + ssid = nm_setting_wireless_get_ssid(NM_SETTING_WIRELESS(wireless_setting)); + mode = nm_setting_wireless_get_mode(NM_SETTING_WIRELESS(wireless_setting)); + if (mode && !strcmp(mode, "adhoc")) + adhoc = TRUE; + + /* Wireless security */ + security_setting = make_wireless_security_setting(ifcfg, file, ssid, adhoc, &s_8021x, &local); + if (local) { + g_object_unref(connection); + g_propagate_error(error, local); + return NULL; + } + if (security_setting) { + nm_connection_add_setting(connection, security_setting); + if (s_8021x) + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + } + + if (ssid) + ssid_utf8 = _nm_utils_ssid_to_utf8(ssid); + + /* Connection */ + con_setting = make_connection_setting(file, + ifcfg, + NM_SETTING_WIRELESS_SETTING_NAME, + nm_str_not_empty(ssid_utf8) ?: "unmanaged", + NULL); + + if (!con_setting) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to create connection setting"); + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, con_setting); + + return connection; } typedef struct { - const char *optname; - union { - guint32 u32; - NMTernary nmternary; - } v; - gboolean has_value; + const char *optname; + union { + guint32 u32; + NMTernary nmternary; + } v; + gboolean has_value; } NMEthtoolIfcfgOption; /* returns an 'iterator' to words * pointing to the next unprocessed option or NULL * in case of failure */ static const char ** -_next_ethtool_options_nmternary (const char **words, - NMEthtoolType ethtool_type, - NMEthtoolIfcfgOption *out_value) +_next_ethtool_options_nmternary(const char ** words, + NMEthtoolType ethtool_type, + NMEthtoolIfcfgOption *out_value) { - const char *opt; - const char *opt_val; - const NMEthtoolData *d = NULL; - NMTernary onoff = NM_TERNARY_DEFAULT; - - nm_assert (out_value); - - out_value->has_value = FALSE; - out_value->optname = NULL; - - if ( !words - || !words[0] - || !words[1]) - return NULL; - - opt = *words; - opt_val = *(++words); - - if (nm_streq0 (opt_val, "on")) - onoff = NM_TERNARY_TRUE; - else if (nm_streq0 (opt_val, "off")) - onoff = NM_TERNARY_FALSE; - - d = nms_ifcfg_rh_utils_get_ethtool_by_name (opt, ethtool_type); - if (!d) { - if (onoff != NM_TERNARY_DEFAULT) { - /* the next value is just the on/off argument. Skip it too. */ - ++words; - } - - /* silently ignore unsupported offloading features. */ - return words; - } - - if (onoff == NM_TERNARY_DEFAULT) { - PARSE_WARNING ("Expects on/off argument for feature '%s'", opt); - return words; - } - - out_value->has_value = TRUE; - out_value->optname = d->optname; - out_value->v.nmternary = onoff; - - return ++words; + const char * opt; + const char * opt_val; + const NMEthtoolData *d = NULL; + NMTernary onoff = NM_TERNARY_DEFAULT; + + nm_assert(out_value); + + out_value->has_value = FALSE; + out_value->optname = NULL; + + if (!words || !words[0] || !words[1]) + return NULL; + + opt = *words; + opt_val = *(++words); + + if (nm_streq0(opt_val, "on")) + onoff = NM_TERNARY_TRUE; + else if (nm_streq0(opt_val, "off")) + onoff = NM_TERNARY_FALSE; + + d = nms_ifcfg_rh_utils_get_ethtool_by_name(opt, ethtool_type); + if (!d) { + if (onoff != NM_TERNARY_DEFAULT) { + /* the next value is just the on/off argument. Skip it too. */ + ++words; + } + + /* silently ignore unsupported offloading features. */ + return words; + } + + if (onoff == NM_TERNARY_DEFAULT) { + PARSE_WARNING("Expects on/off argument for feature '%s'", opt); + return words; + } + + out_value->has_value = TRUE; + out_value->optname = d->optname; + out_value->v.nmternary = onoff; + + return ++words; } /* returns an 'iterator' to words * pointing to the next unprocessed option or NULL * in case of failure */ static const char ** -_next_ethtool_options_uint32 (const char **words, - NMEthtoolType ethtool_type, - NMEthtoolIfcfgOption *out_value) +_next_ethtool_options_uint32(const char ** words, + NMEthtoolType ethtool_type, + NMEthtoolIfcfgOption *out_value) { - gint64 i64; - const char *opt; - const char *opt_val; - const NMEthtoolData *d = NULL; + gint64 i64; + const char * opt; + const char * opt_val; + const NMEthtoolData *d = NULL; - nm_assert (out_value); + nm_assert(out_value); - out_value->has_value = FALSE; - out_value->optname = NULL; + out_value->has_value = FALSE; + out_value->optname = NULL; - if ( !words - || !words[0] - || !words[1]) - return NULL; + if (!words || !words[0] || !words[1]) + return NULL; - opt = *words; - opt_val = *(++words); + opt = *words; + opt_val = *(++words); - i64 = _nm_utils_ascii_str_to_int64 (opt_val, 10, 0, G_MAXUINT32, -1); + i64 = _nm_utils_ascii_str_to_int64(opt_val, 10, 0, G_MAXUINT32, -1); - d = nms_ifcfg_rh_utils_get_ethtool_by_name (opt, ethtool_type); - if (!d) { - if (i64 != -1) { - /* the next value is just the on/off argument. Skip it too. */ - ++words; - } + d = nms_ifcfg_rh_utils_get_ethtool_by_name(opt, ethtool_type); + if (!d) { + if (i64 != -1) { + /* the next value is just the on/off argument. Skip it too. */ + ++words; + } - /* silently ignore unsupported offloading features. */ - return words; - } + /* silently ignore unsupported offloading features. */ + return words; + } - out_value->has_value = TRUE; - out_value->optname = d->optname; - out_value->v.u32 = (guint32) i64; + out_value->has_value = TRUE; + out_value->optname = d->optname; + out_value->v.u32 = (guint32) i64; - return ++words; + return ++words; } -static -NM_UTILS_STRING_TABLE_LOOKUP_DEFINE ( - _get_ethtool_type_by_name, - NMEthtoolType, - { nm_assert (name); }, - { return NM_ETHTOOL_TYPE_UNKNOWN; }, - { "--coalesce", NM_ETHTOOL_TYPE_COALESCE }, - { "--features", NM_ETHTOOL_TYPE_FEATURE }, - { "--offload", NM_ETHTOOL_TYPE_FEATURE }, - { "--set-ring", NM_ETHTOOL_TYPE_RING }, - { "-C", NM_ETHTOOL_TYPE_COALESCE }, - { "-G", NM_ETHTOOL_TYPE_RING }, - { "-K", NM_ETHTOOL_TYPE_FEATURE }, -); +static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( + _get_ethtool_type_by_name, + NMEthtoolType, + { nm_assert(name); }, + { return NM_ETHTOOL_TYPE_UNKNOWN; }, + {"--coalesce", NM_ETHTOOL_TYPE_COALESCE}, + {"--features", NM_ETHTOOL_TYPE_FEATURE}, + {"--offload", NM_ETHTOOL_TYPE_FEATURE}, + {"--set-ring", NM_ETHTOOL_TYPE_RING}, + {"-C", NM_ETHTOOL_TYPE_COALESCE}, + {"-G", NM_ETHTOOL_TYPE_RING}, + {"-K", NM_ETHTOOL_TYPE_FEATURE}, ); static void -parse_ethtool_option (const char *value, - NMSettingWiredWakeOnLan *out_flags, - char **out_password, - gboolean *out_autoneg, - guint32 *out_speed, - const char **out_duplex, - NMSettingEthtool **out_s_ethtool) +parse_ethtool_option(const char * value, + NMSettingWiredWakeOnLan *out_flags, + char ** out_password, + gboolean * out_autoneg, + guint32 * out_speed, + const char ** out_duplex, + NMSettingEthtool ** out_s_ethtool) { - guint i; - const char **w_iter; - NMEthtoolIfcfgOption ifcfg_option; - gs_free const char **words = NULL; - NMEthtoolType ethtool_type = NM_ETHTOOL_TYPE_UNKNOWN; - - words = nm_utils_strsplit_set (value, " \t\n"); - if (!words) - return; - - if (words[0]) - ethtool_type = _get_ethtool_type_by_name (words[0]); - - if (ethtool_type != NM_ETHTOOL_TYPE_UNKNOWN) { - if (!words[1]) { - /* first argument must be the interface name. This is invalid. */ - return; - } - - if (!*out_s_ethtool) - *out_s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ()); - - /* skip ethtool type && interface name */ - w_iter = &words[2]; - - while (w_iter && *w_iter) { - if (ethtool_type == NM_ETHTOOL_TYPE_FEATURE) { - w_iter = _next_ethtool_options_nmternary (w_iter, - ethtool_type, - &ifcfg_option); - - if (ifcfg_option.has_value) { - nm_setting_option_set_boolean (NM_SETTING (*out_s_ethtool), - ifcfg_option.optname, - ifcfg_option.v.nmternary != NM_TERNARY_FALSE); - } - } - if (NM_IN_SET (ethtool_type, - NM_ETHTOOL_TYPE_COALESCE, - NM_ETHTOOL_TYPE_RING)) { - w_iter = _next_ethtool_options_uint32 (w_iter, - ethtool_type, - &ifcfg_option); - - if (ifcfg_option.has_value) { - nm_setting_option_set_uint32 (NM_SETTING (*out_s_ethtool), - ifcfg_option.optname, - ifcfg_option.v.u32); - } - } - } - - return; - } - - /* /sbin/ethtool -s ${REALDEVICE} $opts */ - for (i = 0; words[i]; ) { - const char *opt = words[i]; - const char *opt_val = words[++i]; - - if (nm_streq (opt, "autoneg")) { - if (!opt_val) { - PARSE_WARNING ("Auto-negotiation option missing"); - break; - } - i++; - - if (nm_streq (opt_val, "off")) - *out_autoneg = FALSE; - else if (nm_streq (opt_val, "on")) - *out_autoneg = TRUE; - else - PARSE_WARNING ("Auto-negotiation unknown value: %s", opt_val); - continue; - } - - if (nm_streq (opt, "speed")) { - guint32 speed; - - if (!opt_val) { - PARSE_WARNING ("Speed option missing"); - break; - } - i++; - - speed = _nm_utils_ascii_str_to_int64 (opt_val, 10, 0, G_MAXUINT32, 0); - if (errno == 0) - *out_speed = speed; - else - PARSE_WARNING ("Speed value '%s' is invalid", opt_val); - continue; - } - - if (nm_streq (opt, "duplex")) { - if (!opt_val) { - PARSE_WARNING ("Duplex option missing"); - break; - } - i++; - - if (nm_streq (opt_val, "half")) - *out_duplex = "half"; - else if (nm_streq (opt_val, "full")) - *out_duplex = "full"; - else - PARSE_WARNING ("Duplex unknown value: %s", opt_val); - continue; - } - - if (nm_streq (opt, "wol")) { - NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; - - if (!opt_val) { - PARSE_WARNING ("Wake-on-LAN options missing"); - break; - } - i++; - - for (; *opt_val; opt_val++) { - switch (*opt_val) { - case 'p': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_PHY; - break; - case 'u': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST; - break; - case 'm': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST; - break; - case 'b': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST; - break; - case 'a': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_ARP; - break; - case 'g': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC; - break; - case 's': - break; - case 'd': - wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; - break; - default: - PARSE_WARNING ("unrecognized Wake-on-LAN option '%c'", *opt_val); - } - } - - *out_flags = wol_flags; - continue; - } - - if (nm_streq (opt, "sopass")) { - if (!opt_val) { - PARSE_WARNING ("Wake-on-LAN password missing"); - break; - } - i++; - - if (nm_utils_hwaddr_valid (opt_val, ETH_ALEN)) { - nm_clear_g_free (out_password); - *out_password = g_strdup (opt_val); - } else - PARSE_WARNING ("Wake-on-LAN password '%s' is invalid", opt_val); - continue; - } - - /* Silently skip unknown options */ - } + guint i; + const char ** w_iter; + NMEthtoolIfcfgOption ifcfg_option; + gs_free const char **words = NULL; + NMEthtoolType ethtool_type = NM_ETHTOOL_TYPE_UNKNOWN; + + words = nm_utils_strsplit_set(value, " \t\n"); + if (!words) + return; + + if (words[0]) + ethtool_type = _get_ethtool_type_by_name(words[0]); + + if (ethtool_type != NM_ETHTOOL_TYPE_UNKNOWN) { + if (!words[1]) { + /* first argument must be the interface name. This is invalid. */ + return; + } + + if (!*out_s_ethtool) + *out_s_ethtool = NM_SETTING_ETHTOOL(nm_setting_ethtool_new()); + + /* skip ethtool type && interface name */ + w_iter = &words[2]; + + while (w_iter && *w_iter) { + if (ethtool_type == NM_ETHTOOL_TYPE_FEATURE) { + w_iter = _next_ethtool_options_nmternary(w_iter, ethtool_type, &ifcfg_option); + + if (ifcfg_option.has_value) { + nm_setting_option_set_boolean(NM_SETTING(*out_s_ethtool), + ifcfg_option.optname, + ifcfg_option.v.nmternary != NM_TERNARY_FALSE); + } + } + if (NM_IN_SET(ethtool_type, NM_ETHTOOL_TYPE_COALESCE, NM_ETHTOOL_TYPE_RING)) { + w_iter = _next_ethtool_options_uint32(w_iter, ethtool_type, &ifcfg_option); + + if (ifcfg_option.has_value) { + nm_setting_option_set_uint32(NM_SETTING(*out_s_ethtool), + ifcfg_option.optname, + ifcfg_option.v.u32); + } + } + } + + return; + } + + /* /sbin/ethtool -s ${REALDEVICE} $opts */ + for (i = 0; words[i];) { + const char *opt = words[i]; + const char *opt_val = words[++i]; + + if (nm_streq(opt, "autoneg")) { + if (!opt_val) { + PARSE_WARNING("Auto-negotiation option missing"); + break; + } + i++; + + if (nm_streq(opt_val, "off")) + *out_autoneg = FALSE; + else if (nm_streq(opt_val, "on")) + *out_autoneg = TRUE; + else + PARSE_WARNING("Auto-negotiation unknown value: %s", opt_val); + continue; + } + + if (nm_streq(opt, "speed")) { + guint32 speed; + + if (!opt_val) { + PARSE_WARNING("Speed option missing"); + break; + } + i++; + + speed = _nm_utils_ascii_str_to_int64(opt_val, 10, 0, G_MAXUINT32, 0); + if (errno == 0) + *out_speed = speed; + else + PARSE_WARNING("Speed value '%s' is invalid", opt_val); + continue; + } + + if (nm_streq(opt, "duplex")) { + if (!opt_val) { + PARSE_WARNING("Duplex option missing"); + break; + } + i++; + + if (nm_streq(opt_val, "half")) + *out_duplex = "half"; + else if (nm_streq(opt_val, "full")) + *out_duplex = "full"; + else + PARSE_WARNING("Duplex unknown value: %s", opt_val); + continue; + } + + if (nm_streq(opt, "wol")) { + NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; + + if (!opt_val) { + PARSE_WARNING("Wake-on-LAN options missing"); + break; + } + i++; + + for (; *opt_val; opt_val++) { + switch (*opt_val) { + case 'p': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_PHY; + break; + case 'u': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST; + break; + case 'm': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST; + break; + case 'b': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST; + break; + case 'a': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_ARP; + break; + case 'g': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC; + break; + case 's': + break; + case 'd': + wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; + break; + default: + PARSE_WARNING("unrecognized Wake-on-LAN option '%c'", *opt_val); + } + } + + *out_flags = wol_flags; + continue; + } + + if (nm_streq(opt, "sopass")) { + if (!opt_val) { + PARSE_WARNING("Wake-on-LAN password missing"); + break; + } + i++; + + if (nm_utils_hwaddr_valid(opt_val, ETH_ALEN)) { + nm_clear_g_free(out_password); + *out_password = g_strdup(opt_val); + } else + PARSE_WARNING("Wake-on-LAN password '%s' is invalid", opt_val); + continue; + } + + /* Silently skip unknown options */ + } } static GPtrArray * -read_routing_rules_parse (shvarFile *ifcfg, - gboolean routes_read) +read_routing_rules_parse(shvarFile *ifcfg, gboolean routes_read) { - gs_unref_ptrarray GPtrArray *arr = NULL; - gs_free const char **keys = NULL; - guint i, len; - - keys = svGetKeysSorted (ifcfg, SV_KEY_TYPE_ROUTING_RULE4 | SV_KEY_TYPE_ROUTING_RULE6, &len); - if (len == 0) - return NULL; - - if (!routes_read) { - PARSE_WARNING ("'rule-' or 'rule6-' files are present; Policy routing rules (ROUTING_RULE*) settings are ignored"); - return NULL; - } - - arr = g_ptr_array_new_full (len, (GDestroyNotify) nm_ip_routing_rule_unref); - for (i = 0; i < len; i++) { - const char *key = keys[i]; - nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL; - gs_free_error GError *local = NULL; - gs_free char *value_to_free = NULL; - const char *value; - gboolean key_is_ipv4; - - key_is_ipv4 = (key[NM_STRLEN ("ROUTING_RULE")] == '_'); - nm_assert ( key_is_ipv4 == NM_STR_HAS_PREFIX (key, "ROUTING_RULE_")); - nm_assert ((!key_is_ipv4) == NM_STR_HAS_PREFIX (key, "ROUTING_RULE6_")); - - value = svGetValueStr (ifcfg, key, &value_to_free); - if (!value) - continue; - - rule = nm_ip_routing_rule_from_string (value, - NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE - | (key_is_ipv4 - ? NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET - : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6), - NULL, - &local); - if (!rule) { - PARSE_WARNING ("invalid routing rule %s=\"%s\": %s", key, value, local->message); - continue; - } - - g_ptr_array_add (arr, g_steal_pointer (&rule)); - } - - if (arr->len == 0) - return NULL; - - return g_steal_pointer (&arr); + gs_unref_ptrarray GPtrArray *arr = NULL; + gs_free const char ** keys = NULL; + guint i, len; + + keys = svGetKeysSorted(ifcfg, SV_KEY_TYPE_ROUTING_RULE4 | SV_KEY_TYPE_ROUTING_RULE6, &len); + if (len == 0) + return NULL; + + if (!routes_read) { + PARSE_WARNING("'rule-' or 'rule6-' files are present; Policy routing rules (ROUTING_RULE*) " + "settings are ignored"); + return NULL; + } + + arr = g_ptr_array_new_full(len, (GDestroyNotify) nm_ip_routing_rule_unref); + for (i = 0; i < len; i++) { + const char * key = keys[i]; + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL; + gs_free_error GError *local = NULL; + gs_free char * value_to_free = NULL; + const char * value; + gboolean key_is_ipv4; + + key_is_ipv4 = (key[NM_STRLEN("ROUTING_RULE")] == '_'); + nm_assert(key_is_ipv4 == NM_STR_HAS_PREFIX(key, "ROUTING_RULE_")); + nm_assert((!key_is_ipv4) == NM_STR_HAS_PREFIX(key, "ROUTING_RULE6_")); + + value = svGetValueStr(ifcfg, key, &value_to_free); + if (!value) + continue; + + rule = nm_ip_routing_rule_from_string( + value, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | (key_is_ipv4 ? NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET + : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6), + NULL, + &local); + if (!rule) { + PARSE_WARNING("invalid routing rule %s=\"%s\": %s", key, value, local->message); + continue; + } + + g_ptr_array_add(arr, g_steal_pointer(&rule)); + } + + if (arr->len == 0) + return NULL; + + return g_steal_pointer(&arr); } static void -read_routing_rules (shvarFile *ifcfg, - gboolean routes_read, - NMSettingIPConfig *s_ip4, - NMSettingIPConfig *s_ip6) +read_routing_rules(shvarFile * ifcfg, + gboolean routes_read, + NMSettingIPConfig *s_ip4, + NMSettingIPConfig *s_ip6) { - gs_unref_ptrarray GPtrArray *routing_rules = NULL; - guint i; + gs_unref_ptrarray GPtrArray *routing_rules = NULL; + guint i; - routing_rules = read_routing_rules_parse (ifcfg, routes_read); - if (!routing_rules) - return; + routing_rules = read_routing_rules_parse(ifcfg, routes_read); + if (!routing_rules) + return; - for (i = 0; i < routing_rules->len; i++) { - NMIPRoutingRule *rule = routing_rules->pdata[i]; + for (i = 0; i < routing_rules->len; i++) { + NMIPRoutingRule *rule = routing_rules->pdata[i]; - nm_setting_ip_config_add_routing_rule ( (nm_ip_routing_rule_get_addr_family (rule) == AF_INET) - ? s_ip4 - : s_ip6, - rule); - } + nm_setting_ip_config_add_routing_rule( + (nm_ip_routing_rule_get_addr_family(rule) == AF_INET) ? s_ip4 : s_ip6, + rule); + } } static void -parse_ethtool_options (shvarFile *ifcfg, NMConnection *connection) +parse_ethtool_options(shvarFile *ifcfg, NMConnection *connection) { - NMSettingWired *s_wired; - gs_unref_object NMSettingEthtool *s_ethtool = NULL; - NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT; - gs_free char *ethtool_opts_free = NULL; - const char *ethtool_opts; - gs_free char *wol_password = NULL; - gs_free char *wol_value_free = NULL; - const char *tmp; - gboolean autoneg = FALSE; - guint32 speed = 0; - const char *duplex = NULL; - gboolean wired_found = FALSE; - - ethtool_opts = svGetValue (ifcfg, "ETHTOOL_OPTS", ðtool_opts_free); - if (ethtool_opts) { - wired_found = TRUE; - /* WAKE_ON_LAN_IGNORE is inferred from a specified but empty ETHTOOL_OPTS */ - if (!ethtool_opts[0]) - wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; - else { - gs_free const char **opts = NULL; - const char *const *iter; - - opts = nm_utils_strsplit_set (ethtool_opts, ";"); - for (iter = opts; iter && iter[0]; iter++) { - /* in case of repeated wol_passwords, parse_ethtool_option() - * will do the right thing and clear wol_password before resetting. */ - parse_ethtool_option (iter[0], - &wol_flags, - &wol_password, - &autoneg, - &speed, - &duplex, - &s_ethtool); - } - } - } - - /* ETHTOOL_WAKE_ON_LAN = ignore overrides WoL settings in ETHTOOL_OPTS */ - tmp = svGetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN", &wol_value_free); - if (tmp) - wired_found = TRUE; - if (nm_streq0 (tmp, "ignore")) - wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; - else if (tmp) - PARSE_WARNING ("invalid ETHTOOL_WAKE_ON_LAN value '%s'", tmp); - - if ( wol_password - && !NM_FLAGS_HAS (wol_flags, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) { - PARSE_WARNING ("Wake-on-LAN password not expected"); - nm_clear_g_free (&wol_password); - } - - s_wired = nm_connection_get_setting_wired (connection); - if (!s_wired && wired_found) { - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - } - if (s_wired) { - g_object_set (s_wired, - NM_SETTING_WIRED_WAKE_ON_LAN, wol_flags, - NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, wol_password, - NM_SETTING_WIRED_AUTO_NEGOTIATE, autoneg, - NM_SETTING_WIRED_SPEED, speed, - NM_SETTING_WIRED_DUPLEX, duplex, - NULL); - } - - if (s_ethtool) { - nm_connection_add_setting (connection, - NM_SETTING (g_steal_pointer (&s_ethtool))); - } + NMSettingWired *s_wired; + gs_unref_object NMSettingEthtool *s_ethtool = NULL; + NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT; + gs_free char * ethtool_opts_free = NULL; + const char * ethtool_opts; + gs_free char * wol_password = NULL; + gs_free char * wol_value_free = NULL; + const char * tmp; + gboolean autoneg = FALSE; + guint32 speed = 0; + const char * duplex = NULL; + gboolean wired_found = FALSE; + + ethtool_opts = svGetValue(ifcfg, "ETHTOOL_OPTS", ðtool_opts_free); + if (ethtool_opts) { + wired_found = TRUE; + /* WAKE_ON_LAN_IGNORE is inferred from a specified but empty ETHTOOL_OPTS */ + if (!ethtool_opts[0]) + wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; + else { + gs_free const char **opts = NULL; + const char *const * iter; + + opts = nm_utils_strsplit_set(ethtool_opts, ";"); + for (iter = opts; iter && iter[0]; iter++) { + /* in case of repeated wol_passwords, parse_ethtool_option() + * will do the right thing and clear wol_password before resetting. */ + parse_ethtool_option(iter[0], + &wol_flags, + &wol_password, + &autoneg, + &speed, + &duplex, + &s_ethtool); + } + } + } + + /* ETHTOOL_WAKE_ON_LAN = ignore overrides WoL settings in ETHTOOL_OPTS */ + tmp = svGetValue(ifcfg, "ETHTOOL_WAKE_ON_LAN", &wol_value_free); + if (tmp) + wired_found = TRUE; + if (nm_streq0(tmp, "ignore")) + wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; + else if (tmp) + PARSE_WARNING("invalid ETHTOOL_WAKE_ON_LAN value '%s'", tmp); + + if (wol_password && !NM_FLAGS_HAS(wol_flags, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) { + PARSE_WARNING("Wake-on-LAN password not expected"); + nm_clear_g_free(&wol_password); + } + + s_wired = nm_connection_get_setting_wired(connection); + if (!s_wired && wired_found) { + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + } + if (s_wired) { + g_object_set(s_wired, + NM_SETTING_WIRED_WAKE_ON_LAN, + wol_flags, + NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, + wol_password, + NM_SETTING_WIRED_AUTO_NEGOTIATE, + autoneg, + NM_SETTING_WIRED_SPEED, + speed, + NM_SETTING_WIRED_DUPLEX, + duplex, + NULL); + } + + if (s_ethtool) { + nm_connection_add_setting(connection, NM_SETTING(g_steal_pointer(&s_ethtool))); + } } static NMSetting * -make_wired_setting (shvarFile *ifcfg, - const char *file, - NMSetting8021x **s_8021x, - GError **error) +make_wired_setting(shvarFile *ifcfg, const char *file, NMSetting8021x **s_8021x, GError **error) { - gs_unref_object NMSettingWired *s_wired = NULL; - const char *cvalue; - gs_free char *value = NULL; - gboolean found = FALSE; - - s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); - - cvalue = svGetValue (ifcfg, "MTU", &value); - if (cvalue) { - int mtu; - - mtu = _nm_utils_ascii_str_to_int64 (cvalue, 0, 0, 65535, -1); - if (mtu >= 0) - g_object_set (s_wired, NM_SETTING_WIRED_MTU, (guint) mtu, NULL); - else - PARSE_WARNING ("invalid MTU '%s'", cvalue); - nm_clear_g_free (&value); - found = TRUE; - } - - value = svGetValue_cp (ifcfg, "HWADDR"); - if (value) { - if (value[0] != '\0') { - value = g_strstrip (value); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, value, NULL); - } - nm_clear_g_free (&value); - found = TRUE; - } - - cvalue = svGetValue (ifcfg, "SUBCHANNELS", &value); - if (cvalue) { - if (cvalue[0] != '\0') { - const char *p = cvalue; - gboolean success = TRUE; - - /* basic sanity checks */ - while (*p) { - if (!g_ascii_isxdigit (*p) && (*p != ',') && (*p != '.')) { - PARSE_WARNING ("invalid SUBCHANNELS '%s'", cvalue); - success = FALSE; - break; - } - p++; - } - - if (success) { - gs_free const char **chans = NULL; - guint32 num_chans; - - chans = nm_utils_strsplit_set (cvalue, ","); - num_chans = NM_PTRARRAY_LEN (chans); - if (num_chans < 2 || num_chans > 3) { - PARSE_WARNING ("invalid SUBCHANNELS '%s' (%u channels, 2 or 3 expected)", - cvalue, (unsigned) NM_PTRARRAY_LEN (chans)); - } else - g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, chans, NULL); - } - } - nm_clear_g_free (&value); - found = TRUE; - } - - cvalue = svGetValue (ifcfg, "PORTNAME", &value); - if (cvalue) { - if (cvalue[0] != '\0') - nm_setting_wired_add_s390_option (s_wired, "portname", cvalue); - found = TRUE; - nm_clear_g_free (&value); - } - - cvalue = svGetValue (ifcfg, "CTCPROT", &value); - if (cvalue) { - if (cvalue[0] != '\0') - nm_setting_wired_add_s390_option (s_wired, "ctcprot", cvalue); - nm_clear_g_free (&value); - found = TRUE; - } - - cvalue = svGetValue (ifcfg, "NETTYPE", &value); - if (cvalue) { - if (NM_IN_STRSET (cvalue, "qeth", "lcs", "ctc")) - g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, cvalue, NULL); - else - PARSE_WARNING ("unknown s390 NETTYPE '%s'", cvalue); - nm_clear_g_free (&value); - found = TRUE; - } - - cvalue = svGetValue (ifcfg, "OPTIONS", &value); - if (cvalue) - found = TRUE; - if (cvalue && cvalue[0]) { - gs_free const char **options = NULL; - gsize i; - - options = nm_utils_escaped_tokens_split (cvalue, NM_ASCII_SPACES); - for (i = 0; options && options[i]; i++) { - const char *line = options[i]; - const char *equals; - gboolean valid = FALSE; - - equals = strchr (line, '='); - if (equals) { - ((char *) equals)[0] = '\0'; - valid = nm_setting_wired_add_s390_option (s_wired, line, equals + 1); - } - if (!valid) - PARSE_WARNING ("invalid s390 OPTION '%s'", line); - } - found = TRUE; - } - nm_clear_g_free (&value); - - cvalue = svGetValueStr (ifcfg, "MACADDR", &value); - if (cvalue) { - if (cvalue[0] != '\0') { - g_object_set (s_wired, - NM_SETTING_WIRED_CLONED_MAC_ADDRESS, - cvalue, - NULL); - } - nm_clear_g_free (&value); - found = TRUE; - } - - cvalue = svGetValueStr (ifcfg, "GENERATE_MAC_ADDRESS_MASK", &value); - if (cvalue) { - if (cvalue[0] != '\0') { - g_object_set (s_wired, - NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK, - cvalue, - NULL); - } - nm_clear_g_free (&value); - found = TRUE; - } - - cvalue = svGetValueStr (ifcfg, "HWADDR_BLACKLIST", &value); - if (cvalue) { - gs_free const char **strv = NULL; - - strv = transform_hwaddr_blacklist (cvalue); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, strv, NULL); - nm_clear_g_free (&value); - found = TRUE; - } - - cvalue = svGetValue (ifcfg, "KEY_MGMT", &value); - if (cvalue) - found = TRUE; - if (cvalue && cvalue[0] != '\0') { - if (!strcmp (cvalue, "IEEE8021X")) { - *s_8021x = fill_8021x (ifcfg, file, cvalue, FALSE, error); - if (!*s_8021x) - return NULL; - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Unknown wired KEY_MGMT type '%s'", cvalue); - return NULL; - } - } - nm_clear_g_free (&value); - - if (!found) { - g_set_error (error, - NM_UTILS_ERROR, - NM_UTILS_ERROR_SETTING_MISSING, - "The setting is missing"); - return NULL; - } - - return (NMSetting *) g_steal_pointer (&s_wired); + gs_unref_object NMSettingWired *s_wired = NULL; + const char * cvalue; + gs_free char * value = NULL; + gboolean found = FALSE; + + s_wired = NM_SETTING_WIRED(nm_setting_wired_new()); + + cvalue = svGetValue(ifcfg, "MTU", &value); + if (cvalue) { + int mtu; + + mtu = _nm_utils_ascii_str_to_int64(cvalue, 0, 0, 65535, -1); + if (mtu >= 0) + g_object_set(s_wired, NM_SETTING_WIRED_MTU, (guint) mtu, NULL); + else + PARSE_WARNING("invalid MTU '%s'", cvalue); + nm_clear_g_free(&value); + found = TRUE; + } + + value = svGetValue_cp(ifcfg, "HWADDR"); + if (value) { + if (value[0] != '\0') { + value = g_strstrip(value); + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, value, NULL); + } + nm_clear_g_free(&value); + found = TRUE; + } + + cvalue = svGetValue(ifcfg, "SUBCHANNELS", &value); + if (cvalue) { + if (cvalue[0] != '\0') { + const char *p = cvalue; + gboolean success = TRUE; + + /* basic sanity checks */ + while (*p) { + if (!g_ascii_isxdigit(*p) && (*p != ',') && (*p != '.')) { + PARSE_WARNING("invalid SUBCHANNELS '%s'", cvalue); + success = FALSE; + break; + } + p++; + } + + if (success) { + gs_free const char **chans = NULL; + guint32 num_chans; + + chans = nm_utils_strsplit_set(cvalue, ","); + num_chans = NM_PTRARRAY_LEN(chans); + if (num_chans < 2 || num_chans > 3) { + PARSE_WARNING("invalid SUBCHANNELS '%s' (%u channels, 2 or 3 expected)", + cvalue, + (unsigned) NM_PTRARRAY_LEN(chans)); + } else + g_object_set(s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, chans, NULL); + } + } + nm_clear_g_free(&value); + found = TRUE; + } + + cvalue = svGetValue(ifcfg, "PORTNAME", &value); + if (cvalue) { + if (cvalue[0] != '\0') + nm_setting_wired_add_s390_option(s_wired, "portname", cvalue); + found = TRUE; + nm_clear_g_free(&value); + } + + cvalue = svGetValue(ifcfg, "CTCPROT", &value); + if (cvalue) { + if (cvalue[0] != '\0') + nm_setting_wired_add_s390_option(s_wired, "ctcprot", cvalue); + nm_clear_g_free(&value); + found = TRUE; + } + + cvalue = svGetValue(ifcfg, "NETTYPE", &value); + if (cvalue) { + if (NM_IN_STRSET(cvalue, "qeth", "lcs", "ctc")) + g_object_set(s_wired, NM_SETTING_WIRED_S390_NETTYPE, cvalue, NULL); + else + PARSE_WARNING("unknown s390 NETTYPE '%s'", cvalue); + nm_clear_g_free(&value); + found = TRUE; + } + + cvalue = svGetValue(ifcfg, "OPTIONS", &value); + if (cvalue) + found = TRUE; + if (cvalue && cvalue[0]) { + gs_free const char **options = NULL; + gsize i; + + options = nm_utils_escaped_tokens_split(cvalue, NM_ASCII_SPACES); + for (i = 0; options && options[i]; i++) { + const char *line = options[i]; + const char *equals; + gboolean valid = FALSE; + + equals = strchr(line, '='); + if (equals) { + ((char *) equals)[0] = '\0'; + valid = nm_setting_wired_add_s390_option(s_wired, line, equals + 1); + } + if (!valid) + PARSE_WARNING("invalid s390 OPTION '%s'", line); + } + found = TRUE; + } + nm_clear_g_free(&value); + + cvalue = svGetValueStr(ifcfg, "MACADDR", &value); + if (cvalue) { + if (cvalue[0] != '\0') { + g_object_set(s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, cvalue, NULL); + } + nm_clear_g_free(&value); + found = TRUE; + } + + cvalue = svGetValueStr(ifcfg, "GENERATE_MAC_ADDRESS_MASK", &value); + if (cvalue) { + if (cvalue[0] != '\0') { + g_object_set(s_wired, NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK, cvalue, NULL); + } + nm_clear_g_free(&value); + found = TRUE; + } + + cvalue = svGetValueStr(ifcfg, "HWADDR_BLACKLIST", &value); + if (cvalue) { + gs_free const char **strv = NULL; + + strv = transform_hwaddr_blacklist(cvalue); + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, strv, NULL); + nm_clear_g_free(&value); + found = TRUE; + } + + cvalue = svGetValue(ifcfg, "KEY_MGMT", &value); + if (cvalue) + found = TRUE; + if (cvalue && cvalue[0] != '\0') { + if (!strcmp(cvalue, "IEEE8021X")) { + *s_8021x = fill_8021x(ifcfg, file, cvalue, FALSE, error); + if (!*s_8021x) + return NULL; + } else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Unknown wired KEY_MGMT type '%s'", + cvalue); + return NULL; + } + } + nm_clear_g_free(&value); + + if (!found) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_SETTING_MISSING, + "The setting is missing"); + return NULL; + } + + return (NMSetting *) g_steal_pointer(&s_wired); } static NMConnection * -wired_connection_from_ifcfg (const char *file, - shvarFile *ifcfg, - GError **error) +wired_connection_from_ifcfg(const char *file, shvarFile *ifcfg, GError **error) { - NMConnection *connection = NULL; - NMSetting *con_setting = NULL; - NMSetting *wired_setting = NULL; - NMSetting8021x *s_8021x = NULL; - GError *local = NULL; - - g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (ifcfg != NULL, NULL); - - connection = nm_simple_connection_new (); - - con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL, NULL); - if (!con_setting) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Failed to create connection setting"); - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, con_setting); - - wired_setting = make_wired_setting (ifcfg, file, &s_8021x, &local); - if (local && !g_error_matches (local, NM_UTILS_ERROR, NM_UTILS_ERROR_SETTING_MISSING)) { - g_propagate_error (error, local); - g_object_unref (connection); - return NULL; - } - g_clear_error (&local); - - if (wired_setting) - nm_connection_add_setting (connection, wired_setting); - - if (s_8021x) - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - return connection; + NMConnection * connection = NULL; + NMSetting * con_setting = NULL; + NMSetting * wired_setting = NULL; + NMSetting8021x *s_8021x = NULL; + GError * local = NULL; + + g_return_val_if_fail(file != NULL, NULL); + g_return_val_if_fail(ifcfg != NULL, NULL); + + connection = nm_simple_connection_new(); + + con_setting = make_connection_setting(file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL, NULL); + if (!con_setting) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to create connection setting"); + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, con_setting); + + wired_setting = make_wired_setting(ifcfg, file, &s_8021x, &local); + if (local && !g_error_matches(local, NM_UTILS_ERROR, NM_UTILS_ERROR_SETTING_MISSING)) { + g_propagate_error(error, local); + g_object_unref(connection); + return NULL; + } + g_clear_error(&local); + + if (wired_setting) + nm_connection_add_setting(connection, wired_setting); + + if (s_8021x) + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + return connection; } static gboolean -parse_infiniband_p_key (shvarFile *ifcfg, - int *out_p_key, - char **out_parent, - GError **error) +parse_infiniband_p_key(shvarFile *ifcfg, int *out_p_key, char **out_parent, GError **error) { - char *device = NULL, *physdev = NULL, *pkey_id = NULL; - char *ifname = NULL; - int id; - gboolean ret = FALSE; - - device = svGetValueStr_cp (ifcfg, "DEVICE"); - if (!device) { - PARSE_WARNING ("InfiniBand connection specified PKEY but not DEVICE"); - goto done; - } - - physdev = svGetValueStr_cp (ifcfg, "PHYSDEV"); - if (!physdev) { - PARSE_WARNING ("InfiniBand connection specified PKEY but not PHYSDEV"); - goto done; - } - - pkey_id = svGetValueStr_cp (ifcfg, "PKEY_ID"); - if (!pkey_id) { - PARSE_WARNING ("InfiniBand connection specified PKEY but not PKEY_ID"); - goto done; - } - - id = _nm_utils_ascii_str_to_int64 (pkey_id, 0, 0, 0xFFFF, -1); - if (id == -1) { - PARSE_WARNING ("invalid InfiniBand PKEY_ID '%s'", pkey_id); - goto done; - } - id = (id | 0x8000); - - ifname = g_strdup_printf ("%s.%04x", physdev, (unsigned) id); - if (strcmp (device, ifname) != 0) { - PARSE_WARNING ("InfiniBand DEVICE (%s) does not match PHYSDEV+PKEY_ID (%s)", - device, ifname); - goto done; - } - - *out_p_key = id; - *out_parent = g_strdup (physdev); - ret = TRUE; - - done: - g_free (device); - g_free (physdev); - g_free (pkey_id); - g_free (ifname); - - if (!ret) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Failed to create InfiniBand setting"); - } - return ret; + char * device = NULL, *physdev = NULL, *pkey_id = NULL; + char * ifname = NULL; + int id; + gboolean ret = FALSE; + + device = svGetValueStr_cp(ifcfg, "DEVICE"); + if (!device) { + PARSE_WARNING("InfiniBand connection specified PKEY but not DEVICE"); + goto done; + } + + physdev = svGetValueStr_cp(ifcfg, "PHYSDEV"); + if (!physdev) { + PARSE_WARNING("InfiniBand connection specified PKEY but not PHYSDEV"); + goto done; + } + + pkey_id = svGetValueStr_cp(ifcfg, "PKEY_ID"); + if (!pkey_id) { + PARSE_WARNING("InfiniBand connection specified PKEY but not PKEY_ID"); + goto done; + } + + id = _nm_utils_ascii_str_to_int64(pkey_id, 0, 0, 0xFFFF, -1); + if (id == -1) { + PARSE_WARNING("invalid InfiniBand PKEY_ID '%s'", pkey_id); + goto done; + } + id = (id | 0x8000); + + ifname = g_strdup_printf("%s.%04x", physdev, (unsigned) id); + if (strcmp(device, ifname) != 0) { + PARSE_WARNING("InfiniBand DEVICE (%s) does not match PHYSDEV+PKEY_ID (%s)", device, ifname); + goto done; + } + + *out_p_key = id; + *out_parent = g_strdup(physdev); + ret = TRUE; + +done: + g_free(device); + g_free(physdev); + g_free(pkey_id); + g_free(ifname); + + if (!ret) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to create InfiniBand setting"); + } + return ret; } static NMSetting * -make_infiniband_setting (shvarFile *ifcfg, - const char *file, - GError **error) +make_infiniband_setting(shvarFile *ifcfg, const char *file, GError **error) { - NMSettingInfiniband *s_infiniband; - char *value = NULL; - - s_infiniband = NM_SETTING_INFINIBAND (nm_setting_infiniband_new ()); - - value = svGetValueStr_cp (ifcfg, "MTU"); - if (value) { - int mtu; - - mtu = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1); - if (mtu >= 0) - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MTU, (guint) mtu, NULL); - else - PARSE_WARNING ("invalid MTU '%s'", value); - g_free (value); - } - - value = svGetValueStr_cp (ifcfg, "HWADDR"); - if (value) { - value = g_strstrip (value); - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, value, NULL); - g_free (value); - } - - if (svGetValueBoolean (ifcfg, "CONNECTED_MODE", FALSE)) - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", NULL); - else - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL); - - if (svGetValueBoolean (ifcfg, "PKEY", FALSE)) { - gs_free char *parent = NULL; - int p_key; - - if (!parse_infiniband_p_key (ifcfg, &p_key, &parent, error)) { - g_object_unref (s_infiniband); - return NULL; - } - - g_object_set (s_infiniband, - NM_SETTING_INFINIBAND_P_KEY, p_key, - NM_SETTING_INFINIBAND_PARENT, parent, - NULL); - } - - return (NMSetting *) s_infiniband; + NMSettingInfiniband *s_infiniband; + char * value = NULL; + + s_infiniband = NM_SETTING_INFINIBAND(nm_setting_infiniband_new()); + + value = svGetValueStr_cp(ifcfg, "MTU"); + if (value) { + int mtu; + + mtu = _nm_utils_ascii_str_to_int64(value, 0, 0, 65535, -1); + if (mtu >= 0) + g_object_set(s_infiniband, NM_SETTING_INFINIBAND_MTU, (guint) mtu, NULL); + else + PARSE_WARNING("invalid MTU '%s'", value); + g_free(value); + } + + value = svGetValueStr_cp(ifcfg, "HWADDR"); + if (value) { + value = g_strstrip(value); + g_object_set(s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, value, NULL); + g_free(value); + } + + if (svGetValueBoolean(ifcfg, "CONNECTED_MODE", FALSE)) + g_object_set(s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", NULL); + else + g_object_set(s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL); + + if (svGetValueBoolean(ifcfg, "PKEY", FALSE)) { + gs_free char *parent = NULL; + int p_key; + + if (!parse_infiniband_p_key(ifcfg, &p_key, &parent, error)) { + g_object_unref(s_infiniband); + return NULL; + } + + g_object_set(s_infiniband, + NM_SETTING_INFINIBAND_P_KEY, + p_key, + NM_SETTING_INFINIBAND_PARENT, + parent, + NULL); + } + + return (NMSetting *) s_infiniband; } static NMConnection * -infiniband_connection_from_ifcfg (const char *file, - shvarFile *ifcfg, - GError **error) +infiniband_connection_from_ifcfg(const char *file, shvarFile *ifcfg, GError **error) { - NMConnection *connection = NULL; - NMSetting *con_setting = NULL; - NMSetting *infiniband_setting = NULL; - - g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (ifcfg != NULL, NULL); - - connection = nm_simple_connection_new (); - - con_setting = make_connection_setting (file, ifcfg, NM_SETTING_INFINIBAND_SETTING_NAME, NULL, NULL); - if (!con_setting) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Failed to create connection setting"); - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, con_setting); - - infiniband_setting = make_infiniband_setting (ifcfg, file, error); - if (!infiniband_setting) { - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, infiniband_setting); - - return connection; + NMConnection *connection = NULL; + NMSetting * con_setting = NULL; + NMSetting * infiniband_setting = NULL; + + g_return_val_if_fail(file != NULL, NULL); + g_return_val_if_fail(ifcfg != NULL, NULL); + + connection = nm_simple_connection_new(); + + con_setting = + make_connection_setting(file, ifcfg, NM_SETTING_INFINIBAND_SETTING_NAME, NULL, NULL); + if (!con_setting) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to create connection setting"); + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, con_setting); + + infiniband_setting = make_infiniband_setting(ifcfg, file, error); + if (!infiniband_setting) { + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, infiniband_setting); + + return connection; } static void -handle_bond_option (NMSettingBond *s_bond, - const char *key, - const char *value) +handle_bond_option(NMSettingBond *s_bond, const char *key, const char *value) { - char *sanitized = NULL, *j; - const char *p = value; - - /* Remove any quotes or +/- from arp_ip_target */ - if (!g_strcmp0 (key, NM_SETTING_BOND_OPTION_ARP_IP_TARGET) && value && value[0]) { - if (*p == '\'' || *p == '"') - p++; - j = sanitized = g_malloc0 (strlen (p) + 1); - while (*p) { - if (*p != '+' && *p != '-' && *p != '\'' && *p != '"') - *j++ = *p; - p++; - } - } - - if (!nm_setting_bond_add_option (s_bond, key, sanitized ?: value)) - PARSE_WARNING ("invalid bonding option '%s' = %s", - key, sanitized ?: value); - g_free (sanitized); + char * sanitized = NULL, *j; + const char *p = value; + + /* Remove any quotes or +/- from arp_ip_target */ + if (!g_strcmp0(key, NM_SETTING_BOND_OPTION_ARP_IP_TARGET) && value && value[0]) { + if (*p == '\'' || *p == '"') + p++; + j = sanitized = g_malloc0(strlen(p) + 1); + while (*p) { + if (*p != '+' && *p != '-' && *p != '\'' && *p != '"') + *j++ = *p; + p++; + } + } + + if (!nm_setting_bond_add_option(s_bond, key, sanitized ?: value)) + PARSE_WARNING("invalid bonding option '%s' = %s", key, sanitized ?: value); + g_free(sanitized); } static NMSetting * -make_bond_setting (shvarFile *ifcfg, - const char *file, - GError **error) +make_bond_setting(shvarFile *ifcfg, const char *file, GError **error) { - NMSettingBond *s_bond; - gs_free char *value = NULL; - const char *v; - - v = svGetValueStr (ifcfg, "DEVICE", &value); - if (!v) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "mandatory DEVICE keyword missing"); - return NULL; - } - - s_bond = NM_SETTING_BOND (nm_setting_bond_new ()); - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "BONDING_OPTS", &value); - if (v) { - gs_free const char **items = NULL; - const char *const *iter; - - items = nm_utils_strsplit_set (v, " "); - for (iter = items; iter && *iter; iter++) { - gs_free char *key = NULL; - const char *val; - - val = strchr (*iter, '='); - if (!val) - continue; - key = g_strndup (*iter, val - *iter); - val++; - if (key[0] && val[0]) - handle_bond_option (s_bond, key, val); - } - } - - return (NMSetting *) s_bond; + NMSettingBond *s_bond; + gs_free char * value = NULL; + const char * v; + + v = svGetValueStr(ifcfg, "DEVICE", &value); + if (!v) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "mandatory DEVICE keyword missing"); + return NULL; + } + + s_bond = NM_SETTING_BOND(nm_setting_bond_new()); + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "BONDING_OPTS", &value); + if (v) { + gs_free const char **items = NULL; + const char *const * iter; + + items = nm_utils_strsplit_set(v, " "); + for (iter = items; iter && *iter; iter++) { + gs_free char *key = NULL; + const char * val; + + val = strchr(*iter, '='); + if (!val) + continue; + key = g_strndup(*iter, val - *iter); + val++; + if (key[0] && val[0]) + handle_bond_option(s_bond, key, val); + } + } + + return (NMSetting *) s_bond; } static NMConnection * -bond_connection_from_ifcfg (const char *file, - shvarFile *ifcfg, - GError **error) +bond_connection_from_ifcfg(const char *file, shvarFile *ifcfg, GError **error) { - NMConnection *connection = NULL; - NMSetting *con_setting = NULL; - NMSetting *bond_setting = NULL; - NMSetting *wired_setting = NULL; - NMSetting8021x *s_8021x = NULL; - GError *local = NULL; - - g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (ifcfg != NULL, NULL); - - connection = nm_simple_connection_new (); - - con_setting = make_connection_setting (file, ifcfg, NM_SETTING_BOND_SETTING_NAME, NULL, _("Bond")); - if (!con_setting) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Failed to create connection setting"); - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, con_setting); - - bond_setting = make_bond_setting (ifcfg, file, error); - if (!bond_setting) { - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, bond_setting); - - wired_setting = make_wired_setting (ifcfg, file, &s_8021x, &local); - if (local && !g_error_matches (local, NM_UTILS_ERROR, NM_UTILS_ERROR_SETTING_MISSING)) { - g_propagate_error (error, local); - g_object_unref (connection); - return NULL; - } - g_clear_error (&local); - - if (wired_setting) - nm_connection_add_setting (connection, wired_setting); - - if (s_8021x) - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - return connection; + NMConnection * connection = NULL; + NMSetting * con_setting = NULL; + NMSetting * bond_setting = NULL; + NMSetting * wired_setting = NULL; + NMSetting8021x *s_8021x = NULL; + GError * local = NULL; + + g_return_val_if_fail(file != NULL, NULL); + g_return_val_if_fail(ifcfg != NULL, NULL); + + connection = nm_simple_connection_new(); + + con_setting = + make_connection_setting(file, ifcfg, NM_SETTING_BOND_SETTING_NAME, NULL, _("Bond")); + if (!con_setting) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to create connection setting"); + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, con_setting); + + bond_setting = make_bond_setting(ifcfg, file, error); + if (!bond_setting) { + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, bond_setting); + + wired_setting = make_wired_setting(ifcfg, file, &s_8021x, &local); + if (local && !g_error_matches(local, NM_UTILS_ERROR, NM_UTILS_ERROR_SETTING_MISSING)) { + g_propagate_error(error, local); + g_object_unref(connection); + return NULL; + } + g_clear_error(&local); + + if (wired_setting) + nm_connection_add_setting(connection, wired_setting); + + if (s_8021x) + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + return connection; } static NMSetting * -make_team_setting (shvarFile *ifcfg, - const char *file, - GError **error) +make_team_setting(shvarFile *ifcfg, const char *file, GError **error) { - NMSetting *s_team; - gs_free char *value_device = NULL; - gs_free char *value = NULL; - - if (!svGetValueStr (ifcfg, "DEVICE", &value_device)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "mandatory DEVICE keyword missing"); - return NULL; - } - - s_team = nm_setting_team_new (); - g_object_set (s_team, - NM_SETTING_TEAM_CONFIG, - svGetValue (ifcfg, "TEAM_CONFIG", &value), - NULL); - return s_team; + NMSetting * s_team; + gs_free char *value_device = NULL; + gs_free char *value = NULL; + + if (!svGetValueStr(ifcfg, "DEVICE", &value_device)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "mandatory DEVICE keyword missing"); + return NULL; + } + + s_team = nm_setting_team_new(); + g_object_set(s_team, NM_SETTING_TEAM_CONFIG, svGetValue(ifcfg, "TEAM_CONFIG", &value), NULL); + return s_team; } static NMConnection * -team_connection_from_ifcfg (const char *file, - shvarFile *ifcfg, - GError **error) +team_connection_from_ifcfg(const char *file, shvarFile *ifcfg, GError **error) { - NMConnection *connection = NULL; - NMSetting *con_setting = NULL; - NMSetting *team_setting = NULL; - NMSetting *wired_setting = NULL; - NMSetting8021x *s_8021x = NULL; - GError *local = NULL; - - g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (ifcfg != NULL, NULL); - - connection = nm_simple_connection_new (); - - con_setting = make_connection_setting (file, ifcfg, NM_SETTING_TEAM_SETTING_NAME, NULL, _("Team")); - if (!con_setting) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Failed to create connection setting"); - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, con_setting); - - team_setting = make_team_setting (ifcfg, file, error); - if (!team_setting) { - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, team_setting); - - wired_setting = make_wired_setting (ifcfg, file, &s_8021x, &local); - if (local && !g_error_matches (local, NM_UTILS_ERROR, NM_UTILS_ERROR_SETTING_MISSING)) { - g_propagate_error (error, local); - g_object_unref (connection); - return NULL; - } - g_clear_error (&local); - - if (wired_setting) - nm_connection_add_setting (connection, wired_setting); - - if (s_8021x) - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - return connection; + NMConnection * connection = NULL; + NMSetting * con_setting = NULL; + NMSetting * team_setting = NULL; + NMSetting * wired_setting = NULL; + NMSetting8021x *s_8021x = NULL; + GError * local = NULL; + + g_return_val_if_fail(file != NULL, NULL); + g_return_val_if_fail(ifcfg != NULL, NULL); + + connection = nm_simple_connection_new(); + + con_setting = + make_connection_setting(file, ifcfg, NM_SETTING_TEAM_SETTING_NAME, NULL, _("Team")); + if (!con_setting) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to create connection setting"); + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, con_setting); + + team_setting = make_team_setting(ifcfg, file, error); + if (!team_setting) { + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, team_setting); + + wired_setting = make_wired_setting(ifcfg, file, &s_8021x, &local); + if (local && !g_error_matches(local, NM_UTILS_ERROR, NM_UTILS_ERROR_SETTING_MISSING)) { + g_propagate_error(error, local); + g_object_unref(connection); + return NULL; + } + g_clear_error(&local); + + if (wired_setting) + nm_connection_add_setting(connection, wired_setting); + + if (s_8021x) + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + return connection; } typedef enum { - BRIDGE_OPT_TYPE_MAIN, - BRIDGE_OPT_TYPE_OPTION, - BRIDGE_OPT_TYPE_PORT_MAIN, - BRIDGE_OPT_TYPE_PORT_OPTION, + BRIDGE_OPT_TYPE_MAIN, + BRIDGE_OPT_TYPE_OPTION, + BRIDGE_OPT_TYPE_PORT_MAIN, + BRIDGE_OPT_TYPE_PORT_OPTION, } BridgeOptType; -typedef void (*BridgeOptFunc) (NMSetting *setting, - gboolean stp, - const char *key, - const char *value, - BridgeOptType opt_type); +typedef void (*BridgeOptFunc)(NMSetting * setting, + gboolean stp, + const char * key, + const char * value, + BridgeOptType opt_type); static void -handle_bridge_option (NMSetting *setting, - gboolean stp, - const char *key, - const char *value, - BridgeOptType opt_type) +handle_bridge_option(NMSetting * setting, + gboolean stp, + const char * key, + const char * value, + BridgeOptType opt_type) { - static const struct { - const char *key; - const char *property_name; - BridgeOptType opt_type; - gboolean only_with_stp; - gboolean extended_bool; - } m/*etadata*/[] = { - { "DELAY", NM_SETTING_BRIDGE_FORWARD_DELAY, BRIDGE_OPT_TYPE_MAIN, .only_with_stp = TRUE }, - { "priority", NM_SETTING_BRIDGE_PRIORITY, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE }, - { "hello_time", NM_SETTING_BRIDGE_HELLO_TIME, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE }, - { "max_age", NM_SETTING_BRIDGE_MAX_AGE, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE }, - { "ageing_time", NM_SETTING_BRIDGE_AGEING_TIME, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_last_member_count", NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_last_member_interval", NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_membership_interval", NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_hash_max", NM_SETTING_BRIDGE_MULTICAST_HASH_MAX, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_querier", NM_SETTING_BRIDGE_MULTICAST_QUERIER, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_querier_interval", NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_query_interval", NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_query_response_interval", NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_query_use_ifaddr", NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_snooping", NM_SETTING_BRIDGE_MULTICAST_SNOOPING, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_router", NM_SETTING_BRIDGE_MULTICAST_ROUTER, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_startup_query_count", NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT, BRIDGE_OPT_TYPE_OPTION }, - { "multicast_startup_query_interval", NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL, BRIDGE_OPT_TYPE_OPTION }, - { "vlan_filtering", NM_SETTING_BRIDGE_VLAN_FILTERING, BRIDGE_OPT_TYPE_OPTION }, - { "default_pvid", NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, BRIDGE_OPT_TYPE_OPTION }, - { "group_address", NM_SETTING_BRIDGE_GROUP_ADDRESS, BRIDGE_OPT_TYPE_OPTION }, - { "group_fwd_mask", NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, BRIDGE_OPT_TYPE_OPTION }, - { "vlan_protocol", NM_SETTING_BRIDGE_VLAN_PROTOCOL, BRIDGE_OPT_TYPE_OPTION }, - { "vlan_stats_enabled", NM_SETTING_BRIDGE_VLAN_STATS_ENABLED, BRIDGE_OPT_TYPE_OPTION }, - { "priority", NM_SETTING_BRIDGE_PORT_PRIORITY, BRIDGE_OPT_TYPE_PORT_OPTION }, - { "path_cost", NM_SETTING_BRIDGE_PORT_PATH_COST, BRIDGE_OPT_TYPE_PORT_OPTION }, - { "hairpin_mode", NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, BRIDGE_OPT_TYPE_PORT_OPTION, .extended_bool = TRUE, }, - }; - const char *error_message = NULL; - int i; - gint64 v; - - for (i = 0; i < G_N_ELEMENTS (m); i++) { - GParamSpec *param_spec; - - if (opt_type != m[i].opt_type) - continue; - if (!nm_streq (key, m[i].key)) - continue; - if (m[i].only_with_stp && !stp) { - PARSE_WARNING ("'%s' invalid when STP is disabled", key); - return; - } - - param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), m[i].property_name); - switch (param_spec->value_type) { - case G_TYPE_BOOLEAN: - if (m[i].extended_bool) { - if (!g_ascii_strcasecmp (value, "on") || !g_ascii_strcasecmp (value, "yes") || !strcmp (value, "1")) - v = TRUE; - else if (!g_ascii_strcasecmp (value, "off") || !g_ascii_strcasecmp (value, "no")) - v = FALSE; - else { - error_message = "is not a boolean"; - goto warn; - } - } else { - v = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1); - if (v == -1) { - error_message = nm_strerror_native (errno); - goto warn; - } - } - if (!nm_g_object_set_property_boolean (G_OBJECT (setting), m[i].property_name, v, NULL)) { - error_message = "number is out of range"; - goto warn; - } - return; - case G_TYPE_UINT: - v = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT, -1); - if (v == -1) { - error_message = nm_strerror_native (errno); - goto warn; - } - if (!nm_g_object_set_property_uint (G_OBJECT (setting), m[i].property_name, v, NULL)) { - error_message = "number is out of range"; - goto warn; - } - return; - case G_TYPE_UINT64: { - guint64 vu64; - - vu64 = _nm_utils_ascii_str_to_uint64 (value, 10, 0, G_MAXUINT64, 0); - if (!nm_g_object_set_property_uint64 (G_OBJECT (setting), m[i].property_name, vu64, NULL)) { - error_message = "number is out of range"; - goto warn; - } - } - return; - case G_TYPE_STRING: - nm_g_object_set_property_string (G_OBJECT (setting), m[i].property_name, value, NULL); - return; - default: - nm_assert_not_reached (); - continue; - } + static const struct { + const char * key; + const char * property_name; + BridgeOptType opt_type; + gboolean only_with_stp; + gboolean extended_bool; + } m /*etadata*/[] = { + {"DELAY", NM_SETTING_BRIDGE_FORWARD_DELAY, BRIDGE_OPT_TYPE_MAIN, .only_with_stp = TRUE}, + {"priority", NM_SETTING_BRIDGE_PRIORITY, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE}, + {"hello_time", NM_SETTING_BRIDGE_HELLO_TIME, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE}, + {"max_age", NM_SETTING_BRIDGE_MAX_AGE, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE}, + {"ageing_time", NM_SETTING_BRIDGE_AGEING_TIME, BRIDGE_OPT_TYPE_OPTION}, + {"multicast_last_member_count", + NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT, + BRIDGE_OPT_TYPE_OPTION}, + {"multicast_last_member_interval", + NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL, + BRIDGE_OPT_TYPE_OPTION}, + {"multicast_membership_interval", + NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL, + BRIDGE_OPT_TYPE_OPTION}, + {"multicast_hash_max", NM_SETTING_BRIDGE_MULTICAST_HASH_MAX, BRIDGE_OPT_TYPE_OPTION}, + {"multicast_querier", NM_SETTING_BRIDGE_MULTICAST_QUERIER, BRIDGE_OPT_TYPE_OPTION}, + {"multicast_querier_interval", + NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL, + BRIDGE_OPT_TYPE_OPTION}, + {"multicast_query_interval", + NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL, + BRIDGE_OPT_TYPE_OPTION}, + {"multicast_query_response_interval", + NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL, + BRIDGE_OPT_TYPE_OPTION}, + {"multicast_query_use_ifaddr", + NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR, + BRIDGE_OPT_TYPE_OPTION}, + {"multicast_snooping", NM_SETTING_BRIDGE_MULTICAST_SNOOPING, BRIDGE_OPT_TYPE_OPTION}, + {"multicast_router", NM_SETTING_BRIDGE_MULTICAST_ROUTER, BRIDGE_OPT_TYPE_OPTION}, + {"multicast_startup_query_count", + NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT, + BRIDGE_OPT_TYPE_OPTION}, + {"multicast_startup_query_interval", + NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL, + BRIDGE_OPT_TYPE_OPTION}, + {"vlan_filtering", NM_SETTING_BRIDGE_VLAN_FILTERING, BRIDGE_OPT_TYPE_OPTION}, + {"default_pvid", NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, BRIDGE_OPT_TYPE_OPTION}, + {"group_address", NM_SETTING_BRIDGE_GROUP_ADDRESS, BRIDGE_OPT_TYPE_OPTION}, + {"group_fwd_mask", NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, BRIDGE_OPT_TYPE_OPTION}, + {"vlan_protocol", NM_SETTING_BRIDGE_VLAN_PROTOCOL, BRIDGE_OPT_TYPE_OPTION}, + {"vlan_stats_enabled", NM_SETTING_BRIDGE_VLAN_STATS_ENABLED, BRIDGE_OPT_TYPE_OPTION}, + {"priority", NM_SETTING_BRIDGE_PORT_PRIORITY, BRIDGE_OPT_TYPE_PORT_OPTION}, + {"path_cost", NM_SETTING_BRIDGE_PORT_PATH_COST, BRIDGE_OPT_TYPE_PORT_OPTION}, + { + "hairpin_mode", + NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, + BRIDGE_OPT_TYPE_PORT_OPTION, + .extended_bool = TRUE, + }, + }; + const char *error_message = NULL; + int i; + gint64 v; + + for (i = 0; i < G_N_ELEMENTS(m); i++) { + GParamSpec *param_spec; + + if (opt_type != m[i].opt_type) + continue; + if (!nm_streq(key, m[i].key)) + continue; + if (m[i].only_with_stp && !stp) { + PARSE_WARNING("'%s' invalid when STP is disabled", key); + return; + } + + param_spec = g_object_class_find_property(G_OBJECT_GET_CLASS(setting), m[i].property_name); + switch (param_spec->value_type) { + case G_TYPE_BOOLEAN: + if (m[i].extended_bool) { + if (!g_ascii_strcasecmp(value, "on") || !g_ascii_strcasecmp(value, "yes") + || !strcmp(value, "1")) + v = TRUE; + else if (!g_ascii_strcasecmp(value, "off") || !g_ascii_strcasecmp(value, "no")) + v = FALSE; + else { + error_message = "is not a boolean"; + goto warn; + } + } else { + v = _nm_utils_ascii_str_to_int64(value, 10, 0, 1, -1); + if (v == -1) { + error_message = nm_strerror_native(errno); + goto warn; + } + } + if (!nm_g_object_set_property_boolean(G_OBJECT(setting), m[i].property_name, v, NULL)) { + error_message = "number is out of range"; + goto warn; + } + return; + case G_TYPE_UINT: + v = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT, -1); + if (v == -1) { + error_message = nm_strerror_native(errno); + goto warn; + } + if (!nm_g_object_set_property_uint(G_OBJECT(setting), m[i].property_name, v, NULL)) { + error_message = "number is out of range"; + goto warn; + } + return; + case G_TYPE_UINT64: + { + guint64 vu64; + + vu64 = _nm_utils_ascii_str_to_uint64(value, 10, 0, G_MAXUINT64, 0); + if (!nm_g_object_set_property_uint64(G_OBJECT(setting), + m[i].property_name, + vu64, + NULL)) { + error_message = "number is out of range"; + goto warn; + } + } + return; + case G_TYPE_STRING: + nm_g_object_set_property_string(G_OBJECT(setting), m[i].property_name, value, NULL); + return; + default: + nm_assert_not_reached(); + continue; + } warn: - PARSE_WARNING ("invalid %s value '%s': %s", key, value, error_message); - return; - } + PARSE_WARNING("invalid %s value '%s': %s", key, value, error_message); + return; + } - PARSE_WARNING ("unhandled bridge option '%s'", key); + PARSE_WARNING("unhandled bridge option '%s'", key); } static void -handle_bridging_opts (NMSetting *setting, - gboolean stp, - const char *value, - BridgeOptFunc func, - BridgeOptType opt_type) +handle_bridging_opts(NMSetting * setting, + gboolean stp, + const char * value, + BridgeOptFunc func, + BridgeOptType opt_type) { - gs_free const char **items = NULL; - const char *const *iter; - - items = nm_utils_strsplit_set (value, " "); - for (iter = items; iter && *iter; iter++) { - gs_free char *key = NULL; - const char *val; - - val = strchr (*iter, '='); - if (!val) - continue; - key = g_strndup (*iter, val - *iter); - val++; - if (key[0] && val[0]) - func (setting, stp, key, val, opt_type); - } + gs_free const char **items = NULL; + const char *const * iter; + + items = nm_utils_strsplit_set(value, " "); + for (iter = items; iter && *iter; iter++) { + gs_free char *key = NULL; + const char * val; + + val = strchr(*iter, '='); + if (!val) + continue; + key = g_strndup(*iter, val - *iter); + val++; + if (key[0] && val[0]) + func(setting, stp, key, val, opt_type); + } } static void -read_bridge_vlans (shvarFile *ifcfg, - const char *key, - NMSetting *setting, - const char *property) +read_bridge_vlans(shvarFile *ifcfg, const char *key, NMSetting *setting, const char *property) { - gs_unref_ptrarray GPtrArray *array = NULL; - gs_free char *value_to_free = NULL; - const char *value; - - value = svGetValueStr (ifcfg, key, &value_to_free); - if (value) { - gs_free const char **strv = NULL; - const char *const *iter; - GError *local = NULL; - NMBridgeVlan *vlan; - - array = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref); - - strv = nm_utils_escaped_tokens_split (value, ","); - if (strv) { - for (iter = strv; *iter; iter++) { - vlan = nm_bridge_vlan_from_str (*iter, &local); - if (!vlan) { - PARSE_WARNING ("invalid bridge VLAN: %s", local->message); - g_clear_error (&local); - continue; - } - g_ptr_array_add (array, vlan); - } - } - nm_clear_g_free (&value_to_free); - } - - g_object_set (setting, property, array, NULL); + gs_unref_ptrarray GPtrArray *array = NULL; + gs_free char * value_to_free = NULL; + const char * value; + + value = svGetValueStr(ifcfg, key, &value_to_free); + if (value) { + gs_free const char **strv = NULL; + const char *const * iter; + GError * local = NULL; + NMBridgeVlan * vlan; + + array = g_ptr_array_new_with_free_func((GDestroyNotify) nm_bridge_vlan_unref); + + strv = nm_utils_escaped_tokens_split(value, ","); + if (strv) { + for (iter = strv; *iter; iter++) { + vlan = nm_bridge_vlan_from_str(*iter, &local); + if (!vlan) { + PARSE_WARNING("invalid bridge VLAN: %s", local->message); + g_clear_error(&local); + continue; + } + g_ptr_array_add(array, vlan); + } + } + nm_clear_g_free(&value_to_free); + } + + g_object_set(setting, property, array, NULL); } static NMSetting * -make_bridge_setting (shvarFile *ifcfg, - const char *file, - GError **error) +make_bridge_setting(shvarFile *ifcfg, const char *file, GError **error) { - gs_unref_object NMSettingBridge *s_bridge = NULL; - gs_free char *value_to_free = NULL; - const char *value; - gboolean stp = FALSE; - gboolean stp_set = FALSE; - - value = svGetValueStr (ifcfg, "DEVICE", &value_to_free); - if (!value) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "mandatory DEVICE keyword missing"); - return NULL; - } - nm_clear_g_free (&value_to_free); - - s_bridge = NM_SETTING_BRIDGE (nm_setting_bridge_new ()); - - value = svGetValueStr (ifcfg, "BRIDGE_MACADDR", &value_to_free); - if (value) { - g_object_set (s_bridge, NM_SETTING_BRIDGE_MAC_ADDRESS, value, NULL); - nm_clear_g_free (&value_to_free); - } - - value = svGetValueStr (ifcfg, "STP", &value_to_free); - if (value) { - if (!g_ascii_strcasecmp (value, "on") || !g_ascii_strcasecmp (value, "yes")) { - g_object_set (s_bridge, NM_SETTING_BRIDGE_STP, TRUE, NULL); - stp = TRUE; - stp_set = TRUE; - } else if (!g_ascii_strcasecmp (value, "off") || !g_ascii_strcasecmp (value, "no")) { - g_object_set (s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL); - stp_set = TRUE; - } else - PARSE_WARNING ("invalid STP value '%s'", value); - nm_clear_g_free (&value_to_free); - } - - if (!stp_set) { - /* Missing or invalid STP property means "no" */ - g_object_set (s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL); - } - - value = svGetValueStr (ifcfg, "DELAY", &value_to_free); - if (value) { - handle_bridge_option (NM_SETTING (s_bridge), stp, "DELAY", value, BRIDGE_OPT_TYPE_MAIN); - nm_clear_g_free (&value_to_free); - } - - value = svGetValueStr (ifcfg, "BRIDGING_OPTS", &value_to_free); - if (value) { - handle_bridging_opts (NM_SETTING (s_bridge), stp, value, handle_bridge_option, BRIDGE_OPT_TYPE_OPTION); - nm_clear_g_free (&value_to_free); - } - - read_bridge_vlans (ifcfg, - "BRIDGE_VLANS", - NM_SETTING (s_bridge), - NM_SETTING_BRIDGE_VLANS); - - return (NMSetting *) g_steal_pointer (&s_bridge); + gs_unref_object NMSettingBridge *s_bridge = NULL; + gs_free char * value_to_free = NULL; + const char * value; + gboolean stp = FALSE; + gboolean stp_set = FALSE; + + value = svGetValueStr(ifcfg, "DEVICE", &value_to_free); + if (!value) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "mandatory DEVICE keyword missing"); + return NULL; + } + nm_clear_g_free(&value_to_free); + + s_bridge = NM_SETTING_BRIDGE(nm_setting_bridge_new()); + + value = svGetValueStr(ifcfg, "BRIDGE_MACADDR", &value_to_free); + if (value) { + g_object_set(s_bridge, NM_SETTING_BRIDGE_MAC_ADDRESS, value, NULL); + nm_clear_g_free(&value_to_free); + } + + value = svGetValueStr(ifcfg, "STP", &value_to_free); + if (value) { + if (!g_ascii_strcasecmp(value, "on") || !g_ascii_strcasecmp(value, "yes")) { + g_object_set(s_bridge, NM_SETTING_BRIDGE_STP, TRUE, NULL); + stp = TRUE; + stp_set = TRUE; + } else if (!g_ascii_strcasecmp(value, "off") || !g_ascii_strcasecmp(value, "no")) { + g_object_set(s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL); + stp_set = TRUE; + } else + PARSE_WARNING("invalid STP value '%s'", value); + nm_clear_g_free(&value_to_free); + } + + if (!stp_set) { + /* Missing or invalid STP property means "no" */ + g_object_set(s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL); + } + + value = svGetValueStr(ifcfg, "DELAY", &value_to_free); + if (value) { + handle_bridge_option(NM_SETTING(s_bridge), stp, "DELAY", value, BRIDGE_OPT_TYPE_MAIN); + nm_clear_g_free(&value_to_free); + } + + value = svGetValueStr(ifcfg, "BRIDGING_OPTS", &value_to_free); + if (value) { + handle_bridging_opts(NM_SETTING(s_bridge), + stp, + value, + handle_bridge_option, + BRIDGE_OPT_TYPE_OPTION); + nm_clear_g_free(&value_to_free); + } + + read_bridge_vlans(ifcfg, "BRIDGE_VLANS", NM_SETTING(s_bridge), NM_SETTING_BRIDGE_VLANS); + + return (NMSetting *) g_steal_pointer(&s_bridge); } static NMConnection * -bridge_connection_from_ifcfg (const char *file, - shvarFile *ifcfg, - GError **error) +bridge_connection_from_ifcfg(const char *file, shvarFile *ifcfg, GError **error) { - NMConnection *connection = NULL; - NMSetting *con_setting = NULL; - NMSetting *bridge_setting = NULL; - NMSetting *wired_setting = NULL; - NMSetting8021x *s_8021x = NULL; - GError *local = NULL; - - g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (ifcfg != NULL, NULL); - - connection = nm_simple_connection_new (); - - con_setting = make_connection_setting (file, ifcfg, NM_SETTING_BRIDGE_SETTING_NAME, NULL, _("Bridge")); - if (!con_setting) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Failed to create connection setting"); - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, con_setting); - - bridge_setting = make_bridge_setting (ifcfg, file, error); - if (!bridge_setting) { - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, bridge_setting); - - wired_setting = make_wired_setting (ifcfg, file, &s_8021x, &local); - if (local && !g_error_matches (local, NM_UTILS_ERROR, NM_UTILS_ERROR_SETTING_MISSING)) { - g_propagate_error (error, local); - g_object_unref (connection); - return NULL; - } - g_clear_error (&local); - - if (wired_setting) - nm_connection_add_setting (connection, wired_setting); - - if (s_8021x) - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - return connection; + NMConnection * connection = NULL; + NMSetting * con_setting = NULL; + NMSetting * bridge_setting = NULL; + NMSetting * wired_setting = NULL; + NMSetting8021x *s_8021x = NULL; + GError * local = NULL; + + g_return_val_if_fail(file != NULL, NULL); + g_return_val_if_fail(ifcfg != NULL, NULL); + + connection = nm_simple_connection_new(); + + con_setting = + make_connection_setting(file, ifcfg, NM_SETTING_BRIDGE_SETTING_NAME, NULL, _("Bridge")); + if (!con_setting) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to create connection setting"); + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, con_setting); + + bridge_setting = make_bridge_setting(ifcfg, file, error); + if (!bridge_setting) { + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, bridge_setting); + + wired_setting = make_wired_setting(ifcfg, file, &s_8021x, &local); + if (local && !g_error_matches(local, NM_UTILS_ERROR, NM_UTILS_ERROR_SETTING_MISSING)) { + g_propagate_error(error, local); + g_object_unref(connection); + return NULL; + } + g_clear_error(&local); + + if (wired_setting) + nm_connection_add_setting(connection, wired_setting); + + if (s_8021x) + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + return connection; } static NMSetting * -make_bridge_port_setting (shvarFile *ifcfg) +make_bridge_port_setting(shvarFile *ifcfg) { - NMSetting *s_port = NULL; - gs_free char *value_to_free = NULL; - const char *value; - - g_return_val_if_fail (ifcfg != NULL, FALSE); - - value = svGetValueStr (ifcfg, "BRIDGE_UUID", &value_to_free); - if (!value) - value = svGetValueStr (ifcfg, "BRIDGE", &value_to_free); - if (value) { - nm_clear_g_free (&value_to_free); - - s_port = nm_setting_bridge_port_new (); - value = svGetValueStr (ifcfg, "BRIDGING_OPTS", &value_to_free); - if (value) { - handle_bridging_opts (s_port, FALSE, value, handle_bridge_option, BRIDGE_OPT_TYPE_PORT_OPTION); - nm_clear_g_free (&value_to_free); - } - - read_bridge_vlans (ifcfg, - "BRIDGE_PORT_VLANS", - s_port, - NM_SETTING_BRIDGE_PORT_VLANS); - } - - return s_port; + NMSetting * s_port = NULL; + gs_free char *value_to_free = NULL; + const char * value; + + g_return_val_if_fail(ifcfg != NULL, FALSE); + + value = svGetValueStr(ifcfg, "BRIDGE_UUID", &value_to_free); + if (!value) + value = svGetValueStr(ifcfg, "BRIDGE", &value_to_free); + if (value) { + nm_clear_g_free(&value_to_free); + + s_port = nm_setting_bridge_port_new(); + value = svGetValueStr(ifcfg, "BRIDGING_OPTS", &value_to_free); + if (value) { + handle_bridging_opts(s_port, + FALSE, + value, + handle_bridge_option, + BRIDGE_OPT_TYPE_PORT_OPTION); + nm_clear_g_free(&value_to_free); + } + + read_bridge_vlans(ifcfg, "BRIDGE_PORT_VLANS", s_port, NM_SETTING_BRIDGE_PORT_VLANS); + } + + return s_port; } static NMSetting * -make_team_port_setting (shvarFile *ifcfg) +make_team_port_setting(shvarFile *ifcfg) { - NMSetting *s_port; - gs_free char *value = NULL; - - value = svGetValueStr_cp (ifcfg, "TEAM_PORT_CONFIG"); - if (!value) - return NULL; - - s_port = nm_setting_team_port_new (); - g_object_set (s_port, - NM_SETTING_TEAM_PORT_CONFIG, - value, - NULL); - return s_port; + NMSetting * s_port; + gs_free char *value = NULL; + + value = svGetValueStr_cp(ifcfg, "TEAM_PORT_CONFIG"); + if (!value) + return NULL; + + s_port = nm_setting_team_port_new(); + g_object_set(s_port, NM_SETTING_TEAM_PORT_CONFIG, value, NULL); + return s_port; } static gboolean -is_bond_device (const char *name, shvarFile *parsed) +is_bond_device(const char *name, shvarFile *parsed) { - g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (parsed != NULL, FALSE); + g_return_val_if_fail(name != NULL, FALSE); + g_return_val_if_fail(parsed != NULL, FALSE); - if (svGetValueBoolean (parsed, "BONDING_MASTER", FALSE)) - return TRUE; + if (svGetValueBoolean(parsed, "BONDING_MASTER", FALSE)) + return TRUE; - return FALSE; + return FALSE; } static gboolean -is_vlan_device (const char *name, shvarFile *parsed) +is_vlan_device(const char *name, shvarFile *parsed) { - g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (parsed != NULL, FALSE); + g_return_val_if_fail(name != NULL, FALSE); + g_return_val_if_fail(parsed != NULL, FALSE); - if (svGetValueBoolean (parsed, "VLAN", FALSE)) - return TRUE; + if (svGetValueBoolean(parsed, "VLAN", FALSE)) + return TRUE; - return FALSE; + return FALSE; } static gboolean -is_wifi_device (const char *name, shvarFile *parsed) +is_wifi_device(const char *name, shvarFile *parsed) { - const NMPlatformLink *pllink; + const NMPlatformLink *pllink; - g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (parsed != NULL, FALSE); + g_return_val_if_fail(name != NULL, FALSE); + g_return_val_if_fail(parsed != NULL, FALSE); - pllink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, name); - return pllink - && pllink->type == NM_LINK_TYPE_WIFI; + pllink = nm_platform_link_get_by_ifname(NM_PLATFORM_GET, name); + return pllink && pllink->type == NM_LINK_TYPE_WIFI; } static void -parse_prio_map_list (NMSettingVlan *s_vlan, - shvarFile *ifcfg, - const char *key, - NMVlanPriorityMap map) +parse_prio_map_list(NMSettingVlan *s_vlan, shvarFile *ifcfg, const char *key, NMVlanPriorityMap map) { - gs_free char *value = NULL; - gs_free const char **list = NULL; - const char *const *iter; - const char *v; - - v = svGetValueStr (ifcfg, key, &value); - if (!v) - return; - list = nm_utils_strsplit_set (v, ","); - - for (iter = list; iter && *iter; iter++) { - if (!strchr (*iter, ':')) - continue; - if (!nm_setting_vlan_add_priority_str (s_vlan, map, *iter)) - PARSE_WARNING ("invalid %s priority map item '%s'", key, *iter); - } + gs_free char * value = NULL; + gs_free const char **list = NULL; + const char *const * iter; + const char * v; + + v = svGetValueStr(ifcfg, key, &value); + if (!v) + return; + list = nm_utils_strsplit_set(v, ","); + + for (iter = list; iter && *iter; iter++) { + if (!strchr(*iter, ':')) + continue; + if (!nm_setting_vlan_add_priority_str(s_vlan, map, *iter)) + PARSE_WARNING("invalid %s priority map item '%s'", key, *iter); + } } static NMSetting * -make_vlan_setting (shvarFile *ifcfg, - const char *file, - GError **error) +make_vlan_setting(shvarFile *ifcfg, const char *file, GError **error) { - gs_unref_object NMSettingVlan *s_vlan = NULL; - gs_free char *parent = NULL; - gs_free char *iface_name = NULL; - gs_free char *value = NULL; - const char *v = NULL; - int vlan_id = -1; - guint32 vlan_flags = 0; - int gvrp, reorder_hdr; - - v = svGetValueStr (ifcfg, "VLAN_ID", &value); - if (v) { - vlan_id = _nm_utils_ascii_str_to_int64 (v, 10, 0, 4095, -1); - if (vlan_id == -1) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid VLAN_ID '%s'", v); - return NULL; - } - } - - /* Need DEVICE if we don't have a separate VLAN_ID property */ - iface_name = svGetValueStr_cp (ifcfg, "DEVICE"); - if (!iface_name && vlan_id < 0) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing DEVICE property; cannot determine VLAN ID"); - return NULL; - } - - s_vlan = NM_SETTING_VLAN (nm_setting_vlan_new ()); - - /* Parent interface from PHYSDEV takes precedence if it exists */ - parent = svGetValueStr_cp (ifcfg, "PHYSDEV"); - - if (iface_name) { - v = strchr (iface_name, '.'); - if (v) { - /* eth0.43; PHYSDEV is assumed from it if unknown */ - if (!parent) { - parent = g_strndup (iface_name, v - iface_name); - if (g_str_has_prefix (parent, "vlan")) { - /* Like initscripts, if no PHYSDEV and we get an obviously - * invalid parent interface from DEVICE, fail. - */ - nm_clear_g_free (&parent); - } - } - v++; - } else { - /* format like vlan43; PHYSDEV must be set */ - if (g_str_has_prefix (iface_name, "vlan")) - v = iface_name + 4; - } - - if (v) { - int device_vlan_id; - - /* Grab VLAN ID from interface name; this takes precedence over the - * separate VLAN_ID property for backwards compat. - */ - device_vlan_id = _nm_utils_ascii_str_to_int64 (v, 10, 0, 4095, -1); - if (device_vlan_id != -1) - vlan_id = device_vlan_id; - } - } - - if (vlan_id < 0) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Failed to determine VLAN ID from DEVICE or VLAN_ID"); - return NULL; - } - g_object_set (s_vlan, NM_SETTING_VLAN_ID, vlan_id, NULL); - - if (parent == NULL) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Failed to determine VLAN parent from DEVICE or PHYSDEV"); - return NULL; - } - g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, parent, NULL); - - vlan_flags |= NM_VLAN_FLAG_REORDER_HEADERS; - - gvrp = svGetValueBoolean (ifcfg, "GVRP", -1); - if (gvrp > 0) - vlan_flags |= NM_VLAN_FLAG_GVRP; - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "VLAN_FLAGS", &value); - if (v) { - gs_free const char **strv = NULL; - const char *const *ptr; - - strv = nm_utils_strsplit_set (v, ", "); - for (ptr = strv; ptr && *ptr; ptr++) { - if (nm_streq (*ptr, "GVRP") && gvrp == -1) - vlan_flags |= NM_VLAN_FLAG_GVRP; - if (nm_streq (*ptr, "LOOSE_BINDING")) - vlan_flags |= NM_VLAN_FLAG_LOOSE_BINDING; - if (nm_streq (*ptr, "NO_REORDER_HDR")) - vlan_flags &= ~NM_VLAN_FLAG_REORDER_HEADERS; - } - } - - reorder_hdr = svGetValueBoolean (ifcfg, "REORDER_HDR", -1); - if ( reorder_hdr != -1 - && reorder_hdr != NM_FLAGS_HAS (vlan_flags, NM_VLAN_FLAG_REORDER_HEADERS)) - PARSE_WARNING ("REORDER_HDR key is deprecated, use VLAN_FLAGS"); - - if (svGetValueBoolean (ifcfg, "MVRP", FALSE)) - vlan_flags |= NM_VLAN_FLAG_MVRP; - - g_object_set (s_vlan, NM_SETTING_VLAN_FLAGS, vlan_flags, NULL); - - parse_prio_map_list (s_vlan, ifcfg, "VLAN_INGRESS_PRIORITY_MAP", NM_VLAN_INGRESS_MAP); - parse_prio_map_list (s_vlan, ifcfg, "VLAN_EGRESS_PRIORITY_MAP", NM_VLAN_EGRESS_MAP); - - return NM_SETTING (g_steal_pointer (&s_vlan)); + gs_unref_object NMSettingVlan *s_vlan = NULL; + gs_free char * parent = NULL; + gs_free char * iface_name = NULL; + gs_free char * value = NULL; + const char * v = NULL; + int vlan_id = -1; + guint32 vlan_flags = 0; + int gvrp, reorder_hdr; + + v = svGetValueStr(ifcfg, "VLAN_ID", &value); + if (v) { + vlan_id = _nm_utils_ascii_str_to_int64(v, 10, 0, 4095, -1); + if (vlan_id == -1) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid VLAN_ID '%s'", + v); + return NULL; + } + } + + /* Need DEVICE if we don't have a separate VLAN_ID property */ + iface_name = svGetValueStr_cp(ifcfg, "DEVICE"); + if (!iface_name && vlan_id < 0) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing DEVICE property; cannot determine VLAN ID"); + return NULL; + } + + s_vlan = NM_SETTING_VLAN(nm_setting_vlan_new()); + + /* Parent interface from PHYSDEV takes precedence if it exists */ + parent = svGetValueStr_cp(ifcfg, "PHYSDEV"); + + if (iface_name) { + v = strchr(iface_name, '.'); + if (v) { + /* eth0.43; PHYSDEV is assumed from it if unknown */ + if (!parent) { + parent = g_strndup(iface_name, v - iface_name); + if (g_str_has_prefix(parent, "vlan")) { + /* Like initscripts, if no PHYSDEV and we get an obviously + * invalid parent interface from DEVICE, fail. + */ + nm_clear_g_free(&parent); + } + } + v++; + } else { + /* format like vlan43; PHYSDEV must be set */ + if (g_str_has_prefix(iface_name, "vlan")) + v = iface_name + 4; + } + + if (v) { + int device_vlan_id; + + /* Grab VLAN ID from interface name; this takes precedence over the + * separate VLAN_ID property for backwards compat. + */ + device_vlan_id = _nm_utils_ascii_str_to_int64(v, 10, 0, 4095, -1); + if (device_vlan_id != -1) + vlan_id = device_vlan_id; + } + } + + if (vlan_id < 0) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to determine VLAN ID from DEVICE or VLAN_ID"); + return NULL; + } + g_object_set(s_vlan, NM_SETTING_VLAN_ID, vlan_id, NULL); + + if (parent == NULL) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to determine VLAN parent from DEVICE or PHYSDEV"); + return NULL; + } + g_object_set(s_vlan, NM_SETTING_VLAN_PARENT, parent, NULL); + + vlan_flags |= NM_VLAN_FLAG_REORDER_HEADERS; + + gvrp = svGetValueBoolean(ifcfg, "GVRP", -1); + if (gvrp > 0) + vlan_flags |= NM_VLAN_FLAG_GVRP; + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "VLAN_FLAGS", &value); + if (v) { + gs_free const char **strv = NULL; + const char *const * ptr; + + strv = nm_utils_strsplit_set(v, ", "); + for (ptr = strv; ptr && *ptr; ptr++) { + if (nm_streq(*ptr, "GVRP") && gvrp == -1) + vlan_flags |= NM_VLAN_FLAG_GVRP; + if (nm_streq(*ptr, "LOOSE_BINDING")) + vlan_flags |= NM_VLAN_FLAG_LOOSE_BINDING; + if (nm_streq(*ptr, "NO_REORDER_HDR")) + vlan_flags &= ~NM_VLAN_FLAG_REORDER_HEADERS; + } + } + + reorder_hdr = svGetValueBoolean(ifcfg, "REORDER_HDR", -1); + if (reorder_hdr != -1 && reorder_hdr != NM_FLAGS_HAS(vlan_flags, NM_VLAN_FLAG_REORDER_HEADERS)) + PARSE_WARNING("REORDER_HDR key is deprecated, use VLAN_FLAGS"); + + if (svGetValueBoolean(ifcfg, "MVRP", FALSE)) + vlan_flags |= NM_VLAN_FLAG_MVRP; + + g_object_set(s_vlan, NM_SETTING_VLAN_FLAGS, vlan_flags, NULL); + + parse_prio_map_list(s_vlan, ifcfg, "VLAN_INGRESS_PRIORITY_MAP", NM_VLAN_INGRESS_MAP); + parse_prio_map_list(s_vlan, ifcfg, "VLAN_EGRESS_PRIORITY_MAP", NM_VLAN_EGRESS_MAP); + + return NM_SETTING(g_steal_pointer(&s_vlan)); } static NMConnection * -vlan_connection_from_ifcfg (const char *file, - shvarFile *ifcfg, - GError **error) +vlan_connection_from_ifcfg(const char *file, shvarFile *ifcfg, GError **error) { - NMConnection *connection = NULL; - NMSetting *con_setting = NULL; - NMSetting *wired_setting = NULL; - NMSetting *vlan_setting = NULL; - NMSetting8021x *s_8021x = NULL; - GError *local = NULL; - - g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (ifcfg != NULL, NULL); - - connection = nm_simple_connection_new (); - - con_setting = make_connection_setting (file, ifcfg, NM_SETTING_VLAN_SETTING_NAME, NULL, "Vlan"); - if (!con_setting) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Failed to create connection setting"); - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, con_setting); - - vlan_setting = make_vlan_setting (ifcfg, file, error); - if (!vlan_setting) { - g_object_unref (connection); - return NULL; - } - nm_connection_add_setting (connection, vlan_setting); - - wired_setting = make_wired_setting (ifcfg, file, &s_8021x, &local); - if (local && !g_error_matches (local, NM_UTILS_ERROR, NM_UTILS_ERROR_SETTING_MISSING)) { - g_propagate_error (error, local); - g_object_unref (connection); - return NULL; - } - g_clear_error (&local); - - if (wired_setting) - nm_connection_add_setting (connection, wired_setting); - - if (s_8021x) - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - return connection; + NMConnection * connection = NULL; + NMSetting * con_setting = NULL; + NMSetting * wired_setting = NULL; + NMSetting * vlan_setting = NULL; + NMSetting8021x *s_8021x = NULL; + GError * local = NULL; + + g_return_val_if_fail(file != NULL, NULL); + g_return_val_if_fail(ifcfg != NULL, NULL); + + connection = nm_simple_connection_new(); + + con_setting = make_connection_setting(file, ifcfg, NM_SETTING_VLAN_SETTING_NAME, NULL, "Vlan"); + if (!con_setting) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to create connection setting"); + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, con_setting); + + vlan_setting = make_vlan_setting(ifcfg, file, error); + if (!vlan_setting) { + g_object_unref(connection); + return NULL; + } + nm_connection_add_setting(connection, vlan_setting); + + wired_setting = make_wired_setting(ifcfg, file, &s_8021x, &local); + if (local && !g_error_matches(local, NM_UTILS_ERROR, NM_UTILS_ERROR_SETTING_MISSING)) { + g_propagate_error(error, local); + g_object_unref(connection); + return NULL; + } + g_clear_error(&local); + + if (wired_setting) + nm_connection_add_setting(connection, wired_setting); + + if (s_8021x) + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + return connection; } static NMConnection * -create_unhandled_connection (const char *filename, shvarFile *ifcfg, - const char *type, char **out_spec) +create_unhandled_connection(const char *filename, + shvarFile * ifcfg, + const char *type, + char ** out_spec) { - NMConnection *connection; - NMSetting *s_con; - gs_free char *value = NULL; - const char *v; - - nm_assert (out_spec && !*out_spec); - - connection = nm_simple_connection_new (); - - /* Get NAME, UUID, etc. We need to set a connection type (generic) and add - * an empty type-specific setting as well, to make sure it passes - * nm_connection_verify() later. - */ - s_con = make_connection_setting (filename, ifcfg, NM_SETTING_GENERIC_SETTING_NAME, - NULL, NULL); - nm_connection_add_setting (connection, s_con); - - nm_connection_add_setting (connection, nm_setting_generic_new ()); - - /* Get a spec */ - v = svGetValueStr (ifcfg, "HWADDR", &value); - if (v) { - gs_free char *lower = g_ascii_strdown (v, -1); - - *out_spec = g_strdup_printf ("%s:"NM_MATCH_SPEC_MAC_TAG"%s", type, lower); - return connection; - } - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "SUBCHANNELS", &value); - if (v) { - *out_spec = g_strdup_printf ("%s:"NM_MATCH_SPEC_S390_SUBCHANNELS_TAG"%s", type, v); - return connection; - } - - nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DEVICE", &value); - if (v) { - *out_spec = g_strdup_printf ("%s:"NM_MATCH_SPEC_INTERFACE_NAME_TAG"=%s", type, v); - return connection; - } - - g_object_unref (connection); - return NULL; + NMConnection *connection; + NMSetting * s_con; + gs_free char *value = NULL; + const char * v; + + nm_assert(out_spec && !*out_spec); + + connection = nm_simple_connection_new(); + + /* Get NAME, UUID, etc. We need to set a connection type (generic) and add + * an empty type-specific setting as well, to make sure it passes + * nm_connection_verify() later. + */ + s_con = make_connection_setting(filename, ifcfg, NM_SETTING_GENERIC_SETTING_NAME, NULL, NULL); + nm_connection_add_setting(connection, s_con); + + nm_connection_add_setting(connection, nm_setting_generic_new()); + + /* Get a spec */ + v = svGetValueStr(ifcfg, "HWADDR", &value); + if (v) { + gs_free char *lower = g_ascii_strdown(v, -1); + + *out_spec = g_strdup_printf("%s:" NM_MATCH_SPEC_MAC_TAG "%s", type, lower); + return connection; + } + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "SUBCHANNELS", &value); + if (v) { + *out_spec = g_strdup_printf("%s:" NM_MATCH_SPEC_S390_SUBCHANNELS_TAG "%s", type, v); + return connection; + } + + nm_clear_g_free(&value); + v = svGetValueStr(ifcfg, "DEVICE", &value); + if (v) { + *out_spec = g_strdup_printf("%s:" NM_MATCH_SPEC_INTERFACE_NAME_TAG "=%s", type, v); + return connection; + } + + g_object_unref(connection); + return NULL; } static void -check_dns_search_domains (shvarFile *ifcfg, NMSetting *s_ip4, NMSetting *s_ip6) +check_dns_search_domains(shvarFile *ifcfg, NMSetting *s_ip4, NMSetting *s_ip6) { - if (!s_ip6) - return; - - /* If there is no IPv4 config or it doesn't contain DNS searches, - * read DOMAIN and put the domains into IPv6. - */ - if ( !s_ip4 - || nm_setting_ip_config_get_num_dns_searches (NM_SETTING_IP_CONFIG (s_ip4)) == 0) { - /* DNS searches */ - gs_free char *value = NULL; - const char *v; - - v = svGetValueStr (ifcfg, "DOMAIN", &value); - if (v) { - gs_free const char **searches = NULL; - const char *const *item; - - searches = nm_utils_strsplit_set (v, " "); - if (searches) { - for (item = searches; *item; item++) { - if (!nm_setting_ip_config_add_dns_search (NM_SETTING_IP_CONFIG (s_ip6), *item)) - PARSE_WARNING ("duplicate DNS domain '%s'", *item); - } - } - } - } + if (!s_ip6) + return; + + /* If there is no IPv4 config or it doesn't contain DNS searches, + * read DOMAIN and put the domains into IPv6. + */ + if (!s_ip4 || nm_setting_ip_config_get_num_dns_searches(NM_SETTING_IP_CONFIG(s_ip4)) == 0) { + /* DNS searches */ + gs_free char *value = NULL; + const char * v; + + v = svGetValueStr(ifcfg, "DOMAIN", &value); + if (v) { + gs_free const char **searches = NULL; + const char *const * item; + + searches = nm_utils_strsplit_set(v, " "); + if (searches) { + for (item = searches; *item; item++) { + if (!nm_setting_ip_config_add_dns_search(NM_SETTING_IP_CONFIG(s_ip6), *item)) + PARSE_WARNING("duplicate DNS domain '%s'", *item); + } + } + } + } } static NMConnection * -connection_from_file_full (const char *filename, - const char *network_file, /* for unit tests only */ - const char *test_type, /* for unit tests only */ - char **out_unhandled, - GError **error, - gboolean *out_ignore_error) +connection_from_file_full(const char *filename, + const char *network_file, /* for unit tests only */ + const char *test_type, /* for unit tests only */ + char ** out_unhandled, + GError ** error, + gboolean * out_ignore_error) { - nm_auto_shvar_file_close shvarFile *main_ifcfg = NULL; - nm_auto_shvar_file_close shvarFile *network_ifcfg = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_free char *type = NULL; - char *devtype, *bootproto; - NMSetting *s_ip4, *s_ip6, *s_tc, *s_proxy, *s_port, *s_dcb = NULL, *s_user; - NMSetting *s_sriov, *s_match; - const char *ifcfg_name = NULL; - gboolean has_ip4_defroute = FALSE; - gboolean has_complex_routes_v4; - gboolean has_complex_routes_v6; - - g_return_val_if_fail (filename != NULL, NULL); - g_return_val_if_fail (out_unhandled && !*out_unhandled, NULL); - - NM_SET_OUT (out_ignore_error, FALSE); - - /* Non-NULL only for unit tests; normally use /etc/sysconfig/network */ - if (!network_file) - network_file = SYSCONFDIR "/sysconfig/network"; - - ifcfg_name = utils_get_ifcfg_name (filename, TRUE); - if (!ifcfg_name) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Ignoring connection '%s' because it's not an ifcfg file", filename); - return NULL; - } - - main_ifcfg = svOpenFile (filename, error); - if (!main_ifcfg) - return NULL; - - network_ifcfg = svOpenFile (network_file, NULL); - - if (!svGetValueBoolean (main_ifcfg, "NM_CONTROLLED", TRUE)) { - connection = create_unhandled_connection (filename, main_ifcfg, "unmanaged", out_unhandled); - if (!connection) { - NM_SET_OUT (out_ignore_error, TRUE); - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "NM_CONTROLLED was false but device was not uniquely identified; device will be managed"); - } - return g_steal_pointer (&connection); - } - - /* iBFT is handled by nm-initrd-generator during boot. */ - bootproto = svGetValueStr_cp (main_ifcfg, "BOOTPROTO"); - if (bootproto && !g_ascii_strcasecmp (bootproto, "ibft")) { - NM_SET_OUT (out_ignore_error, TRUE); - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Ignoring iBFT configuration"); - g_free (bootproto); - return NULL; - } - g_free (bootproto); - - devtype = svGetValueStr_cp (main_ifcfg, "DEVICETYPE"); - if (devtype) { - if (!g_ascii_strcasecmp (devtype, TYPE_TEAM)) - type = g_strdup (TYPE_TEAM); - else if (!g_ascii_strcasecmp (devtype, TYPE_TEAM_PORT)) { - gs_free char *device = NULL; - - type = svGetValueStr_cp (main_ifcfg, "TYPE"); - device = svGetValueStr_cp (main_ifcfg, "DEVICE"); - - if (type) { - /* nothing to do */ - } else if (device && is_vlan_device (device, main_ifcfg)) - type = g_strdup (TYPE_VLAN); - else - type = g_strdup (TYPE_ETHERNET); - } - g_free (devtype); - } - if (!type) { - gs_free char *t = NULL; - - /* Team and TeamPort types are also accepted by the mere - * presence of TEAM_CONFIG/TEAM_MASTER. They don't require - * DEVICETYPE. */ - t = svGetValueStr_cp (main_ifcfg, "TEAM_CONFIG"); - if (t) - type = g_strdup (TYPE_TEAM); - } - - if (!type) - type = svGetValueStr_cp (main_ifcfg, "TYPE"); - - if (!type) { - gs_free char *tmp = NULL; - char *device; - - if ((tmp = svGetValueStr_cp (main_ifcfg, "IPV6TUNNELIPV4"))) { - NM_SET_OUT (out_ignore_error, TRUE); - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Ignoring unsupported connection due to IPV6TUNNELIPV4"); - return NULL; - } - - device = svGetValueStr_cp (main_ifcfg, "DEVICE"); - if (!device) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "File '%s' had neither TYPE nor DEVICE keys", filename); - return NULL; - } - - if (!strcmp (device, "lo")) { - NM_SET_OUT (out_ignore_error, TRUE); - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Ignoring loopback device config"); - g_free (device); - return NULL; - } - - if (!test_type) { - if (is_bond_device (device, main_ifcfg)) - type = g_strdup (TYPE_BOND); - else if (is_vlan_device (device, main_ifcfg)) - type = g_strdup (TYPE_VLAN); - else if (is_wifi_device (device, main_ifcfg)) - type = g_strdup (TYPE_WIRELESS); - else { - gs_free char *p_path = NULL; - char *p_device; - gsize i; - - /* network-functions detects DEVICETYPE based on the ifcfg-* name and the existence - * of a ifup script: - * [ -z "$DEVICETYPE" ] && DEVICETYPE=$(echo ${DEVICE} | sed "s/[0-9]*$//") - * later... - * OTHERSCRIPT="/etc/sysconfig/network-scripts/ifup-${DEVICETYPE}" - * */ + nm_auto_shvar_file_close shvarFile *main_ifcfg = NULL; + nm_auto_shvar_file_close shvarFile *network_ifcfg = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_free char * type = NULL; + char * devtype, *bootproto; + NMSetting * s_ip4, *s_ip6, *s_tc, *s_proxy, *s_port, *s_dcb = NULL, *s_user; + NMSetting * s_sriov, *s_match; + const char * ifcfg_name = NULL; + gboolean has_ip4_defroute = FALSE; + gboolean has_complex_routes_v4; + gboolean has_complex_routes_v6; + + g_return_val_if_fail(filename != NULL, NULL); + g_return_val_if_fail(out_unhandled && !*out_unhandled, NULL); + + NM_SET_OUT(out_ignore_error, FALSE); + + /* Non-NULL only for unit tests; normally use /etc/sysconfig/network */ + if (!network_file) + network_file = SYSCONFDIR "/sysconfig/network"; + + ifcfg_name = utils_get_ifcfg_name(filename, TRUE); + if (!ifcfg_name) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Ignoring connection '%s' because it's not an ifcfg file", + filename); + return NULL; + } + + main_ifcfg = svOpenFile(filename, error); + if (!main_ifcfg) + return NULL; + + network_ifcfg = svOpenFile(network_file, NULL); + + if (!svGetValueBoolean(main_ifcfg, "NM_CONTROLLED", TRUE)) { + connection = create_unhandled_connection(filename, main_ifcfg, "unmanaged", out_unhandled); + if (!connection) { + NM_SET_OUT(out_ignore_error, TRUE); + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "NM_CONTROLLED was false but device was not uniquely identified; device " + "will be managed"); + } + return g_steal_pointer(&connection); + } + + /* iBFT is handled by nm-initrd-generator during boot. */ + bootproto = svGetValueStr_cp(main_ifcfg, "BOOTPROTO"); + if (bootproto && !g_ascii_strcasecmp(bootproto, "ibft")) { + NM_SET_OUT(out_ignore_error, TRUE); + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Ignoring iBFT configuration"); + g_free(bootproto); + return NULL; + } + g_free(bootproto); + + devtype = svGetValueStr_cp(main_ifcfg, "DEVICETYPE"); + if (devtype) { + if (!g_ascii_strcasecmp(devtype, TYPE_TEAM)) + type = g_strdup(TYPE_TEAM); + else if (!g_ascii_strcasecmp(devtype, TYPE_TEAM_PORT)) { + gs_free char *device = NULL; + + type = svGetValueStr_cp(main_ifcfg, "TYPE"); + device = svGetValueStr_cp(main_ifcfg, "DEVICE"); + + if (type) { + /* nothing to do */ + } else if (device && is_vlan_device(device, main_ifcfg)) + type = g_strdup(TYPE_VLAN); + else + type = g_strdup(TYPE_ETHERNET); + } + g_free(devtype); + } + if (!type) { + gs_free char *t = NULL; + + /* Team and TeamPort types are also accepted by the mere + * presence of TEAM_CONFIG/TEAM_MASTER. They don't require + * DEVICETYPE. */ + t = svGetValueStr_cp(main_ifcfg, "TEAM_CONFIG"); + if (t) + type = g_strdup(TYPE_TEAM); + } + + if (!type) + type = svGetValueStr_cp(main_ifcfg, "TYPE"); + + if (!type) { + gs_free char *tmp = NULL; + char * device; + + if ((tmp = svGetValueStr_cp(main_ifcfg, "IPV6TUNNELIPV4"))) { + NM_SET_OUT(out_ignore_error, TRUE); + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Ignoring unsupported connection due to IPV6TUNNELIPV4"); + return NULL; + } + + device = svGetValueStr_cp(main_ifcfg, "DEVICE"); + if (!device) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "File '%s' had neither TYPE nor DEVICE keys", + filename); + return NULL; + } + + if (!strcmp(device, "lo")) { + NM_SET_OUT(out_ignore_error, TRUE); + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Ignoring loopback device config"); + g_free(device); + return NULL; + } + + if (!test_type) { + if (is_bond_device(device, main_ifcfg)) + type = g_strdup(TYPE_BOND); + else if (is_vlan_device(device, main_ifcfg)) + type = g_strdup(TYPE_VLAN); + else if (is_wifi_device(device, main_ifcfg)) + type = g_strdup(TYPE_WIRELESS); + else { + gs_free char *p_path = NULL; + char * p_device; + gsize i; + + /* network-functions detects DEVICETYPE based on the ifcfg-* name and the existence + * of a ifup script: + * [ -z "$DEVICETYPE" ] && DEVICETYPE=$(echo ${DEVICE} | sed "s/[0-9]*$//") + * later... + * OTHERSCRIPT="/etc/sysconfig/network-scripts/ifup-${DEVICETYPE}" + * */ #define IFUP_PATH_PREFIX "/etc/sysconfig/network-scripts/ifup-" - i = strlen (device); - p_path = g_malloc (NM_STRLEN (IFUP_PATH_PREFIX) + i + 1); - p_device = &p_path[NM_STRLEN (IFUP_PATH_PREFIX)]; - memcpy (p_device, device, i + 1); - - /* strip trailing numbers */ - while (i >= 1) { - i--; - if (p_device[i] < '0' || p_device[i] > '9') - break; - p_device[i] = '\0'; - } - - if (nm_streq (p_device, "eth")) - type = g_strdup (TYPE_ETHERNET); - else if (nm_streq (p_device, "wireless")) - type = g_strdup (TYPE_WIRELESS); - else if (p_device[0]) { - memcpy (p_path, IFUP_PATH_PREFIX, NM_STRLEN (IFUP_PATH_PREFIX)); - if (access (p_path, X_OK) == 0) { - /* for all other types, this is not something we want to handle. */ - NM_SET_OUT (out_ignore_error, TRUE); - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Ignore script for unknown device type which has a matching %s script", - p_path); - return NULL; - } - } - - if (!type) - type = g_strdup (TYPE_ETHERNET); - } - } else { - /* For the unit tests, there won't necessarily be any - * adapters of the connection's type in the system so the - * type can't be tested with ioctls. - */ - type = g_strdup (test_type); - } - - g_free (device); - } else { - /* Check for IBM s390 CTC devices and call them Ethernet */ - if (g_strcmp0 (type, "CTC") == 0) { - g_free (type); - type = g_strdup (TYPE_ETHERNET); - } - } - - if (nm_streq0 (type, TYPE_ETHERNET)) { - gs_free char *bond_options = NULL; - - if (svGetValueStr (main_ifcfg, "BONDING_OPTS", &bond_options)) { - /* initscripts consider these as bond masters */ - g_free (type); - type = g_strdup (TYPE_BOND); - } - } - - if (svGetValueBoolean (main_ifcfg, "BONDING_MASTER", FALSE) && - g_ascii_strcasecmp (type, TYPE_BOND)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "BONDING_MASTER=yes key only allowed in TYPE=bond connections"); - return NULL; - } - - /* Construct the connection */ - if (!g_ascii_strcasecmp (type, TYPE_ETHERNET)) - connection = wired_connection_from_ifcfg (filename, main_ifcfg, error); - else if (!g_ascii_strcasecmp (type, TYPE_WIRELESS)) - connection = wireless_connection_from_ifcfg (filename, main_ifcfg, error); - else if (!g_ascii_strcasecmp (type, TYPE_INFINIBAND)) - connection = infiniband_connection_from_ifcfg (filename, main_ifcfg, error); - else if (!g_ascii_strcasecmp (type, TYPE_BOND)) - connection = bond_connection_from_ifcfg (filename, main_ifcfg, error); - else if (!g_ascii_strcasecmp (type, TYPE_TEAM)) - connection = team_connection_from_ifcfg (filename, main_ifcfg, error); - else if (!g_ascii_strcasecmp (type, TYPE_VLAN)) - connection = vlan_connection_from_ifcfg (filename, main_ifcfg, error); - else if (!g_ascii_strcasecmp (type, TYPE_BRIDGE)) - connection = bridge_connection_from_ifcfg (filename, main_ifcfg, error); - else { - connection = create_unhandled_connection (filename, main_ifcfg, "unrecognized", out_unhandled); - if (!connection) { - PARSE_WARNING ("connection type was unrecognized but device was not uniquely identified; device may be managed"); - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Failed to read unrecognized connection"); - } - return g_steal_pointer (&connection); - } - - if (!connection) - return NULL; - - parse_ethtool_options (main_ifcfg, connection); - - has_complex_routes_v4 = utils_has_complex_routes (filename, AF_INET); - has_complex_routes_v6 = utils_has_complex_routes (filename, AF_INET6); - - if (has_complex_routes_v4 || has_complex_routes_v6) { - if (has_complex_routes_v4 && !has_complex_routes_v6) - PARSE_WARNING ("'rule-' file is present; you will need to use a dispatcher script to apply these routes"); - else if (has_complex_routes_v6 && !has_complex_routes_v4) - PARSE_WARNING ("'rule6-' file is present; you will need to use a dispatcher script to apply these routes"); - else - PARSE_WARNING ("'rule-' and 'rule6-' files are present; you will need to use a dispatcher script to apply these routes"); - } - - s_ip6 = make_ip6_setting (main_ifcfg, - network_ifcfg, - !has_complex_routes_v4 && !has_complex_routes_v6, - error); - if (!s_ip6) - return NULL; - nm_connection_add_setting (connection, s_ip6); - - s_ip4 = make_ip4_setting (main_ifcfg, - network_ifcfg, - !has_complex_routes_v4 && !has_complex_routes_v6, - &has_ip4_defroute, - error); - if (!s_ip4) - return NULL; - read_aliases (NM_SETTING_IP_CONFIG (s_ip4), - !has_ip4_defroute && !nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (s_ip4)), - filename); - nm_connection_add_setting (connection, s_ip4); - - read_routing_rules (main_ifcfg, - !has_complex_routes_v4 && !has_complex_routes_v6, - NM_SETTING_IP_CONFIG (s_ip4), - NM_SETTING_IP_CONFIG (s_ip6)); - - s_sriov = make_sriov_setting (main_ifcfg); - if (s_sriov) - nm_connection_add_setting (connection, s_sriov); - - s_tc = make_tc_setting (main_ifcfg); - if (s_tc) - nm_connection_add_setting (connection, s_tc); - - /* For backwards compatibility, if IPv4 is disabled or the - * config fails for some reason, we read DOMAIN and put the - * values into IPv6 config instead of IPv4. - */ - check_dns_search_domains (main_ifcfg, s_ip4, s_ip6); - - s_proxy = make_proxy_setting (main_ifcfg); - if (s_proxy) - nm_connection_add_setting (connection, s_proxy); - - s_user = make_user_setting (main_ifcfg); - if (s_user) - nm_connection_add_setting (connection, s_user); - - s_match = make_match_setting (main_ifcfg); - if (s_match) - nm_connection_add_setting (connection, s_match); - - s_port = make_bridge_port_setting (main_ifcfg); - if (s_port) - nm_connection_add_setting (connection, s_port); - - s_port = make_team_port_setting (main_ifcfg); - if (s_port) - nm_connection_add_setting (connection, s_port); - - if (!make_dcb_setting (main_ifcfg, &s_dcb, error)) - return NULL; - if (s_dcb) - nm_connection_add_setting (connection, s_dcb); - - if (!nm_connection_normalize (connection, NULL, NULL, error)) - return NULL; - - return g_steal_pointer (&connection); + i = strlen(device); + p_path = g_malloc(NM_STRLEN(IFUP_PATH_PREFIX) + i + 1); + p_device = &p_path[NM_STRLEN(IFUP_PATH_PREFIX)]; + memcpy(p_device, device, i + 1); + + /* strip trailing numbers */ + while (i >= 1) { + i--; + if (p_device[i] < '0' || p_device[i] > '9') + break; + p_device[i] = '\0'; + } + + if (nm_streq(p_device, "eth")) + type = g_strdup(TYPE_ETHERNET); + else if (nm_streq(p_device, "wireless")) + type = g_strdup(TYPE_WIRELESS); + else if (p_device[0]) { + memcpy(p_path, IFUP_PATH_PREFIX, NM_STRLEN(IFUP_PATH_PREFIX)); + if (access(p_path, X_OK) == 0) { + /* for all other types, this is not something we want to handle. */ + NM_SET_OUT(out_ignore_error, TRUE); + g_set_error( + error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Ignore script for unknown device type which has a matching %s script", + p_path); + return NULL; + } + } + + if (!type) + type = g_strdup(TYPE_ETHERNET); + } + } else { + /* For the unit tests, there won't necessarily be any + * adapters of the connection's type in the system so the + * type can't be tested with ioctls. + */ + type = g_strdup(test_type); + } + + g_free(device); + } else { + /* Check for IBM s390 CTC devices and call them Ethernet */ + if (g_strcmp0(type, "CTC") == 0) { + g_free(type); + type = g_strdup(TYPE_ETHERNET); + } + } + + if (nm_streq0(type, TYPE_ETHERNET)) { + gs_free char *bond_options = NULL; + + if (svGetValueStr(main_ifcfg, "BONDING_OPTS", &bond_options)) { + /* initscripts consider these as bond masters */ + g_free(type); + type = g_strdup(TYPE_BOND); + } + } + + if (svGetValueBoolean(main_ifcfg, "BONDING_MASTER", FALSE) + && g_ascii_strcasecmp(type, TYPE_BOND)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "BONDING_MASTER=yes key only allowed in TYPE=bond connections"); + return NULL; + } + + /* Construct the connection */ + if (!g_ascii_strcasecmp(type, TYPE_ETHERNET)) + connection = wired_connection_from_ifcfg(filename, main_ifcfg, error); + else if (!g_ascii_strcasecmp(type, TYPE_WIRELESS)) + connection = wireless_connection_from_ifcfg(filename, main_ifcfg, error); + else if (!g_ascii_strcasecmp(type, TYPE_INFINIBAND)) + connection = infiniband_connection_from_ifcfg(filename, main_ifcfg, error); + else if (!g_ascii_strcasecmp(type, TYPE_BOND)) + connection = bond_connection_from_ifcfg(filename, main_ifcfg, error); + else if (!g_ascii_strcasecmp(type, TYPE_TEAM)) + connection = team_connection_from_ifcfg(filename, main_ifcfg, error); + else if (!g_ascii_strcasecmp(type, TYPE_VLAN)) + connection = vlan_connection_from_ifcfg(filename, main_ifcfg, error); + else if (!g_ascii_strcasecmp(type, TYPE_BRIDGE)) + connection = bridge_connection_from_ifcfg(filename, main_ifcfg, error); + else { + connection = + create_unhandled_connection(filename, main_ifcfg, "unrecognized", out_unhandled); + if (!connection) { + PARSE_WARNING("connection type was unrecognized but device was not uniquely " + "identified; device may be managed"); + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to read unrecognized connection"); + } + return g_steal_pointer(&connection); + } + + if (!connection) + return NULL; + + parse_ethtool_options(main_ifcfg, connection); + + has_complex_routes_v4 = utils_has_complex_routes(filename, AF_INET); + has_complex_routes_v6 = utils_has_complex_routes(filename, AF_INET6); + + if (has_complex_routes_v4 || has_complex_routes_v6) { + if (has_complex_routes_v4 && !has_complex_routes_v6) + PARSE_WARNING("'rule-' file is present; you will need to use a dispatcher script to " + "apply these routes"); + else if (has_complex_routes_v6 && !has_complex_routes_v4) + PARSE_WARNING("'rule6-' file is present; you will need to use a dispatcher script to " + "apply these routes"); + else + PARSE_WARNING("'rule-' and 'rule6-' files are present; you will need to use a " + "dispatcher script to apply these routes"); + } + + s_ip6 = make_ip6_setting(main_ifcfg, + network_ifcfg, + !has_complex_routes_v4 && !has_complex_routes_v6, + error); + if (!s_ip6) + return NULL; + nm_connection_add_setting(connection, s_ip6); + + s_ip4 = make_ip4_setting(main_ifcfg, + network_ifcfg, + !has_complex_routes_v4 && !has_complex_routes_v6, + &has_ip4_defroute, + error); + if (!s_ip4) + return NULL; + read_aliases(NM_SETTING_IP_CONFIG(s_ip4), + !has_ip4_defroute + && !nm_setting_ip_config_get_gateway(NM_SETTING_IP_CONFIG(s_ip4)), + filename); + nm_connection_add_setting(connection, s_ip4); + + read_routing_rules(main_ifcfg, + !has_complex_routes_v4 && !has_complex_routes_v6, + NM_SETTING_IP_CONFIG(s_ip4), + NM_SETTING_IP_CONFIG(s_ip6)); + + s_sriov = make_sriov_setting(main_ifcfg); + if (s_sriov) + nm_connection_add_setting(connection, s_sriov); + + s_tc = make_tc_setting(main_ifcfg); + if (s_tc) + nm_connection_add_setting(connection, s_tc); + + /* For backwards compatibility, if IPv4 is disabled or the + * config fails for some reason, we read DOMAIN and put the + * values into IPv6 config instead of IPv4. + */ + check_dns_search_domains(main_ifcfg, s_ip4, s_ip6); + + s_proxy = make_proxy_setting(main_ifcfg); + if (s_proxy) + nm_connection_add_setting(connection, s_proxy); + + s_user = make_user_setting(main_ifcfg); + if (s_user) + nm_connection_add_setting(connection, s_user); + + s_match = make_match_setting(main_ifcfg); + if (s_match) + nm_connection_add_setting(connection, s_match); + + s_port = make_bridge_port_setting(main_ifcfg); + if (s_port) + nm_connection_add_setting(connection, s_port); + + s_port = make_team_port_setting(main_ifcfg); + if (s_port) + nm_connection_add_setting(connection, s_port); + + if (!make_dcb_setting(main_ifcfg, &s_dcb, error)) + return NULL; + if (s_dcb) + nm_connection_add_setting(connection, s_dcb); + + if (!nm_connection_normalize(connection, NULL, NULL, error)) + return NULL; + + return g_steal_pointer(&connection); } NMConnection * -connection_from_file (const char *filename, - char **out_unhandled, - GError **error, - gboolean *out_ignore_error) +connection_from_file(const char *filename, + char ** out_unhandled, + GError ** error, + gboolean * out_ignore_error) { - return connection_from_file_full (filename, NULL, NULL, - out_unhandled, - error, - out_ignore_error); + return connection_from_file_full(filename, NULL, NULL, out_unhandled, error, out_ignore_error); } NMConnection * -nmtst_connection_from_file (const char *filename, - const char *network_file, - const char *test_type, - char **out_unhandled, - GError **error) +nmtst_connection_from_file(const char *filename, + const char *network_file, + const char *test_type, + char ** out_unhandled, + GError ** error) { - return connection_from_file_full (filename, - network_file, - test_type, - out_unhandled, - error, - NULL); + return connection_from_file_full(filename, network_file, test_type, out_unhandled, error, NULL); } diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h index 9319a064..7bbb6d80 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 Red Hat, Inc. */ @@ -8,15 +8,15 @@ #include "nm-connection.h" -NMConnection *connection_from_file (const char *filename, - char **out_unhandled, - GError **error, - gboolean *out_ignore_error); +NMConnection *connection_from_file(const char *filename, + char ** out_unhandled, + GError ** error, + gboolean * out_ignore_error); -NMConnection *nmtst_connection_from_file (const char *filename, - const char *network_file, - const char *test_type, - char **out_unhandled, - GError **error); +NMConnection *nmtst_connection_from_file(const char *filename, + const char *network_file, + const char *test_type, + char ** out_unhandled, + GError ** error); -#endif /* __NMS_IFCFG_RH_READER_H__ */ +#endif /* __NMS_IFCFG_RH_READER_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c index 79101296..28ec893f 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -15,170 +15,161 @@ /*****************************************************************************/ struct _NMSIfcfgRHStorageClass { - NMSettingsStorageClass parent; + NMSettingsStorageClass parent; }; -G_DEFINE_TYPE (NMSIfcfgRHStorage, nms_ifcfg_rh_storage, NM_TYPE_SETTINGS_STORAGE) +G_DEFINE_TYPE(NMSIfcfgRHStorage, nms_ifcfg_rh_storage, NM_TYPE_SETTINGS_STORAGE) /*****************************************************************************/ gboolean -nms_ifcfg_rh_storage_equal_type (const NMSIfcfgRHStorage *self_a, - const NMSIfcfgRHStorage *self_b) +nms_ifcfg_rh_storage_equal_type(const NMSIfcfgRHStorage *self_a, const NMSIfcfgRHStorage *self_b) { - return (self_a == self_b) - || ( self_a - && self_b - && nm_streq0 (nms_ifcfg_rh_storage_get_uuid_opt (self_a), - nms_ifcfg_rh_storage_get_uuid_opt (self_b)) - && nm_streq0 (self_a->unmanaged_spec, - self_b->unmanaged_spec) - && nm_streq0 (self_a->unrecognized_spec, - self_b->unrecognized_spec)); + return (self_a == self_b) + || (self_a && self_b + && nm_streq0(nms_ifcfg_rh_storage_get_uuid_opt(self_a), + nms_ifcfg_rh_storage_get_uuid_opt(self_b)) + && nm_streq0(self_a->unmanaged_spec, self_b->unmanaged_spec) + && nm_streq0(self_a->unrecognized_spec, self_b->unrecognized_spec)); } void -nms_ifcfg_rh_storage_copy_content (NMSIfcfgRHStorage *dst, - const NMSIfcfgRHStorage *src) +nms_ifcfg_rh_storage_copy_content(NMSIfcfgRHStorage *dst, const NMSIfcfgRHStorage *src) { - nm_assert (src != dst); - nm_assert (src && dst); - nm_assert (nms_ifcfg_rh_storage_equal_type (dst, src)); - nm_assert ( nms_ifcfg_rh_storage_get_filename (dst) - && nm_streq (nms_ifcfg_rh_storage_get_filename (dst), - nms_ifcfg_rh_storage_get_filename (src))); - - nm_g_object_ref_set (&dst->connection, src->connection); - g_free (dst->unmanaged_spec); - g_free (dst->unrecognized_spec); - dst->unmanaged_spec = g_strdup (src->unmanaged_spec); - dst->unrecognized_spec = g_strdup (src->unrecognized_spec); - dst->stat_mtime = src->stat_mtime; + nm_assert(src != dst); + nm_assert(src && dst); + nm_assert(nms_ifcfg_rh_storage_equal_type(dst, src)); + nm_assert(nms_ifcfg_rh_storage_get_filename(dst) + && nm_streq(nms_ifcfg_rh_storage_get_filename(dst), + nms_ifcfg_rh_storage_get_filename(src))); + + nm_g_object_ref_set(&dst->connection, src->connection); + g_free(dst->unmanaged_spec); + g_free(dst->unrecognized_spec); + dst->unmanaged_spec = g_strdup(src->unmanaged_spec); + dst->unrecognized_spec = g_strdup(src->unrecognized_spec); + dst->stat_mtime = src->stat_mtime; } NMConnection * -nms_ifcfg_rh_storage_steal_connection (NMSIfcfgRHStorage *self) +nms_ifcfg_rh_storage_steal_connection(NMSIfcfgRHStorage *self) { - nm_assert (NMS_IS_IFCFG_RH_STORAGE (self)); + nm_assert(NMS_IS_IFCFG_RH_STORAGE(self)); - return g_steal_pointer (&self->connection); + return g_steal_pointer(&self->connection); } /*****************************************************************************/ static int -cmp_fcn (const NMSIfcfgRHStorage *a, - const NMSIfcfgRHStorage *b) +cmp_fcn(const NMSIfcfgRHStorage *a, const NMSIfcfgRHStorage *b) { - nm_assert (NMS_IS_IFCFG_RH_STORAGE (a)); - nm_assert (NMS_IS_IFCFG_RH_STORAGE (b)); - nm_assert (a != b); + nm_assert(NMS_IS_IFCFG_RH_STORAGE(a)); + nm_assert(NMS_IS_IFCFG_RH_STORAGE(b)); + nm_assert(a != b); - /* newer files are more important. */ - NM_CMP_FIELD (a, b, stat_mtime.tv_sec); - NM_CMP_FIELD (a, b, stat_mtime.tv_nsec); + /* newer files are more important. */ + NM_CMP_FIELD(a, b, stat_mtime.tv_sec); + NM_CMP_FIELD(a, b, stat_mtime.tv_nsec); - NM_CMP_DIRECT_STRCMP (nms_ifcfg_rh_storage_get_filename (a), nms_ifcfg_rh_storage_get_filename (b)); + NM_CMP_DIRECT_STRCMP(nms_ifcfg_rh_storage_get_filename(a), + nms_ifcfg_rh_storage_get_filename(b)); - return 0; + return 0; } /*****************************************************************************/ static void -nms_ifcfg_rh_storage_init (NMSIfcfgRHStorage *self) -{ -} +nms_ifcfg_rh_storage_init(NMSIfcfgRHStorage *self) +{} static NMSIfcfgRHStorage * -_storage_new (NMSIfcfgRHPlugin *plugin, - const char *uuid, - const char *filename) +_storage_new(NMSIfcfgRHPlugin *plugin, const char *uuid, const char *filename) { - nm_assert (NMS_IS_IFCFG_RH_PLUGIN (plugin)); - nm_assert (!uuid || nm_utils_is_uuid (uuid)); - nm_assert (filename && filename[0] == '/'); - - return g_object_new (NMS_TYPE_IFCFG_RH_STORAGE, - NM_SETTINGS_STORAGE_PLUGIN, plugin, - NM_SETTINGS_STORAGE_UUID, uuid, - NM_SETTINGS_STORAGE_FILENAME, filename, - NULL); + nm_assert(NMS_IS_IFCFG_RH_PLUGIN(plugin)); + nm_assert(!uuid || nm_utils_is_uuid(uuid)); + nm_assert(filename && filename[0] == '/'); + + return g_object_new(NMS_TYPE_IFCFG_RH_STORAGE, + NM_SETTINGS_STORAGE_PLUGIN, + plugin, + NM_SETTINGS_STORAGE_UUID, + uuid, + NM_SETTINGS_STORAGE_FILENAME, + filename, + NULL); } NMSIfcfgRHStorage * -nms_ifcfg_rh_storage_new_connection (NMSIfcfgRHPlugin *plugin, - const char *filename, - NMConnection *connection_take, - const struct timespec *mtime) +nms_ifcfg_rh_storage_new_connection(NMSIfcfgRHPlugin * plugin, + const char * filename, + NMConnection * connection_take, + const struct timespec *mtime) { - NMSIfcfgRHStorage *self; - - nm_assert (NM_IS_CONNECTION (connection_take)); - nm_assert (_nm_connection_verify (connection_take, NULL) == NM_SETTING_VERIFY_SUCCESS); - nmtst_connection_assert_unchanging (connection_take); - - self = _storage_new (plugin, - nm_connection_get_uuid (connection_take), - filename); - self->connection = connection_take; - if (mtime) - self->stat_mtime = *mtime; - return self; + NMSIfcfgRHStorage *self; + + nm_assert(NM_IS_CONNECTION(connection_take)); + nm_assert(_nm_connection_verify(connection_take, NULL) == NM_SETTING_VERIFY_SUCCESS); + nmtst_connection_assert_unchanging(connection_take); + + self = _storage_new(plugin, nm_connection_get_uuid(connection_take), filename); + self->connection = connection_take; + if (mtime) + self->stat_mtime = *mtime; + return self; } NMSIfcfgRHStorage * -nms_ifcfg_rh_storage_new_unhandled (NMSIfcfgRHPlugin *plugin, - const char *filename, - const char *unmanaged_spec, - const char *unrecognized_spec) +nms_ifcfg_rh_storage_new_unhandled(NMSIfcfgRHPlugin *plugin, + const char * filename, + const char * unmanaged_spec, + const char * unrecognized_spec) { - NMSIfcfgRHStorage *self; + NMSIfcfgRHStorage *self; - nm_assert (unmanaged_spec || unrecognized_spec); + nm_assert(unmanaged_spec || unrecognized_spec); - self = _storage_new (plugin, - NULL, - filename); - self->unmanaged_spec = g_strdup (unmanaged_spec); - self->unrecognized_spec = g_strdup (unrecognized_spec); - return self; + self = _storage_new(plugin, NULL, filename); + self->unmanaged_spec = g_strdup(unmanaged_spec); + self->unrecognized_spec = g_strdup(unrecognized_spec); + return self; } static void -_storage_clear (NMSIfcfgRHStorage *self) +_storage_clear(NMSIfcfgRHStorage *self) { - c_list_unlink (&self->parent._storage_lst); - c_list_unlink (&self->parent._storage_by_uuid_lst); - nm_clear_g_free (&self->unmanaged_spec); - nm_clear_g_free (&self->unrecognized_spec); - g_clear_object (&self->connection); + c_list_unlink(&self->parent._storage_lst); + c_list_unlink(&self->parent._storage_by_uuid_lst); + nm_clear_g_free(&self->unmanaged_spec); + nm_clear_g_free(&self->unrecognized_spec); + g_clear_object(&self->connection); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMSIfcfgRHStorage *self = NMS_IFCFG_RH_STORAGE (object); + NMSIfcfgRHStorage *self = NMS_IFCFG_RH_STORAGE(object); - _storage_clear (self); + _storage_clear(self); - G_OBJECT_CLASS (nms_ifcfg_rh_storage_parent_class)->dispose (object); + G_OBJECT_CLASS(nms_ifcfg_rh_storage_parent_class)->dispose(object); } void -nms_ifcfg_rh_storage_destroy (NMSIfcfgRHStorage *self) +nms_ifcfg_rh_storage_destroy(NMSIfcfgRHStorage *self) { - _storage_clear (self); - g_object_unref (self); + _storage_clear(self); + g_object_unref(self); } static void -nms_ifcfg_rh_storage_class_init (NMSIfcfgRHStorageClass *klass) +nms_ifcfg_rh_storage_class_init(NMSIfcfgRHStorageClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMSettingsStorageClass *storage_class = NM_SETTINGS_STORAGE_CLASS (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingsStorageClass *storage_class = NM_SETTINGS_STORAGE_CLASS(klass); - object_class->dispose = dispose; + object_class->dispose = dispose; - storage_class->cmp_fcn = (int (*) (NMSettingsStorage *, NMSettingsStorage *)) cmp_fcn; + storage_class->cmp_fcn = (int (*)(NMSettingsStorage *, NMSettingsStorage *)) cmp_fcn; } diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h index 1b2b58e6..b8787def 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2019 Red Hat, Inc. */ @@ -11,69 +11,72 @@ /*****************************************************************************/ -#define NMS_TYPE_IFCFG_RH_STORAGE (nms_ifcfg_rh_storage_get_type ()) -#define NMS_IFCFG_RH_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMS_TYPE_IFCFG_RH_STORAGE, NMSIfcfgRHStorage)) -#define NMS_IFCFG_RH_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMS_TYPE_IFCFG_RH_STORAGE, NMSIfcfgRHStorageClass)) -#define NMS_IS_IFCFG_RH_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMS_TYPE_IFCFG_RH_STORAGE)) -#define NMS_IS_IFCFG_RH_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMS_TYPE_IFCFG_RH_STORAGE)) -#define NMS_IFCFG_RH_STORAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMS_TYPE_IFCFG_RH_STORAGE, NMSIfcfgRHStorageClass)) +#define NMS_TYPE_IFCFG_RH_STORAGE (nms_ifcfg_rh_storage_get_type()) +#define NMS_IFCFG_RH_STORAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NMS_TYPE_IFCFG_RH_STORAGE, NMSIfcfgRHStorage)) +#define NMS_IFCFG_RH_STORAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NMS_TYPE_IFCFG_RH_STORAGE, NMSIfcfgRHStorageClass)) +#define NMS_IS_IFCFG_RH_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMS_TYPE_IFCFG_RH_STORAGE)) +#define NMS_IS_IFCFG_RH_STORAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NMS_TYPE_IFCFG_RH_STORAGE)) +#define NMS_IFCFG_RH_STORAGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NMS_TYPE_IFCFG_RH_STORAGE, NMSIfcfgRHStorageClass)) typedef struct { - NMSettingsStorage parent; + NMSettingsStorage parent; - NMConnection *connection; + NMConnection *connection; - char *unmanaged_spec; - char *unrecognized_spec; + char *unmanaged_spec; + char *unrecognized_spec; - /* The timestamp (stat's mtime) of the file. Newer files have - * higher priority. */ - struct timespec stat_mtime; + /* The timestamp (stat's mtime) of the file. Newer files have + * higher priority. */ + struct timespec stat_mtime; - bool dirty:1; + bool dirty : 1; } NMSIfcfgRHStorage; typedef struct _NMSIfcfgRHStorageClass NMSIfcfgRHStorageClass; -GType nms_ifcfg_rh_storage_get_type (void); +GType nms_ifcfg_rh_storage_get_type(void); struct _NMSIfcfgRHPlugin; -NMSIfcfgRHStorage *nms_ifcfg_rh_storage_new_connection (struct _NMSIfcfgRHPlugin *plugin, - const char *filename, - NMConnection *connection_take, - const struct timespec *mtime); +NMSIfcfgRHStorage *nms_ifcfg_rh_storage_new_connection(struct _NMSIfcfgRHPlugin *plugin, + const char * filename, + NMConnection * connection_take, + const struct timespec * mtime); -NMSIfcfgRHStorage *nms_ifcfg_rh_storage_new_unhandled (struct _NMSIfcfgRHPlugin *plugin, - const char *filename, - const char *unmanaged_spec, - const char *unrecognized_spec); +NMSIfcfgRHStorage *nms_ifcfg_rh_storage_new_unhandled(struct _NMSIfcfgRHPlugin *plugin, + const char * filename, + const char * unmanaged_spec, + const char * unrecognized_spec); -void nms_ifcfg_rh_storage_destroy (NMSIfcfgRHStorage *self); +void nms_ifcfg_rh_storage_destroy(NMSIfcfgRHStorage *self); /*****************************************************************************/ -gboolean nms_ifcfg_rh_storage_equal_type (const NMSIfcfgRHStorage *self_a, - const NMSIfcfgRHStorage *self_b); +gboolean nms_ifcfg_rh_storage_equal_type(const NMSIfcfgRHStorage *self_a, + const NMSIfcfgRHStorage *self_b); -void nms_ifcfg_rh_storage_copy_content (NMSIfcfgRHStorage *dst, - const NMSIfcfgRHStorage *src); +void nms_ifcfg_rh_storage_copy_content(NMSIfcfgRHStorage *dst, const NMSIfcfgRHStorage *src); -NMConnection *nms_ifcfg_rh_storage_steal_connection (NMSIfcfgRHStorage *self); +NMConnection *nms_ifcfg_rh_storage_steal_connection(NMSIfcfgRHStorage *self); /*****************************************************************************/ static inline const char * -nms_ifcfg_rh_storage_get_uuid_opt (const NMSIfcfgRHStorage *self) +nms_ifcfg_rh_storage_get_uuid_opt(const NMSIfcfgRHStorage *self) { - return nm_settings_storage_get_uuid_opt ((const NMSettingsStorage *) self); + return nm_settings_storage_get_uuid_opt((const NMSettingsStorage *) self); } static inline const char * -nms_ifcfg_rh_storage_get_filename (const NMSIfcfgRHStorage *self) +nms_ifcfg_rh_storage_get_filename(const NMSIfcfgRHStorage *self) { - return nm_settings_storage_get_filename ((const NMSettingsStorage *) self); + return nm_settings_storage_get_filename((const NMSettingsStorage *) self); } #endif /* __NMS_IFCFG_RH_STORAGE_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c index d1500dbd..567dc8a8 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 - 2017 Red Hat, Inc. */ @@ -17,25 +17,25 @@ /*****************************************************************************/ gboolean -nms_ifcfg_rh_utils_parse_unhandled_spec (const char *unhandled_spec, - const char **out_unmanaged_spec, - const char **out_unrecognized_spec) +nms_ifcfg_rh_utils_parse_unhandled_spec(const char * unhandled_spec, + const char **out_unmanaged_spec, + const char **out_unrecognized_spec) { - if (unhandled_spec) { - if (NM_STR_HAS_PREFIX (unhandled_spec, "unmanaged:")) { - NM_SET_OUT (out_unmanaged_spec, &unhandled_spec[NM_STRLEN ("unmanaged:")]); - NM_SET_OUT (out_unrecognized_spec, NULL); - return TRUE; - } - if (NM_STR_HAS_PREFIX (unhandled_spec, "unrecognized:")) { - NM_SET_OUT (out_unmanaged_spec, NULL); - NM_SET_OUT (out_unrecognized_spec, &unhandled_spec[NM_STRLEN ("unrecognized:")]); - return TRUE; - } - } - NM_SET_OUT (out_unmanaged_spec, NULL); - NM_SET_OUT (out_unrecognized_spec, NULL); - return FALSE; + if (unhandled_spec) { + if (NM_STR_HAS_PREFIX(unhandled_spec, "unmanaged:")) { + NM_SET_OUT(out_unmanaged_spec, &unhandled_spec[NM_STRLEN("unmanaged:")]); + NM_SET_OUT(out_unrecognized_spec, NULL); + return TRUE; + } + if (NM_STR_HAS_PREFIX(unhandled_spec, "unrecognized:")) { + NM_SET_OUT(out_unmanaged_spec, NULL); + NM_SET_OUT(out_unrecognized_spec, &unhandled_spec[NM_STRLEN("unrecognized:")]); + return TRUE; + } + } + NM_SET_OUT(out_unmanaged_spec, NULL); + NM_SET_OUT(out_unrecognized_spec, NULL); + return FALSE; } /*****************************************************************************/ @@ -47,210 +47,206 @@ nms_ifcfg_rh_utils_parse_unhandled_spec (const char *unhandled_spec, * Implementation taken from upstart. */ static gboolean -check_rpm_temp_suffix (const char *path) +check_rpm_temp_suffix(const char *path) { - const char *ptr; + const char *ptr; - g_return_val_if_fail (path != NULL, FALSE); + g_return_val_if_fail(path != NULL, FALSE); - /* Matches *;[a-fA-F0-9]{8}; used by rpm */ - ptr = strrchr (path, ';'); - if ( ptr - && strspn (ptr + 1, "abcdefABCDEF0123456789") == 8 - && !ptr[9]) - return TRUE; - return FALSE; + /* Matches *;[a-fA-F0-9]{8}; used by rpm */ + ptr = strrchr(path, ';'); + if (ptr && strspn(ptr + 1, "abcdefABCDEF0123456789") == 8 && !ptr[9]) + return TRUE; + return FALSE; } static gboolean -check_suffix (const char *base, const char *tag) +check_suffix(const char *base, const char *tag) { - int len, tag_len; + int len, tag_len; - g_return_val_if_fail (base != NULL, TRUE); - g_return_val_if_fail (tag != NULL, TRUE); + g_return_val_if_fail(base != NULL, TRUE); + g_return_val_if_fail(tag != NULL, TRUE); - len = strlen (base); - tag_len = strlen (tag); - if ((len > tag_len) && !g_ascii_strcasecmp (base + len - tag_len, tag)) - return TRUE; - return FALSE; + len = strlen(base); + tag_len = strlen(tag); + if ((len > tag_len) && !g_ascii_strcasecmp(base + len - tag_len, tag)) + return TRUE; + return FALSE; } gboolean -utils_should_ignore_file (const char *filename, gboolean only_ifcfg) +utils_should_ignore_file(const char *filename, gboolean only_ifcfg) { - gs_free char *base = NULL; - - g_return_val_if_fail (filename != NULL, TRUE); - - base = g_path_get_basename (filename); - - /* Only handle ifcfg, keys, and routes files */ - if (strncmp (base, IFCFG_TAG, strlen (IFCFG_TAG)) != 0) { - if (only_ifcfg) - return TRUE; - else if ( strncmp (base, KEYS_TAG, strlen (KEYS_TAG)) != 0 - && strncmp (base, ROUTE_TAG, strlen (ROUTE_TAG)) != 0 - && strncmp (base, ROUTE6_TAG, strlen (ROUTE6_TAG)) != 0) - return TRUE; - } - - /* But not those that have certain suffixes */ - if ( check_suffix (base, BAK_TAG) - || check_suffix (base, TILDE_TAG) - || check_suffix (base, ORIG_TAG) - || check_suffix (base, REJ_TAG) - || check_suffix (base, RPMNEW_TAG) - || check_suffix (base, AUGNEW_TAG) - || check_suffix (base, AUGTMP_TAG) - || check_rpm_temp_suffix (base)) - return TRUE; - - return FALSE; + gs_free char *base = NULL; + + g_return_val_if_fail(filename != NULL, TRUE); + + base = g_path_get_basename(filename); + + /* Only handle ifcfg, keys, and routes files */ + if (strncmp(base, IFCFG_TAG, strlen(IFCFG_TAG)) != 0) { + if (only_ifcfg) + return TRUE; + else if (strncmp(base, KEYS_TAG, strlen(KEYS_TAG)) != 0 + && strncmp(base, ROUTE_TAG, strlen(ROUTE_TAG)) != 0 + && strncmp(base, ROUTE6_TAG, strlen(ROUTE6_TAG)) != 0) + return TRUE; + } + + /* But not those that have certain suffixes */ + if (check_suffix(base, BAK_TAG) || check_suffix(base, TILDE_TAG) || check_suffix(base, ORIG_TAG) + || check_suffix(base, REJ_TAG) || check_suffix(base, RPMNEW_TAG) + || check_suffix(base, AUGNEW_TAG) || check_suffix(base, AUGTMP_TAG) + || check_rpm_temp_suffix(base)) + return TRUE; + + return FALSE; } char * -utils_cert_path (const char *parent, const char *suffix, const char *extension) +utils_cert_path(const char *parent, const char *suffix, const char *extension) { - gs_free char *dir = NULL; - const char *name; + gs_free char *dir = NULL; + const char * name; - g_return_val_if_fail (parent, NULL); - g_return_val_if_fail (suffix, NULL); - g_return_val_if_fail (extension, NULL); + g_return_val_if_fail(parent, NULL); + g_return_val_if_fail(suffix, NULL); + g_return_val_if_fail(extension, NULL); - name = utils_get_ifcfg_name (parent, FALSE); - g_return_val_if_fail (name, NULL); + name = utils_get_ifcfg_name(parent, FALSE); + g_return_val_if_fail(name, NULL); - dir = g_path_get_dirname (parent); - return g_strdup_printf ("%s/%s-%s.%s", dir, name, suffix, extension); + dir = g_path_get_dirname(parent); + return g_strdup_printf("%s/%s-%s.%s", dir, name, suffix, extension); } const char * -utils_get_ifcfg_name (const char *file, gboolean only_ifcfg) +utils_get_ifcfg_name(const char *file, gboolean only_ifcfg) { - const char *name; - - g_return_val_if_fail (file != NULL, NULL); - - name = strrchr (file, '/'); - if (!name) - name = file; - else - name++; - if (!*name) - return NULL; - -#define MATCH_TAG_AND_RETURN(name, TAG) \ - G_STMT_START { \ - if (strncmp (name, TAG, NM_STRLEN (TAG)) == 0) { \ - name += NM_STRLEN (TAG); \ - if (name[0] == '\0') \ - return NULL; \ - else \ - return name; \ - } \ - } G_STMT_END - - /* Do not detect alias files and return 'eth0:0' instead of 'eth0'. - * Unfortunately, we cannot be sure that our files don't contain colons, - * so we cannot reject files with colons. - * - * Instead, you must not call utils_get_ifcfg_name() with an alias file - * or files that are ignored. */ - MATCH_TAG_AND_RETURN (name, IFCFG_TAG); - if (!only_ifcfg) { - MATCH_TAG_AND_RETURN (name, KEYS_TAG); - MATCH_TAG_AND_RETURN (name, ROUTE_TAG); - MATCH_TAG_AND_RETURN (name, ROUTE6_TAG); - } - - return NULL; + const char *name; + + g_return_val_if_fail(file != NULL, NULL); + + name = strrchr(file, '/'); + if (!name) + name = file; + else + name++; + if (!*name) + return NULL; + +#define MATCH_TAG_AND_RETURN(name, TAG) \ + G_STMT_START \ + { \ + if (strncmp(name, TAG, NM_STRLEN(TAG)) == 0) { \ + name += NM_STRLEN(TAG); \ + if (name[0] == '\0') \ + return NULL; \ + else \ + return name; \ + } \ + } \ + G_STMT_END + + /* Do not detect alias files and return 'eth0:0' instead of 'eth0'. + * Unfortunately, we cannot be sure that our files don't contain colons, + * so we cannot reject files with colons. + * + * Instead, you must not call utils_get_ifcfg_name() with an alias file + * or files that are ignored. */ + MATCH_TAG_AND_RETURN(name, IFCFG_TAG); + if (!only_ifcfg) { + MATCH_TAG_AND_RETURN(name, KEYS_TAG); + MATCH_TAG_AND_RETURN(name, ROUTE_TAG); + MATCH_TAG_AND_RETURN(name, ROUTE6_TAG); + } + + return NULL; } /* Used to get any ifcfg/extra file path from any other ifcfg/extra path * in the form . */ static char * -utils_get_extra_path (const char *parent, const char *tag) +utils_get_extra_path(const char *parent, const char *tag) { - char *item_path = NULL, *dirname; - const char *name; - - g_return_val_if_fail (parent != NULL, NULL); - g_return_val_if_fail (tag != NULL, NULL); - - dirname = g_path_get_dirname (parent); - if (!dirname) - g_return_val_if_reached (NULL); - - name = utils_get_ifcfg_name (parent, FALSE); - if (name) { - if (!strcmp (dirname, ".")) - item_path = g_strdup_printf ("%s%s", tag, name); - else - item_path = g_strdup_printf ("%s/%s%s", dirname, tag, name); - } - g_free (dirname); - - return item_path; + char * item_path = NULL, *dirname; + const char *name; + + g_return_val_if_fail(parent != NULL, NULL); + g_return_val_if_fail(tag != NULL, NULL); + + dirname = g_path_get_dirname(parent); + if (!dirname) + g_return_val_if_reached(NULL); + + name = utils_get_ifcfg_name(parent, FALSE); + if (name) { + if (!strcmp(dirname, ".")) + item_path = g_strdup_printf("%s%s", tag, name); + else + item_path = g_strdup_printf("%s/%s%s", dirname, tag, name); + } + g_free(dirname); + + return item_path; } char * -utils_get_ifcfg_path (const char *parent) +utils_get_ifcfg_path(const char *parent) { - return utils_get_extra_path (parent, IFCFG_TAG); + return utils_get_extra_path(parent, IFCFG_TAG); } char * -utils_get_keys_path (const char *parent) +utils_get_keys_path(const char *parent) { - return utils_get_extra_path (parent, KEYS_TAG); + return utils_get_extra_path(parent, KEYS_TAG); } char * -utils_get_route_path (const char *parent) +utils_get_route_path(const char *parent) { - return utils_get_extra_path (parent, ROUTE_TAG); + return utils_get_extra_path(parent, ROUTE_TAG); } char * -utils_get_route6_path (const char *parent) +utils_get_route6_path(const char *parent) { - return utils_get_extra_path (parent, ROUTE6_TAG); + return utils_get_extra_path(parent, ROUTE6_TAG); } shvarFile * -utils_get_extra_ifcfg (const char *parent, const char *tag, gboolean should_create) +utils_get_extra_ifcfg(const char *parent, const char *tag, gboolean should_create) { - shvarFile *ifcfg = NULL; - char *path; + shvarFile *ifcfg = NULL; + char * path; - path = utils_get_extra_path (parent, tag); - if (!path) - return NULL; + path = utils_get_extra_path(parent, tag); + if (!path) + return NULL; - if (should_create && !g_file_test (path, G_FILE_TEST_EXISTS)) - ifcfg = svCreateFile (path); + if (should_create && !g_file_test(path, G_FILE_TEST_EXISTS)) + ifcfg = svCreateFile(path); - if (!ifcfg) - ifcfg = svOpenFile (path, NULL); + if (!ifcfg) + ifcfg = svOpenFile(path, NULL); - g_free (path); - return ifcfg; + g_free(path); + return ifcfg; } shvarFile * -utils_get_keys_ifcfg (const char *parent, gboolean should_create) +utils_get_keys_ifcfg(const char *parent, gboolean should_create) { - return utils_get_extra_ifcfg (parent, KEYS_TAG, should_create); + return utils_get_extra_ifcfg(parent, KEYS_TAG, should_create); } shvarFile * -utils_get_route_ifcfg (const char *parent, gboolean should_create) +utils_get_route_ifcfg(const char *parent, gboolean should_create) { - return utils_get_extra_ifcfg (parent, ROUTE_TAG, should_create); + return utils_get_extra_ifcfg(parent, ROUTE_TAG, should_create); } /* Finds out if route file has new or older format @@ -258,83 +254,82 @@ utils_get_route_ifcfg (const char *parent, gboolean should_create) * FALSE - older syntax, i.e. argument to 'ip route add' (1.2.3.0/24 via 11.22.33.44) */ gboolean -utils_has_route_file_new_syntax (const char *filename) +utils_has_route_file_new_syntax(const char *filename) { - gs_free char *contents_data = NULL; - gsize len; + gs_free char *contents_data = NULL; + gsize len; - g_return_val_if_fail (filename != NULL, TRUE); + g_return_val_if_fail(filename != NULL, TRUE); - if (!g_file_get_contents (filename, &contents_data, &len, NULL)) - return TRUE; + if (!g_file_get_contents(filename, &contents_data, &len, NULL)) + return TRUE; - return utils_has_route_file_new_syntax_content (contents_data, len); + return utils_has_route_file_new_syntax_content(contents_data, len); } gboolean -utils_has_route_file_new_syntax_content (const char *contents, - gsize len) +utils_has_route_file_new_syntax_content(const char *contents, gsize len) { - if (len <= 0) - return TRUE; - - while (TRUE) { - const char *line = contents; - char *eol; - gboolean found = FALSE; - - /* matches regex "^[[:space:]]*ADDRESS[0-9]+=" */ - - eol = (char *) strchr (contents, '\n'); - if (eol) { - eol[0] = '\0'; - contents = &eol[1]; - } - - line = nm_str_skip_leading_spaces (line); - if (NM_STR_HAS_PREFIX (line, "ADDRESS")) { - line += NM_STRLEN ("ADDRESS"); - if (g_ascii_isdigit (line[0])) { - while (g_ascii_isdigit ((++line)[0])) { - /* pass */ - } - if (line[0] == '=') - found = TRUE; - } - } - - if (eol) { - /* restore the line ending. We don't want to mangle the content from - * POV of the caller. */ - eol[0] = '\n'; - } - - if (found) - return TRUE; - if (!eol) - return FALSE; - } + if (len <= 0) + return TRUE; + + while (TRUE) { + const char *line = contents; + char * eol; + gboolean found = FALSE; + + /* matches regex "^[[:space:]]*ADDRESS[0-9]+=" */ + + eol = (char *) strchr(contents, '\n'); + if (eol) { + eol[0] = '\0'; + contents = &eol[1]; + } + + line = nm_str_skip_leading_spaces(line); + if (NM_STR_HAS_PREFIX(line, "ADDRESS")) { + line += NM_STRLEN("ADDRESS"); + if (g_ascii_isdigit(line[0])) { + while (g_ascii_isdigit((++line)[0])) { + /* pass */ + } + if (line[0] == '=') + found = TRUE; + } + } + + if (eol) { + /* restore the line ending. We don't want to mangle the content from + * POV of the caller. */ + eol[0] = '\n'; + } + + if (found) + return TRUE; + if (!eol) + return FALSE; + } } gboolean -utils_has_complex_routes (const char *filename, int addr_family) +utils_has_complex_routes(const char *filename, int addr_family) { - g_return_val_if_fail (filename, TRUE); + g_return_val_if_fail(filename, TRUE); - if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET)) { - gs_free char *rules = utils_get_extra_path (filename, RULE_TAG); + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) { + gs_free char *rules = utils_get_extra_path(filename, RULE_TAG); - if (g_file_test (rules, G_FILE_TEST_EXISTS)) - return TRUE; - } + if (g_file_test(rules, G_FILE_TEST_EXISTS)) + return TRUE; + } - if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET6)) { - gs_free char *rules = utils_get_extra_path (filename, RULE6_TAG); - if (g_file_test (rules, G_FILE_TEST_EXISTS)) - return TRUE; - } + if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) { + gs_free char *rules = utils_get_extra_path(filename, RULE6_TAG); + if (g_file_test(rules, G_FILE_TEST_EXISTS)) + return TRUE; + } - return FALSE; + return FALSE; } /* Find out if the 'alias' file name might be an alias file for 'ifcfg' file name, @@ -342,775 +337,766 @@ utils_has_complex_routes (const char *filename, int addr_family) * alias name; that happens in reader.c */ gboolean -utils_is_ifcfg_alias_file (const char *alias, const char *ifcfg) +utils_is_ifcfg_alias_file(const char *alias, const char *ifcfg) { - g_return_val_if_fail (alias != NULL, FALSE); + g_return_val_if_fail(alias != NULL, FALSE); - if (strncmp (alias, IFCFG_TAG, strlen (IFCFG_TAG))) - return FALSE; + if (strncmp(alias, IFCFG_TAG, strlen(IFCFG_TAG))) + return FALSE; - if (ifcfg) { - size_t len = strlen (ifcfg); + if (ifcfg) { + size_t len = strlen(ifcfg); - return (strncmp (alias, ifcfg, len) == 0 && alias[len] == ':'); - } else { - return (strchr (alias, ':') != NULL); - } + return (strncmp(alias, ifcfg, len) == 0 && alias[len] == ':'); + } else { + return (strchr(alias, ':') != NULL); + } } char * -utils_detect_ifcfg_path (const char *path, gboolean only_ifcfg) +utils_detect_ifcfg_path(const char *path, gboolean only_ifcfg) { - const char *base; - - g_return_val_if_fail (path != NULL, NULL); - - if (utils_should_ignore_file (path, only_ifcfg)) - return NULL; - - base = strrchr (path, '/'); - if (!base) - base = path; - else - base += 1; - - if (NM_STR_HAS_PREFIX (base, IFCFG_TAG)) { - if (base[NM_STRLEN (IFCFG_TAG)] == '\0') - return NULL; - if (utils_is_ifcfg_alias_file (base, NULL)) { - gs_free char *ifcfg = NULL; - char *ptr; - - ifcfg = g_strdup (path); - ptr = strrchr (ifcfg, ':'); - if ( ptr - && ptr > ifcfg - && !strchr (ptr, '/')) { - *ptr = '\0'; - if (g_file_test (ifcfg, G_FILE_TEST_EXISTS)) { - /* the file has a colon, so it is probably an alias. - * To be ~more~ certain that this is an alias file, - * check whether a corresponding base file exists. */ - if (only_ifcfg) - return NULL; - return g_steal_pointer (&ifcfg); - } - } - } - return g_strdup (path); - } - - if (only_ifcfg) - return NULL; - return utils_get_ifcfg_path (path); + const char *base; + + g_return_val_if_fail(path != NULL, NULL); + + if (utils_should_ignore_file(path, only_ifcfg)) + return NULL; + + base = strrchr(path, '/'); + if (!base) + base = path; + else + base += 1; + + if (NM_STR_HAS_PREFIX(base, IFCFG_TAG)) { + if (base[NM_STRLEN(IFCFG_TAG)] == '\0') + return NULL; + if (utils_is_ifcfg_alias_file(base, NULL)) { + gs_free char *ifcfg = NULL; + char * ptr; + + ifcfg = g_strdup(path); + ptr = strrchr(ifcfg, ':'); + if (ptr && ptr > ifcfg && !strchr(ptr, '/')) { + *ptr = '\0'; + if (g_file_test(ifcfg, G_FILE_TEST_EXISTS)) { + /* the file has a colon, so it is probably an alias. + * To be ~more~ certain that this is an alias file, + * check whether a corresponding base file exists. */ + if (only_ifcfg) + return NULL; + return g_steal_pointer(&ifcfg); + } + } + } + return g_strdup(path); + } + + if (only_ifcfg) + return NULL; + return utils_get_ifcfg_path(path); } void -nms_ifcfg_rh_utils_user_key_encode (const char *key, GString *str_buffer) +nms_ifcfg_rh_utils_user_key_encode(const char *key, GString *str_buffer) { - gsize i; - - nm_assert (key); - nm_assert (str_buffer); - - for (i = 0; key[i]; i++) { - char ch = key[i]; - - /* we encode the key in only upper case letters, digits, and underscore. - * As we expect lower-case letters to be more common, we encode lower-case - * letters as upper case, and upper-case letters with a leading underscore. */ - - if (ch >= '0' && ch <= '9') { - g_string_append_c (str_buffer, ch); - continue; - } - if (ch >= 'a' && ch <= 'z') { - g_string_append_c (str_buffer, ch - 'a' + 'A'); - continue; - } - if (ch == '.') { - g_string_append (str_buffer, "__"); - continue; - } - if (ch >= 'A' && ch <= 'Z') { - g_string_append_c (str_buffer, '_'); - g_string_append_c (str_buffer, ch); - continue; - } - g_string_append_printf (str_buffer, "_%03o", (unsigned) ch); - } + gsize i; + + nm_assert(key); + nm_assert(str_buffer); + + for (i = 0; key[i]; i++) { + char ch = key[i]; + + /* we encode the key in only upper case letters, digits, and underscore. + * As we expect lower-case letters to be more common, we encode lower-case + * letters as upper case, and upper-case letters with a leading underscore. */ + + if (ch >= '0' && ch <= '9') { + g_string_append_c(str_buffer, ch); + continue; + } + if (ch >= 'a' && ch <= 'z') { + g_string_append_c(str_buffer, ch - 'a' + 'A'); + continue; + } + if (ch == '.') { + g_string_append(str_buffer, "__"); + continue; + } + if (ch >= 'A' && ch <= 'Z') { + g_string_append_c(str_buffer, '_'); + g_string_append_c(str_buffer, ch); + continue; + } + g_string_append_printf(str_buffer, "_%03o", (unsigned) ch); + } } gboolean -nms_ifcfg_rh_utils_user_key_decode (const char *name, GString *str_buffer) +nms_ifcfg_rh_utils_user_key_decode(const char *name, GString *str_buffer) { - gsize i; - - nm_assert (name); - nm_assert (str_buffer); - - if (!name[0]) - return FALSE; - - for (i = 0; name[i]; ) { - char ch = name[i]; - - if (ch >= '0' && ch <= '9') { - g_string_append_c (str_buffer, ch); - i++; - continue; - } - if (ch >= 'A' && ch <= 'Z') { - g_string_append_c (str_buffer, ch - 'A' + 'a'); - i++; - continue; - } - - if (ch == '_') { - ch = name[i + 1]; - if (ch == '_') { - g_string_append_c (str_buffer, '.'); - i += 2; - continue; - } - if (ch >= 'A' && ch <= 'Z') { - g_string_append_c (str_buffer, ch); - i += 2; - continue; - } - if (ch >= '0' && ch <= '7') { - char ch2, ch3; - unsigned v; - - ch2 = name[i + 2]; - if (!(ch2 >= '0' && ch2 <= '7')) - return FALSE; - - ch3 = name[i + 3]; - if (!(ch3 >= '0' && ch3 <= '7')) - return FALSE; + gsize i; + + nm_assert(name); + nm_assert(str_buffer); + + if (!name[0]) + return FALSE; + + for (i = 0; name[i];) { + char ch = name[i]; + + if (ch >= '0' && ch <= '9') { + g_string_append_c(str_buffer, ch); + i++; + continue; + } + if (ch >= 'A' && ch <= 'Z') { + g_string_append_c(str_buffer, ch - 'A' + 'a'); + i++; + continue; + } + + if (ch == '_') { + ch = name[i + 1]; + if (ch == '_') { + g_string_append_c(str_buffer, '.'); + i += 2; + continue; + } + if (ch >= 'A' && ch <= 'Z') { + g_string_append_c(str_buffer, ch); + i += 2; + continue; + } + if (ch >= '0' && ch <= '7') { + char ch2, ch3; + unsigned v; + + ch2 = name[i + 2]; + if (!(ch2 >= '0' && ch2 <= '7')) + return FALSE; + + ch3 = name[i + 3]; + if (!(ch3 >= '0' && ch3 <= '7')) + return FALSE; #define OCTAL_VALUE(ch) ((unsigned) ((ch) - '0')) - v = (OCTAL_VALUE (ch) << 6) + - (OCTAL_VALUE (ch2) << 3) + - OCTAL_VALUE (ch3); - if ( v > 0xFF - || v == 0) - return FALSE; - ch = (char) v; - if ( (ch >= 'A' && ch <= 'Z') - || (ch >= '0' && ch <= '9') - || (ch == '.') - || (ch >= 'a' && ch <= 'z')) { - /* such characters are not expected to be encoded via - * octal representation. The encoding is invalid. */ - return FALSE; - } - g_string_append_c (str_buffer, ch); - i += 4; - continue; - } - return FALSE; - } - - return FALSE; - } - - return TRUE; + v = (OCTAL_VALUE(ch) << 6) + (OCTAL_VALUE(ch2) << 3) + OCTAL_VALUE(ch3); + if (v > 0xFF || v == 0) + return FALSE; + ch = (char) v; + if ((ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '.') + || (ch >= 'a' && ch <= 'z')) { + /* such characters are not expected to be encoded via + * octal representation. The encoding is invalid. */ + return FALSE; + } + g_string_append_c(str_buffer, ch); + i += 4; + continue; + } + return FALSE; + } + + return FALSE; + } + + return TRUE; } /*****************************************************************************/ const char *const _nm_ethtool_ifcfg_names[] = { -#define ETHT_NAME(eid, ename) [eid] = ""ename"" - /* indexed by NMEthtoolID */ - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX, "adaptive-rx"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX, "adaptive-tx"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_FRAMES, "rx-frames"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH, "rx-frames-high"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ, "rx-frames-irq"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW, "rx-frames-low"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH, "pkt-rate-high"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW, "pkt-rate-low"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_USECS, "rx-usecs"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH, "rx-usecs-high"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ, "rx-usecs-irq"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW, "rx-usecs-low"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL, "sample-interval"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS, "stats-block-usecs"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_FRAMES, "tx-frames"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH, "tx-frames-high"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ, "tx-frames-irq"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW, "tx-frames-low"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_USECS, "tx-usecs"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH, "tx-usecs-high"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ, "tx-usecs-irq"), - ETHT_NAME (NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW, "tx-usecs-low"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD, "esp-hw-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, "esp-tx-csum-hw-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_FCOE_MTU, "fcoe-mtu"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GRO, "gro"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GSO, "gso"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_HIGHDMA, "highdma"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, "hw-tc-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, "l2-fwd-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_LOOPBACK, "loopback"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_LRO, "lro"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_NTUPLE, "ntuple"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX, "rx"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXHASH, "rxhash"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rxvlan"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_ALL, "rx-all"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_FCS, "rx-fcs"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, "rx-gro-hw"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, "rx-udp_tunnel-port-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, "rx-vlan-filter"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, "rx-vlan-stag-filter"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, "rx-vlan-stag-hw-parse"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_SG, "sg"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, "tls-hw-record"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, "tls-hw-tx-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TSO, "tso"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX, "tx"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TXVLAN, "txvlan"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, "tx-checksum-fcoe-crc"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, "tx-checksum-ipv4"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, "tx-checksum-ipv6"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, "tx-checksum-ip-generic"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, "tx-checksum-sctp"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, "tx-esp-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, "tx-fcoe-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, "tx-gre-csum-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, "tx-gre-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, "tx-gso-partial"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, "tx-gso-robust"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, "tx-ipxip4-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, "tx-ipxip6-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, "tx-nocache-copy"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, "tx-scatter-gather"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, "tx-scatter-gather-fraglist"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, "tx-sctp-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, "tx-tcp-ecn-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, "tx-tcp-mangleid-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, "tx-udp-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, "tx-udp_tnl-csum-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, "tx-udp_tnl-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, "tx-vlan-stag-hw-insert"), - ETHT_NAME (NM_ETHTOOL_ID_RING_RX, "rx"), - ETHT_NAME (NM_ETHTOOL_ID_RING_RX_JUMBO, "rx-jumbo"), - ETHT_NAME (NM_ETHTOOL_ID_RING_RX_MINI, "rx-mini"), - ETHT_NAME (NM_ETHTOOL_ID_RING_TX, "tx"), +#define ETHT_NAME(eid, ename) [eid] = "" ename "" + /* indexed by NMEthtoolID */ + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX, "adaptive-rx"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX, "adaptive-tx"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_RX_FRAMES, "rx-frames"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH, "rx-frames-high"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ, "rx-frames-irq"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW, "rx-frames-low"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH, "pkt-rate-high"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW, "pkt-rate-low"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_RX_USECS, "rx-usecs"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH, "rx-usecs-high"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ, "rx-usecs-irq"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW, "rx-usecs-low"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL, "sample-interval"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS, "stats-block-usecs"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_TX_FRAMES, "tx-frames"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH, "tx-frames-high"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ, "tx-frames-irq"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW, "tx-frames-low"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_TX_USECS, "tx-usecs"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH, "tx-usecs-high"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ, "tx-usecs-irq"), + ETHT_NAME(NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW, "tx-usecs-low"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD, "esp-hw-offload"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, "esp-tx-csum-hw-offload"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_FCOE_MTU, "fcoe-mtu"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_GRO, "gro"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_GSO, "gso"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_HIGHDMA, "highdma"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, "hw-tc-offload"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, "l2-fwd-offload"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_LOOPBACK, "loopback"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_LRO, "lro"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_NTUPLE, "ntuple"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_RX, "rx"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_RXHASH, "rxhash"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_RXVLAN, "rxvlan"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_RX_ALL, "rx-all"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_RX_FCS, "rx-fcs"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, "rx-gro-hw"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, "rx-udp_tunnel-port-offload"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, "rx-vlan-filter"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, "rx-vlan-stag-filter"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, "rx-vlan-stag-hw-parse"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_SG, "sg"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, "tls-hw-record"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, "tls-hw-tx-offload"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TSO, "tso"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX, "tx"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TXVLAN, "txvlan"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, "tx-checksum-fcoe-crc"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, "tx-checksum-ipv4"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, "tx-checksum-ipv6"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, "tx-checksum-ip-generic"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, "tx-checksum-sctp"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, "tx-esp-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, "tx-fcoe-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, "tx-gre-csum-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, "tx-gre-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, "tx-gso-partial"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, "tx-gso-robust"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, "tx-ipxip4-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, "tx-ipxip6-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, "tx-nocache-copy"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, "tx-scatter-gather"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, "tx-scatter-gather-fraglist"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, "tx-sctp-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, "tx-tcp-ecn-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, "tx-tcp-mangleid-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, "tx-udp-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, "tx-udp_tnl-csum-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, "tx-udp_tnl-segmentation"), + ETHT_NAME(NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, "tx-vlan-stag-hw-insert"), + ETHT_NAME(NM_ETHTOOL_ID_RING_RX, "rx"), + ETHT_NAME(NM_ETHTOOL_ID_RING_RX_JUMBO, "rx-jumbo"), + ETHT_NAME(NM_ETHTOOL_ID_RING_RX_MINI, "rx-mini"), + ETHT_NAME(NM_ETHTOOL_ID_RING_TX, "tx"), }; -static -NM_UTILS_STRING_TABLE_LOOKUP_DEFINE ( - _get_ethtoolid_coalesce_by_name, - NMEthtoolID, - { nm_assert (name); }, - { return NM_ETHTOOL_ID_UNKNOWN; }, - { "adaptive-rx", NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX }, - { "adaptive-tx", NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX }, - { "pkt-rate-high", NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH }, - { "pkt-rate-low", NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW }, - { "rx-frames", NM_ETHTOOL_ID_COALESCE_RX_FRAMES }, - { "rx-frames-high", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH }, - { "rx-frames-irq", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ }, - { "rx-frames-low", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW }, - { "rx-usecs", NM_ETHTOOL_ID_COALESCE_RX_USECS }, - { "rx-usecs-high", NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH }, - { "rx-usecs-irq", NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ }, - { "rx-usecs-low", NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW }, - { "sample-interval", NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL }, - { "stats-block-usecs", NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS }, - { "tx-frames", NM_ETHTOOL_ID_COALESCE_TX_FRAMES }, - { "tx-frames-high", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH }, - { "tx-frames-irq", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ }, - { "tx-frames-low", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW }, - { "tx-usecs", NM_ETHTOOL_ID_COALESCE_TX_USECS }, - { "tx-usecs-high", NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH }, - { "tx-usecs-irq", NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ }, - { "tx-usecs-low", NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW }, -); - -static -NM_UTILS_STRING_TABLE_LOOKUP_DEFINE ( - _get_ethtoolid_feature_by_name, - NMEthtoolID, - { nm_assert (name); }, - { return NM_ETHTOOL_ID_UNKNOWN; }, - - /* Map the names from kernel/ethtool/ifcfg to NMEthtoolID. Note that ethtool utility has built-in - * features and NetworkManager's API follows the naming of these built-in features, whenever - * they exist. - * For example, NM's "ethtool.feature-ntuple" corresponds to ethtool utility's "ntuple" - * feature. However the underlying kernel feature is called "rx-ntuple-filter" (as reported - * for ETH_SS_FEATURES). - * - * With ethtool utility, whose command line we attempt to parse here, the user can also - * specify the name of the underlying kernel feature directly. So, check whether that is - * the case and if yes, map them to the corresponding NetworkManager's features. - * - * That is why there are duplicate IDs in this list. */ - { "esp-hw-offload", NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD }, - { "esp-tx-csum-hw-offload", NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD }, - { "fcoe-mtu", NM_ETHTOOL_ID_FEATURE_FCOE_MTU }, - { "gro", NM_ETHTOOL_ID_FEATURE_GRO }, - { "gso", NM_ETHTOOL_ID_FEATURE_GSO }, - { "highdma", NM_ETHTOOL_ID_FEATURE_HIGHDMA }, - { "hw-tc-offload", NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD }, - { "l2-fwd-offload", NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD }, - { "loopback", NM_ETHTOOL_ID_FEATURE_LOOPBACK }, - { "lro", NM_ETHTOOL_ID_FEATURE_LRO }, - { "ntuple", NM_ETHTOOL_ID_FEATURE_NTUPLE }, - { "rx", NM_ETHTOOL_ID_FEATURE_RX }, - { "rx-all", NM_ETHTOOL_ID_FEATURE_RX_ALL }, - { "rx-checksum", NM_ETHTOOL_ID_FEATURE_RX }, // kernel-only name - { "rx-fcs", NM_ETHTOOL_ID_FEATURE_RX_FCS }, - { "rx-gro", NM_ETHTOOL_ID_FEATURE_GRO }, // kernel-only name - { "rx-gro-hw", NM_ETHTOOL_ID_FEATURE_RX_GRO_HW }, - { "rx-hashing", NM_ETHTOOL_ID_FEATURE_RXHASH }, // kernel-only name - { "rx-lro", NM_ETHTOOL_ID_FEATURE_LRO }, // kernel-only name - { "rx-ntuple-filter", NM_ETHTOOL_ID_FEATURE_NTUPLE }, // kernel-only name - { "rx-udp_tunnel-port-offload", NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD }, - { "rx-vlan-filter", NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER }, - { "rx-vlan-hw-parse", NM_ETHTOOL_ID_FEATURE_RXVLAN }, // kernel-only name - { "rx-vlan-stag-filter", NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER }, - { "rx-vlan-stag-hw-parse", NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE }, - { "rxhash", NM_ETHTOOL_ID_FEATURE_RXHASH }, - { "rxvlan", NM_ETHTOOL_ID_FEATURE_RXVLAN }, - { "sg", NM_ETHTOOL_ID_FEATURE_SG }, - { "tls-hw-record", NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD }, - { "tls-hw-tx-offload", NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD }, - { "tso", NM_ETHTOOL_ID_FEATURE_TSO }, - { "tx", NM_ETHTOOL_ID_FEATURE_TX }, - { "tx-checksum-fcoe-crc", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC }, - { "tx-checksum-ip-generic", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC }, - { "tx-checksum-ipv4", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4 }, - { "tx-checksum-ipv6", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6 }, - { "tx-checksum-sctp", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP }, - { "tx-esp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION }, - { "tx-fcoe-segmentation", NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION }, - { "tx-generic-segmentation", NM_ETHTOOL_ID_FEATURE_GSO }, // kernel-only name - { "tx-gre-csum-segmentation", NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION }, - { "tx-gre-segmentation", NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION }, - { "tx-gso-partial", NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL }, - { "tx-gso-robust", NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST }, - { "tx-ipxip4-segmentation", NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION }, - { "tx-ipxip6-segmentation", NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION }, - { "tx-nocache-copy", NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY }, - { "tx-scatter-gather", NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER }, - { "tx-scatter-gather-fraglist", NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST }, - { "tx-sctp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION }, - { "tx-tcp-ecn-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION }, - { "tx-tcp-mangleid-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION }, - { "tx-tcp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION }, - { "tx-tcp6-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION }, - { "tx-udp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION }, - { "tx-udp_tnl-csum-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION }, - { "tx-udp_tnl-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION }, - { "tx-vlan-hw-insert", NM_ETHTOOL_ID_FEATURE_TXVLAN }, // kernel-only name - { "tx-vlan-stag-hw-insert", NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT }, - { "txvlan", NM_ETHTOOL_ID_FEATURE_TXVLAN }, -); - -static -NM_UTILS_STRING_TABLE_LOOKUP_DEFINE ( - _get_ethtoolid_ring_by_name, - NMEthtoolID, - { nm_assert (name); }, - { return NM_ETHTOOL_ID_UNKNOWN; }, - { "rx", NM_ETHTOOL_ID_RING_RX }, - { "rx-jumbo", NM_ETHTOOL_ID_RING_RX_JUMBO }, - { "rx-mini", NM_ETHTOOL_ID_RING_RX_MINI }, - { "tx", NM_ETHTOOL_ID_RING_TX }, -); +static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( + _get_ethtoolid_coalesce_by_name, + NMEthtoolID, + { nm_assert(name); }, + { return NM_ETHTOOL_ID_UNKNOWN; }, + {"adaptive-rx", NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX}, + {"adaptive-tx", NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX}, + {"pkt-rate-high", NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH}, + {"pkt-rate-low", NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW}, + {"rx-frames", NM_ETHTOOL_ID_COALESCE_RX_FRAMES}, + {"rx-frames-high", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH}, + {"rx-frames-irq", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ}, + {"rx-frames-low", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW}, + {"rx-usecs", NM_ETHTOOL_ID_COALESCE_RX_USECS}, + {"rx-usecs-high", NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH}, + {"rx-usecs-irq", NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ}, + {"rx-usecs-low", NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW}, + {"sample-interval", NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL}, + {"stats-block-usecs", NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS}, + {"tx-frames", NM_ETHTOOL_ID_COALESCE_TX_FRAMES}, + {"tx-frames-high", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH}, + {"tx-frames-irq", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ}, + {"tx-frames-low", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW}, + {"tx-usecs", NM_ETHTOOL_ID_COALESCE_TX_USECS}, + {"tx-usecs-high", NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH}, + {"tx-usecs-irq", NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ}, + {"tx-usecs-low", NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW}, ); + +static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( + _get_ethtoolid_feature_by_name, + NMEthtoolID, + { nm_assert(name); }, + { return NM_ETHTOOL_ID_UNKNOWN; }, + + /* Map the names from kernel/ethtool/ifcfg to NMEthtoolID. Note that ethtool utility has built-in + * features and NetworkManager's API follows the naming of these built-in features, whenever + * they exist. + * For example, NM's "ethtool.feature-ntuple" corresponds to ethtool utility's "ntuple" + * feature. However the underlying kernel feature is called "rx-ntuple-filter" (as reported + * for ETH_SS_FEATURES). + * + * With ethtool utility, whose command line we attempt to parse here, the user can also + * specify the name of the underlying kernel feature directly. So, check whether that is + * the case and if yes, map them to the corresponding NetworkManager's features. + * + * That is why there are duplicate IDs in this list. */ + {"esp-hw-offload", NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD}, + {"esp-tx-csum-hw-offload", NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD}, + {"fcoe-mtu", NM_ETHTOOL_ID_FEATURE_FCOE_MTU}, + {"gro", NM_ETHTOOL_ID_FEATURE_GRO}, + {"gso", NM_ETHTOOL_ID_FEATURE_GSO}, + {"highdma", NM_ETHTOOL_ID_FEATURE_HIGHDMA}, + {"hw-tc-offload", NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD}, + {"l2-fwd-offload", NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD}, + {"loopback", NM_ETHTOOL_ID_FEATURE_LOOPBACK}, + {"lro", NM_ETHTOOL_ID_FEATURE_LRO}, + {"ntuple", NM_ETHTOOL_ID_FEATURE_NTUPLE}, + {"rx", NM_ETHTOOL_ID_FEATURE_RX}, + {"rx-all", NM_ETHTOOL_ID_FEATURE_RX_ALL}, + {"rx-checksum", NM_ETHTOOL_ID_FEATURE_RX}, // kernel-only name + {"rx-fcs", NM_ETHTOOL_ID_FEATURE_RX_FCS}, + {"rx-gro", NM_ETHTOOL_ID_FEATURE_GRO}, // kernel-only name + {"rx-gro-hw", NM_ETHTOOL_ID_FEATURE_RX_GRO_HW}, + {"rx-hashing", NM_ETHTOOL_ID_FEATURE_RXHASH}, // kernel-only name + {"rx-lro", NM_ETHTOOL_ID_FEATURE_LRO}, // kernel-only name + {"rx-ntuple-filter", NM_ETHTOOL_ID_FEATURE_NTUPLE}, // kernel-only name + {"rx-udp_tunnel-port-offload", NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD}, + {"rx-vlan-filter", NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER}, + {"rx-vlan-hw-parse", NM_ETHTOOL_ID_FEATURE_RXVLAN}, // kernel-only name + {"rx-vlan-stag-filter", NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER}, + {"rx-vlan-stag-hw-parse", NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE}, + {"rxhash", NM_ETHTOOL_ID_FEATURE_RXHASH}, + {"rxvlan", NM_ETHTOOL_ID_FEATURE_RXVLAN}, + {"sg", NM_ETHTOOL_ID_FEATURE_SG}, + {"tls-hw-record", NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD}, + {"tls-hw-tx-offload", NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD}, + {"tso", NM_ETHTOOL_ID_FEATURE_TSO}, + {"tx", NM_ETHTOOL_ID_FEATURE_TX}, + {"tx-checksum-fcoe-crc", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC}, + {"tx-checksum-ip-generic", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC}, + {"tx-checksum-ipv4", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4}, + {"tx-checksum-ipv6", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6}, + {"tx-checksum-sctp", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP}, + {"tx-esp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION}, + {"tx-fcoe-segmentation", NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION}, + {"tx-generic-segmentation", NM_ETHTOOL_ID_FEATURE_GSO}, // kernel-only name + {"tx-gre-csum-segmentation", NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION}, + {"tx-gre-segmentation", NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION}, + {"tx-gso-partial", NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL}, + {"tx-gso-robust", NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST}, + {"tx-ipxip4-segmentation", NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION}, + {"tx-ipxip6-segmentation", NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION}, + {"tx-nocache-copy", NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY}, + {"tx-scatter-gather", NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER}, + {"tx-scatter-gather-fraglist", NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST}, + {"tx-sctp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION}, + {"tx-tcp-ecn-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION}, + {"tx-tcp-mangleid-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION}, + {"tx-tcp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION}, + {"tx-tcp6-segmentation", NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION}, + {"tx-udp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION}, + {"tx-udp_tnl-csum-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION}, + {"tx-udp_tnl-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION}, + {"tx-vlan-hw-insert", NM_ETHTOOL_ID_FEATURE_TXVLAN}, // kernel-only name + {"tx-vlan-stag-hw-insert", NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT}, + {"txvlan", NM_ETHTOOL_ID_FEATURE_TXVLAN}, ); + +static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( + _get_ethtoolid_ring_by_name, + NMEthtoolID, + { nm_assert(name); }, + { return NM_ETHTOOL_ID_UNKNOWN; }, + {"rx", NM_ETHTOOL_ID_RING_RX}, + {"rx-jumbo", NM_ETHTOOL_ID_RING_RX_JUMBO}, + {"rx-mini", NM_ETHTOOL_ID_RING_RX_MINI}, + {"tx", NM_ETHTOOL_ID_RING_TX}, ); const NMEthtoolData * -nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name, - NMEthtoolType ethtool_type) +nms_ifcfg_rh_utils_get_ethtool_by_name(const char *name, NMEthtoolType ethtool_type) { - NMEthtoolID id; - - switch (ethtool_type) { - case NM_ETHTOOL_TYPE_COALESCE: - id = _get_ethtoolid_coalesce_by_name (name); - break; - case NM_ETHTOOL_TYPE_FEATURE: - id = _get_ethtoolid_feature_by_name (name); - break; - case NM_ETHTOOL_TYPE_RING: - id = _get_ethtoolid_ring_by_name (name); - break; - default: - nm_assert_not_reached(); - return NULL; - } - - if (id == NM_ETHTOOL_ID_UNKNOWN) - return NULL; - - nm_assert (_NM_INT_NOT_NEGATIVE (id)); - nm_assert (id < G_N_ELEMENTS (nm_ethtool_data)); - nm_assert (nm_ethtool_data[id]); - nm_assert (nm_ethtool_data[id]->id == id); - return nm_ethtool_data[id]; + NMEthtoolID id; + + switch (ethtool_type) { + case NM_ETHTOOL_TYPE_COALESCE: + id = _get_ethtoolid_coalesce_by_name(name); + break; + case NM_ETHTOOL_TYPE_FEATURE: + id = _get_ethtoolid_feature_by_name(name); + break; + case NM_ETHTOOL_TYPE_RING: + id = _get_ethtoolid_ring_by_name(name); + break; + default: + nm_assert_not_reached(); + return NULL; + } + + if (id == NM_ETHTOOL_ID_UNKNOWN) + return NULL; + + nm_assert(_NM_INT_NOT_NEGATIVE(id)); + nm_assert(id < G_N_ELEMENTS(nm_ethtool_data)); + nm_assert(nm_ethtool_data[id]); + nm_assert(nm_ethtool_data[id]->id == id); + return nm_ethtool_data[id]; } /*****************************************************************************/ gboolean -nms_ifcfg_rh_utils_is_numbered_tag_impl (const char *key, - const char *tag, - gsize tag_len, - gint64 *out_idx) +nms_ifcfg_rh_utils_is_numbered_tag_impl(const char *key, + const char *tag, + gsize tag_len, + gint64 * out_idx) { - gint64 idx; + gint64 idx; - nm_assert (key); - nm_assert (tag); - nm_assert (tag_len == strlen (tag)); - nm_assert (tag_len > 0); + nm_assert(key); + nm_assert(tag); + nm_assert(tag_len == strlen(tag)); + nm_assert(tag_len > 0); - if (strncmp (key, tag, tag_len) != 0) - return FALSE; + if (strncmp(key, tag, tag_len) != 0) + return FALSE; - key += tag_len; + key += tag_len; - if (key[0] == '\0') { - /* The key has no number suffix. We treat this also as a numbered - * tag, and it is for certain tags like "IPADDR", but not so much - * for others like "ROUTING_RULE_". The caller may want to handle - * this case specially. */ - NM_SET_OUT (out_idx, -1); - return TRUE; - } + if (key[0] == '\0') { + /* The key has no number suffix. We treat this also as a numbered + * tag, and it is for certain tags like "IPADDR", but not so much + * for others like "ROUTING_RULE_". The caller may want to handle + * this case specially. */ + NM_SET_OUT(out_idx, -1); + return TRUE; + } - if (!NM_STRCHAR_ALL (key, ch, g_ascii_isdigit (ch))) - return FALSE; + if (!NM_STRCHAR_ALL(key, ch, g_ascii_isdigit(ch))) + return FALSE; - idx = _nm_utils_ascii_str_to_int64 (key, 10, 0, G_MAXINT64, -1); - if (idx == -1) - return FALSE; + idx = _nm_utils_ascii_str_to_int64(key, 10, 0, G_MAXINT64, -1); + if (idx == -1) + return FALSE; - NM_SET_OUT (out_idx, idx); - return TRUE; + NM_SET_OUT(out_idx, idx); + return TRUE; } /*****************************************************************************/ -#define _KEY_TYPE(key, flags) { .key_name = ""key"", .key_flags = ((NMS_IFCFG_KEY_TYPE_WELL_KNOWN) | (flags)), } +#define _KEY_TYPE(key, flags) \ + { \ + .key_name = "" key "", .key_flags = ((NMS_IFCFG_KEY_TYPE_WELL_KNOWN) | (flags)), \ + } const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = { - _KEY_TYPE ("ACD_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("ADDRESS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("ARPING_WAIT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("AUTH_RETRIES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("AUTOCONNECT_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("AUTOCONNECT_RETRIES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("AUTOCONNECT_SLAVES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BAND", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BONDING_MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BONDING_OPTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BOOTPROTO", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BRIDGE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BRIDGE_MACADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BRIDGE_PORT_VLANS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BRIDGE_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BRIDGE_VLANS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BRIDGING_OPTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BROWSER_ONLY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("BSSID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("CHANNEL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("CIPHER_GROUP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("CIPHER_PAIRWISE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("CONNECTED_MODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("CONNECTION_METERED", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("CTCPROT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DCB", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_APP_FCOE_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_APP_FCOE_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_APP_FCOE_MODE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DCB_APP_FCOE_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_APP_FCOE_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_APP_FIP_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_APP_FIP_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DCB_APP_FIP_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_APP_FIP_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_APP_ISCSI_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_APP_ISCSI_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DCB_APP_ISCSI_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_APP_ISCSI_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PFC_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PFC_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PFC_UP, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PFC_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PG_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PG_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PG_ID, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PG_PCT, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PG_STRICT, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PG_UP2TC, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PG_UPPCT, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE (KEY_DCB_PG_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DEFAULTKEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DEFROUTE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DELAY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DEVICE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DEVICETYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DEVTIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCPV6C", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCPV6_DUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCPV6_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCPV6_HOSTNAME_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCPV6_IAID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCPV6_SEND_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCP_CLIENT_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCP_FQDN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCP_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCP_HOSTNAME_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCP_IAID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCP_SEND_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCPv6_DUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DHCPv6_IAID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("DNS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("DOMAIN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("ESSID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("ETHTOOL_OPTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("ETHTOOL_WAKE_ON_LAN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("FILS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("FILTER", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("GATEWAY", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("GATEWAYDEV", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("GATEWAY_PING_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("GENERATE_MAC_ADDRESS_MASK", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("GVRP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("HWADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("HWADDR_BLACKLIST", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_ALTSUBJECT_MATCHES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_ANON_IDENTITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_AUTH_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_CA_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_CA_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_CA_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_CA_PATH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_CLIENT_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_CLIENT_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_CLIENT_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_DOMAIN_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_DOMAIN_SUFFIX_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_EAP_METHODS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_FAST_PROVISIONING", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_IDENTITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_INNER_AUTH_METHODS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_INNER_CA_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_INNER_CA_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_INNER_CA_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_INNER_CLIENT_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_INNER_CLIENT_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_INNER_CLIENT_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_INNER_PRIVATE_KEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_OPTIONAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PAC_FILE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PASSWORD_RAW", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PASSWORD_RAW_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PEAP_FORCE_NEW_LABEL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PEAP_VERSION", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PHASE1_AUTH_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PHASE2_CA_PATH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PHASE2_DOMAIN_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PHASE2_DOMAIN_SUFFIX_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PHASE2_SUBJECT_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PIN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PIN_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PRIVATE_KEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PRIVATE_KEY_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_SUBJECT_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IEEE_8021X_SYSTEM_CA_CERTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPADDR", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("IPV4_DHCP_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV4_DNS_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV4_FAILURE_FATAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV4_ROUTE_METRIC", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV4_ROUTE_TABLE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6ADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6ADDR_SECONDARIES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6FORWARDING", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6INIT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6TUNNELIPV4", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_ADDR_GEN_MODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_AUTOCONF", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_DEFAULTDEV", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_DEFAULTGW", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_DEFROUTE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_DHCP_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_DISABLED", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_DNS_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_DOMAIN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_FAILURE_FATAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_PEERDNS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_PEERROUTES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_PRIVACY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_PRIVACY_PREFER_PUBLIC_IP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_RA_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_RES_OPTIONS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_ROUTE_METRIC", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_ROUTE_TABLE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("IPV6_TOKEN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("KEY", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("KEY_MGMT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("KEY_PASSPHRASE", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("KEY_TYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("LLDP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("LLMNR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MACADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MAC_ADDRESS_RANDOMIZATION", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MASTER_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MATCH_DRIVER", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MATCH_INTERFACE_NAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MATCH_KERNEL_COMMAND_LINE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MATCH_PATH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MDNS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("METRIC", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("MODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MTU", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MUD_URL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MULTI_CONNECT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("MVRP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("NAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("NETMASK", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("NETTYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("NM_CONTROLLED", NMS_IFCFG_KEY_TYPE_IS_PLAIN | NMS_IFCFG_KEY_TYPE_KEEP_WHEN_DIRTY ), - _KEY_TYPE ("NM_USER_", NMS_IFCFG_KEY_TYPE_IS_PREFIX ), - _KEY_TYPE ("ONBOOT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("OPTIONS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("OVS_PORT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("OVS_PORT_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("PAC_SCRIPT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("PAC_URL", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("PEERDNS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("PEERROUTES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("PHYSDEV", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("PKEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("PKEY_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("PMF", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("PORTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("POWERSAVE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("PREFIX", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("PROXY_METHOD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("QDISC", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("REORDER_HDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("RES_OPTIONS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("ROUTING_RULE6_", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("ROUTING_RULE_", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("SEARCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("SECONDARY_UUIDS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("SECURITYMODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("SLAVE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("SRIOV_AUTOPROBE_DRIVERS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("SRIOV_TOTAL_VFS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("SRIOV_VF", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ), - _KEY_TYPE ("SSID_HIDDEN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("STABLE_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("STP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("SUBCHANNELS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("TEAM_CONFIG", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("TEAM_MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("TEAM_MASTER_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("TEAM_PORT_CONFIG", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("TYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("USERS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("VLAN", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("VLAN_EGRESS_PRIORITY_MAP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("VLAN_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("VLAN_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("VLAN_INGRESS_PRIORITY_MAP", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("VRF", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("VRF_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("WEP_KEY_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("WPA_ALLOW_WPA", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("WPA_ALLOW_WPA2", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("WPA_PSK", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("WPA_PSK_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("WPS_METHOD", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), - _KEY_TYPE ("ZONE", NMS_IFCFG_KEY_TYPE_IS_PLAIN ), + _KEY_TYPE("ACD_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("ADDRESS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("AP_ISOLATION", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("ARPING_WAIT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("AUTH_RETRIES", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("AUTOCONNECT_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("AUTOCONNECT_RETRIES", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("AUTOCONNECT_SLAVES", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BAND", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BONDING_MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BONDING_OPTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BOOTPROTO", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BRIDGE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BRIDGE_MACADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BRIDGE_PORT_VLANS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BRIDGE_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BRIDGE_VLANS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BRIDGING_OPTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BROWSER_ONLY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BSSID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("CHANNEL", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("CIPHER_GROUP", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("CIPHER_PAIRWISE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("CONNECTED_MODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("CONNECTION_METERED", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("CTCPROT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DCB", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_APP_FCOE_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_APP_FCOE_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_APP_FCOE_MODE, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DCB_APP_FCOE_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_APP_FCOE_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_APP_FIP_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_APP_FIP_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DCB_APP_FIP_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_APP_FIP_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_APP_ISCSI_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_APP_ISCSI_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DCB_APP_ISCSI_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_APP_ISCSI_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PFC_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PFC_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PFC_UP, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PFC_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PG_ADVERTISE, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PG_ENABLE, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PG_ID, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PG_PCT, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PG_STRICT, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PG_UP2TC, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PG_UPPCT, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE(KEY_DCB_PG_WILLING, NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DEFAULTKEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DEFROUTE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DELAY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DEVICE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DEVICETYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DEVTIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCPV6C", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCPV6_DUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCPV6_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCPV6_HOSTNAME_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCPV6_IAID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCPV6_SEND_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCP_CLIENT_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCP_FQDN", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCP_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCP_HOSTNAME_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCP_IAID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCP_REJECT_SERVERS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCP_SEND_HOSTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCP_VENDOR_CLASS_IDENTIFIER", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCPv6_DUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DHCPv6_IAID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("DNS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("DOMAIN", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("ESSID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("ETHTOOL_OPTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("ETHTOOL_WAKE_ON_LAN", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("FILS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("FILTER", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("GATEWAY", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("GATEWAYDEV", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("GATEWAY_PING_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("GENERATE_MAC_ADDRESS_MASK", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("GVRP", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("HWADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("HWADDR_BLACKLIST", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_ALTSUBJECT_MATCHES", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_ANON_IDENTITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_AUTH_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_CA_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_CA_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_CA_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_CA_PATH", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_CLIENT_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_CLIENT_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_CLIENT_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_DOMAIN_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_DOMAIN_SUFFIX_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_EAP_METHODS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_FAST_PROVISIONING", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_IDENTITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_INNER_AUTH_METHODS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_INNER_CA_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_INNER_CA_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_INNER_CA_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_INNER_CLIENT_CERT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_INNER_CLIENT_CERT_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_INNER_CLIENT_CERT_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_INNER_PRIVATE_KEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_OPTIONAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PAC_FILE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PASSWORD_RAW", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PASSWORD_RAW_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PEAP_FORCE_NEW_LABEL", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PEAP_VERSION", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PHASE1_AUTH_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PHASE2_CA_PATH", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PHASE2_DOMAIN_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PHASE2_DOMAIN_SUFFIX_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PHASE2_SUBJECT_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PIN", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PIN_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PRIVATE_KEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PRIVATE_KEY_PASSWORD", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_SUBJECT_MATCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IEEE_8021X_SYSTEM_CA_CERTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPADDR", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("IPV4_DHCP_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV4_DNS_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV4_FAILURE_FATAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV4_ROUTE_METRIC", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV4_ROUTE_TABLE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6ADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6ADDR_SECONDARIES", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6FORWARDING", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6INIT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6TUNNELIPV4", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_ADDR_GEN_MODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_AUTOCONF", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_DEFAULTDEV", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_DEFAULTGW", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_DEFROUTE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_DHCP_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_DISABLED", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_DNS_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_DOMAIN", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_FAILURE_FATAL", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_PEERDNS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_PEERROUTES", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_PRIVACY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_PRIVACY_PREFER_PUBLIC_IP", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_RA_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_RES_OPTIONS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_ROUTE_METRIC", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_ROUTE_TABLE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("IPV6_TOKEN", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("KEY", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("KEY_MGMT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("KEY_PASSPHRASE", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("KEY_TYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("LLDP", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("LLMNR", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MACADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MAC_ADDRESS_RANDOMIZATION", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MASTER_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MATCH_DRIVER", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MATCH_INTERFACE_NAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MATCH_KERNEL_COMMAND_LINE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MATCH_PATH", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MDNS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("METRIC", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("MODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MTU", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MUD_URL", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MULTI_CONNECT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("MVRP", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("NAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("NETMASK", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("NETTYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("NM_CONTROLLED", NMS_IFCFG_KEY_TYPE_IS_PLAIN | NMS_IFCFG_KEY_TYPE_KEEP_WHEN_DIRTY), + _KEY_TYPE("NM_USER_", NMS_IFCFG_KEY_TYPE_IS_PREFIX), + _KEY_TYPE("ONBOOT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("OPTIONS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("OVS_PORT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("OVS_PORT_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("PAC_SCRIPT", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("PAC_URL", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("PEERDNS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("PEERROUTES", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("PHYSDEV", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("PKEY", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("PKEY_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("PMF", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("PORTNAME", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("POWERSAVE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("PREFIX", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("PROXY_METHOD", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("QDISC", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("REORDER_HDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("RES_OPTIONS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("ROUTING_RULE6_", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("ROUTING_RULE_", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("SEARCH", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("SECONDARY_UUIDS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("SECURITYMODE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("SLAVE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("SRIOV_AUTOPROBE_DRIVERS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("SRIOV_TOTAL_VFS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("SRIOV_VF", NMS_IFCFG_KEY_TYPE_IS_NUMBERED), + _KEY_TYPE("SSID_HIDDEN", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("STABLE_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("STP", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("SUBCHANNELS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("TEAM_CONFIG", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("TEAM_MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("TEAM_MASTER_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("TEAM_PORT_CONFIG", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("TYPE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("USERS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("VLAN", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("VLAN_EGRESS_PRIORITY_MAP", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("VLAN_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("VLAN_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("VLAN_INGRESS_PRIORITY_MAP", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("VRF", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("VRF_UUID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("WEP_KEY_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("WPA_ALLOW_WPA", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("WPA_ALLOW_WPA2", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("WPA_PSK", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("WPA_PSK_FLAGS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("WPS_METHOD", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("ZONE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), }; const NMSIfcfgKeyTypeInfo * -nms_ifcfg_well_known_key_find_info (const char *key, gssize *out_idx) +nms_ifcfg_well_known_key_find_info(const char *key, gssize *out_idx) { - gssize idx; - - G_STATIC_ASSERT (G_STRUCT_OFFSET (NMSIfcfgKeyTypeInfo, key_name) == 0); - - idx = nm_utils_array_find_binary_search (nms_ifcfg_well_known_keys, - sizeof (nms_ifcfg_well_known_keys[0]), - G_N_ELEMENTS (nms_ifcfg_well_known_keys), - &key, - nm_strcmp_p_with_data, - NULL); - NM_SET_OUT (out_idx, idx); - if (idx < 0) - return NULL; - return &nms_ifcfg_well_known_keys[idx]; + gssize idx; + + G_STATIC_ASSERT(G_STRUCT_OFFSET(NMSIfcfgKeyTypeInfo, key_name) == 0); + + idx = nm_utils_array_find_binary_search(nms_ifcfg_well_known_keys, + sizeof(nms_ifcfg_well_known_keys[0]), + G_N_ELEMENTS(nms_ifcfg_well_known_keys), + &key, + nm_strcmp_p_with_data, + NULL); + NM_SET_OUT(out_idx, idx); + if (idx < 0) + return NULL; + return &nms_ifcfg_well_known_keys[idx]; } const NMSIfcfgKeyTypeInfo * -nms_ifcfg_rh_utils_is_well_known_key (const char *key) +nms_ifcfg_rh_utils_is_well_known_key(const char *key) { - const NMSIfcfgKeyTypeInfo *ti; - gssize idx; - - nm_assert (key); - - ti = nms_ifcfg_well_known_key_find_info (key, &idx); - - if (ti) { - if (NM_FLAGS_ANY (ti->key_flags, NMS_IFCFG_KEY_TYPE_IS_PLAIN - | NMS_IFCFG_KEY_TYPE_IS_NUMBERED)) { - /* These tags are valid on full match. - * - * Note that numbered tags we also treat as valid if they have no - * suffix. That is correct for "IPADDR", but less so for "ROUTING_RULE_". */ - return ti; - } - nm_assert (NM_FLAGS_HAS (ti->key_flags, NMS_IFCFG_KEY_TYPE_IS_PREFIX)); - /* a prefix tag needs some extra suffix afterwards to be valid. */ - return NULL; - } - - /* Not found. Maybe it's a numbered/prefixed key? With idx we got the index where - * we should insert the key. Since the numbered/prefixed keys share a prefix, we can - * find the possible prefix at the index before the insert position. */ - idx = ~idx; - if (idx == 0) - return NULL; - - ti = &nms_ifcfg_well_known_keys[idx - 1]; - - if (NM_FLAGS_HAS (ti->key_flags, NMS_IFCFG_KEY_TYPE_IS_NUMBERED)) { - if (nms_ifcfg_rh_utils_is_numbered_tag (key, ti->key_name, NULL)) - return ti; - return NULL; - } - - if (NM_FLAGS_HAS (ti->key_flags, NMS_IFCFG_KEY_TYPE_IS_PREFIX)) { - gsize l = strlen (ti->key_name); - - if ( strncmp (key, ti->key_name, l) == 0 - && key[l] != '\0') - return ti; - return NULL; - } - - return NULL; + const NMSIfcfgKeyTypeInfo *ti; + gssize idx; + + nm_assert(key); + + ti = nms_ifcfg_well_known_key_find_info(key, &idx); + + if (ti) { + if (NM_FLAGS_ANY(ti->key_flags, + NMS_IFCFG_KEY_TYPE_IS_PLAIN | NMS_IFCFG_KEY_TYPE_IS_NUMBERED)) { + /* These tags are valid on full match. + * + * Note that numbered tags we also treat as valid if they have no + * suffix. That is correct for "IPADDR", but less so for "ROUTING_RULE_". */ + return ti; + } + nm_assert(NM_FLAGS_HAS(ti->key_flags, NMS_IFCFG_KEY_TYPE_IS_PREFIX)); + /* a prefix tag needs some extra suffix afterwards to be valid. */ + return NULL; + } + + /* Not found. Maybe it's a numbered/prefixed key? With idx we got the index where + * we should insert the key. Since the numbered/prefixed keys share a prefix, we can + * find the possible prefix at the index before the insert position. */ + idx = ~idx; + if (idx == 0) + return NULL; + + ti = &nms_ifcfg_well_known_keys[idx - 1]; + + if (NM_FLAGS_HAS(ti->key_flags, NMS_IFCFG_KEY_TYPE_IS_NUMBERED)) { + if (nms_ifcfg_rh_utils_is_numbered_tag(key, ti->key_name, NULL)) + return ti; + return NULL; + } + + if (NM_FLAGS_HAS(ti->key_flags, NMS_IFCFG_KEY_TYPE_IS_PREFIX)) { + gsize l = strlen(ti->key_name); + + if (strncmp(key, ti->key_name, l) == 0 && key[l] != '\0') + return ti; + return NULL; + } + + return NULL; } diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h index 459c5ae9..16ea7f0f 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 - 2017 Red Hat, Inc. */ @@ -14,146 +14,151 @@ /*****************************************************************************/ typedef enum { - NMS_IFCFG_KEY_TYPE_UNKNOWN = 0, - NMS_IFCFG_KEY_TYPE_WELL_KNOWN = (1u << 0), + NMS_IFCFG_KEY_TYPE_UNKNOWN = 0, + NMS_IFCFG_KEY_TYPE_WELL_KNOWN = (1u << 0), - NMS_IFCFG_KEY_TYPE_IS_PLAIN = (1u << 1), - NMS_IFCFG_KEY_TYPE_IS_NUMBERED = (1u << 2), - NMS_IFCFG_KEY_TYPE_IS_PREFIX = (1u << 3), + NMS_IFCFG_KEY_TYPE_IS_PLAIN = (1u << 1), + NMS_IFCFG_KEY_TYPE_IS_NUMBERED = (1u << 2), + NMS_IFCFG_KEY_TYPE_IS_PREFIX = (1u << 3), - /* by default, well knowns keys that are not explicitly set - * by the writer (the unvisited, dirty ones) are removed. - * With this flag, such keys are kept if they are present. */ - NMS_IFCFG_KEY_TYPE_KEEP_WHEN_DIRTY = (1u << 4), + /* by default, well knowns keys that are not explicitly set + * by the writer (the unvisited, dirty ones) are removed. + * With this flag, such keys are kept if they are present. */ + NMS_IFCFG_KEY_TYPE_KEEP_WHEN_DIRTY = (1u << 4), } NMSIfcfgKeyTypeFlags; typedef struct { - const char *key_name; - NMSIfcfgKeyTypeFlags key_flags; + const char * key_name; + NMSIfcfgKeyTypeFlags key_flags; } NMSIfcfgKeyTypeInfo; -extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[240]; +extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[243]; -const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info (const char *key, gssize *out_idx); +const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info(const char *key, gssize *out_idx); static inline NMSIfcfgKeyTypeFlags -nms_ifcfg_well_known_key_find_info_flags (const char *key) +nms_ifcfg_well_known_key_find_info_flags(const char *key) { - const NMSIfcfgKeyTypeInfo *ti; + const NMSIfcfgKeyTypeInfo *ti; - ti = nms_ifcfg_well_known_key_find_info (key, NULL); - if (!ti) - return NMS_IFCFG_KEY_TYPE_UNKNOWN; - return ti->key_flags; + ti = nms_ifcfg_well_known_key_find_info(key, NULL); + if (!ti) + return NMS_IFCFG_KEY_TYPE_UNKNOWN; + return ti->key_flags; } /*****************************************************************************/ -gboolean nms_ifcfg_rh_utils_parse_unhandled_spec (const char *unhandled_spec, - const char **out_unmanaged_spec, - const char **out_unrecognized_spec); +gboolean nms_ifcfg_rh_utils_parse_unhandled_spec(const char * unhandled_spec, + const char **out_unmanaged_spec, + const char **out_unrecognized_spec); -#define NM_IFCFG_CONNECTION_LOG_PATH(path) ((path) ?: "in-memory") -#define NM_IFCFG_CONNECTION_LOG_FMT "%s (%s,\"%s\")" -#define NM_IFCFG_CONNECTION_LOG_ARG(con) NM_IFCFG_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_settings_connection_get_uuid ((NMSettingsConnection *) (con)), nm_settings_connection_get_id ((NMSettingsConnection *) (con)) -#define NM_IFCFG_CONNECTION_LOG_FMTD "%s (%s,\"%s\",%p)" -#define NM_IFCFG_CONNECTION_LOG_ARGD(con) NM_IFCFG_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_settings_connection_get_uuid ((NMSettingsConnection *) (con)), nm_settings_connection_get_id ((NMSettingsConnection *) (con)), (con) +#define NM_IFCFG_CONNECTION_LOG_PATH(path) ((path) ?: "in-memory") +#define NM_IFCFG_CONNECTION_LOG_FMT "%s (%s,\"%s\")" +#define NM_IFCFG_CONNECTION_LOG_ARG(con) \ + NM_IFCFG_CONNECTION_LOG_PATH( \ + nm_settings_connection_get_filename((NMSettingsConnection *) (con))), \ + nm_settings_connection_get_uuid((NMSettingsConnection *) (con)), \ + nm_settings_connection_get_id((NMSettingsConnection *) (con)) +#define NM_IFCFG_CONNECTION_LOG_FMTD "%s (%s,\"%s\",%p)" +#define NM_IFCFG_CONNECTION_LOG_ARGD(con) \ + NM_IFCFG_CONNECTION_LOG_PATH( \ + nm_settings_connection_get_filename((NMSettingsConnection *) (con))), \ + nm_settings_connection_get_uuid((NMSettingsConnection *) (con)), \ + nm_settings_connection_get_id((NMSettingsConnection *) (con)), (con) -char *utils_cert_path (const char *parent, const char *suffix, const char *extension); +char *utils_cert_path(const char *parent, const char *suffix, const char *extension); -const char *utils_get_ifcfg_name (const char *file, gboolean only_ifcfg); +const char *utils_get_ifcfg_name(const char *file, gboolean only_ifcfg); -gboolean utils_should_ignore_file (const char *filename, gboolean only_ifcfg); +gboolean utils_should_ignore_file(const char *filename, gboolean only_ifcfg); -char *utils_get_ifcfg_path (const char *parent); -char *utils_get_keys_path (const char *parent); -char *utils_get_route_path (const char *parent); -char *utils_get_route6_path (const char *parent); +char *utils_get_ifcfg_path(const char *parent); +char *utils_get_keys_path(const char *parent); +char *utils_get_route_path(const char *parent); +char *utils_get_route6_path(const char *parent); -shvarFile *utils_get_extra_ifcfg (const char *parent, const char *tag, gboolean should_create); -shvarFile *utils_get_keys_ifcfg (const char *parent, gboolean should_create); -shvarFile *utils_get_route_ifcfg (const char *parent, gboolean should_create); +shvarFile *utils_get_extra_ifcfg(const char *parent, const char *tag, gboolean should_create); +shvarFile *utils_get_keys_ifcfg(const char *parent, gboolean should_create); +shvarFile *utils_get_route_ifcfg(const char *parent, gboolean should_create); -gboolean utils_has_route_file_new_syntax (const char *filename); -gboolean utils_has_route_file_new_syntax_content (const char *contents, - gsize len); -gboolean utils_has_complex_routes (const char *filename, int addr_family); +gboolean utils_has_route_file_new_syntax(const char *filename); +gboolean utils_has_route_file_new_syntax_content(const char *contents, gsize len); +gboolean utils_has_complex_routes(const char *filename, int addr_family); -gboolean utils_is_ifcfg_alias_file (const char *alias, const char *ifcfg); +gboolean utils_is_ifcfg_alias_file(const char *alias, const char *ifcfg); -char *utils_detect_ifcfg_path (const char *path, gboolean only_ifcfg); +char *utils_detect_ifcfg_path(const char *path, gboolean only_ifcfg); -void nms_ifcfg_rh_utils_user_key_encode (const char *key, GString *str_buffer); -gboolean nms_ifcfg_rh_utils_user_key_decode (const char *name, GString *str_buffer); +void nms_ifcfg_rh_utils_user_key_encode(const char *key, GString *str_buffer); +gboolean nms_ifcfg_rh_utils_user_key_decode(const char *name, GString *str_buffer); static inline const char * -_nms_ifcfg_rh_utils_numbered_tag (char *buf, gsize buf_len, const char *tag_name, int which) +_nms_ifcfg_rh_utils_numbered_tag(char *buf, gsize buf_len, const char *tag_name, int which) { - gsize l; + gsize l; #if NM_MORE_ASSERTS > 5 - nm_assert (NM_FLAGS_ALL (nms_ifcfg_well_known_key_find_info_flags (tag_name), - NMS_IFCFG_KEY_TYPE_WELL_KNOWN - | NMS_IFCFG_KEY_TYPE_IS_NUMBERED)); + nm_assert(NM_FLAGS_ALL(nms_ifcfg_well_known_key_find_info_flags(tag_name), + NMS_IFCFG_KEY_TYPE_WELL_KNOWN | NMS_IFCFG_KEY_TYPE_IS_NUMBERED)); #endif - l = g_strlcpy (buf, tag_name, buf_len); - nm_assert (l < buf_len); - if (which != -1) { - buf_len -= l; - l = g_snprintf (&buf[l], buf_len, "%d", which); - nm_assert (l < buf_len); - } - return buf; + l = g_strlcpy(buf, tag_name, buf_len); + nm_assert(l < buf_len); + if (which != -1) { + buf_len -= l; + l = g_snprintf(&buf[l], buf_len, "%d", which); + nm_assert(l < buf_len); + } + return buf; } -#define numbered_tag(buf, tag_name, which) \ - ({ \ - _nm_unused char *const _buf = (buf); \ - \ - /* some static assert trying to ensure that the buffer is statically allocated. - * It disallows a buffer size of sizeof(gpointer) to catch that. */ \ - G_STATIC_ASSERT (G_N_ELEMENTS (buf) == sizeof (buf) && sizeof (buf) != sizeof (char *) && sizeof (buf) < G_MAXINT); \ - _nms_ifcfg_rh_utils_numbered_tag (buf, sizeof (buf), ""tag_name"", (which)); \ - }) - -gboolean nms_ifcfg_rh_utils_is_numbered_tag_impl (const char *key, - const char *tag, - gsize tag_len, - gint64 *out_idx); +#define numbered_tag(buf, tag_name, which) \ + ({ \ + _nm_unused char *const _buf = (buf); \ + \ + /* some static assert trying to ensure that the buffer is statically allocated. + * It disallows a buffer size of sizeof(gpointer) to catch that. */ \ + G_STATIC_ASSERT(G_N_ELEMENTS(buf) == sizeof(buf) && sizeof(buf) != sizeof(char *) \ + && sizeof(buf) < G_MAXINT); \ + _nms_ifcfg_rh_utils_numbered_tag(buf, sizeof(buf), "" tag_name "", (which)); \ + }) + +gboolean nms_ifcfg_rh_utils_is_numbered_tag_impl(const char *key, + const char *tag, + gsize tag_len, + gint64 * out_idx); static inline gboolean -nms_ifcfg_rh_utils_is_numbered_tag (const char *key, - const char *tag, - gint64 *out_idx) +nms_ifcfg_rh_utils_is_numbered_tag(const char *key, const char *tag, gint64 *out_idx) { - nm_assert (tag); + nm_assert(tag); - return nms_ifcfg_rh_utils_is_numbered_tag_impl (key, tag, strlen (tag), out_idx); + return nms_ifcfg_rh_utils_is_numbered_tag_impl(key, tag, strlen(tag), out_idx); } #define NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG(key, tag, out_idx) \ - nms_ifcfg_rh_utils_is_numbered_tag_impl (key, tag, NM_STRLEN (tag), out_idx) + nms_ifcfg_rh_utils_is_numbered_tag_impl(key, tag, NM_STRLEN(tag), out_idx) /*****************************************************************************/ -const NMSIfcfgKeyTypeInfo *nms_ifcfg_rh_utils_is_well_known_key (const char *key); +const NMSIfcfgKeyTypeInfo *nms_ifcfg_rh_utils_is_well_known_key(const char *key); /*****************************************************************************/ extern const char *const _nm_ethtool_ifcfg_names[_NM_ETHTOOL_ID_NUM]; static inline const char * -nms_ifcfg_rh_utils_get_ethtool_name (NMEthtoolID ethtool_id) +nms_ifcfg_rh_utils_get_ethtool_name(NMEthtoolID ethtool_id) { - nm_assert (ethtool_id >= _NM_ETHTOOL_ID_FIRST && ethtool_id <= _NM_ETHTOOL_ID_LAST); - nm_assert (ethtool_id < G_N_ELEMENTS (_nm_ethtool_ifcfg_names)); - nm_assert (_nm_ethtool_ifcfg_names[ethtool_id]); + nm_assert(ethtool_id >= _NM_ETHTOOL_ID_FIRST && ethtool_id <= _NM_ETHTOOL_ID_LAST); + nm_assert(ethtool_id < G_N_ELEMENTS(_nm_ethtool_ifcfg_names)); + nm_assert(_nm_ethtool_ifcfg_names[ethtool_id]); - return _nm_ethtool_ifcfg_names[ethtool_id]; + return _nm_ethtool_ifcfg_names[ethtool_id]; } -const NMEthtoolData *nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name, - NMEthtoolType ethtool_type); +const NMEthtoolData *nms_ifcfg_rh_utils_get_ethtool_by_name(const char * name, + NMEthtoolType ethtool_type); -#endif /* _UTILS_H_ */ +#endif /* _UTILS_H_ */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index e6526944..64884672 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2009 - 2015 Red Hat, Inc. */ @@ -46,3447 +46,3585 @@ #define _NMLOG_DOMAIN LOGD_SETTINGS #define _NMLOG_PREFIX_NAME "ifcfg-rh" -#define _NMLOG(level, ...) \ - G_STMT_START { \ - nm_log ((level), (_NMLOG_DOMAIN), NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME": " \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } G_STMT_END +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + nm_log((level), \ + (_NMLOG_DOMAIN), \ + NULL, \ + NULL, \ + "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME ": " _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END /*****************************************************************************/ static void -save_secret_flags (shvarFile *ifcfg, - const char *key, - NMSettingSecretFlags flags) +save_secret_flags(shvarFile *ifcfg, const char *key, NMSettingSecretFlags flags) { - GString *str; + GString *str; - g_return_if_fail (ifcfg != NULL); - g_return_if_fail (key != NULL); + g_return_if_fail(ifcfg != NULL); + g_return_if_fail(key != NULL); - if (flags == NM_SETTING_SECRET_FLAG_NONE) - return; + if (flags == NM_SETTING_SECRET_FLAG_NONE) + return; - /* Convert flags bitfield into string representation */ - str = g_string_sized_new (20); - if (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED) - g_string_append (str, SECRET_FLAG_AGENT); + /* Convert flags bitfield into string representation */ + str = g_string_sized_new(20); + if (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED) + g_string_append(str, SECRET_FLAG_AGENT); - if (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) { - if (str->len) - g_string_append_c (str, ' '); - g_string_append (str, SECRET_FLAG_NOT_SAVED); - } + if (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) { + if (str->len) + g_string_append_c(str, ' '); + g_string_append(str, SECRET_FLAG_NOT_SAVED); + } - if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) { - if (str->len) - g_string_append_c (str, ' '); - g_string_append (str, SECRET_FLAG_NOT_REQUIRED); - } + if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) { + if (str->len) + g_string_append_c(str, ' '); + g_string_append(str, SECRET_FLAG_NOT_REQUIRED); + } - svSetValueStr (ifcfg, key, str->len ? str->str : NULL); - g_string_free (str, TRUE); + svSetValueStr(ifcfg, key, str->len ? str->str : NULL); + g_string_free(str, TRUE); } static void -set_secret (shvarFile *ifcfg, - GHashTable *secrets, - const char *key, - const char *value, - const char *flags_key, - NMSettingSecretFlags flags) +set_secret(shvarFile * ifcfg, + GHashTable * secrets, + const char * key, + const char * value, + const char * flags_key, + NMSettingSecretFlags flags) { - /* Save secret flags */ - save_secret_flags (ifcfg, flags_key, flags); + /* Save secret flags */ + save_secret_flags(ifcfg, flags_key, flags); - /* Only write the secret if it's system owned and supposed to be saved */ - if (flags != NM_SETTING_SECRET_FLAG_NONE) - value = NULL; + /* Only write the secret if it's system owned and supposed to be saved */ + if (flags != NM_SETTING_SECRET_FLAG_NONE) + value = NULL; - g_hash_table_replace (secrets, g_strdup (key), g_strdup (value)); + g_hash_table_replace(secrets, g_strdup(key), g_strdup(value)); } static gboolean -write_secrets (shvarFile *ifcfg, - GHashTable *secrets, - GError **error) +write_secrets(shvarFile *ifcfg, GHashTable *secrets, GError **error) { - nm_auto_shvar_file_close shvarFile *keyfile = NULL; - gs_free const char **secrets_keys = NULL; - guint i, secrets_keys_n; - GError *local = NULL; - gboolean any_secrets = FALSE; - - keyfile = utils_get_keys_ifcfg (svFileGetName (ifcfg), TRUE); - if (!keyfile) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Failure to create secrets file for '%s'", svFileGetName (ifcfg)); - return FALSE; - } - - secrets_keys = nm_utils_strdict_get_keys (secrets, TRUE, &secrets_keys_n); - for (i = 0; i < secrets_keys_n; i++) { - const char *k = secrets_keys[i]; - const char *v = g_hash_table_lookup (secrets, k); - - if (v) { - svSetValueStr (keyfile, k, v); - any_secrets = TRUE; - } - } - - if (!any_secrets) - (void) unlink (svFileGetName (keyfile)); - else if (!svWriteFileWithoutDirtyWellknown (keyfile, 0600, &local)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Failure to write secrets to '%s': %s", svFileGetName (keyfile), local->message); - return FALSE; - } - - return TRUE; + nm_auto_shvar_file_close shvarFile *keyfile = NULL; + gs_free NMUtilsNamedValue *secrets_arr_free = NULL; + NMUtilsNamedValue secrets_arr_static[30]; + const NMUtilsNamedValue * secrets_arr; + guint secrets_len; + GError * local = NULL; + gboolean any_secrets = FALSE; + guint i; + + keyfile = utils_get_keys_ifcfg(svFileGetName(ifcfg), TRUE); + if (!keyfile) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Failure to create secrets file for '%s'", + svFileGetName(ifcfg)); + return FALSE; + } + + secrets_arr = nm_utils_named_values_from_strdict(secrets, + &secrets_len, + secrets_arr_static, + &secrets_arr_free); + for (i = 0; i < secrets_len; i++) { + const char *k = secrets_arr[i].name; + const char *v = secrets_arr[i].value_str; + + if (v) { + svSetValueStr(keyfile, k, v); + any_secrets = TRUE; + } + } + + if (!any_secrets) + (void) unlink(svFileGetName(keyfile)); + else if (!svWriteFileWithoutDirtyWellknown(keyfile, 0600, &local)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Failure to write secrets to '%s': %s", + svFileGetName(keyfile), + local->message); + return FALSE; + } + + return TRUE; } typedef struct { - const NMSetting8021xSchemeVtable *vtable; - const char *ifcfg_rh_key; + const NMSetting8021xSchemeVtable *vtable; + const char * ifcfg_rh_key; } Setting8021xSchemeVtable; static const Setting8021xSchemeVtable setting_8021x_scheme_vtable[] = { -#define _D(_scheme_type, _ifcfg_rh_key) \ - [(_scheme_type)] = { \ - .vtable = &nm_setting_8021x_scheme_vtable[(_scheme_type)], \ - .ifcfg_rh_key = ""_ifcfg_rh_key"", \ - } - _D (NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT, "IEEE_8021X_CA_CERT"), - _D (NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT, "IEEE_8021X_INNER_CA_CERT"), - _D (NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT, "IEEE_8021X_CLIENT_CERT"), - _D (NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT, "IEEE_8021X_INNER_CLIENT_CERT"), - _D (NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY, "IEEE_8021X_PRIVATE_KEY"), - _D (NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY, "IEEE_8021X_INNER_PRIVATE_KEY"), +#define _D(_scheme_type, _ifcfg_rh_key) \ + [(_scheme_type)] = { \ + .vtable = &nm_setting_8021x_scheme_vtable[(_scheme_type)], \ + .ifcfg_rh_key = ""_ifcfg_rh_key \ + "", \ + } + _D(NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT, "IEEE_8021X_CA_CERT"), + _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT, "IEEE_8021X_INNER_CA_CERT"), + _D(NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT, "IEEE_8021X_CLIENT_CERT"), + _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT, "IEEE_8021X_INNER_CLIENT_CERT"), + _D(NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY, "IEEE_8021X_PRIVATE_KEY"), + _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY, "IEEE_8021X_INNER_PRIVATE_KEY"), #undef _D }; static gboolean -write_object (NMSetting8021x *s_8021x, - shvarFile *ifcfg, - GHashTable *secrets, - GHashTable *blobs, - const Setting8021xSchemeVtable *objtype, - gboolean force_write, - GError **error) +write_object(NMSetting8021x * s_8021x, + shvarFile * ifcfg, + GHashTable * secrets, + GHashTable * blobs, + const Setting8021xSchemeVtable *objtype, + gboolean force_write, + GError ** error) { - NMSetting8021xCKScheme scheme; - const char *value = NULL; - GBytes *blob = NULL; - const char *password = NULL; - NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; - char secret_name[100]; - char secret_flags[sizeof (secret_name) + NM_STRLEN ("_FLAGS")]; - const char *extension; - char *standard_file; - - g_return_val_if_fail (ifcfg != NULL, FALSE); - g_return_val_if_fail (objtype != NULL, FALSE); - - scheme = (*(objtype->vtable->scheme_func))(s_8021x); - switch (scheme) { - case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN: - break; - case NM_SETTING_802_1X_CK_SCHEME_BLOB: - blob = (*(objtype->vtable->blob_func))(s_8021x); - break; - case NM_SETTING_802_1X_CK_SCHEME_PATH: - value = (*(objtype->vtable->path_func))(s_8021x); - break; - case NM_SETTING_802_1X_CK_SCHEME_PKCS11: - value = (*(objtype->vtable->uri_func))(s_8021x); - break; - default: - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Unhandled certificate object scheme"); - return FALSE; - } - - /* Set the password for certificate/private key. */ - nm_sprintf_buf (secret_name, "%s_PASSWORD", objtype->ifcfg_rh_key); - nm_sprintf_buf (secret_flags, "%s_PASSWORD_FLAGS", objtype->ifcfg_rh_key); - password = (*(objtype->vtable->passwd_func))(s_8021x); - flags = (*(objtype->vtable->pwflag_func))(s_8021x); - set_secret (ifcfg, secrets, secret_name, password, secret_flags, flags); - - if (!objtype->vtable->format_func) - extension = "der"; - else if (objtype->vtable->format_func (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) - extension = "p12"; - else - extension = "pem"; - - /* If the object path was specified, prefer that over any raw cert data that - * may have been sent. - */ - if (value) { - svSetValueStr (ifcfg, objtype->ifcfg_rh_key, value); - return TRUE; - } - - /* If it's raw certificate data, write the data out to the standard file */ - if (blob) { - char *new_file; - - new_file = utils_cert_path (svFileGetName (ifcfg), objtype->vtable->file_suffix, extension); - g_hash_table_replace (blobs, new_file, g_bytes_ref (blob)); - svSetValueStr (ifcfg, objtype->ifcfg_rh_key, new_file); - return TRUE; - } - - /* If certificate/private key wasn't sent, the connection may no longer be - * 802.1x and thus we clear out the paths and certs. - * - * Since no cert/private key is now being used, delete any standard file - * that was created for this connection, but leave other files alone. - * Thus, for example, - * /etc/sysconfig/network-scripts/ca-cert-Test_Write_Wifi_WPA_EAP-TLS.der - * will be deleted, but /etc/pki/tls/cert.pem will not. - */ - standard_file = utils_cert_path (svFileGetName (ifcfg), objtype->vtable->file_suffix, extension); - g_hash_table_replace (blobs, standard_file, NULL); - svSetValue (ifcfg, objtype->ifcfg_rh_key, force_write ? "" : NULL); - return TRUE; + NMSetting8021xCKScheme scheme; + const char * value = NULL; + GBytes * blob = NULL; + const char * password = NULL; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + char secret_name[100]; + char secret_flags[sizeof(secret_name) + NM_STRLEN("_FLAGS")]; + const char * extension; + char * standard_file; + + g_return_val_if_fail(ifcfg != NULL, FALSE); + g_return_val_if_fail(objtype != NULL, FALSE); + + scheme = (*(objtype->vtable->scheme_func))(s_8021x); + switch (scheme) { + case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN: + break; + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + blob = (*(objtype->vtable->blob_func))(s_8021x); + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + value = (*(objtype->vtable->path_func))(s_8021x); + break; + case NM_SETTING_802_1X_CK_SCHEME_PKCS11: + value = (*(objtype->vtable->uri_func))(s_8021x); + break; + default: + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Unhandled certificate object scheme"); + return FALSE; + } + + /* Set the password for certificate/private key. */ + nm_sprintf_buf(secret_name, "%s_PASSWORD", objtype->ifcfg_rh_key); + nm_sprintf_buf(secret_flags, "%s_PASSWORD_FLAGS", objtype->ifcfg_rh_key); + password = (*(objtype->vtable->passwd_func))(s_8021x); + flags = (*(objtype->vtable->pwflag_func))(s_8021x); + set_secret(ifcfg, secrets, secret_name, password, secret_flags, flags); + + if (!objtype->vtable->format_func) + extension = "der"; + else if (objtype->vtable->format_func(s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) + extension = "p12"; + else + extension = "pem"; + + /* If the object path was specified, prefer that over any raw cert data that + * may have been sent. + */ + if (value) { + svSetValueStr(ifcfg, objtype->ifcfg_rh_key, value); + return TRUE; + } + + /* If it's raw certificate data, write the data out to the standard file */ + if (blob) { + char *new_file; + + new_file = utils_cert_path(svFileGetName(ifcfg), objtype->vtable->file_suffix, extension); + g_hash_table_replace(blobs, new_file, g_bytes_ref(blob)); + svSetValueStr(ifcfg, objtype->ifcfg_rh_key, new_file); + return TRUE; + } + + /* If certificate/private key wasn't sent, the connection may no longer be + * 802.1x and thus we clear out the paths and certs. + * + * Since no cert/private key is now being used, delete any standard file + * that was created for this connection, but leave other files alone. + * Thus, for example, + * /etc/sysconfig/network-scripts/ca-cert-Test_Write_Wifi_WPA_EAP-TLS.der + * will be deleted, but /etc/pki/tls/cert.pem will not. + */ + standard_file = utils_cert_path(svFileGetName(ifcfg), objtype->vtable->file_suffix, extension); + g_hash_table_replace(blobs, standard_file, NULL); + svSetValue(ifcfg, objtype->ifcfg_rh_key, force_write ? "" : NULL); + return TRUE; } static gboolean -write_blobs (GHashTable *blobs, GError **error) +write_blobs(GHashTable *blobs, GError **error) { - GHashTableIter iter; - const char *filename; - GBytes *blob; - - if (!blobs) - return TRUE; - - g_hash_table_iter_init (&iter, blobs); - while (g_hash_table_iter_next (&iter, (gpointer *) &filename, (gpointer *) &blob)) { - GError *write_error = NULL; - - if (!blob) { - (void) unlink (filename); - continue; - } - - /* Write the raw certificate data out to the standard file so that we - * can use paths from now on instead of pushing around the certificate - * data itself. - */ - if (!nm_utils_file_set_contents (filename, - (const char *) g_bytes_get_data (blob, NULL), - g_bytes_get_size (blob), - 0600, - NULL, - &write_error)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Could not write certificate to file \"%s\": %s", - filename, - write_error->message); - return FALSE; - } - } - - return TRUE; + GHashTableIter iter; + const char * filename; + GBytes * blob; + + if (!blobs) + return TRUE; + + g_hash_table_iter_init(&iter, blobs); + while (g_hash_table_iter_next(&iter, (gpointer *) &filename, (gpointer *) &blob)) { + GError *write_error = NULL; + + if (!blob) { + (void) unlink(filename); + continue; + } + + /* Write the raw certificate data out to the standard file so that we + * can use paths from now on instead of pushing around the certificate + * data itself. + */ + if (!nm_utils_file_set_contents(filename, + (const char *) g_bytes_get_data(blob, NULL), + g_bytes_get_size(blob), + 0600, + NULL, + &write_error)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Could not write certificate to file \"%s\": %s", + filename, + write_error->message); + return FALSE; + } + } + + return TRUE; } static gboolean -write_8021x_certs (NMSetting8021x *s_8021x, - GHashTable *secrets, - GHashTable *blobs, - gboolean phase2, - shvarFile *ifcfg, - GError **error) +write_8021x_certs(NMSetting8021x *s_8021x, + GHashTable * secrets, + GHashTable * blobs, + gboolean phase2, + shvarFile * ifcfg, + GError ** error) { - const Setting8021xSchemeVtable *pk_otype = NULL; - gs_free char *value_to_free = NULL; - - /* CA certificate */ - if (!write_object (s_8021x, ifcfg, secrets, blobs, - phase2 - ? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT] - : &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT], - FALSE, - error)) - return FALSE; - - /* Private key */ - if (phase2) - pk_otype = &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY]; - else - pk_otype = &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY]; - - /* Save the private key */ - if (!write_object (s_8021x, ifcfg, secrets, blobs, pk_otype, FALSE, error)) - return FALSE; - - /* Save the client certificate. - * If there is a private key, always write a property for the - * client certificate even if it is empty, so that the reader - * doesn't have to read the private key file to determine if it - * is a PKCS #12 one which serves also as client certificate. - */ - if (!write_object (s_8021x, ifcfg, secrets, blobs, - phase2 - ? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT] - : &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT], - !!svGetValue (ifcfg, pk_otype->ifcfg_rh_key, &value_to_free), - error)) - return FALSE; - - return TRUE; + const Setting8021xSchemeVtable *pk_otype = NULL; + gs_free char * value_to_free = NULL; + + /* CA certificate */ + if (!write_object( + s_8021x, + ifcfg, + secrets, + blobs, + phase2 ? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT] + : &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT], + FALSE, + error)) + return FALSE; + + /* Private key */ + if (phase2) + pk_otype = &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY]; + else + pk_otype = &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY]; + + /* Save the private key */ + if (!write_object(s_8021x, ifcfg, secrets, blobs, pk_otype, FALSE, error)) + return FALSE; + + /* Save the client certificate. + * If there is a private key, always write a property for the + * client certificate even if it is empty, so that the reader + * doesn't have to read the private key file to determine if it + * is a PKCS #12 one which serves also as client certificate. + */ + if (!write_object( + s_8021x, + ifcfg, + secrets, + blobs, + phase2 ? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT] + : &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT], + !!svGetValue(ifcfg, pk_otype->ifcfg_rh_key, &value_to_free), + error)) + return FALSE; + + return TRUE; } static gboolean -write_8021x_setting (NMConnection *connection, - shvarFile *ifcfg, - GHashTable *secrets, - GHashTable *blobs, - gboolean wired, - GError **error) +write_8021x_setting(NMConnection *connection, + shvarFile * ifcfg, + GHashTable * secrets, + GHashTable * blobs, + gboolean wired, + GError ** error) { - NMSetting8021x *s_8021x; - NMSetting8021xAuthFlags auth_flags; - const char *value, *match; - gconstpointer ptr; - GBytes* bytes; - char *tmp = NULL; - GString *phase2_auth; - GString *str; - guint32 i, num; - gsize size; - int vint; - - s_8021x = nm_connection_get_setting_802_1x (connection); - if (!s_8021x) - return TRUE; - - /* If wired, write KEY_MGMT */ - if (wired) - svSetValueStr (ifcfg, "KEY_MGMT", "IEEE8021X"); - - /* EAP method */ - if (nm_setting_802_1x_get_num_eap_methods (s_8021x)) { - value = nm_setting_802_1x_get_eap_method (s_8021x, 0); - if (value) - tmp = g_ascii_strup (value, -1); - } - svSetValueStr (ifcfg, "IEEE_8021X_EAP_METHODS", tmp); - g_free (tmp); - - svSetValueStr (ifcfg, "IEEE_8021X_IDENTITY", - nm_setting_802_1x_get_identity (s_8021x)); - - svSetValueStr (ifcfg, "IEEE_8021X_ANON_IDENTITY", - nm_setting_802_1x_get_anonymous_identity (s_8021x)); - - set_secret (ifcfg, - secrets, - "IEEE_8021X_PASSWORD", - nm_setting_802_1x_get_password (s_8021x), - "IEEE_8021X_PASSWORD_FLAGS", - nm_setting_802_1x_get_password_flags (s_8021x)); - - tmp = NULL; - bytes = nm_setting_802_1x_get_password_raw (s_8021x); - if (bytes) { - ptr = g_bytes_get_data (bytes, &size); - tmp = nm_utils_bin2hexstr (ptr, size, -1); - } - set_secret (ifcfg, - secrets, - "IEEE_8021X_PASSWORD_RAW", - tmp, - "IEEE_8021X_PASSWORD_RAW_FLAGS", - nm_setting_802_1x_get_password_raw_flags (s_8021x)); - g_free (tmp); - - svSetValueBoolean_cond_true (ifcfg, - "IEEE_8021X_SYSTEM_CA_CERTS", - nm_setting_802_1x_get_system_ca_certs (s_8021x)); - - value = nm_setting_802_1x_get_phase1_peapver (s_8021x); - svSetValueStr (ifcfg, "IEEE_8021X_PEAP_VERSION", value); - - svSetValueBoolean_cond_true (ifcfg, - "IEEE_8021X_PEAP_FORCE_NEW_LABEL", - nm_streq0 (nm_setting_802_1x_get_phase1_peaplabel (s_8021x), "1")); - - svSetValueStr (ifcfg, - "IEEE_8021X_PAC_FILE", - nm_setting_802_1x_get_pac_file (s_8021x)); - - /* FAST PAC provisioning */ - value = nm_setting_802_1x_get_phase1_fast_provisioning (s_8021x); - if (value) { - if (strcmp (value, "1") == 0) - value = "allow-unauth"; - else if (strcmp (value, "2") == 0) - value = "allow-auth"; - else if (strcmp (value, "3") == 0) - value = "allow-unauth allow-auth"; - else - value = NULL; - } - svSetValueStr (ifcfg, "IEEE_8021X_FAST_PROVISIONING", value); - - /* Phase2 auth methods */ - phase2_auth = g_string_new (NULL); - - value = nm_setting_802_1x_get_phase2_auth (s_8021x); - if (value) { - tmp = g_ascii_strup (value, -1); - g_string_append (phase2_auth, tmp); - g_free (tmp); - } - - value = nm_setting_802_1x_get_phase2_autheap (s_8021x); - if (value) { - if (phase2_auth->len) - g_string_append_c (phase2_auth, ' '); - - tmp = g_ascii_strup (value, -1); - g_string_append_printf (phase2_auth, "EAP-%s", tmp); - g_free (tmp); - } - - auth_flags = nm_setting_802_1x_get_phase1_auth_flags (s_8021x); - if (auth_flags != NM_SETTING_802_1X_AUTH_FLAGS_NONE) { - svSetValueEnum (ifcfg, "IEEE_8021X_PHASE1_AUTH_FLAGS", - nm_setting_802_1x_auth_flags_get_type(), - auth_flags); - } - - svSetValueStr (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", - phase2_auth->len ? phase2_auth->str : NULL); - - g_string_free (phase2_auth, TRUE); - - svSetValueStr (ifcfg, "IEEE_8021X_SUBJECT_MATCH", - nm_setting_802_1x_get_subject_match (s_8021x)); - - svSetValueStr (ifcfg, "IEEE_8021X_PHASE2_SUBJECT_MATCH", - nm_setting_802_1x_get_phase2_subject_match (s_8021x)); - - str = g_string_new (NULL); - num = nm_setting_802_1x_get_num_altsubject_matches (s_8021x); - for (i = 0; i < num; i++) { - if (i > 0) - g_string_append_c (str, ' '); - match = nm_setting_802_1x_get_altsubject_match (s_8021x, i); - g_string_append (str, match); - } - if (str->len > 0) - svSetValueStr (ifcfg, "IEEE_8021X_ALTSUBJECT_MATCHES", str->str); - g_string_free (str, TRUE); - - str = g_string_new (NULL); - num = nm_setting_802_1x_get_num_phase2_altsubject_matches (s_8021x); - for (i = 0; i < num; i++) { - if (i > 0) - g_string_append_c (str, ' '); - match = nm_setting_802_1x_get_phase2_altsubject_match (s_8021x, i); - g_string_append (str, match); - } - if (str->len > 0) - svSetValueStr (ifcfg, "IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES", str->str); - g_string_free (str, TRUE); - - svSetValueStr (ifcfg, "IEEE_8021X_DOMAIN_SUFFIX_MATCH", - nm_setting_802_1x_get_domain_suffix_match (s_8021x)); - svSetValueStr (ifcfg, "IEEE_8021X_PHASE2_DOMAIN_SUFFIX_MATCH", - nm_setting_802_1x_get_phase2_domain_suffix_match (s_8021x)); - - svSetValueStr (ifcfg, "IEEE_8021X_DOMAIN_MATCH", - nm_setting_802_1x_get_domain_match (s_8021x)); - svSetValueStr (ifcfg, "IEEE_8021X_PHASE2_DOMAIN_MATCH", - nm_setting_802_1x_get_phase2_domain_match (s_8021x)); - - vint = nm_setting_802_1x_get_auth_timeout (s_8021x); - svSetValueInt64_cond (ifcfg, "IEEE_8021X_AUTH_TIMEOUT", vint > 0, vint); - - svSetValueBoolean_cond_true (ifcfg, - "IEEE_8021X_OPTIONAL", - nm_setting_802_1x_get_optional (s_8021x)); - - svSetValue (ifcfg, "IEEE_8021X_CA_PATH", - nm_setting_802_1x_get_ca_path (s_8021x)); - svSetValue (ifcfg, "IEEE_8021X_PHASE2_CA_PATH", - nm_setting_802_1x_get_phase2_ca_path (s_8021x)); - - set_secret (ifcfg, - secrets, - "IEEE_8021X_PIN", - nm_setting_802_1x_get_pin (s_8021x), - "IEEE_8021X_PIN_FLAGS", - nm_setting_802_1x_get_pin_flags (s_8021x)); - - if (!write_8021x_certs (s_8021x, secrets, blobs, FALSE, ifcfg, error)) - return FALSE; - - /* phase2/inner certs */ - if (!write_8021x_certs (s_8021x, secrets, blobs, TRUE, ifcfg, error)) - return FALSE; - - return TRUE; + NMSetting8021x * s_8021x; + NMSetting8021xAuthFlags auth_flags; + const char * value, *match; + gconstpointer ptr; + GBytes * bytes; + char * tmp = NULL; + GString * phase2_auth; + GString * str; + guint32 i, num; + gsize size; + int vint; + + s_8021x = nm_connection_get_setting_802_1x(connection); + if (!s_8021x) + return TRUE; + + /* If wired, write KEY_MGMT */ + if (wired) + svSetValueStr(ifcfg, "KEY_MGMT", "IEEE8021X"); + + /* EAP method */ + if (nm_setting_802_1x_get_num_eap_methods(s_8021x)) { + value = nm_setting_802_1x_get_eap_method(s_8021x, 0); + if (value) + tmp = g_ascii_strup(value, -1); + } + svSetValueStr(ifcfg, "IEEE_8021X_EAP_METHODS", tmp); + g_free(tmp); + + svSetValueStr(ifcfg, "IEEE_8021X_IDENTITY", nm_setting_802_1x_get_identity(s_8021x)); + + svSetValueStr(ifcfg, + "IEEE_8021X_ANON_IDENTITY", + nm_setting_802_1x_get_anonymous_identity(s_8021x)); + + set_secret(ifcfg, + secrets, + "IEEE_8021X_PASSWORD", + nm_setting_802_1x_get_password(s_8021x), + "IEEE_8021X_PASSWORD_FLAGS", + nm_setting_802_1x_get_password_flags(s_8021x)); + + tmp = NULL; + bytes = nm_setting_802_1x_get_password_raw(s_8021x); + if (bytes) { + ptr = g_bytes_get_data(bytes, &size); + tmp = nm_utils_bin2hexstr(ptr, size, -1); + } + set_secret(ifcfg, + secrets, + "IEEE_8021X_PASSWORD_RAW", + tmp, + "IEEE_8021X_PASSWORD_RAW_FLAGS", + nm_setting_802_1x_get_password_raw_flags(s_8021x)); + g_free(tmp); + + svSetValueBoolean_cond_true(ifcfg, + "IEEE_8021X_SYSTEM_CA_CERTS", + nm_setting_802_1x_get_system_ca_certs(s_8021x)); + + value = nm_setting_802_1x_get_phase1_peapver(s_8021x); + svSetValueStr(ifcfg, "IEEE_8021X_PEAP_VERSION", value); + + svSetValueBoolean_cond_true(ifcfg, + "IEEE_8021X_PEAP_FORCE_NEW_LABEL", + nm_streq0(nm_setting_802_1x_get_phase1_peaplabel(s_8021x), "1")); + + svSetValueStr(ifcfg, "IEEE_8021X_PAC_FILE", nm_setting_802_1x_get_pac_file(s_8021x)); + + /* FAST PAC provisioning */ + value = nm_setting_802_1x_get_phase1_fast_provisioning(s_8021x); + if (value) { + if (strcmp(value, "1") == 0) + value = "allow-unauth"; + else if (strcmp(value, "2") == 0) + value = "allow-auth"; + else if (strcmp(value, "3") == 0) + value = "allow-unauth allow-auth"; + else + value = NULL; + } + svSetValueStr(ifcfg, "IEEE_8021X_FAST_PROVISIONING", value); + + /* Phase2 auth methods */ + phase2_auth = g_string_new(NULL); + + value = nm_setting_802_1x_get_phase2_auth(s_8021x); + if (value) { + tmp = g_ascii_strup(value, -1); + g_string_append(phase2_auth, tmp); + g_free(tmp); + } + + value = nm_setting_802_1x_get_phase2_autheap(s_8021x); + if (value) { + if (phase2_auth->len) + g_string_append_c(phase2_auth, ' '); + + tmp = g_ascii_strup(value, -1); + g_string_append_printf(phase2_auth, "EAP-%s", tmp); + g_free(tmp); + } + + auth_flags = nm_setting_802_1x_get_phase1_auth_flags(s_8021x); + if (auth_flags != NM_SETTING_802_1X_AUTH_FLAGS_NONE) { + svSetValueEnum(ifcfg, + "IEEE_8021X_PHASE1_AUTH_FLAGS", + nm_setting_802_1x_auth_flags_get_type(), + auth_flags); + } + + svSetValueStr(ifcfg, + "IEEE_8021X_INNER_AUTH_METHODS", + phase2_auth->len ? phase2_auth->str : NULL); + + g_string_free(phase2_auth, TRUE); + + svSetValueStr(ifcfg, "IEEE_8021X_SUBJECT_MATCH", nm_setting_802_1x_get_subject_match(s_8021x)); + + svSetValueStr(ifcfg, + "IEEE_8021X_PHASE2_SUBJECT_MATCH", + nm_setting_802_1x_get_phase2_subject_match(s_8021x)); + + str = g_string_new(NULL); + num = nm_setting_802_1x_get_num_altsubject_matches(s_8021x); + for (i = 0; i < num; i++) { + if (i > 0) + g_string_append_c(str, ' '); + match = nm_setting_802_1x_get_altsubject_match(s_8021x, i); + g_string_append(str, match); + } + if (str->len > 0) + svSetValueStr(ifcfg, "IEEE_8021X_ALTSUBJECT_MATCHES", str->str); + g_string_free(str, TRUE); + + str = g_string_new(NULL); + num = nm_setting_802_1x_get_num_phase2_altsubject_matches(s_8021x); + for (i = 0; i < num; i++) { + if (i > 0) + g_string_append_c(str, ' '); + match = nm_setting_802_1x_get_phase2_altsubject_match(s_8021x, i); + g_string_append(str, match); + } + if (str->len > 0) + svSetValueStr(ifcfg, "IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES", str->str); + g_string_free(str, TRUE); + + svSetValueStr(ifcfg, + "IEEE_8021X_DOMAIN_SUFFIX_MATCH", + nm_setting_802_1x_get_domain_suffix_match(s_8021x)); + svSetValueStr(ifcfg, + "IEEE_8021X_PHASE2_DOMAIN_SUFFIX_MATCH", + nm_setting_802_1x_get_phase2_domain_suffix_match(s_8021x)); + + svSetValueStr(ifcfg, "IEEE_8021X_DOMAIN_MATCH", nm_setting_802_1x_get_domain_match(s_8021x)); + svSetValueStr(ifcfg, + "IEEE_8021X_PHASE2_DOMAIN_MATCH", + nm_setting_802_1x_get_phase2_domain_match(s_8021x)); + + vint = nm_setting_802_1x_get_auth_timeout(s_8021x); + svSetValueInt64_cond(ifcfg, "IEEE_8021X_AUTH_TIMEOUT", vint > 0, vint); + + svSetValueBoolean_cond_true(ifcfg, + "IEEE_8021X_OPTIONAL", + nm_setting_802_1x_get_optional(s_8021x)); + + svSetValue(ifcfg, "IEEE_8021X_CA_PATH", nm_setting_802_1x_get_ca_path(s_8021x)); + svSetValue(ifcfg, "IEEE_8021X_PHASE2_CA_PATH", nm_setting_802_1x_get_phase2_ca_path(s_8021x)); + + set_secret(ifcfg, + secrets, + "IEEE_8021X_PIN", + nm_setting_802_1x_get_pin(s_8021x), + "IEEE_8021X_PIN_FLAGS", + nm_setting_802_1x_get_pin_flags(s_8021x)); + + if (!write_8021x_certs(s_8021x, secrets, blobs, FALSE, ifcfg, error)) + return FALSE; + + /* phase2/inner certs */ + if (!write_8021x_certs(s_8021x, secrets, blobs, TRUE, ifcfg, error)) + return FALSE; + + return TRUE; } static gboolean -write_wireless_security_setting (NMConnection *connection, - shvarFile *ifcfg, - GHashTable *secrets, - gboolean adhoc, - gboolean *no_8021x, - GError **error) +write_wireless_security_setting(NMConnection *connection, + shvarFile * ifcfg, + GHashTable * secrets, + gboolean adhoc, + gboolean * no_8021x, + GError ** error) { - NMSettingWirelessSecurity *s_wsec; - const char *key_mgmt, *auth_alg, *key, *proto, *cipher; - const char *psk = NULL; - gboolean wep = FALSE, wpa = FALSE, dynamic_wep = FALSE; - NMSettingWirelessSecurityWpsMethod wps_method; - char *tmp; - guint32 i, num; - GString *str; - - s_wsec = nm_connection_get_setting_wireless_security (connection); - if (!s_wsec) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Missing '%s' setting", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); - return FALSE; - } - - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); - nm_assert (key_mgmt); - - auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); - - if (!strcmp (key_mgmt, "none")) { - wep = TRUE; - *no_8021x = TRUE; - } else if (!strcmp (key_mgmt, "wpa-psk")) { - svSetValueStr (ifcfg, "KEY_MGMT", "WPA-PSK"); - wpa = TRUE; - *no_8021x = TRUE; - } else if (!strcmp (key_mgmt, "sae")) { - svSetValueStr (ifcfg, "KEY_MGMT", "SAE"); - wpa = TRUE; - *no_8021x = TRUE; - } else if (!strcmp (key_mgmt, "owe")) { - svSetValueStr (ifcfg, "KEY_MGMT", "OWE"); - wpa = FALSE; - *no_8021x = TRUE; - } else if (!strcmp (key_mgmt, "ieee8021x")) { - svSetValueStr (ifcfg, "KEY_MGMT", "IEEE8021X"); - dynamic_wep = TRUE; - } else if (!strcmp (key_mgmt, "wpa-eap")) { - svSetValueStr (ifcfg, "KEY_MGMT", "WPA-EAP"); - wpa = TRUE; - } - - if (auth_alg) { - if (!strcmp (auth_alg, "shared")) - svSetValueStr (ifcfg, "SECURITYMODE", "restricted"); - else if (!strcmp (auth_alg, "open")) - svSetValueStr (ifcfg, "SECURITYMODE", "open"); - else if (!strcmp (auth_alg, "leap")) { - svSetValueStr (ifcfg, "SECURITYMODE", "leap"); - svSetValueStr (ifcfg, "IEEE_8021X_IDENTITY", - nm_setting_wireless_security_get_leap_username (s_wsec)); - set_secret (ifcfg, - secrets, - "IEEE_8021X_PASSWORD", - nm_setting_wireless_security_get_leap_password (s_wsec), - "IEEE_8021X_PASSWORD_FLAGS", - nm_setting_wireless_security_get_leap_password_flags (s_wsec)); - *no_8021x = TRUE; - } - } - - wps_method = nm_setting_wireless_security_get_wps_method (s_wsec); - if (wps_method != NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT) - svSetValueEnum (ifcfg, "WPS_METHOD", nm_setting_wireless_security_wps_method_get_type (), wps_method); - - /* WEP keys */ - - /* Clear any default key */ - set_secret (ifcfg, secrets, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); - - /* Clear existing keys */ - for (i = 0; i < 4; i++) { - char tag[64]; - - numbered_tag (tag, "KEY_PASSPHRASE", i + 1); - set_secret (ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); - - numbered_tag (tag, "KEY", i + 1); - set_secret (ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); - } - - /* And write the new ones out */ - if (wep) { - NMWepKeyType key_type; - const char *key_type_str = NULL; - - /* Default WEP TX key index */ - svSetValueInt64 (ifcfg, "DEFAULTKEY", nm_setting_wireless_security_get_wep_tx_keyidx(s_wsec) + 1); - - key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); - switch (key_type) { - case NM_WEP_KEY_TYPE_KEY: - key_type_str = "key"; - break; - case NM_WEP_KEY_TYPE_PASSPHRASE: - key_type_str = "passphrase"; - break; - case NM_WEP_KEY_TYPE_UNKNOWN: - break; - } - svSetValue (ifcfg, "KEY_TYPE", key_type_str); - - for (i = 0; i < 4; i++) { - key = nm_setting_wireless_security_get_wep_key (s_wsec, i); - if (key) { - gs_free char *ascii_key = NULL; - char tag[64]; - gboolean key_valid = TRUE; - - /* Passphrase needs a different ifcfg key since with WEP, there - * are some passphrases that are indistinguishable from WEP hex - * keys. - */ - if (key_type == NM_WEP_KEY_TYPE_UNKNOWN) { - if (nm_utils_wep_key_valid (key, NM_WEP_KEY_TYPE_KEY)) - key_type = NM_WEP_KEY_TYPE_KEY; - else if (nm_utils_wep_key_valid (key, NM_WEP_KEY_TYPE_PASSPHRASE)) - key_type = NM_WEP_KEY_TYPE_PASSPHRASE; - } - - if (key_type == NM_WEP_KEY_TYPE_PASSPHRASE) - numbered_tag (tag, "KEY_PASSPHRASE", i + 1); - else if (key_type == NM_WEP_KEY_TYPE_KEY) { - numbered_tag (tag, "KEY", i + 1); - - /* Add 's:' prefix for ASCII keys */ - if (strlen (key) == 5 || strlen (key) == 13) { - ascii_key = g_strdup_printf ("s:%s", key); - key = ascii_key; - } - } else { - g_warn_if_reached (); - key_valid = FALSE; - } - - if (key_valid) { - set_secret (ifcfg, - secrets, - tag, - key, - "WEP_KEY_FLAGS", - nm_setting_wireless_security_get_wep_key_flags (s_wsec)); - } - } - } - } - - /* WPA protos */ - num = nm_setting_wireless_security_get_num_protos (s_wsec); - for (i = 0; i < num; i++) { - proto = nm_setting_wireless_security_get_proto (s_wsec, i); - if (proto && !strcmp (proto, "wpa")) - svSetValueStr (ifcfg, "WPA_ALLOW_WPA", "yes"); - else if (proto && !strcmp (proto, "rsn")) - svSetValueStr (ifcfg, "WPA_ALLOW_WPA2", "yes"); - } - - /* WPA Pairwise ciphers */ - str = g_string_new (NULL); - num = nm_setting_wireless_security_get_num_pairwise (s_wsec); - for (i = 0; i < num; i++) { - if (i > 0) - g_string_append_c (str, ' '); - cipher = nm_setting_wireless_security_get_pairwise (s_wsec, i); - - /* Don't write out WEP40 or WEP104 if for some reason they are set; they - * are not valid pairwise ciphers. - */ - if (strcmp (cipher, "wep40") && strcmp (cipher, "wep104")) { - tmp = g_ascii_strup (cipher, -1); - g_string_append (str, tmp); - g_free (tmp); - } - } - if (strlen (str->str) && (dynamic_wep == FALSE)) - svSetValueStr (ifcfg, "CIPHER_PAIRWISE", str->str); - g_string_free (str, TRUE); - - /* WPA Group ciphers */ - str = g_string_new (NULL); - num = nm_setting_wireless_security_get_num_groups (s_wsec); - for (i = 0; i < num; i++) { - if (i > 0) - g_string_append_c (str, ' '); - cipher = nm_setting_wireless_security_get_group (s_wsec, i); - tmp = g_ascii_strup (cipher, -1); - g_string_append (str, tmp); - g_free (tmp); - } - if (strlen (str->str) && (dynamic_wep == FALSE)) - svSetValueStr (ifcfg, "CIPHER_GROUP", str->str); - g_string_free (str, TRUE); - - if (wpa) - psk = nm_setting_wireless_security_get_psk (s_wsec); - - set_secret (ifcfg, - secrets, - "WPA_PSK", - psk, - "WPA_PSK_FLAGS", - wpa ? nm_setting_wireless_security_get_psk_flags (s_wsec) : NM_SETTING_SECRET_FLAG_NONE); - - if (nm_setting_wireless_security_get_pmf (s_wsec) != NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT) { - svSetValueEnum (ifcfg, "PMF", nm_setting_wireless_security_pmf_get_type (), - nm_setting_wireless_security_get_pmf (s_wsec)); - } - - if (nm_setting_wireless_security_get_fils (s_wsec) != NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT) { - svSetValueEnum (ifcfg, "FILS", nm_setting_wireless_security_fils_get_type (), - nm_setting_wireless_security_get_fils (s_wsec)); - } - - return TRUE; + NMSettingWirelessSecurity * s_wsec; + const char * key_mgmt, *auth_alg, *key, *proto, *cipher; + const char * psk = NULL; + gboolean wep = FALSE, wpa = FALSE, dynamic_wep = FALSE; + NMSettingWirelessSecurityWpsMethod wps_method; + char * tmp; + guint32 i, num; + GString * str; + + s_wsec = nm_connection_get_setting_wireless_security(connection); + if (!s_wsec) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Missing '%s' setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + return FALSE; + } + + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + nm_assert(key_mgmt); + + auth_alg = nm_setting_wireless_security_get_auth_alg(s_wsec); + + if (!strcmp(key_mgmt, "none")) { + wep = TRUE; + *no_8021x = TRUE; + } else if (!strcmp(key_mgmt, "wpa-psk")) { + svSetValueStr(ifcfg, "KEY_MGMT", "WPA-PSK"); + wpa = TRUE; + *no_8021x = TRUE; + } else if (!strcmp(key_mgmt, "sae")) { + svSetValueStr(ifcfg, "KEY_MGMT", "SAE"); + wpa = TRUE; + *no_8021x = TRUE; + } else if (!strcmp(key_mgmt, "owe")) { + svSetValueStr(ifcfg, "KEY_MGMT", "OWE"); + wpa = FALSE; + *no_8021x = TRUE; + } else if (!strcmp(key_mgmt, "ieee8021x")) { + svSetValueStr(ifcfg, "KEY_MGMT", "IEEE8021X"); + dynamic_wep = TRUE; + } else if (!strcmp(key_mgmt, "wpa-eap")) { + svSetValueStr(ifcfg, "KEY_MGMT", "WPA-EAP"); + wpa = TRUE; + } + + if (auth_alg) { + if (!strcmp(auth_alg, "shared")) + svSetValueStr(ifcfg, "SECURITYMODE", "restricted"); + else if (!strcmp(auth_alg, "open")) + svSetValueStr(ifcfg, "SECURITYMODE", "open"); + else if (!strcmp(auth_alg, "leap")) { + svSetValueStr(ifcfg, "SECURITYMODE", "leap"); + svSetValueStr(ifcfg, + "IEEE_8021X_IDENTITY", + nm_setting_wireless_security_get_leap_username(s_wsec)); + set_secret(ifcfg, + secrets, + "IEEE_8021X_PASSWORD", + nm_setting_wireless_security_get_leap_password(s_wsec), + "IEEE_8021X_PASSWORD_FLAGS", + nm_setting_wireless_security_get_leap_password_flags(s_wsec)); + *no_8021x = TRUE; + } + } + + wps_method = nm_setting_wireless_security_get_wps_method(s_wsec); + if (wps_method != NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT) + svSetValueEnum(ifcfg, + "WPS_METHOD", + nm_setting_wireless_security_wps_method_get_type(), + wps_method); + + /* WEP keys */ + + /* Clear any default key */ + set_secret(ifcfg, secrets, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); + + /* Clear existing keys */ + for (i = 0; i < 4; i++) { + char tag[64]; + + numbered_tag(tag, "KEY_PASSPHRASE", i + 1); + set_secret(ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); + + numbered_tag(tag, "KEY", i + 1); + set_secret(ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); + } + + /* And write the new ones out */ + if (wep) { + NMWepKeyType key_type; + const char * key_type_str = NULL; + + /* Default WEP TX key index */ + svSetValueInt64(ifcfg, + "DEFAULTKEY", + nm_setting_wireless_security_get_wep_tx_keyidx(s_wsec) + 1); + + key_type = nm_setting_wireless_security_get_wep_key_type(s_wsec); + switch (key_type) { + case NM_WEP_KEY_TYPE_KEY: + key_type_str = "key"; + break; + case NM_WEP_KEY_TYPE_PASSPHRASE: + key_type_str = "passphrase"; + break; + case NM_WEP_KEY_TYPE_UNKNOWN: + break; + } + svSetValue(ifcfg, "KEY_TYPE", key_type_str); + + for (i = 0; i < 4; i++) { + key = nm_setting_wireless_security_get_wep_key(s_wsec, i); + if (key) { + gs_free char *ascii_key = NULL; + char tag[64]; + gboolean key_valid = TRUE; + + /* Passphrase needs a different ifcfg key since with WEP, there + * are some passphrases that are indistinguishable from WEP hex + * keys. + */ + if (key_type == NM_WEP_KEY_TYPE_UNKNOWN) { + if (nm_utils_wep_key_valid(key, NM_WEP_KEY_TYPE_KEY)) + key_type = NM_WEP_KEY_TYPE_KEY; + else if (nm_utils_wep_key_valid(key, NM_WEP_KEY_TYPE_PASSPHRASE)) + key_type = NM_WEP_KEY_TYPE_PASSPHRASE; + } + + if (key_type == NM_WEP_KEY_TYPE_PASSPHRASE) + numbered_tag(tag, "KEY_PASSPHRASE", i + 1); + else if (key_type == NM_WEP_KEY_TYPE_KEY) { + numbered_tag(tag, "KEY", i + 1); + + /* Add 's:' prefix for ASCII keys */ + if (strlen(key) == 5 || strlen(key) == 13) { + ascii_key = g_strdup_printf("s:%s", key); + key = ascii_key; + } + } else { + g_warn_if_reached(); + key_valid = FALSE; + } + + if (key_valid) { + set_secret(ifcfg, + secrets, + tag, + key, + "WEP_KEY_FLAGS", + nm_setting_wireless_security_get_wep_key_flags(s_wsec)); + } + } + } + } + + /* WPA protos */ + num = nm_setting_wireless_security_get_num_protos(s_wsec); + for (i = 0; i < num; i++) { + proto = nm_setting_wireless_security_get_proto(s_wsec, i); + if (proto && !strcmp(proto, "wpa")) + svSetValueStr(ifcfg, "WPA_ALLOW_WPA", "yes"); + else if (proto && !strcmp(proto, "rsn")) + svSetValueStr(ifcfg, "WPA_ALLOW_WPA2", "yes"); + } + + /* WPA Pairwise ciphers */ + str = g_string_new(NULL); + num = nm_setting_wireless_security_get_num_pairwise(s_wsec); + for (i = 0; i < num; i++) { + if (i > 0) + g_string_append_c(str, ' '); + cipher = nm_setting_wireless_security_get_pairwise(s_wsec, i); + + /* Don't write out WEP40 or WEP104 if for some reason they are set; they + * are not valid pairwise ciphers. + */ + if (strcmp(cipher, "wep40") && strcmp(cipher, "wep104")) { + tmp = g_ascii_strup(cipher, -1); + g_string_append(str, tmp); + g_free(tmp); + } + } + if (strlen(str->str) && (dynamic_wep == FALSE)) + svSetValueStr(ifcfg, "CIPHER_PAIRWISE", str->str); + g_string_free(str, TRUE); + + /* WPA Group ciphers */ + str = g_string_new(NULL); + num = nm_setting_wireless_security_get_num_groups(s_wsec); + for (i = 0; i < num; i++) { + if (i > 0) + g_string_append_c(str, ' '); + cipher = nm_setting_wireless_security_get_group(s_wsec, i); + tmp = g_ascii_strup(cipher, -1); + g_string_append(str, tmp); + g_free(tmp); + } + if (strlen(str->str) && (dynamic_wep == FALSE)) + svSetValueStr(ifcfg, "CIPHER_GROUP", str->str); + g_string_free(str, TRUE); + + if (wpa) + psk = nm_setting_wireless_security_get_psk(s_wsec); + + set_secret(ifcfg, + secrets, + "WPA_PSK", + psk, + "WPA_PSK_FLAGS", + wpa ? nm_setting_wireless_security_get_psk_flags(s_wsec) + : NM_SETTING_SECRET_FLAG_NONE); + + if (nm_setting_wireless_security_get_pmf(s_wsec) != NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT) { + svSetValueEnum(ifcfg, + "PMF", + nm_setting_wireless_security_pmf_get_type(), + nm_setting_wireless_security_get_pmf(s_wsec)); + } + + if (nm_setting_wireless_security_get_fils(s_wsec) + != NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT) { + svSetValueEnum(ifcfg, + "FILS", + nm_setting_wireless_security_fils_get_type(), + nm_setting_wireless_security_get_fils(s_wsec)); + } + + return TRUE; } static gboolean -write_wireless_setting (NMConnection *connection, - shvarFile *ifcfg, - GHashTable *secrets, - gboolean *no_8021x, - GError **error) +write_wireless_setting(NMConnection *connection, + shvarFile * ifcfg, + GHashTable * secrets, + gboolean * no_8021x, + GError ** error) { - NMSettingWireless *s_wireless; - GBytes *ssid; - const guint8 *ssid_data; - gsize ssid_len; - const char *mode, *bssid; - const char *device_mac, *cloned_mac; - guint32 mtu, chan, i; - gboolean adhoc = FALSE, hex_ssid = FALSE; - const char *const*macaddr_blacklist; - - s_wireless = nm_connection_get_setting_wireless (connection); - if (!s_wireless) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Missing '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); - return FALSE; - } - - device_mac = nm_setting_wireless_get_mac_address (s_wireless); - svSetValueStr (ifcfg, "HWADDR", device_mac); - - cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless); - svSetValueStr (ifcfg, "MACADDR", cloned_mac); - - svSetValueStr (ifcfg, "GENERATE_MAC_ADDRESS_MASK", - nm_setting_wireless_get_generate_mac_address_mask (s_wireless)); - - macaddr_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless); - if (macaddr_blacklist[0]) { - gs_free char *blacklist_str = NULL; - - blacklist_str = g_strjoinv (" ", (char **) macaddr_blacklist); - svSetValueStr (ifcfg, "HWADDR_BLACKLIST", blacklist_str); - } - - mtu = nm_setting_wireless_get_mtu (s_wireless); - svSetValueInt64_cond (ifcfg, "MTU", mtu != 0, mtu); - - ssid = nm_setting_wireless_get_ssid (s_wireless); - if (!ssid) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Missing SSID in '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); - return FALSE; - } - ssid_data = g_bytes_get_data (ssid, &ssid_len); - if (!ssid_len || ssid_len > 32) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Invalid SSID in '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); - return FALSE; - } - - /* If the SSID contains any non-printable characters, we need to use the - * hex notation of the SSID instead. - */ - if ( ssid_len > 2 - && ssid_data[0] == '0' - && ssid_data[1] == 'x') { - hex_ssid = TRUE; - for (i = 2; i < ssid_len; i++) { - if (!g_ascii_isxdigit (ssid_data[i])) { - hex_ssid = FALSE; - break; - } - } - } - if (!hex_ssid) { - for (i = 0; i < ssid_len; i++) { - if (!g_ascii_isprint (ssid_data[i])) { - hex_ssid = TRUE; - break; - } - } - } - - if (hex_ssid) { - GString *str; - - /* Hex SSIDs don't get quoted */ - str = g_string_sized_new (ssid_len * 2 + 3); - g_string_append (str, "0x"); - for (i = 0; i < ssid_len; i++) - g_string_append_printf (str, "%02X", ssid_data[i]); - svSetValueStr (ifcfg, "ESSID", str->str); - g_string_free (str, TRUE); - } else { - char buf[33]; - - nm_assert (ssid_len <= 32); - memcpy (buf, ssid_data, ssid_len); - buf[ssid_len] = '\0'; - svSetValueStr (ifcfg, "ESSID", buf); - } - - mode = nm_setting_wireless_get_mode (s_wireless); - if (!mode) { - /* pass */ - } else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_INFRA)) - svSetValueStr (ifcfg, "MODE", "Managed"); - else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { - svSetValueStr (ifcfg, "MODE", "Ad-Hoc"); - adhoc = TRUE; - } else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_AP)) - svSetValueStr (ifcfg, "MODE", "Ap"); - else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Invalid mode '%s' in '%s' setting", - mode, NM_SETTING_WIRELESS_SETTING_NAME); - return FALSE; - } - - chan = nm_setting_wireless_get_channel (s_wireless); - if (chan) { - svSetValueInt64 (ifcfg, "CHANNEL", chan); - } else { - /* Band only set if channel is not, since channel implies band */ - svSetValueStr (ifcfg, "BAND", nm_setting_wireless_get_band (s_wireless)); - } - - bssid = nm_setting_wireless_get_bssid (s_wireless); - svSetValueStr (ifcfg, "BSSID", bssid); - - /* Ensure DEFAULTKEY and SECURITYMODE are cleared unless there's security; - * otherwise there's no way to detect WEP vs. open when WEP keys aren't - * saved. - */ - - if (nm_connection_get_setting_wireless_security (connection)) { - if (!write_wireless_security_setting (connection, ifcfg, secrets, adhoc, no_8021x, error)) - return FALSE; - } else { - /* Clear out wifi security keys */ - set_secret (ifcfg, secrets, "IEEE_8021X_PASSWORD", NULL, "IEEE_8021X_PASSWORD_FLAGS", NM_SETTING_SECRET_FLAG_NONE); - - /* Clear existing keys */ - set_secret (ifcfg, secrets, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); - for (i = 0; i < 4; i++) { - char tag[64]; - - numbered_tag (tag, "KEY_PASSPHRASE", i + 1); - set_secret (ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); - - numbered_tag (tag, "KEY", i + 1); - set_secret (ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); - } - - set_secret (ifcfg, secrets, "WPA_PSK", NULL, "WPA_PSK_FLAGS", NM_SETTING_SECRET_FLAG_NONE); - } - - svSetValueStr (ifcfg, "SSID_HIDDEN", nm_setting_wireless_get_hidden (s_wireless) ? "yes" : NULL); - - switch (nm_setting_wireless_get_powersave (s_wireless)) { - case NM_SETTING_WIRELESS_POWERSAVE_IGNORE: - svSetValueStr (ifcfg, "POWERSAVE", "ignore"); - break; - case NM_SETTING_WIRELESS_POWERSAVE_DISABLE: - svSetValueStr (ifcfg, "POWERSAVE", "disable"); - break; - case NM_SETTING_WIRELESS_POWERSAVE_ENABLE: - svSetValueStr (ifcfg, "POWERSAVE", "enable"); - break; - default: - case NM_SETTING_WIRELESS_POWERSAVE_DEFAULT: - break; - } - - switch (nm_setting_wireless_get_mac_address_randomization (s_wireless)) { - case NM_SETTING_MAC_RANDOMIZATION_NEVER: - svSetValueStr (ifcfg, "MAC_ADDRESS_RANDOMIZATION", "never"); - break; - case NM_SETTING_MAC_RANDOMIZATION_ALWAYS: - svSetValueStr (ifcfg, "MAC_ADDRESS_RANDOMIZATION", "always"); - break; - case NM_SETTING_MAC_RANDOMIZATION_DEFAULT: - default: - svSetValueStr (ifcfg, "MAC_ADDRESS_RANDOMIZATION", "default"); - break; - } - - svSetValueStr (ifcfg, "TYPE", TYPE_WIRELESS); - - return TRUE; + NMSettingWireless *s_wireless; + GBytes * ssid; + const guint8 * ssid_data; + gsize ssid_len; + const char * mode, *bssid; + const char * device_mac, *cloned_mac; + guint32 mtu, chan, i; + gboolean adhoc = FALSE, hex_ssid = FALSE; + const char *const *macaddr_blacklist; + + s_wireless = nm_connection_get_setting_wireless(connection); + if (!s_wireless) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Missing '%s' setting", + NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + device_mac = nm_setting_wireless_get_mac_address(s_wireless); + svSetValueStr(ifcfg, "HWADDR", device_mac); + + cloned_mac = nm_setting_wireless_get_cloned_mac_address(s_wireless); + svSetValueStr(ifcfg, "MACADDR", cloned_mac); + + svSetValueStr(ifcfg, + "GENERATE_MAC_ADDRESS_MASK", + nm_setting_wireless_get_generate_mac_address_mask(s_wireless)); + + macaddr_blacklist = nm_setting_wireless_get_mac_address_blacklist(s_wireless); + if (macaddr_blacklist[0]) { + gs_free char *blacklist_str = NULL; + + blacklist_str = g_strjoinv(" ", (char **) macaddr_blacklist); + svSetValueStr(ifcfg, "HWADDR_BLACKLIST", blacklist_str); + } + + mtu = nm_setting_wireless_get_mtu(s_wireless); + svSetValueInt64_cond(ifcfg, "MTU", mtu != 0, mtu); + + ssid = nm_setting_wireless_get_ssid(s_wireless); + if (!ssid) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Missing SSID in '%s' setting", + NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + ssid_data = g_bytes_get_data(ssid, &ssid_len); + if (!ssid_len || ssid_len > 32) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Invalid SSID in '%s' setting", + NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + /* If the SSID contains any non-printable characters, we need to use the + * hex notation of the SSID instead. + */ + if (ssid_len > 2 && ssid_data[0] == '0' && ssid_data[1] == 'x') { + hex_ssid = TRUE; + for (i = 2; i < ssid_len; i++) { + if (!g_ascii_isxdigit(ssid_data[i])) { + hex_ssid = FALSE; + break; + } + } + } + if (!hex_ssid) { + for (i = 0; i < ssid_len; i++) { + if (!g_ascii_isprint(ssid_data[i])) { + hex_ssid = TRUE; + break; + } + } + } + + if (hex_ssid) { + GString *str; + + /* Hex SSIDs don't get quoted */ + str = g_string_sized_new(ssid_len * 2 + 3); + g_string_append(str, "0x"); + for (i = 0; i < ssid_len; i++) + g_string_append_printf(str, "%02X", ssid_data[i]); + svSetValueStr(ifcfg, "ESSID", str->str); + g_string_free(str, TRUE); + } else { + char buf[33]; + + nm_assert(ssid_len <= 32); + memcpy(buf, ssid_data, ssid_len); + buf[ssid_len] = '\0'; + svSetValueStr(ifcfg, "ESSID", buf); + } + + mode = nm_setting_wireless_get_mode(s_wireless); + if (!mode) { + /* pass */ + } else if (nm_streq(mode, NM_SETTING_WIRELESS_MODE_INFRA)) + svSetValueStr(ifcfg, "MODE", "Managed"); + else if (nm_streq(mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { + svSetValueStr(ifcfg, "MODE", "Ad-Hoc"); + adhoc = TRUE; + } else if (nm_streq(mode, NM_SETTING_WIRELESS_MODE_AP)) + svSetValueStr(ifcfg, "MODE", "Ap"); + else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Invalid mode '%s' in '%s' setting", + mode, + NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + chan = nm_setting_wireless_get_channel(s_wireless); + if (chan) { + svSetValueInt64(ifcfg, "CHANNEL", chan); + } else { + /* Band only set if channel is not, since channel implies band */ + svSetValueStr(ifcfg, "BAND", nm_setting_wireless_get_band(s_wireless)); + } + + bssid = nm_setting_wireless_get_bssid(s_wireless); + svSetValueStr(ifcfg, "BSSID", bssid); + + /* Ensure DEFAULTKEY and SECURITYMODE are cleared unless there's security; + * otherwise there's no way to detect WEP vs. open when WEP keys aren't + * saved. + */ + + if (nm_connection_get_setting_wireless_security(connection)) { + if (!write_wireless_security_setting(connection, ifcfg, secrets, adhoc, no_8021x, error)) + return FALSE; + } else { + /* Clear out wifi security keys */ + set_secret(ifcfg, + secrets, + "IEEE_8021X_PASSWORD", + NULL, + "IEEE_8021X_PASSWORD_FLAGS", + NM_SETTING_SECRET_FLAG_NONE); + + /* Clear existing keys */ + set_secret(ifcfg, secrets, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); + for (i = 0; i < 4; i++) { + char tag[64]; + + numbered_tag(tag, "KEY_PASSPHRASE", i + 1); + set_secret(ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); + + numbered_tag(tag, "KEY", i + 1); + set_secret(ifcfg, secrets, tag, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE); + } + + set_secret(ifcfg, secrets, "WPA_PSK", NULL, "WPA_PSK_FLAGS", NM_SETTING_SECRET_FLAG_NONE); + } + + svSetValueStr(ifcfg, "SSID_HIDDEN", nm_setting_wireless_get_hidden(s_wireless) ? "yes" : NULL); + + switch (nm_setting_wireless_get_powersave(s_wireless)) { + case NM_SETTING_WIRELESS_POWERSAVE_IGNORE: + svSetValueStr(ifcfg, "POWERSAVE", "ignore"); + break; + case NM_SETTING_WIRELESS_POWERSAVE_DISABLE: + svSetValueStr(ifcfg, "POWERSAVE", "disable"); + break; + case NM_SETTING_WIRELESS_POWERSAVE_ENABLE: + svSetValueStr(ifcfg, "POWERSAVE", "enable"); + break; + default: + case NM_SETTING_WIRELESS_POWERSAVE_DEFAULT: + break; + } + + switch (nm_setting_wireless_get_mac_address_randomization(s_wireless)) { + case NM_SETTING_MAC_RANDOMIZATION_NEVER: + svSetValueStr(ifcfg, "MAC_ADDRESS_RANDOMIZATION", "never"); + break; + case NM_SETTING_MAC_RANDOMIZATION_ALWAYS: + svSetValueStr(ifcfg, "MAC_ADDRESS_RANDOMIZATION", "always"); + break; + case NM_SETTING_MAC_RANDOMIZATION_DEFAULT: + default: + svSetValueStr(ifcfg, "MAC_ADDRESS_RANDOMIZATION", "default"); + break; + } + + svSetValueTernary(ifcfg, "AP_ISOLATION", nm_setting_wireless_get_ap_isolation(s_wireless)); + + svSetValueStr(ifcfg, "TYPE", TYPE_WIRELESS); + + return TRUE; } static gboolean -write_infiniband_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +write_infiniband_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) { - NMSettingInfiniband *s_infiniband; - const char *mac, *transport_mode, *parent; - guint32 mtu; - int p_key; - - s_infiniband = nm_connection_get_setting_infiniband (connection); - if (!s_infiniband) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Missing '%s' setting", NM_SETTING_INFINIBAND_SETTING_NAME); - return FALSE; - } - - mac = nm_setting_infiniband_get_mac_address (s_infiniband); - svSetValueStr (ifcfg, "HWADDR", mac); - - mtu = nm_setting_infiniband_get_mtu (s_infiniband); - svSetValueInt64_cond (ifcfg, "MTU", mtu != 0, mtu); - - transport_mode = nm_setting_infiniband_get_transport_mode (s_infiniband); - svSetValueBoolean (ifcfg, "CONNECTED_MODE", nm_streq (transport_mode, "connected")); - - p_key = nm_setting_infiniband_get_p_key (s_infiniband); - if (p_key != -1) { - svSetValueStr (ifcfg, "PKEY", "yes"); - svSetValueInt64 (ifcfg, "PKEY_ID", p_key); - - parent = nm_setting_infiniband_get_parent (s_infiniband); - if (parent) - svSetValueStr (ifcfg, "PHYSDEV", parent); - } - - svSetValueStr (ifcfg, "TYPE", TYPE_INFINIBAND); - - return TRUE; + NMSettingInfiniband *s_infiniband; + const char * mac, *transport_mode, *parent; + guint32 mtu; + int p_key; + + s_infiniband = nm_connection_get_setting_infiniband(connection); + if (!s_infiniband) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Missing '%s' setting", + NM_SETTING_INFINIBAND_SETTING_NAME); + return FALSE; + } + + mac = nm_setting_infiniband_get_mac_address(s_infiniband); + svSetValueStr(ifcfg, "HWADDR", mac); + + mtu = nm_setting_infiniband_get_mtu(s_infiniband); + svSetValueInt64_cond(ifcfg, "MTU", mtu != 0, mtu); + + transport_mode = nm_setting_infiniband_get_transport_mode(s_infiniband); + svSetValueBoolean(ifcfg, "CONNECTED_MODE", nm_streq(transport_mode, "connected")); + + p_key = nm_setting_infiniband_get_p_key(s_infiniband); + if (p_key != -1) { + svSetValueStr(ifcfg, "PKEY", "yes"); + svSetValueInt64(ifcfg, "PKEY_ID", p_key); + + parent = nm_setting_infiniband_get_parent(s_infiniband); + if (parent) + svSetValueStr(ifcfg, "PHYSDEV", parent); + } + + svSetValueStr(ifcfg, "TYPE", TYPE_INFINIBAND); + + return TRUE; } static gboolean -write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +write_wired_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) { - NMSettingWired *s_wired; - const char *const*s390_subchannels; - guint32 mtu, num_opts, i; - const char *const*macaddr_blacklist; - - s_wired = nm_connection_get_setting_wired (connection); - if (!s_wired) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Missing '%s' setting", NM_SETTING_WIRED_SETTING_NAME); - return FALSE; - } - - svSetValueStr (ifcfg, "HWADDR", - nm_setting_wired_get_mac_address (s_wired)); - - svSetValueStr (ifcfg, "MACADDR", - nm_setting_wired_get_cloned_mac_address (s_wired)); - - svSetValueStr (ifcfg, "GENERATE_MAC_ADDRESS_MASK", - nm_setting_wired_get_generate_mac_address_mask (s_wired)); - - macaddr_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); - if (macaddr_blacklist[0]) { - gs_free char *blacklist_str = NULL; - - blacklist_str = g_strjoinv (" ", (char **) macaddr_blacklist); - svSetValueStr (ifcfg, "HWADDR_BLACKLIST", blacklist_str); - } - - mtu = nm_setting_wired_get_mtu (s_wired); - svSetValueInt64_cond (ifcfg, "MTU", mtu != 0, mtu); - - s390_subchannels = nm_setting_wired_get_s390_subchannels (s_wired); - - { - gs_free char *tmp = NULL; - gsize len = NM_PTRARRAY_LEN (s390_subchannels); - - if (len == 2) { - tmp = g_strdup_printf ("%s,%s", - s390_subchannels[0], - s390_subchannels[1]); - } else if (len == 3) { - tmp = g_strdup_printf ("%s,%s,%s", - s390_subchannels[0], - s390_subchannels[1], - s390_subchannels[2]); - } - - svSetValueStr (ifcfg, "SUBCHANNELS", tmp); - } - - svSetValueStr (ifcfg, "NETTYPE", - nm_setting_wired_get_s390_nettype (s_wired)); - - svSetValueStr (ifcfg, "PORTNAME", - nm_setting_wired_get_s390_option_by_key (s_wired, "portname")); - - svSetValueStr (ifcfg, "CTCPROT", - nm_setting_wired_get_s390_option_by_key (s_wired, "ctcprot")); - - num_opts = nm_setting_wired_get_num_s390_options (s_wired); - if (s390_subchannels && num_opts) { - nm_auto_free_gstring GString *tmp = NULL; - - for (i = 0; i < num_opts; i++) { - const char *s390_key, *s390_val; - - nm_setting_wired_get_s390_option (s_wired, i, &s390_key, &s390_val); - - /* portname is handled separately */ - if (NM_IN_STRSET (s390_key, "portname", "ctcprot")) - continue; - - if (strchr (s390_key, '=')) { - /* this key cannot be expressed. But after all, it's not valid anyway - * and the connection shouldn't even verify. */ - continue; - } - - if (!tmp) - tmp = g_string_sized_new (30); - else - g_string_append_c (tmp, ' '); - nm_utils_escaped_tokens_escape_gstr (s390_key, NM_ASCII_SPACES, tmp); - g_string_append_c (tmp, '='); - nm_utils_escaped_tokens_escape_gstr (s390_val, NM_ASCII_SPACES, tmp); - } - if (tmp) - svSetValueStr (ifcfg, "OPTIONS", tmp->str); - } - - svSetValueStr (ifcfg, "TYPE", TYPE_ETHERNET); - - return TRUE; + NMSettingWired * s_wired; + const char *const *s390_subchannels; + guint32 mtu, num_opts, i; + const char *const *macaddr_blacklist; + + s_wired = nm_connection_get_setting_wired(connection); + if (!s_wired) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Missing '%s' setting", + NM_SETTING_WIRED_SETTING_NAME); + return FALSE; + } + + svSetValueStr(ifcfg, "HWADDR", nm_setting_wired_get_mac_address(s_wired)); + + svSetValueStr(ifcfg, "MACADDR", nm_setting_wired_get_cloned_mac_address(s_wired)); + + svSetValueStr(ifcfg, + "GENERATE_MAC_ADDRESS_MASK", + nm_setting_wired_get_generate_mac_address_mask(s_wired)); + + macaddr_blacklist = nm_setting_wired_get_mac_address_blacklist(s_wired); + if (macaddr_blacklist[0]) { + gs_free char *blacklist_str = NULL; + + blacklist_str = g_strjoinv(" ", (char **) macaddr_blacklist); + svSetValueStr(ifcfg, "HWADDR_BLACKLIST", blacklist_str); + } + + mtu = nm_setting_wired_get_mtu(s_wired); + svSetValueInt64_cond(ifcfg, "MTU", mtu != 0, mtu); + + s390_subchannels = nm_setting_wired_get_s390_subchannels(s_wired); + + { + gs_free char *tmp = NULL; + gsize len = NM_PTRARRAY_LEN(s390_subchannels); + + if (len == 2) { + tmp = g_strdup_printf("%s,%s", s390_subchannels[0], s390_subchannels[1]); + } else if (len == 3) { + tmp = g_strdup_printf("%s,%s,%s", + s390_subchannels[0], + s390_subchannels[1], + s390_subchannels[2]); + } + + svSetValueStr(ifcfg, "SUBCHANNELS", tmp); + } + + svSetValueStr(ifcfg, "NETTYPE", nm_setting_wired_get_s390_nettype(s_wired)); + + svSetValueStr(ifcfg, "PORTNAME", nm_setting_wired_get_s390_option_by_key(s_wired, "portname")); + + svSetValueStr(ifcfg, "CTCPROT", nm_setting_wired_get_s390_option_by_key(s_wired, "ctcprot")); + + num_opts = nm_setting_wired_get_num_s390_options(s_wired); + if (s390_subchannels && num_opts) { + nm_auto_free_gstring GString *tmp = NULL; + + for (i = 0; i < num_opts; i++) { + const char *s390_key, *s390_val; + + nm_setting_wired_get_s390_option(s_wired, i, &s390_key, &s390_val); + + /* portname is handled separately */ + if (NM_IN_STRSET(s390_key, "portname", "ctcprot")) + continue; + + if (strchr(s390_key, '=')) { + /* this key cannot be expressed. But after all, it's not valid anyway + * and the connection shouldn't even verify. */ + continue; + } + + if (!tmp) + tmp = g_string_sized_new(30); + else + g_string_append_c(tmp, ' '); + nm_utils_escaped_tokens_escape_gstr(s390_key, NM_ASCII_SPACES, tmp); + g_string_append_c(tmp, '='); + nm_utils_escaped_tokens_escape_gstr(s390_val, NM_ASCII_SPACES, tmp); + } + if (tmp) + svSetValueStr(ifcfg, "OPTIONS", tmp->str); + } + + svSetValueStr(ifcfg, "TYPE", TYPE_ETHERNET); + + return TRUE; } static void -_ethtool_gstring_prepare (GString **str, - gboolean *is_first, - char cmdline_flag, - const char *iface) +_ethtool_gstring_prepare(GString **str, gboolean *is_first, char cmdline_flag, const char *iface) { - if (!*is_first) { - nm_assert (*str && (*str)->len > 0); - return; - } - - if (!*str) - *str = g_string_sized_new (30); - else { - nm_assert ((*str)->len > 0); - g_string_append (*str, " ; "); - } - g_string_append_printf (*str, "-%c %s", cmdline_flag, iface); - *is_first = FALSE; + if (!*is_first) { + nm_assert(*str && (*str)->len > 0); + return; + } + + if (!*str) + *str = g_string_sized_new(30); + else { + nm_assert((*str)->len > 0); + g_string_append(*str, " ; "); + } + g_string_append_printf(*str, "-%c %s", cmdline_flag, iface); + *is_first = FALSE; } static gboolean -write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +write_ethtool_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) { - NMSettingWired *s_wired; - NMSettingEthtool *s_ethtool; - const char *duplex; - guint32 speed; - GString *str = NULL; - gboolean auto_negotiate; - NMSettingWiredWakeOnLan wol; - const char *wol_password; - - s_wired = nm_connection_get_setting_wired (connection); - s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (connection, NM_TYPE_SETTING_ETHTOOL)); - - if ( !s_wired - && !s_ethtool) - return TRUE; - - if (s_wired) { - auto_negotiate = nm_setting_wired_get_auto_negotiate (s_wired); - speed = nm_setting_wired_get_speed (s_wired); - duplex = nm_setting_wired_get_duplex (s_wired); - - /* autoneg off + speed 0 + duplex NULL, means we want NM - * to skip link configuration which is default. So write - * down link config only if we have auto-negotiate true or - * a valid value for one among speed and duplex. - */ - if (auto_negotiate) { - str = g_string_sized_new (64); - g_string_printf (str, "autoneg on"); - } else if (speed || duplex) { - str = g_string_sized_new (64); - g_string_printf (str, "autoneg off"); - } - if (speed) - g_string_append_printf (str, " speed %u", speed); - if (duplex) - g_string_append_printf (str, " duplex %s", duplex); - - wol = nm_setting_wired_get_wake_on_lan (s_wired); - wol_password = nm_setting_wired_get_wake_on_lan_password (s_wired); - - svSetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN", - wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE - ? "ignore" - : NULL); - if (!NM_IN_SET (wol, NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE, - NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT)) { - if (!str) - str = g_string_sized_new (30); - else - g_string_append (str, " "); - - g_string_append (str, "wol "); - - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_PHY)) - g_string_append (str, "p"); - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST)) - g_string_append (str, "u"); - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST)) - g_string_append (str, "m"); - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST)) - g_string_append (str, "b"); - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ARP)) - g_string_append (str, "a"); - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) - g_string_append (str, "g"); - - if (!NM_FLAGS_ANY (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ALL)) - g_string_append (str, "d"); - - if (wol_password && NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) - g_string_append_printf (str, "s sopass %s", wol_password); - } - } - - if (s_ethtool) { - NMEthtoolID ethtool_id; - NMSettingConnection *s_con; - const char *iface; - gboolean is_first; - guint32 u32; - gboolean b; - - s_con = nm_connection_get_setting_connection (connection); - if (s_con) { - iface = nm_setting_connection_get_interface_name (s_con); - if ( iface - && ( !iface[0] - || !NM_STRCHAR_ALL (iface, ch, (ch >= 'a' && ch <= 'z') - || (ch >= 'A' && ch <= 'Z') - || (ch >= '0' && ch <= '9') - || NM_IN_SET (ch, '_')))) - iface = NULL; - } else - iface = NULL; - if (!iface) - iface = "net0"; - - is_first = TRUE; - for (ethtool_id = _NM_ETHTOOL_ID_FEATURE_FIRST; ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST; ethtool_id++) { - nm_assert (nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); - if (!nm_setting_option_get_boolean (NM_SETTING (s_ethtool), nm_ethtool_data[ethtool_id]->optname, &b)) - continue; - - _ethtool_gstring_prepare (&str, &is_first, 'K', iface); - g_string_append_c (str, ' '); - g_string_append (str, nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); - g_string_append (str, b ? " on" : " off"); - } - - is_first = TRUE; - for (ethtool_id = _NM_ETHTOOL_ID_COALESCE_FIRST; ethtool_id <= _NM_ETHTOOL_ID_COALESCE_LAST; ethtool_id++) { - nm_assert (nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); - if (!nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), nm_ethtool_data[ethtool_id]->optname, &u32)) - continue; - - _ethtool_gstring_prepare (&str, &is_first, 'C', iface); - g_string_append_c (str, ' '); - g_string_append (str, nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); - g_string_append_printf (str, " %"G_GUINT32_FORMAT, u32); - } - - is_first = TRUE; - for (ethtool_id = _NM_ETHTOOL_ID_RING_FIRST; ethtool_id <= _NM_ETHTOOL_ID_RING_LAST; ethtool_id++) { - nm_assert (nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); - if (!nm_setting_option_get_uint32 (NM_SETTING (s_ethtool), nm_ethtool_data[ethtool_id]->optname, &u32)) - continue; - - _ethtool_gstring_prepare (&str, &is_first, 'G', iface); - g_string_append_c (str, ' '); - g_string_append (str, nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); - g_string_append_printf (str, " %"G_GUINT32_FORMAT, u32); - } - } - - if (str) { - svSetValueStr (ifcfg, "ETHTOOL_OPTS", str->str); - g_string_free (str, TRUE); - } - - return TRUE; + NMSettingWired * s_wired; + NMSettingEthtool * s_ethtool; + const char * duplex; + guint32 speed; + GString * str = NULL; + gboolean auto_negotiate; + NMSettingWiredWakeOnLan wol; + const char * wol_password; + + s_wired = nm_connection_get_setting_wired(connection); + s_ethtool = NM_SETTING_ETHTOOL(nm_connection_get_setting(connection, NM_TYPE_SETTING_ETHTOOL)); + + if (!s_wired && !s_ethtool) + return TRUE; + + if (s_wired) { + auto_negotiate = nm_setting_wired_get_auto_negotiate(s_wired); + speed = nm_setting_wired_get_speed(s_wired); + duplex = nm_setting_wired_get_duplex(s_wired); + + /* autoneg off + speed 0 + duplex NULL, means we want NM + * to skip link configuration which is default. So write + * down link config only if we have auto-negotiate true or + * a valid value for one among speed and duplex. + */ + if (auto_negotiate) { + str = g_string_sized_new(64); + g_string_printf(str, "autoneg on"); + } else if (speed || duplex) { + str = g_string_sized_new(64); + g_string_printf(str, "autoneg off"); + } + if (speed) + g_string_append_printf(str, " speed %u", speed); + if (duplex) + g_string_append_printf(str, " duplex %s", duplex); + + wol = nm_setting_wired_get_wake_on_lan(s_wired); + wol_password = nm_setting_wired_get_wake_on_lan_password(s_wired); + + svSetValue(ifcfg, + "ETHTOOL_WAKE_ON_LAN", + wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE ? "ignore" : NULL); + if (!NM_IN_SET(wol, + NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE, + NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT)) { + if (!str) + str = g_string_sized_new(30); + else + g_string_append(str, " "); + + g_string_append(str, "wol "); + + if (NM_FLAGS_HAS(wol, NM_SETTING_WIRED_WAKE_ON_LAN_PHY)) + g_string_append(str, "p"); + if (NM_FLAGS_HAS(wol, NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST)) + g_string_append(str, "u"); + if (NM_FLAGS_HAS(wol, NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST)) + g_string_append(str, "m"); + if (NM_FLAGS_HAS(wol, NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST)) + g_string_append(str, "b"); + if (NM_FLAGS_HAS(wol, NM_SETTING_WIRED_WAKE_ON_LAN_ARP)) + g_string_append(str, "a"); + if (NM_FLAGS_HAS(wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) + g_string_append(str, "g"); + + if (!NM_FLAGS_ANY(wol, NM_SETTING_WIRED_WAKE_ON_LAN_ALL)) + g_string_append(str, "d"); + + if (wol_password && NM_FLAGS_HAS(wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) + g_string_append_printf(str, "s sopass %s", wol_password); + } + } + + if (s_ethtool) { + NMEthtoolID ethtool_id; + NMSettingConnection *s_con; + const char * iface; + gboolean is_first; + guint32 u32; + gboolean b; + + s_con = nm_connection_get_setting_connection(connection); + if (s_con) { + iface = nm_setting_connection_get_interface_name(s_con); + if (iface + && (!iface[0] + || !NM_STRCHAR_ALL(iface, + ch, + (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') + || (ch >= '0' && ch <= '9') || NM_IN_SET(ch, '_')))) + iface = NULL; + } else + iface = NULL; + if (!iface) + iface = "net0"; + + is_first = TRUE; + for (ethtool_id = _NM_ETHTOOL_ID_FEATURE_FIRST; ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST; + ethtool_id++) { + nm_assert(nms_ifcfg_rh_utils_get_ethtool_name(ethtool_id)); + if (!nm_setting_option_get_boolean(NM_SETTING(s_ethtool), + nm_ethtool_data[ethtool_id]->optname, + &b)) + continue; + + _ethtool_gstring_prepare(&str, &is_first, 'K', iface); + g_string_append_c(str, ' '); + g_string_append(str, nms_ifcfg_rh_utils_get_ethtool_name(ethtool_id)); + g_string_append(str, b ? " on" : " off"); + } + + is_first = TRUE; + for (ethtool_id = _NM_ETHTOOL_ID_COALESCE_FIRST; ethtool_id <= _NM_ETHTOOL_ID_COALESCE_LAST; + ethtool_id++) { + nm_assert(nms_ifcfg_rh_utils_get_ethtool_name(ethtool_id)); + if (!nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + nm_ethtool_data[ethtool_id]->optname, + &u32)) + continue; + + _ethtool_gstring_prepare(&str, &is_first, 'C', iface); + g_string_append_c(str, ' '); + g_string_append(str, nms_ifcfg_rh_utils_get_ethtool_name(ethtool_id)); + g_string_append_printf(str, " %" G_GUINT32_FORMAT, u32); + } + + is_first = TRUE; + for (ethtool_id = _NM_ETHTOOL_ID_RING_FIRST; ethtool_id <= _NM_ETHTOOL_ID_RING_LAST; + ethtool_id++) { + nm_assert(nms_ifcfg_rh_utils_get_ethtool_name(ethtool_id)); + if (!nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + nm_ethtool_data[ethtool_id]->optname, + &u32)) + continue; + + _ethtool_gstring_prepare(&str, &is_first, 'G', iface); + g_string_append_c(str, ' '); + g_string_append(str, nms_ifcfg_rh_utils_get_ethtool_name(ethtool_id)); + g_string_append_printf(str, " %" G_GUINT32_FORMAT, u32); + } + } + + if (str) { + svSetValueStr(ifcfg, "ETHTOOL_OPTS", str->str); + g_string_free(str, TRUE); + } + + return TRUE; } static char * -vlan_priority_maplist_to_stringlist (NMSettingVlan *s_vlan, NMVlanPriorityMap map) +vlan_priority_maplist_to_stringlist(NMSettingVlan *s_vlan, NMVlanPriorityMap map) { - char **strlist; - char *value; - - if (map == NM_VLAN_INGRESS_MAP) - g_object_get (G_OBJECT (s_vlan), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, &strlist, NULL); - else if (map == NM_VLAN_EGRESS_MAP) - g_object_get (G_OBJECT (s_vlan), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, &strlist, NULL); - else - return NULL; - - if (strlist[0]) - value = g_strjoinv (",", strlist); - else - value = NULL; - g_strfreev (strlist); - - return value; + char **strlist; + char * value; + + if (map == NM_VLAN_INGRESS_MAP) + g_object_get(G_OBJECT(s_vlan), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, &strlist, NULL); + else if (map == NM_VLAN_EGRESS_MAP) + g_object_get(G_OBJECT(s_vlan), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, &strlist, NULL); + else + return NULL; + + if (strlist[0]) + value = g_strjoinv(",", strlist); + else + value = NULL; + g_strfreev(strlist); + + return value; } static gboolean -write_wired_for_virtual (NMConnection *connection, shvarFile *ifcfg) +write_wired_for_virtual(NMConnection *connection, shvarFile *ifcfg) { - NMSettingWired *s_wired; - gboolean has_wired = FALSE; + NMSettingWired *s_wired; + gboolean has_wired = FALSE; - s_wired = nm_connection_get_setting_wired (connection); - if (s_wired) { - const char *device_mac, *cloned_mac; - guint32 mtu; + s_wired = nm_connection_get_setting_wired(connection); + if (s_wired) { + const char *device_mac, *cloned_mac; + guint32 mtu; - has_wired = TRUE; + has_wired = TRUE; - device_mac = nm_setting_wired_get_mac_address (s_wired); - svSetValue (ifcfg, "HWADDR", device_mac ?: ""); + device_mac = nm_setting_wired_get_mac_address(s_wired); + svSetValue(ifcfg, "HWADDR", device_mac ?: ""); - cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - svSetValueStr (ifcfg, "MACADDR", cloned_mac); + cloned_mac = nm_setting_wired_get_cloned_mac_address(s_wired); + svSetValueStr(ifcfg, "MACADDR", cloned_mac); - svSetValueStr (ifcfg, "GENERATE_MAC_ADDRESS_MASK", - nm_setting_wired_get_generate_mac_address_mask (s_wired)); + svSetValueStr(ifcfg, + "GENERATE_MAC_ADDRESS_MASK", + nm_setting_wired_get_generate_mac_address_mask(s_wired)); - mtu = nm_setting_wired_get_mtu (s_wired); - svSetValueInt64_cond (ifcfg, "MTU", mtu != 0, mtu); - } - return has_wired; + mtu = nm_setting_wired_get_mtu(s_wired); + svSetValueInt64_cond(ifcfg, "MTU", mtu != 0, mtu); + } + return has_wired; } static gboolean -write_vlan_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error) +write_vlan_setting(NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error) { - NMSettingVlan *s_vlan; - char *tmp; - guint32 vlan_flags = 0; - gsize s_buf_len; - char s_buf[50], *s_buf_ptr; + NMSettingVlan *s_vlan; + char * tmp; + guint32 vlan_flags = 0; + gsize s_buf_len; + char s_buf[50], *s_buf_ptr; - s_vlan = nm_connection_get_setting_vlan (connection); - if (!s_vlan) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Missing VLAN setting"); - return FALSE; - } + s_vlan = nm_connection_get_setting_vlan(connection); + if (!s_vlan) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Missing VLAN setting"); + return FALSE; + } - svSetValueStr (ifcfg, "VLAN", "yes"); - svSetValueStr (ifcfg, "TYPE", TYPE_VLAN); - svSetValueStr (ifcfg, "PHYSDEV", nm_setting_vlan_get_parent (s_vlan)); - svSetValueInt64 (ifcfg, "VLAN_ID", nm_setting_vlan_get_id (s_vlan)); + svSetValueStr(ifcfg, "VLAN", "yes"); + svSetValueStr(ifcfg, "TYPE", TYPE_VLAN); + svSetValueStr(ifcfg, "PHYSDEV", nm_setting_vlan_get_parent(s_vlan)); + svSetValueInt64(ifcfg, "VLAN_ID", nm_setting_vlan_get_id(s_vlan)); - vlan_flags = nm_setting_vlan_get_flags (s_vlan); - svSetValueBoolean (ifcfg, "REORDER_HDR", NM_FLAGS_HAS (vlan_flags, NM_VLAN_FLAG_REORDER_HEADERS)); - svSetValueBoolean (ifcfg, "GVRP", NM_FLAGS_HAS (vlan_flags, NM_VLAN_FLAG_GVRP)); + vlan_flags = nm_setting_vlan_get_flags(s_vlan); + svSetValueBoolean(ifcfg, "REORDER_HDR", NM_FLAGS_HAS(vlan_flags, NM_VLAN_FLAG_REORDER_HEADERS)); + svSetValueBoolean(ifcfg, "GVRP", NM_FLAGS_HAS(vlan_flags, NM_VLAN_FLAG_GVRP)); - nm_utils_strbuf_init (s_buf, &s_buf_ptr, &s_buf_len); + nm_utils_strbuf_init(s_buf, &s_buf_ptr, &s_buf_len); - if (NM_FLAGS_HAS (vlan_flags, NM_VLAN_FLAG_LOOSE_BINDING)) - nm_utils_strbuf_append_str (&s_buf_ptr, &s_buf_len, "LOOSE_BINDING"); - if (!NM_FLAGS_HAS (vlan_flags, NM_VLAN_FLAG_REORDER_HEADERS)) - nm_utils_strbuf_append (&s_buf_ptr, &s_buf_len, "%sNO_REORDER_HDR", s_buf[0] ? "," : ""); + if (NM_FLAGS_HAS(vlan_flags, NM_VLAN_FLAG_LOOSE_BINDING)) + nm_utils_strbuf_append_str(&s_buf_ptr, &s_buf_len, "LOOSE_BINDING"); + if (!NM_FLAGS_HAS(vlan_flags, NM_VLAN_FLAG_REORDER_HEADERS)) + nm_utils_strbuf_append(&s_buf_ptr, &s_buf_len, "%sNO_REORDER_HDR", s_buf[0] ? "," : ""); - svSetValueStr (ifcfg, "VLAN_FLAGS", s_buf); + svSetValueStr(ifcfg, "VLAN_FLAGS", s_buf); - svSetValueBoolean (ifcfg, "MVRP", NM_FLAGS_HAS (vlan_flags, NM_VLAN_FLAG_MVRP)); + svSetValueBoolean(ifcfg, "MVRP", NM_FLAGS_HAS(vlan_flags, NM_VLAN_FLAG_MVRP)); - tmp = vlan_priority_maplist_to_stringlist (s_vlan, NM_VLAN_INGRESS_MAP); - svSetValueStr (ifcfg, "VLAN_INGRESS_PRIORITY_MAP", tmp); - g_free (tmp); + tmp = vlan_priority_maplist_to_stringlist(s_vlan, NM_VLAN_INGRESS_MAP); + svSetValueStr(ifcfg, "VLAN_INGRESS_PRIORITY_MAP", tmp); + g_free(tmp); - tmp = vlan_priority_maplist_to_stringlist (s_vlan, NM_VLAN_EGRESS_MAP); - svSetValueStr (ifcfg, "VLAN_EGRESS_PRIORITY_MAP", tmp); - g_free (tmp); + tmp = vlan_priority_maplist_to_stringlist(s_vlan, NM_VLAN_EGRESS_MAP); + svSetValueStr(ifcfg, "VLAN_EGRESS_PRIORITY_MAP", tmp); + g_free(tmp); - *wired = write_wired_for_virtual (connection, ifcfg); + *wired = write_wired_for_virtual(connection, ifcfg); - return TRUE; + return TRUE; } static gboolean -write_bond_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error) +write_bond_setting(NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error) { - NMSettingBond *s_bond; - guint32 i, num_opts; - - s_bond = nm_connection_get_setting_bond (connection); - if (!s_bond) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Missing '%s' setting", NM_SETTING_BOND_SETTING_NAME); - return FALSE; - } - - num_opts = nm_setting_bond_get_num_options (s_bond); - if (num_opts) { - nm_auto_free_gstring GString *str = NULL; - const char *name, *value; - - str = g_string_sized_new (64); - for (i = 0; i < num_opts; i++) { - if (str->len) - g_string_append_c (str, ' '); - nm_setting_bond_get_option (s_bond, i, &name, &value); - g_string_append_printf (str, "%s=%s", name, value); - } - - svSetValueStr (ifcfg, "BONDING_OPTS", str->str); - } - - svSetValueStr (ifcfg, "TYPE", TYPE_BOND); - svSetValueStr (ifcfg, "BONDING_MASTER", "yes"); - - *wired = write_wired_for_virtual (connection, ifcfg); - - return TRUE; + NMSettingBond *s_bond; + guint32 i, num_opts; + + s_bond = nm_connection_get_setting_bond(connection); + if (!s_bond) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Missing '%s' setting", + NM_SETTING_BOND_SETTING_NAME); + return FALSE; + } + + num_opts = nm_setting_bond_get_num_options(s_bond); + if (num_opts) { + nm_auto_free_gstring GString *str = NULL; + const char * name, *value; + + str = g_string_sized_new(64); + for (i = 0; i < num_opts; i++) { + if (str->len) + g_string_append_c(str, ' '); + nm_setting_bond_get_option(s_bond, i, &name, &value); + g_string_append_printf(str, "%s=%s", name, value); + } + + svSetValueStr(ifcfg, "BONDING_OPTS", str->str); + } + + svSetValueStr(ifcfg, "TYPE", TYPE_BOND); + svSetValueStr(ifcfg, "BONDING_MASTER", "yes"); + + *wired = write_wired_for_virtual(connection, ifcfg); + + return TRUE; } static gboolean -write_team_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error) +write_team_setting(NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error) { - NMSettingTeam *s_team; - const char *config; + NMSettingTeam *s_team; + const char * config; - s_team = nm_connection_get_setting_team (connection); - if (!s_team) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Missing '%s' setting", NM_SETTING_TEAM_SETTING_NAME); - return FALSE; - } + s_team = nm_connection_get_setting_team(connection); + if (!s_team) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Missing '%s' setting", + NM_SETTING_TEAM_SETTING_NAME); + return FALSE; + } - config = nm_setting_team_get_config (s_team); - svSetValueStr (ifcfg, "TEAM_CONFIG", config); + config = nm_setting_team_get_config(s_team); + svSetValueStr(ifcfg, "TEAM_CONFIG", config); - *wired = write_wired_for_virtual (connection, ifcfg); + *wired = write_wired_for_virtual(connection, ifcfg); - return TRUE; + return TRUE; } -static gboolean -get_setting_default_boolean (gpointer setting, const char *prop) -{ - return NM_G_PARAM_SPEC_GET_DEFAULT_BOOLEAN (g_object_class_find_property (G_OBJECT_GET_CLASS (setting), prop)); -} - -static guint -get_setting_default_uint (gpointer setting, const char *prop) -{ - return NM_G_PARAM_SPEC_GET_DEFAULT_UINT (g_object_class_find_property (G_OBJECT_GET_CLASS (setting), prop)); -} - -static guint64 -get_setting_default_uint64 (gpointer setting, const char *prop) -{ - return NM_G_PARAM_SPEC_GET_DEFAULT_UINT64 (g_object_class_find_property (G_OBJECT_GET_CLASS (setting), prop)); -} +#define get_setting_default_checked_boolean(dflt, setting, prop) \ + ({ \ + const gboolean _dflt = (dflt); \ + \ + nm_assert(NM_G_PARAM_SPEC_GET_DEFAULT_BOOLEAN( \ + g_object_class_find_property(G_OBJECT_GET_CLASS(setting), prop)) \ + == _dflt); \ + _dflt; \ + }) + +#define get_setting_default_checked_uint(dflt, setting, prop) \ + ({ \ + const guint _dflt = (dflt); \ + \ + nm_assert(NM_G_PARAM_SPEC_GET_DEFAULT_UINT( \ + g_object_class_find_property(G_OBJECT_GET_CLASS(setting), prop)) \ + == _dflt); \ + _dflt; \ + }) + +#define get_setting_default_checked_uint64(dflt, setting, prop) \ + ({ \ + const guint64 _dflt = (dflt); \ + \ + nm_assert(NM_G_PARAM_SPEC_GET_DEFAULT_UINT64( \ + g_object_class_find_property(G_OBJECT_GET_CLASS(setting), prop)) \ + == _dflt); \ + _dflt; \ + }) static gboolean -write_bridge_vlans (NMSetting *setting, - const char *property_name, - shvarFile *ifcfg, - const char *key, - GError **error) +write_bridge_vlans(NMSetting * setting, + const char *property_name, + shvarFile * ifcfg, + const char *key, + GError ** error) { - gs_unref_ptrarray GPtrArray *vlans = NULL; - NMBridgeVlan *vlan; - GString *string; - guint i; - - g_object_get (setting, property_name, &vlans, NULL); - - if ( !vlans - || !vlans->len) - return TRUE; - - string = g_string_new (""); - for (i = 0; i < vlans->len; i++) { - gs_free char *vlan_str = NULL; - - vlan = vlans->pdata[i]; - vlan_str = nm_bridge_vlan_to_str (vlan, error); - if (!vlan_str) - return FALSE; - if (string->len > 0) - g_string_append (string, ","); - nm_utils_escaped_tokens_escape_gstr_assert (vlan_str, ",", string); - } - - svSetValueStr (ifcfg, key, string->str); - g_string_free (string, TRUE); - return TRUE; + gs_unref_ptrarray GPtrArray *vlans = NULL; + NMBridgeVlan * vlan; + GString * string; + guint i; + + g_object_get(setting, property_name, &vlans, NULL); + + if (!vlans || !vlans->len) + return TRUE; + + string = g_string_new(""); + for (i = 0; i < vlans->len; i++) { + gs_free char *vlan_str = NULL; + + vlan = vlans->pdata[i]; + vlan_str = nm_bridge_vlan_to_str(vlan, error); + if (!vlan_str) + return FALSE; + if (string->len > 0) + g_string_append(string, ","); + nm_utils_escaped_tokens_escape_gstr_assert(vlan_str, ",", string); + } + + svSetValueStr(ifcfg, key, string->str); + g_string_free(string, TRUE); + return TRUE; } static gboolean -write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error) +write_bridge_setting(NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error) { - NMSettingBridge *s_bridge; - guint32 u32; - guint64 u64; - gboolean b; - const char *s; - GString *opts; - - s_bridge = nm_connection_get_setting_bridge (connection); - if (!s_bridge) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Missing '%s' setting", NM_SETTING_BRIDGE_SETTING_NAME); - return FALSE; - } - - svSetValueBoolean (ifcfg, "STP", FALSE); - - s = nm_setting_bridge_get_mac_address (s_bridge); - svSetValueStr (ifcfg, "BRIDGE_MACADDR", s); - - /* Bridge options */ - opts = g_string_sized_new (32); - - if (nm_setting_bridge_get_stp (s_bridge)) { - svSetValueStr (ifcfg, "STP", "yes"); - - u32 = nm_setting_bridge_get_forward_delay (s_bridge); - if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_FORWARD_DELAY)) - svSetValueInt64 (ifcfg, "DELAY", u32); - - g_string_append_printf (opts, "priority=%u", nm_setting_bridge_get_priority (s_bridge)); - - u32 = nm_setting_bridge_get_hello_time (s_bridge); - if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_HELLO_TIME)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "hello_time=%u", u32); - } - - u32 = nm_setting_bridge_get_max_age (s_bridge); - if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_MAX_AGE)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "max_age=%u", u32); - } - } - - u32 = nm_setting_bridge_get_ageing_time (s_bridge); - if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_AGEING_TIME)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "ageing_time=%u", u32); - } - - s = nm_setting_bridge_get_group_address (s_bridge); - if (s) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "group_address=%s", s); - } - - u32 = nm_setting_bridge_get_group_forward_mask (s_bridge); - if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_GROUP_FORWARD_MASK)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "group_fwd_mask=%u", u32); - } - - - u32 = nm_setting_bridge_get_multicast_hash_max (s_bridge); - if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_MULTICAST_HASH_MAX)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_hash_max=%u", u32); - } - - u32 = nm_setting_bridge_get_multicast_last_member_count (s_bridge); - if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_last_member_count=%u", u32); - } - - u64 = nm_setting_bridge_get_multicast_last_member_interval (s_bridge); - if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_last_member_interval=%"G_GUINT64_FORMAT, u64); - } - - u64 = nm_setting_bridge_get_multicast_membership_interval (s_bridge); - if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_membership_interval=%"G_GUINT64_FORMAT, u64); - } - - b = nm_setting_bridge_get_multicast_querier (s_bridge); - if (b != get_setting_default_boolean (s_bridge, NM_SETTING_BRIDGE_MULTICAST_QUERIER)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_querier=%u", (guint) b); - } - - u64 = nm_setting_bridge_get_multicast_querier_interval (s_bridge); - if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_querier_interval=%"G_GUINT64_FORMAT, u64); - } - - u64 = nm_setting_bridge_get_multicast_query_interval (s_bridge); - if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_query_interval=%"G_GUINT64_FORMAT, u64); - } - - u64 = nm_setting_bridge_get_multicast_query_response_interval (s_bridge); - if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_query_response_interval=%"G_GUINT64_FORMAT, u64); - } - - b = nm_setting_bridge_get_multicast_query_use_ifaddr (s_bridge); - if (b != get_setting_default_boolean (s_bridge, NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_query_use_ifaddr=%u", (guint) b); - } - - b = nm_setting_bridge_get_multicast_snooping (s_bridge); - if (b != get_setting_default_boolean (s_bridge, NM_SETTING_BRIDGE_MULTICAST_SNOOPING)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_snooping=%u", (guint32) b); - } - - u32 = nm_setting_bridge_get_multicast_startup_query_count (s_bridge); - if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_startup_query_count=%u", u32); - } - - u64 = nm_setting_bridge_get_multicast_startup_query_interval (s_bridge); - if (u64 != get_setting_default_uint64 (s_bridge, NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_startup_query_interval=%"G_GUINT64_FORMAT, u64); - } - - s = nm_setting_bridge_get_multicast_router (s_bridge); - if (s) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "multicast_router=%s", s); - } - - b = nm_setting_bridge_get_vlan_filtering (s_bridge); - if (b != get_setting_default_boolean (s_bridge, NM_SETTING_BRIDGE_VLAN_FILTERING)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "vlan_filtering=%u", (guint32) b); - } - - u32 = nm_setting_bridge_get_vlan_default_pvid (s_bridge); - if (u32 != get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "default_pvid=%u", u32); - } - - s = nm_setting_bridge_get_vlan_protocol (s_bridge); - if (s) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "vlan_protocol=%s", s); - } - - b = nm_setting_bridge_get_vlan_stats_enabled (s_bridge); - if (b != get_setting_default_boolean (s_bridge, NM_SETTING_BRIDGE_VLAN_STATS_ENABLED)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "vlan_stats_enabled=%u", (guint) b); - } - - if (opts->len) - svSetValueStr (ifcfg, "BRIDGING_OPTS", opts->str); - g_string_free (opts, TRUE); - - if (!write_bridge_vlans ((NMSetting *) s_bridge, - NM_SETTING_BRIDGE_VLANS, - ifcfg, - "BRIDGE_VLANS", - error)) - return FALSE; - - svSetValueStr (ifcfg, "TYPE", TYPE_BRIDGE); - - *wired = write_wired_for_virtual (connection, ifcfg); - - return TRUE; + NMSettingBridge *s_bridge; + guint32 u32; + guint64 u64; + guint u; + gboolean b; + const char * s; + GString * opts; + + s_bridge = nm_connection_get_setting_bridge(connection); + if (!s_bridge) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Missing '%s' setting", + NM_SETTING_BRIDGE_SETTING_NAME); + return FALSE; + } + + svSetValueBoolean(ifcfg, "STP", FALSE); + + s = nm_setting_bridge_get_mac_address(s_bridge); + svSetValueStr(ifcfg, "BRIDGE_MACADDR", s); + + /* Bridge options */ + opts = g_string_sized_new(32); + + if (nm_setting_bridge_get_stp(s_bridge)) { + svSetValueStr(ifcfg, "STP", "yes"); + + u32 = nm_setting_bridge_get_forward_delay(s_bridge); + if (u32 + != get_setting_default_checked_uint(NM_BRIDGE_FORWARD_DELAY_DEF, + s_bridge, + NM_SETTING_BRIDGE_FORWARD_DELAY)) + svSetValueInt64(ifcfg, "DELAY", u32); + + g_string_append_printf(opts, "priority=%u", nm_setting_bridge_get_priority(s_bridge)); + + u32 = nm_setting_bridge_get_hello_time(s_bridge); + if (u32 + != get_setting_default_checked_uint(NM_BRIDGE_HELLO_TIME_DEF, + s_bridge, + NM_SETTING_BRIDGE_HELLO_TIME)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "hello_time=%u", u32); + } + + u32 = nm_setting_bridge_get_max_age(s_bridge); + if (u32 + != get_setting_default_checked_uint(NM_BRIDGE_MAX_AGE_DEF, + s_bridge, + NM_SETTING_BRIDGE_MAX_AGE)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "max_age=%u", u32); + } + } + + u = nm_setting_bridge_get_ageing_time(s_bridge); + if (u + != get_setting_default_checked_uint(NM_BRIDGE_AGEING_TIME_DEF, + s_bridge, + NM_SETTING_BRIDGE_AGEING_TIME)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "ageing_time=%u", u); + } + + s = nm_setting_bridge_get_group_address(s_bridge); + if (s) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "group_address=%s", s); + } + + u32 = nm_setting_bridge_get_group_forward_mask(s_bridge); + if (u32 + != get_setting_default_checked_uint(0, s_bridge, NM_SETTING_BRIDGE_GROUP_FORWARD_MASK)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "group_fwd_mask=%u", u32); + } + + u32 = nm_setting_bridge_get_multicast_hash_max(s_bridge); + if (u32 + != get_setting_default_checked_uint(NM_BRIDGE_MULTICAST_HASH_MAX_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_HASH_MAX)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_hash_max=%u", u32); + } + + u32 = nm_setting_bridge_get_multicast_last_member_count(s_bridge); + if (u32 + != get_setting_default_checked_uint(NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_last_member_count=%u", u32); + } + + u64 = nm_setting_bridge_get_multicast_last_member_interval(s_bridge); + if (u64 + != get_setting_default_checked_uint64(NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_last_member_interval=%" G_GUINT64_FORMAT, u64); + } + + u64 = nm_setting_bridge_get_multicast_membership_interval(s_bridge); + if (u64 + != get_setting_default_checked_uint64(NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_membership_interval=%" G_GUINT64_FORMAT, u64); + } + + b = nm_setting_bridge_get_multicast_querier(s_bridge); + if (b + != get_setting_default_checked_boolean(NM_BRIDGE_MULTICAST_QUERIER_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_QUERIER)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_querier=%u", (guint) b); + } + + u64 = nm_setting_bridge_get_multicast_querier_interval(s_bridge); + if (u64 + != get_setting_default_checked_uint64(NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_querier_interval=%" G_GUINT64_FORMAT, u64); + } + + u64 = nm_setting_bridge_get_multicast_query_interval(s_bridge); + if (u64 + != get_setting_default_checked_uint64(NM_BRIDGE_MULTICAST_QUERY_INTERVAL_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_query_interval=%" G_GUINT64_FORMAT, u64); + } + + u64 = nm_setting_bridge_get_multicast_query_response_interval(s_bridge); + if (u64 + != get_setting_default_checked_uint64( + NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_query_response_interval=%" G_GUINT64_FORMAT, u64); + } + + b = nm_setting_bridge_get_multicast_query_use_ifaddr(s_bridge); + if (b + != get_setting_default_checked_boolean(NM_BRIDGE_MULTICAST_QUERY_USE_IFADDR_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_query_use_ifaddr=%u", (guint) b); + } + + b = nm_setting_bridge_get_multicast_snooping(s_bridge); + if (b + != get_setting_default_checked_boolean(NM_BRIDGE_MULTICAST_SNOOPING_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_SNOOPING)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_snooping=%u", (guint32) b); + } + + u32 = nm_setting_bridge_get_multicast_startup_query_count(s_bridge); + if (u32 + != get_setting_default_checked_uint(NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_startup_query_count=%u", u32); + } + + u64 = nm_setting_bridge_get_multicast_startup_query_interval(s_bridge); + if (u64 + != get_setting_default_checked_uint64(NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_DEF, + s_bridge, + NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_startup_query_interval=%" G_GUINT64_FORMAT, u64); + } + + s = nm_setting_bridge_get_multicast_router(s_bridge); + if (s) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "multicast_router=%s", s); + } + + b = nm_setting_bridge_get_vlan_filtering(s_bridge); + if (b + != get_setting_default_checked_boolean(FALSE, s_bridge, NM_SETTING_BRIDGE_VLAN_FILTERING)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "vlan_filtering=%u", (guint32) b); + } + + u32 = nm_setting_bridge_get_vlan_default_pvid(s_bridge); + if (u32 + != get_setting_default_checked_uint(NM_BRIDGE_VLAN_DEFAULT_PVID_DEF, + s_bridge, + NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "default_pvid=%u", u32); + } + + s = nm_setting_bridge_get_vlan_protocol(s_bridge); + if (s) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "vlan_protocol=%s", s); + } + + b = nm_setting_bridge_get_vlan_stats_enabled(s_bridge); + if (b + != get_setting_default_checked_boolean(NM_BRIDGE_VLAN_STATS_ENABLED_DEF, + s_bridge, + NM_SETTING_BRIDGE_VLAN_STATS_ENABLED)) { + nm_gstring_add_space_delimiter(opts); + g_string_append_printf(opts, "vlan_stats_enabled=%u", (guint) b); + } + + if (opts->len) + svSetValueStr(ifcfg, "BRIDGING_OPTS", opts->str); + g_string_free(opts, TRUE); + + if (!write_bridge_vlans((NMSetting *) s_bridge, + NM_SETTING_BRIDGE_VLANS, + ifcfg, + "BRIDGE_VLANS", + error)) + return FALSE; + + svSetValueStr(ifcfg, "TYPE", TYPE_BRIDGE); + + *wired = write_wired_for_virtual(connection, ifcfg); + + return TRUE; } static gboolean -write_bridge_port_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +write_bridge_port_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) { - NMSettingBridgePort *s_port; - guint32 u32; - GString *string; - - s_port = nm_connection_get_setting_bridge_port (connection); - if (!s_port) - return TRUE; - - /* Bridge options */ - string = g_string_sized_new (32); - - u32 = nm_setting_bridge_port_get_priority (s_port); - if (u32 != get_setting_default_uint (NM_SETTING (s_port), NM_SETTING_BRIDGE_PORT_PRIORITY)) - g_string_append_printf (string, "priority=%u", u32); - - u32 = nm_setting_bridge_port_get_path_cost (s_port); - if (u32 != get_setting_default_uint (NM_SETTING (s_port), NM_SETTING_BRIDGE_PORT_PATH_COST)) { - if (string->len) - g_string_append_c (string, ' '); - g_string_append_printf (string, "path_cost=%u", u32); - } - - if (nm_setting_bridge_port_get_hairpin_mode (s_port)) { - if (string->len) - g_string_append_c (string, ' '); - g_string_append_printf (string, "hairpin_mode=1"); - } - - if (string->len) - svSetValueStr (ifcfg, "BRIDGING_OPTS", string->str); - g_string_free (string, TRUE); - - if (!write_bridge_vlans ((NMSetting *) s_port, - NM_SETTING_BRIDGE_PORT_VLANS, - ifcfg, - "BRIDGE_PORT_VLANS", - error)) - return FALSE; - - return TRUE; + NMSettingBridgePort *s_port; + guint32 u32; + GString * string; + + s_port = nm_connection_get_setting_bridge_port(connection); + if (!s_port) + return TRUE; + + /* Bridge options */ + string = g_string_sized_new(32); + + u32 = nm_setting_bridge_port_get_priority(s_port); + if (u32 + != get_setting_default_checked_uint(NM_BRIDGE_PORT_PRIORITY_DEF, + s_port, + NM_SETTING_BRIDGE_PORT_PRIORITY)) + g_string_append_printf(string, "priority=%u", u32); + + u32 = nm_setting_bridge_port_get_path_cost(s_port); + if (u32 + != get_setting_default_checked_uint(NM_BRIDGE_PORT_PATH_COST_DEF, + s_port, + NM_SETTING_BRIDGE_PORT_PATH_COST)) { + if (string->len) + g_string_append_c(string, ' '); + g_string_append_printf(string, "path_cost=%u", u32); + } + + if (nm_setting_bridge_port_get_hairpin_mode(s_port)) { + if (string->len) + g_string_append_c(string, ' '); + g_string_append_printf(string, "hairpin_mode=1"); + } + + if (string->len) + svSetValueStr(ifcfg, "BRIDGING_OPTS", string->str); + g_string_free(string, TRUE); + + if (!write_bridge_vlans((NMSetting *) s_port, + NM_SETTING_BRIDGE_PORT_VLANS, + ifcfg, + "BRIDGE_PORT_VLANS", + error)) + return FALSE; + + return TRUE; } static gboolean -write_team_port_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +write_team_port_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) { - NMSettingTeamPort *s_port; - const char *config; + NMSettingTeamPort *s_port; + const char * config; - s_port = nm_connection_get_setting_team_port (connection); - if (!s_port) - return TRUE; + s_port = nm_connection_get_setting_team_port(connection); + if (!s_port) + return TRUE; - config = nm_setting_team_port_get_config (s_port); - svSetValueStr (ifcfg, "TEAM_PORT_CONFIG", config); + config = nm_setting_team_port_get_config(s_port); + svSetValueStr(ifcfg, "TEAM_PORT_CONFIG", config); - return TRUE; + return TRUE; } static void -write_dcb_flags (shvarFile *ifcfg, const char *tag, NMSettingDcbFlags flags) +write_dcb_flags(shvarFile *ifcfg, const char *tag, NMSettingDcbFlags flags) { - char prop[NM_STRLEN ("DCB_xxxxxxxxxxxxxxxxxxxxxxx_yyyyyyyyyyyyyyyyyyyy")]; + char prop[NM_STRLEN("DCB_xxxxxxxxxxxxxxxxxxxxxxx_yyyyyyyyyyyyyyyyyyyy")]; - nm_sprintf_buf (prop, "DCB_%s_ENABLE", tag); - svSetValueStr (ifcfg, prop, (flags & NM_SETTING_DCB_FLAG_ENABLE) ? "yes" : NULL); + nm_sprintf_buf(prop, "DCB_%s_ENABLE", tag); + svSetValueStr(ifcfg, prop, (flags & NM_SETTING_DCB_FLAG_ENABLE) ? "yes" : NULL); - nm_sprintf_buf (prop, "DCB_%s_ADVERTISE", tag); - svSetValueStr (ifcfg, prop, (flags & NM_SETTING_DCB_FLAG_ADVERTISE) ? "yes" : NULL); + nm_sprintf_buf(prop, "DCB_%s_ADVERTISE", tag); + svSetValueStr(ifcfg, prop, (flags & NM_SETTING_DCB_FLAG_ADVERTISE) ? "yes" : NULL); - nm_sprintf_buf (prop, "DCB_%s_WILLING", tag); - svSetValueStr (ifcfg, prop, (flags & NM_SETTING_DCB_FLAG_WILLING) ? "yes" : NULL); + nm_sprintf_buf(prop, "DCB_%s_WILLING", tag); + svSetValueStr(ifcfg, prop, (flags & NM_SETTING_DCB_FLAG_WILLING) ? "yes" : NULL); } static void -write_dcb_app (shvarFile *ifcfg, - const char *tag, - NMSettingDcbFlags flags, - int priority) +write_dcb_app(shvarFile *ifcfg, const char *tag, NMSettingDcbFlags flags, int priority) { - char prop[NM_STRLEN ("DCB_xxxxxxxxxxxxxxxxxxxxxxx_yyyyyyyyyyyyyyyyyyyy")]; + char prop[NM_STRLEN("DCB_xxxxxxxxxxxxxxxxxxxxxxx_yyyyyyyyyyyyyyyyyyyy")]; - write_dcb_flags (ifcfg, tag, flags); + write_dcb_flags(ifcfg, tag, flags); - if ( (flags & NM_SETTING_DCB_FLAG_ENABLE) - && (priority >= 0)) { - nm_sprintf_buf (prop, "DCB_%s_PRIORITY", tag); - svSetValueInt64 (ifcfg, prop, priority); - } + if ((flags & NM_SETTING_DCB_FLAG_ENABLE) && (priority >= 0)) { + nm_sprintf_buf(prop, "DCB_%s_PRIORITY", tag); + svSetValueInt64(ifcfg, prop, priority); + } } -typedef gboolean (*DcbGetBoolFunc) (NMSettingDcb *, guint); +typedef gboolean (*DcbGetBoolFunc)(NMSettingDcb *, guint); static void -write_dcb_bool_array (shvarFile *ifcfg, - const char *key, - NMSettingDcb *s_dcb, - NMSettingDcbFlags flags, - DcbGetBoolFunc get_func) +write_dcb_bool_array(shvarFile * ifcfg, + const char * key, + NMSettingDcb * s_dcb, + NMSettingDcbFlags flags, + DcbGetBoolFunc get_func) { - char str[9]; - guint i; + char str[9]; + guint i; - if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) - return; + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) + return; - str[8] = 0; - for (i = 0; i < 8; i++) - str[i] = get_func (s_dcb, i) ? '1' : '0'; - svSetValueStr (ifcfg, key, str); + str[8] = 0; + for (i = 0; i < 8; i++) + str[i] = get_func(s_dcb, i) ? '1' : '0'; + svSetValueStr(ifcfg, key, str); } -typedef guint (*DcbGetUintFunc) (NMSettingDcb *, guint); +typedef guint (*DcbGetUintFunc)(NMSettingDcb *, guint); static void -write_dcb_uint_array (shvarFile *ifcfg, - const char *key, - NMSettingDcb *s_dcb, - NMSettingDcbFlags flags, - DcbGetUintFunc get_func) +write_dcb_uint_array(shvarFile * ifcfg, + const char * key, + NMSettingDcb * s_dcb, + NMSettingDcbFlags flags, + DcbGetUintFunc get_func) { - char str[9]; - guint i, num; - - if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) - return; - - str[8] = 0; - for (i = 0; i < 8; i++) { - num = get_func (s_dcb, i); - if (num < 10) - str[i] = '0' + num; - else if (num == 15) - str[i] = 'f'; - else - g_assert_not_reached (); - } - svSetValueStr (ifcfg, key, str); + char str[9]; + guint i, num; + + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) + return; + + str[8] = 0; + for (i = 0; i < 8; i++) { + num = get_func(s_dcb, i); + if (num < 10) + str[i] = '0' + num; + else if (num == 15) + str[i] = 'f'; + else + g_assert_not_reached(); + } + svSetValueStr(ifcfg, key, str); } static void -write_dcb_percent_array (shvarFile *ifcfg, - const char *key, - NMSettingDcb *s_dcb, - NMSettingDcbFlags flags, - DcbGetUintFunc get_func) +write_dcb_percent_array(shvarFile * ifcfg, + const char * key, + NMSettingDcb * s_dcb, + NMSettingDcbFlags flags, + DcbGetUintFunc get_func) { - GString *str; - guint i; - - if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) - return; - - str = g_string_sized_new (30); - for (i = 0; i < 8; i++) { - if (str->len) - g_string_append_c (str, ','); - g_string_append_printf (str, "%d", get_func (s_dcb, i)); - } - svSetValueStr (ifcfg, key, str->str); - g_string_free (str, TRUE); + GString *str; + guint i; + + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) + return; + + str = g_string_sized_new(30); + for (i = 0; i < 8; i++) { + if (str->len) + g_string_append_c(str, ','); + g_string_append_printf(str, "%d", get_func(s_dcb, i)); + } + svSetValueStr(ifcfg, key, str->str); + g_string_free(str, TRUE); } static gboolean -write_dcb_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +write_dcb_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) { - NMSettingDcb *s_dcb; - NMSettingDcbFlags flags; - - s_dcb = nm_connection_get_setting_dcb (connection); - if (!s_dcb) - return TRUE; - - svSetValueStr (ifcfg, "DCB", "yes"); - - write_dcb_app (ifcfg, "APP_FCOE", - nm_setting_dcb_get_app_fcoe_flags (s_dcb), - nm_setting_dcb_get_app_fcoe_priority (s_dcb)); - if (nm_setting_dcb_get_app_fcoe_flags (s_dcb) & NM_SETTING_DCB_FLAG_ENABLE) - svSetValueStr (ifcfg, KEY_DCB_APP_FCOE_MODE, nm_setting_dcb_get_app_fcoe_mode (s_dcb)); - - write_dcb_app (ifcfg, "APP_ISCSI", - nm_setting_dcb_get_app_iscsi_flags (s_dcb), - nm_setting_dcb_get_app_iscsi_priority (s_dcb)); - write_dcb_app (ifcfg, "APP_FIP", - nm_setting_dcb_get_app_fip_flags (s_dcb), - nm_setting_dcb_get_app_fip_priority (s_dcb)); - - write_dcb_flags (ifcfg, "PFC", nm_setting_dcb_get_priority_flow_control_flags (s_dcb)); - write_dcb_bool_array (ifcfg, KEY_DCB_PFC_UP, s_dcb, - nm_setting_dcb_get_priority_flow_control_flags (s_dcb), - nm_setting_dcb_get_priority_flow_control); - - flags = nm_setting_dcb_get_priority_group_flags (s_dcb); - write_dcb_flags (ifcfg, "PG", flags); - write_dcb_uint_array (ifcfg, KEY_DCB_PG_ID, s_dcb, flags, nm_setting_dcb_get_priority_group_id); - write_dcb_percent_array (ifcfg, KEY_DCB_PG_PCT, s_dcb, flags, nm_setting_dcb_get_priority_group_bandwidth); - write_dcb_percent_array (ifcfg, KEY_DCB_PG_UPPCT, s_dcb, flags, nm_setting_dcb_get_priority_bandwidth); - write_dcb_bool_array (ifcfg, KEY_DCB_PG_STRICT, s_dcb, flags, nm_setting_dcb_get_priority_strict_bandwidth); - write_dcb_uint_array (ifcfg, KEY_DCB_PG_UP2TC, s_dcb, flags, nm_setting_dcb_get_priority_traffic_class); - - return TRUE; + NMSettingDcb * s_dcb; + NMSettingDcbFlags flags; + + s_dcb = nm_connection_get_setting_dcb(connection); + if (!s_dcb) + return TRUE; + + svSetValueStr(ifcfg, "DCB", "yes"); + + write_dcb_app(ifcfg, + "APP_FCOE", + nm_setting_dcb_get_app_fcoe_flags(s_dcb), + nm_setting_dcb_get_app_fcoe_priority(s_dcb)); + if (nm_setting_dcb_get_app_fcoe_flags(s_dcb) & NM_SETTING_DCB_FLAG_ENABLE) + svSetValueStr(ifcfg, KEY_DCB_APP_FCOE_MODE, nm_setting_dcb_get_app_fcoe_mode(s_dcb)); + + write_dcb_app(ifcfg, + "APP_ISCSI", + nm_setting_dcb_get_app_iscsi_flags(s_dcb), + nm_setting_dcb_get_app_iscsi_priority(s_dcb)); + write_dcb_app(ifcfg, + "APP_FIP", + nm_setting_dcb_get_app_fip_flags(s_dcb), + nm_setting_dcb_get_app_fip_priority(s_dcb)); + + write_dcb_flags(ifcfg, "PFC", nm_setting_dcb_get_priority_flow_control_flags(s_dcb)); + write_dcb_bool_array(ifcfg, + KEY_DCB_PFC_UP, + s_dcb, + nm_setting_dcb_get_priority_flow_control_flags(s_dcb), + nm_setting_dcb_get_priority_flow_control); + + flags = nm_setting_dcb_get_priority_group_flags(s_dcb); + write_dcb_flags(ifcfg, "PG", flags); + write_dcb_uint_array(ifcfg, KEY_DCB_PG_ID, s_dcb, flags, nm_setting_dcb_get_priority_group_id); + write_dcb_percent_array(ifcfg, + KEY_DCB_PG_PCT, + s_dcb, + flags, + nm_setting_dcb_get_priority_group_bandwidth); + write_dcb_percent_array(ifcfg, + KEY_DCB_PG_UPPCT, + s_dcb, + flags, + nm_setting_dcb_get_priority_bandwidth); + write_dcb_bool_array(ifcfg, + KEY_DCB_PG_STRICT, + s_dcb, + flags, + nm_setting_dcb_get_priority_strict_bandwidth); + write_dcb_uint_array(ifcfg, + KEY_DCB_PG_UP2TC, + s_dcb, + flags, + nm_setting_dcb_get_priority_traffic_class); + + return TRUE; } static void -write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) +write_connection_setting(NMSettingConnection *s_con, shvarFile *ifcfg) { - guint32 n, i; - GString *str; - const char *master, *master_iface = NULL, *type; - int vint; - gint32 vint32; - NMSettingConnectionMdns mdns; - NMSettingConnectionLlmnr llmnr; - guint32 vuint32; - const char *tmp, *mud_url; - - svSetValueStr (ifcfg, "NAME", nm_setting_connection_get_id (s_con)); - svSetValueStr (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con)); - svSetValueStr (ifcfg, "STABLE_ID", nm_setting_connection_get_stable_id (s_con)); - svSetValueStr (ifcfg, "DEVICE", nm_setting_connection_get_interface_name (s_con)); - svSetValueBoolean (ifcfg, "ONBOOT", nm_setting_connection_get_autoconnect (s_con)); - - vint = nm_setting_connection_get_autoconnect_priority (s_con); - svSetValueInt64_cond (ifcfg, "AUTOCONNECT_PRIORITY", - vint != NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT, - vint); - - vint = nm_setting_connection_get_autoconnect_retries (s_con); - svSetValueInt64_cond (ifcfg, "AUTOCONNECT_RETRIES", - vint != -1, - vint); - - vint = nm_setting_connection_get_multi_connect (s_con); - svSetValueInt64_cond (ifcfg, "MULTI_CONNECT", - vint != NM_CONNECTION_MULTI_CONNECT_DEFAULT, - vint); - - /* Only save the value for master connections */ - type = nm_setting_connection_get_connection_type (s_con); - if (_nm_connection_type_is_master (type)) { - NMSettingConnectionAutoconnectSlaves autoconnect_slaves; - autoconnect_slaves = nm_setting_connection_get_autoconnect_slaves (s_con); - svSetValueStr (ifcfg, "AUTOCONNECT_SLAVES", - autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES ? "yes" : - autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO ? "no" : NULL); - } - switch (nm_setting_connection_get_lldp (s_con)) { - case NM_SETTING_CONNECTION_LLDP_ENABLE_RX: - tmp = "rx"; - break; - case NM_SETTING_CONNECTION_LLDP_DISABLE: - tmp = "no"; - break; - default: - tmp = NULL; - } - svSetValueStr (ifcfg, "LLDP", tmp); - - /* Permissions */ - n = nm_setting_connection_get_num_permissions (s_con); - if (n > 0) { - str = g_string_sized_new (n * 20); - - for (i = 0; i < n; i++) { - const char *puser = NULL; - - /* Items separated by space for consistency with eg - * IPV6ADDR_SECONDARIES and DOMAIN. - */ - if (str->len) - g_string_append_c (str, ' '); - - if (nm_setting_connection_get_permission (s_con, i, NULL, &puser, NULL)) - g_string_append (str, puser); - } - svSetValueStr (ifcfg, "USERS", str->str); - g_string_free (str, TRUE); - } - - svSetValueStr (ifcfg, "ZONE", nm_setting_connection_get_zone (s_con)); - - svSetValueStr (ifcfg, "MASTER_UUID", NULL); - svSetValueStr (ifcfg, "MASTER", NULL); - svSetValueStr (ifcfg, "SLAVE", NULL); - svSetValueStr (ifcfg, "BRIDGE_UUID", NULL); - svSetValueStr (ifcfg, "BRIDGE", NULL); - svSetValueStr (ifcfg, "TEAM_MASTER_UUID", NULL); - svSetValueStr (ifcfg, "TEAM_MASTER", NULL); - - mud_url = nm_setting_connection_get_mud_url (s_con); - svSetValue (ifcfg, "MUD_URL", mud_url); - - master = nm_setting_connection_get_master (s_con); - if (master) { - /* The reader prefers the *_UUID variants, however we still try to resolve - * it into an interface name, so that legacy tooling is not confused. */ - if (!nm_utils_get_testing ()) { - /* This is conditional for easier testing. */ - master_iface = nm_manager_iface_for_uuid (NM_MANAGER_GET, master); - } - if (!master_iface) { - master_iface = master; - master = NULL; - - } - - if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BOND_SETTING_NAME)) { - svSetValueStr (ifcfg, "MASTER_UUID", master); - svSetValueStr (ifcfg, "MASTER", master_iface); - svSetValueStr (ifcfg, "SLAVE", "yes"); - } else if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BRIDGE_SETTING_NAME)) { - svSetValueStr (ifcfg, "BRIDGE_UUID", master); - svSetValueStr (ifcfg, "BRIDGE", master_iface); - } else if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_TEAM_SETTING_NAME)) { - svSetValueStr (ifcfg, "TEAM_MASTER_UUID", master); - svSetValueStr (ifcfg, "TEAM_MASTER", master_iface); - if (NM_IN_STRSET (type, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_VLAN_SETTING_NAME)) - svUnsetValue (ifcfg, "TYPE"); - } else if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_OVS_PORT_SETTING_NAME)) { - svSetValueStr (ifcfg, "OVS_PORT_UUID", master); - svSetValueStr (ifcfg, "OVS_PORT", master_iface); - } else if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_VRF_SETTING_NAME)) { - svSetValueStr (ifcfg, "VRF_UUID", master); - svSetValueStr (ifcfg, "VRF", master_iface); - } else { - _LOGW ("don't know how to set master for a %s slave", - nm_setting_connection_get_slave_type (s_con)); - } - } - - if (nm_streq0 (type, NM_SETTING_TEAM_SETTING_NAME)) - svSetValueStr (ifcfg, "DEVICETYPE", TYPE_TEAM); - else if (master_iface && nm_setting_connection_is_slave_type (s_con, NM_SETTING_TEAM_SETTING_NAME)) - svSetValueStr (ifcfg, "DEVICETYPE", TYPE_TEAM_PORT); - - /* secondary connection UUIDs */ - n = nm_setting_connection_get_num_secondaries (s_con); - if (n > 0) { - str = g_string_sized_new (n * 37); - - for (i = 0; i < n; i++) { - const char *uuid; - - /* Items separated by space for consistency with eg - * IPV6ADDR_SECONDARIES and DOMAIN. - */ - if (str->len) - g_string_append_c (str, ' '); - - if ((uuid = nm_setting_connection_get_secondary (s_con, i)) != NULL) - g_string_append (str, uuid); - } - svSetValueStr (ifcfg, "SECONDARY_UUIDS", str->str); - g_string_free (str, TRUE); - } - - vuint32 = nm_setting_connection_get_gateway_ping_timeout (s_con); - svSetValueInt64_cond (ifcfg, "GATEWAY_PING_TIMEOUT", - vuint32 != 0, - vuint32); - - switch (nm_setting_connection_get_metered (s_con)) { - case NM_METERED_YES: - svSetValueStr (ifcfg, "CONNECTION_METERED", "yes"); - break; - case NM_METERED_NO: - svSetValueStr (ifcfg, "CONNECTION_METERED", "no"); - break; - case NM_METERED_UNKNOWN: - case NM_METERED_GUESS_YES: - case NM_METERED_GUESS_NO: - break; - } - - vint = nm_setting_connection_get_auth_retries (s_con); - svSetValueInt64_cond (ifcfg, "AUTH_RETRIES", vint >= 0, vint); - - vint32 = nm_setting_connection_get_wait_device_timeout (s_con); - if (vint32 == -1) { - /* pass */ - } else if ((vint32 % 1000) == 0) - svSetValueInt64 (ifcfg, "DEVTIMEOUT", vint32 / 1000); - else { - char b[100]; - - svSetValueStr (ifcfg, - "DEVTIMEOUT", - nm_sprintf_buf (b, "%.3f", ((double) vint) / 1000.0)); - } - - mdns = nm_setting_connection_get_mdns (s_con); - if (mdns != NM_SETTING_CONNECTION_MDNS_DEFAULT) { - svSetValueEnum (ifcfg, "MDNS", nm_setting_connection_mdns_get_type (), - mdns); - } - - llmnr = nm_setting_connection_get_llmnr (s_con); - if (llmnr != NM_SETTING_CONNECTION_LLMNR_DEFAULT) { - svSetValueEnum (ifcfg, "LLMNR", nm_setting_connection_llmnr_get_type (), - llmnr); - } + guint32 n, i; + nm_auto_free_gstring GString *str = NULL; + const char * master, *master_iface = NULL, *type; + int vint; + gint32 vint32; + NMSettingConnectionMdns mdns; + NMSettingConnectionLlmnr llmnr; + guint32 vuint32; + const char * tmp, *mud_url; + + svSetValueStr(ifcfg, "NAME", nm_setting_connection_get_id(s_con)); + svSetValueStr(ifcfg, "UUID", nm_setting_connection_get_uuid(s_con)); + svSetValueStr(ifcfg, "STABLE_ID", nm_setting_connection_get_stable_id(s_con)); + svSetValueStr(ifcfg, "DEVICE", nm_setting_connection_get_interface_name(s_con)); + svSetValueBoolean(ifcfg, "ONBOOT", nm_setting_connection_get_autoconnect(s_con)); + + vint = nm_setting_connection_get_autoconnect_priority(s_con); + svSetValueInt64_cond(ifcfg, + "AUTOCONNECT_PRIORITY", + vint != NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT, + vint); + + vint = nm_setting_connection_get_autoconnect_retries(s_con); + svSetValueInt64_cond(ifcfg, "AUTOCONNECT_RETRIES", vint != -1, vint); + + vint = nm_setting_connection_get_multi_connect(s_con); + svSetValueInt64_cond(ifcfg, "MULTI_CONNECT", vint != NM_CONNECTION_MULTI_CONNECT_DEFAULT, vint); + + /* Only save the value for master connections */ + type = nm_setting_connection_get_connection_type(s_con); + if (_nm_connection_type_is_master(type)) { + NMSettingConnectionAutoconnectSlaves autoconnect_slaves; + autoconnect_slaves = nm_setting_connection_get_autoconnect_slaves(s_con); + svSetValueStr(ifcfg, + "AUTOCONNECT_SLAVES", + autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES ? "yes" + : autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO ? "no" + : NULL); + } + switch (nm_setting_connection_get_lldp(s_con)) { + case NM_SETTING_CONNECTION_LLDP_ENABLE_RX: + tmp = "rx"; + break; + case NM_SETTING_CONNECTION_LLDP_DISABLE: + tmp = "no"; + break; + default: + tmp = NULL; + } + svSetValueStr(ifcfg, "LLDP", tmp); + + /* Permissions */ + n = nm_setting_connection_get_num_permissions(s_con); + if (n > 0) { + nm_gstring_prepare(&str); + for (i = 0; i < n; i++) { + const char *ptype = NULL; + const char *puser = NULL; + + if (!nm_setting_connection_get_permission(s_con, i, &ptype, &puser, NULL)) + continue; + if (!nm_streq(ptype, NM_SETTINGS_CONNECTION_PERMISSION_USER)) + continue; + + /* Items separated by space for consistency with eg + * IPV6ADDR_SECONDARIES and DOMAIN. + */ + if (str->len) + g_string_append_c(str, ' '); + + g_string_append(str, puser); + } + svSetValueStr(ifcfg, "USERS", str->str); + } + + svSetValueStr(ifcfg, "ZONE", nm_setting_connection_get_zone(s_con)); + + svSetValueStr(ifcfg, "MASTER_UUID", NULL); + svSetValueStr(ifcfg, "MASTER", NULL); + svSetValueStr(ifcfg, "SLAVE", NULL); + svSetValueStr(ifcfg, "BRIDGE_UUID", NULL); + svSetValueStr(ifcfg, "BRIDGE", NULL); + svSetValueStr(ifcfg, "TEAM_MASTER_UUID", NULL); + svSetValueStr(ifcfg, "TEAM_MASTER", NULL); + + mud_url = nm_setting_connection_get_mud_url(s_con); + svSetValue(ifcfg, "MUD_URL", mud_url); + + master = nm_setting_connection_get_master(s_con); + if (master) { + /* The reader prefers the *_UUID variants, however we still try to resolve + * it into an interface name, so that legacy tooling is not confused. */ + if (!nm_utils_get_testing()) { + /* This is conditional for easier testing. */ + master_iface = nm_manager_iface_for_uuid(NM_MANAGER_GET, master); + } + if (!master_iface) { + master_iface = master; + master = NULL; + } + + if (nm_setting_connection_is_slave_type(s_con, NM_SETTING_BOND_SETTING_NAME)) { + svSetValueStr(ifcfg, "MASTER_UUID", master); + svSetValueStr(ifcfg, "MASTER", master_iface); + svSetValueStr(ifcfg, "SLAVE", "yes"); + } else if (nm_setting_connection_is_slave_type(s_con, NM_SETTING_BRIDGE_SETTING_NAME)) { + svSetValueStr(ifcfg, "BRIDGE_UUID", master); + svSetValueStr(ifcfg, "BRIDGE", master_iface); + } else if (nm_setting_connection_is_slave_type(s_con, NM_SETTING_TEAM_SETTING_NAME)) { + svSetValueStr(ifcfg, "TEAM_MASTER_UUID", master); + svSetValueStr(ifcfg, "TEAM_MASTER", master_iface); + if (NM_IN_STRSET(type, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_VLAN_SETTING_NAME)) + svUnsetValue(ifcfg, "TYPE"); + } else if (nm_setting_connection_is_slave_type(s_con, NM_SETTING_OVS_PORT_SETTING_NAME)) { + svSetValueStr(ifcfg, "OVS_PORT_UUID", master); + svSetValueStr(ifcfg, "OVS_PORT", master_iface); + } else if (nm_setting_connection_is_slave_type(s_con, NM_SETTING_VRF_SETTING_NAME)) { + svSetValueStr(ifcfg, "VRF_UUID", master); + svSetValueStr(ifcfg, "VRF", master_iface); + } else { + _LOGW("don't know how to set master for a %s slave", + nm_setting_connection_get_slave_type(s_con)); + } + } + + if (nm_streq0(type, NM_SETTING_TEAM_SETTING_NAME)) + svSetValueStr(ifcfg, "DEVICETYPE", TYPE_TEAM); + else if (master_iface + && nm_setting_connection_is_slave_type(s_con, NM_SETTING_TEAM_SETTING_NAME)) + svSetValueStr(ifcfg, "DEVICETYPE", TYPE_TEAM_PORT); + + /* secondary connection UUIDs */ + n = nm_setting_connection_get_num_secondaries(s_con); + if (n > 0) { + nm_gstring_prepare(&str); + for (i = 0; i < n; i++) { + const char *uuid; + + /* Items separated by space for consistency with eg + * IPV6ADDR_SECONDARIES and DOMAIN. + */ + if (!(uuid = nm_setting_connection_get_secondary(s_con, i))) + continue; + + if (str->len) + g_string_append_c(str, ' '); + g_string_append(str, uuid); + } + svSetValueStr(ifcfg, "SECONDARY_UUIDS", str->str); + } + + vuint32 = nm_setting_connection_get_gateway_ping_timeout(s_con); + svSetValueInt64_cond(ifcfg, "GATEWAY_PING_TIMEOUT", vuint32 != 0, vuint32); + + switch (nm_setting_connection_get_metered(s_con)) { + case NM_METERED_YES: + svSetValueStr(ifcfg, "CONNECTION_METERED", "yes"); + break; + case NM_METERED_NO: + svSetValueStr(ifcfg, "CONNECTION_METERED", "no"); + break; + case NM_METERED_UNKNOWN: + case NM_METERED_GUESS_YES: + case NM_METERED_GUESS_NO: + break; + } + + vint = nm_setting_connection_get_auth_retries(s_con); + svSetValueInt64_cond(ifcfg, "AUTH_RETRIES", vint >= 0, vint); + + vint32 = nm_setting_connection_get_wait_device_timeout(s_con); + if (vint32 == -1) { + /* pass */ + } else if ((vint32 % 1000) == 0) + svSetValueInt64(ifcfg, "DEVTIMEOUT", vint32 / 1000); + else { + char b[100]; + + svSetValueStr(ifcfg, "DEVTIMEOUT", nm_sprintf_buf(b, "%.3f", ((double) vint) / 1000.0)); + } + + mdns = nm_setting_connection_get_mdns(s_con); + if (mdns != NM_SETTING_CONNECTION_MDNS_DEFAULT) { + svSetValueEnum(ifcfg, "MDNS", nm_setting_connection_mdns_get_type(), mdns); + } + + llmnr = nm_setting_connection_get_llmnr(s_con); + if (llmnr != NM_SETTING_CONNECTION_LLMNR_DEFAULT) { + svSetValueEnum(ifcfg, "LLMNR", nm_setting_connection_llmnr_get_type(), llmnr); + } } static char * -get_route_attributes_string (NMIPRoute *route, int family) +get_route_attributes_string(NMIPRoute *route, int family) { - gs_free const char **names = NULL; - GVariant *attr, *lock; - GString *str; - guint i, len; - - names = _nm_ip_route_get_attribute_names (route, TRUE, &len); - if (!len) - return NULL; - - str = g_string_new (""); - - attr = nm_ip_route_get_attribute (route, NM_IP_ROUTE_ATTRIBUTE_TYPE); - if ( attr - && nm_ip_route_attribute_validate (NM_IP_ROUTE_ATTRIBUTE_TYPE, attr, family, NULL, NULL)) - g_string_append_printf (str, "%s ", g_variant_get_string (attr, NULL)); - - for (i = 0; i < len; i++) { - if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_TYPE)) - continue; - - attr = nm_ip_route_get_attribute (route, names[i]); - - if (!nm_ip_route_attribute_validate (names[i], attr, family, NULL, NULL)) - continue; - - if (NM_IN_STRSET (names[i], NM_IP_ROUTE_ATTRIBUTE_WINDOW, - NM_IP_ROUTE_ATTRIBUTE_CWND, - NM_IP_ROUTE_ATTRIBUTE_INITCWND, - NM_IP_ROUTE_ATTRIBUTE_INITRWND, - NM_IP_ROUTE_ATTRIBUTE_MTU)) { - char lock_name[256]; - - nm_sprintf_buf (lock_name, "lock-%s", names[i]); - lock = nm_ip_route_get_attribute (route, lock_name); - - g_string_append_printf (str, - "%s %s%u", - names[i], - (lock && g_variant_get_boolean (lock)) ? "lock " : "", - g_variant_get_uint32 (attr)); - } else if (strstr (names[i], "lock-")) { - const char *n = &(names[i])[NM_STRLEN ("lock-")]; - - attr = nm_ip_route_get_attribute (route, n); - if (!attr) { - g_string_append_printf (str, - "%s lock 0", - n); - } else { - /* we also have a corresponding attribute with the numeric value. The - * lock setting is handled above. */ - } - } else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_SCOPE)) { - g_string_append_printf (str, "%s %u", names[i], (unsigned) g_variant_get_byte (attr)); - } else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_TOS)) { - g_string_append_printf (str, "%s 0x%02x", names[i], (unsigned) g_variant_get_byte (attr)); - } else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_TABLE)) { - g_string_append_printf (str, "%s %u", names[i], (unsigned) g_variant_get_uint32 (attr)); - } else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_ONLINK)) { - if (g_variant_get_boolean (attr)) - g_string_append (str, "onlink"); - } else if (NM_IN_STRSET (names[i], NM_IP_ROUTE_ATTRIBUTE_SRC, - NM_IP_ROUTE_ATTRIBUTE_FROM)) { - char *arg = nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_SRC) ? "src" : "from"; - - g_string_append_printf (str, "%s %s", arg, g_variant_get_string (attr, NULL)); - } else { - g_warn_if_reached (); - continue; - } - if (names[i + 1]) - g_string_append_c (str, ' '); - } - - return g_string_free (str, FALSE); + gs_free const char **names = NULL; + GVariant * attr, *lock; + GString * str; + guint i, len; + + names = _nm_ip_route_get_attribute_names(route, TRUE, &len); + if (!len) + return NULL; + + str = g_string_new(""); + + attr = nm_ip_route_get_attribute(route, NM_IP_ROUTE_ATTRIBUTE_TYPE); + if (attr + && nm_ip_route_attribute_validate(NM_IP_ROUTE_ATTRIBUTE_TYPE, attr, family, NULL, NULL)) + g_string_append_printf(str, "%s ", g_variant_get_string(attr, NULL)); + + for (i = 0; i < len; i++) { + if (nm_streq(names[i], NM_IP_ROUTE_ATTRIBUTE_TYPE)) + continue; + + attr = nm_ip_route_get_attribute(route, names[i]); + + if (!nm_ip_route_attribute_validate(names[i], attr, family, NULL, NULL)) + continue; + + if (NM_IN_STRSET(names[i], + NM_IP_ROUTE_ATTRIBUTE_WINDOW, + NM_IP_ROUTE_ATTRIBUTE_CWND, + NM_IP_ROUTE_ATTRIBUTE_INITCWND, + NM_IP_ROUTE_ATTRIBUTE_INITRWND, + NM_IP_ROUTE_ATTRIBUTE_MTU)) { + char lock_name[256]; + + nm_sprintf_buf(lock_name, "lock-%s", names[i]); + lock = nm_ip_route_get_attribute(route, lock_name); + + g_string_append_printf(str, + "%s %s%u", + names[i], + (lock && g_variant_get_boolean(lock)) ? "lock " : "", + g_variant_get_uint32(attr)); + } else if (strstr(names[i], "lock-")) { + const char *n = &(names[i])[NM_STRLEN("lock-")]; + + attr = nm_ip_route_get_attribute(route, n); + if (!attr) { + g_string_append_printf(str, "%s lock 0", n); + } else { + /* we also have a corresponding attribute with the numeric value. The + * lock setting is handled above. */ + } + } else if (nm_streq(names[i], NM_IP_ROUTE_ATTRIBUTE_SCOPE)) { + g_string_append_printf(str, "%s %u", names[i], (unsigned) g_variant_get_byte(attr)); + } else if (nm_streq(names[i], NM_IP_ROUTE_ATTRIBUTE_TOS)) { + g_string_append_printf(str, "%s 0x%02x", names[i], (unsigned) g_variant_get_byte(attr)); + } else if (nm_streq(names[i], NM_IP_ROUTE_ATTRIBUTE_TABLE)) { + g_string_append_printf(str, "%s %u", names[i], (unsigned) g_variant_get_uint32(attr)); + } else if (nm_streq(names[i], NM_IP_ROUTE_ATTRIBUTE_ONLINK)) { + if (g_variant_get_boolean(attr)) + g_string_append(str, "onlink"); + } else if (NM_IN_STRSET(names[i], NM_IP_ROUTE_ATTRIBUTE_SRC, NM_IP_ROUTE_ATTRIBUTE_FROM)) { + char *arg = nm_streq(names[i], NM_IP_ROUTE_ATTRIBUTE_SRC) ? "src" : "from"; + + g_string_append_printf(str, "%s %s", arg, g_variant_get_string(attr, NULL)); + } else { + g_warn_if_reached(); + continue; + } + if (names[i + 1]) + g_string_append_c(str, ' '); + } + + return g_string_free(str, FALSE); } static shvarFile * -write_route_file_svformat (const char *filename, NMSettingIPConfig *s_ip4) +write_route_file_svformat(const char *filename, NMSettingIPConfig *s_ip4) { - shvarFile *routefile; - guint i, num; - - routefile = utils_get_route_ifcfg (filename, TRUE); - - num = nm_setting_ip_config_get_num_routes (s_ip4); - for (i = 0; i < num; i++) { - char buf[INET_ADDRSTRLEN]; - NMIPRoute *route; - guint32 netmask; - gint64 metric; - char addr_key[64]; - char gw_key[64]; - char netmask_key[64]; - char metric_key[64]; - char options_key[64]; - gs_free char *options = NULL; - - numbered_tag (addr_key, "ADDRESS", i); - numbered_tag (netmask_key, "NETMASK", i); - numbered_tag (gw_key, "GATEWAY", i); - - route = nm_setting_ip_config_get_route (s_ip4, i); - - svSetValueStr (routefile, addr_key, nm_ip_route_get_dest (route)); - - netmask = _nm_utils_ip4_prefix_to_netmask (nm_ip_route_get_prefix (route)); - svSetValueStr (routefile, netmask_key, - _nm_utils_inet4_ntop (netmask, buf)); - - svSetValueStr (routefile, gw_key, nm_ip_route_get_next_hop (route)); - - metric = nm_ip_route_get_metric (route); - if (metric != -1) { - svSetValueInt64 (routefile, - numbered_tag (metric_key, "METRIC", i), - metric); - } - - options = get_route_attributes_string (route, AF_INET); - if (options) { - svSetValueStr (routefile, - numbered_tag (options_key, "OPTIONS", i), - options); - } - } - - return routefile; + shvarFile *routefile; + guint i, num; + + routefile = utils_get_route_ifcfg(filename, TRUE); + + num = nm_setting_ip_config_get_num_routes(s_ip4); + for (i = 0; i < num; i++) { + char buf[INET_ADDRSTRLEN]; + NMIPRoute * route; + guint32 netmask; + gint64 metric; + char addr_key[64]; + char gw_key[64]; + char netmask_key[64]; + char metric_key[64]; + char options_key[64]; + gs_free char *options = NULL; + + numbered_tag(addr_key, "ADDRESS", i); + numbered_tag(netmask_key, "NETMASK", i); + numbered_tag(gw_key, "GATEWAY", i); + + route = nm_setting_ip_config_get_route(s_ip4, i); + + svSetValueStr(routefile, addr_key, nm_ip_route_get_dest(route)); + + netmask = _nm_utils_ip4_prefix_to_netmask(nm_ip_route_get_prefix(route)); + svSetValueStr(routefile, netmask_key, _nm_utils_inet4_ntop(netmask, buf)); + + svSetValueStr(routefile, gw_key, nm_ip_route_get_next_hop(route)); + + metric = nm_ip_route_get_metric(route); + if (metric != -1) { + svSetValueInt64(routefile, numbered_tag(metric_key, "METRIC", i), metric); + } + + options = get_route_attributes_string(route, AF_INET); + if (options) { + svSetValueStr(routefile, numbered_tag(options_key, "OPTIONS", i), options); + } + } + + return routefile; } static GString * -write_route_file (NMSettingIPConfig *s_ip) +write_route_file(NMSettingIPConfig *s_ip) { - GString *contents; - NMIPRoute *route; - guint32 i, num; - int addr_family; - - addr_family = nm_setting_ip_config_get_addr_family (s_ip); - - num = nm_setting_ip_config_get_num_routes (s_ip); - if (num == 0) - return NULL; - - contents = g_string_new (""); - - for (i = 0; i < num; i++) { - gs_free char *options = NULL; - const char *next_hop; - gint64 metric; - - route = nm_setting_ip_config_get_route (s_ip, i); - next_hop = nm_ip_route_get_next_hop (route); - metric = nm_ip_route_get_metric (route); - options = get_route_attributes_string (route, addr_family); - - g_string_append_printf (contents, "%s/%u", - nm_ip_route_get_dest (route), - nm_ip_route_get_prefix (route)); - if (next_hop) - g_string_append_printf (contents, " via %s", next_hop); - if (metric >= 0) - g_string_append_printf (contents, " metric %u", (guint) metric); - if (options) { - g_string_append_c (contents, ' '); - g_string_append (contents, options); - } - - g_string_append_c (contents, '\n'); - } - - return contents; + GString * contents; + NMIPRoute *route; + guint32 i, num; + int addr_family; + + addr_family = nm_setting_ip_config_get_addr_family(s_ip); + + num = nm_setting_ip_config_get_num_routes(s_ip); + if (num == 0) + return NULL; + + contents = g_string_new(""); + + for (i = 0; i < num; i++) { + gs_free char *options = NULL; + const char * next_hop; + gint64 metric; + + route = nm_setting_ip_config_get_route(s_ip, i); + next_hop = nm_ip_route_get_next_hop(route); + metric = nm_ip_route_get_metric(route); + options = get_route_attributes_string(route, addr_family); + + g_string_append_printf(contents, + "%s/%u", + nm_ip_route_get_dest(route), + nm_ip_route_get_prefix(route)); + if (next_hop) + g_string_append_printf(contents, " via %s", next_hop); + if (metric >= 0) + g_string_append_printf(contents, " metric %u", (guint) metric); + if (options) { + g_string_append_c(contents, ' '); + g_string_append(contents, options); + } + + g_string_append_c(contents, '\n'); + } + + return contents; } static gboolean -write_proxy_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +write_proxy_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) { - NMSettingProxy *s_proxy; - NMSettingProxyMethod method; - const char *pac_url, *pac_script; + NMSettingProxy * s_proxy; + NMSettingProxyMethod method; + const char * pac_url, *pac_script; - s_proxy = nm_connection_get_setting_proxy (connection); - if (!s_proxy) - return TRUE; + s_proxy = nm_connection_get_setting_proxy(connection); + if (!s_proxy) + return TRUE; - method = nm_setting_proxy_get_method (s_proxy); - switch (method) { - case NM_SETTING_PROXY_METHOD_AUTO: - svSetValueStr (ifcfg, "PROXY_METHOD", "auto"); + method = nm_setting_proxy_get_method(s_proxy); + switch (method) { + case NM_SETTING_PROXY_METHOD_AUTO: + svSetValueStr(ifcfg, "PROXY_METHOD", "auto"); - pac_url = nm_setting_proxy_get_pac_url (s_proxy); - if (pac_url) - svSetValueStr (ifcfg, "PAC_URL", pac_url); + pac_url = nm_setting_proxy_get_pac_url(s_proxy); + if (pac_url) + svSetValueStr(ifcfg, "PAC_URL", pac_url); - pac_script = nm_setting_proxy_get_pac_script (s_proxy); - if (pac_script) - svSetValueStr (ifcfg, "PAC_SCRIPT", pac_script); + pac_script = nm_setting_proxy_get_pac_script(s_proxy); + if (pac_script) + svSetValueStr(ifcfg, "PAC_SCRIPT", pac_script); - break; - case NM_SETTING_PROXY_METHOD_NONE: - svSetValueStr (ifcfg, "PROXY_METHOD", "none"); - break; - } + break; + case NM_SETTING_PROXY_METHOD_NONE: + svSetValueStr(ifcfg, "PROXY_METHOD", "none"); + break; + } - svSetValueBoolean (ifcfg, "BROWSER_ONLY", nm_setting_proxy_get_browser_only (s_proxy)); + svSetValueBoolean(ifcfg, "BROWSER_ONLY", nm_setting_proxy_get_browser_only(s_proxy)); - return TRUE; + return TRUE; } static gboolean -write_user_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +write_user_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) { - NMSettingUser *s_user; - guint i, len; - const char *const*keys; + NMSettingUser * s_user; + guint i, len; + const char *const *keys; - s_user = NM_SETTING_USER (nm_connection_get_setting (connection, NM_TYPE_SETTING_USER)); + s_user = NM_SETTING_USER(nm_connection_get_setting(connection, NM_TYPE_SETTING_USER)); - if (!s_user) - return TRUE; + if (!s_user) + return TRUE; - keys = nm_setting_user_get_keys (s_user, &len); - if (len) { - nm_auto_free_gstring GString *str = g_string_sized_new (100); + keys = nm_setting_user_get_keys(s_user, &len); + if (len) { + nm_auto_free_gstring GString *str = g_string_sized_new(100); - for (i = 0; i < len; i++) { - const char *key = keys[i]; + for (i = 0; i < len; i++) { + const char *key = keys[i]; - g_string_set_size (str, 0); - g_string_append (str, "NM_USER_"); - nms_ifcfg_rh_utils_user_key_encode (key, str); - svSetValue (ifcfg, - str->str, - nm_setting_user_get_data (s_user, key)); - } - } + g_string_set_size(str, 0); + g_string_append(str, "NM_USER_"); + nms_ifcfg_rh_utils_user_key_encode(key, str); + svSetValue(ifcfg, str->str, nm_setting_user_get_data(s_user, key)); + } + } - return TRUE; + return TRUE; } static void -write_sriov_setting (NMConnection *connection, shvarFile *ifcfg) +write_sriov_setting(NMConnection *connection, shvarFile *ifcfg) { - NMSettingSriov *s_sriov; - guint i, num = 0; - NMTernary b; - NMSriovVF *vf; - char key[32]; - char *str; - - s_sriov = NM_SETTING_SRIOV (nm_connection_get_setting (connection, - NM_TYPE_SETTING_SRIOV)); - if (!s_sriov) { - return; - } - - svSetValueInt64 (ifcfg, "SRIOV_TOTAL_VFS", nm_setting_sriov_get_total_vfs (s_sriov)); - - b = nm_setting_sriov_get_autoprobe_drivers (s_sriov); - if (b != NM_TERNARY_DEFAULT) - svSetValueInt64 (ifcfg, "SRIOV_AUTOPROBE_DRIVERS", b); - - num = nm_setting_sriov_get_num_vfs (s_sriov); - for (i = 0; i < num; i++) { - vf = nm_setting_sriov_get_vf (s_sriov, i); - nm_sprintf_buf (key, "SRIOV_VF%u", nm_sriov_vf_get_index (vf)); - str = nm_utils_sriov_vf_to_str (vf, TRUE, NULL); - svSetValueStr (ifcfg, key, str); - g_free (str); - } + NMSettingSriov *s_sriov; + guint i, num = 0; + NMTernary b; + NMSriovVF * vf; + char key[32]; + char * str; + + s_sriov = NM_SETTING_SRIOV(nm_connection_get_setting(connection, NM_TYPE_SETTING_SRIOV)); + if (!s_sriov) { + return; + } + + svSetValueInt64(ifcfg, "SRIOV_TOTAL_VFS", nm_setting_sriov_get_total_vfs(s_sriov)); + + b = nm_setting_sriov_get_autoprobe_drivers(s_sriov); + if (b != NM_TERNARY_DEFAULT) + svSetValueInt64(ifcfg, "SRIOV_AUTOPROBE_DRIVERS", b); + + num = nm_setting_sriov_get_num_vfs(s_sriov); + for (i = 0; i < num; i++) { + vf = nm_setting_sriov_get_vf(s_sriov, i); + nm_sprintf_buf(key, "SRIOV_VF%u", nm_sriov_vf_get_index(vf)); + str = nm_utils_sriov_vf_to_str(vf, TRUE, NULL); + svSetValueStr(ifcfg, key, str); + g_free(str); + } } static gboolean -write_tc_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +write_tc_setting(NMConnection *connection, shvarFile *ifcfg, GError **error) { - NMSettingTCConfig *s_tc; - guint i, num, n; - char tag[64]; - - s_tc = nm_connection_get_setting_tc_config (connection); - if (!s_tc) - return TRUE; - - num = nm_setting_tc_config_get_num_qdiscs (s_tc); - for (n = 1, i = 0; i < num; i++) { - NMTCQdisc *qdisc; - gs_free char *str = NULL; - - qdisc = nm_setting_tc_config_get_qdisc (s_tc, i); - str = nm_utils_tc_qdisc_to_str (qdisc, error); - if (!str) - return FALSE; - - svSetValueStr (ifcfg, numbered_tag (tag, "QDISC", n), str); - n++; - } - - num = nm_setting_tc_config_get_num_tfilters (s_tc); - for (n = 1, i = 0; i < num; i++) { - NMTCTfilter *tfilter; - gs_free char *str = NULL; - - tfilter = nm_setting_tc_config_get_tfilter (s_tc, i); - str = nm_utils_tc_tfilter_to_str (tfilter, error); - if (!str) - return FALSE; - - svSetValueStr (ifcfg, numbered_tag (tag, "FILTER", n), str); - n++; - } - - return TRUE; + NMSettingTCConfig *s_tc; + guint i, num, n; + char tag[64]; + + s_tc = nm_connection_get_setting_tc_config(connection); + if (!s_tc) + return TRUE; + + num = nm_setting_tc_config_get_num_qdiscs(s_tc); + for (n = 1, i = 0; i < num; i++) { + NMTCQdisc * qdisc; + gs_free char *str = NULL; + + qdisc = nm_setting_tc_config_get_qdisc(s_tc, i); + str = nm_utils_tc_qdisc_to_str(qdisc, error); + if (!str) + return FALSE; + + svSetValueStr(ifcfg, numbered_tag(tag, "QDISC", n), str); + n++; + } + + num = nm_setting_tc_config_get_num_tfilters(s_tc); + for (n = 1, i = 0; i < num; i++) { + NMTCTfilter * tfilter; + gs_free char *str = NULL; + + tfilter = nm_setting_tc_config_get_tfilter(s_tc, i); + str = nm_utils_tc_tfilter_to_str(tfilter, error); + if (!str) + return FALSE; + + svSetValueStr(ifcfg, numbered_tag(tag, "FILTER", n), str); + n++; + } + + return TRUE; } static void -write_match_setting (NMConnection *connection, shvarFile *ifcfg) +write_match_setting(NMConnection *connection, shvarFile *ifcfg) { - nm_auto_free_gstring GString *str = NULL; - NMSettingMatch *s_match; - guint i, num; - const char *name; - - s_match = (NMSettingMatch *) nm_connection_get_setting (connection, NM_TYPE_SETTING_MATCH); - if (!s_match) - return; - - num = nm_setting_match_get_num_drivers (s_match); - if (num > 0) { - nm_gstring_prepare (&str); - for (i = 0; i < num; i++) { - name = nm_setting_match_get_driver (s_match, i); - nm_gstring_add_space_delimiter (str); - nm_utils_escaped_tokens_escape_gstr (name, NM_ASCII_SPACES, str); - } - svSetValueStr (ifcfg, "MATCH_DRIVER", str->str); - } - - num = nm_setting_match_get_num_interface_names (s_match); - if (num > 0) { - nm_gstring_prepare (&str); - for (i = 0; i < num; i++) { - name = nm_setting_match_get_interface_name (s_match, i); - nm_gstring_add_space_delimiter (str); - nm_utils_escaped_tokens_escape_gstr (name, NM_ASCII_SPACES, str); - } - svSetValueStr (ifcfg, "MATCH_INTERFACE_NAME", str->str); - } - - num = nm_setting_match_get_num_kernel_command_lines (s_match); - if (num > 0) { - nm_gstring_prepare (&str); - for (i = 0; i < num; i++) { - name = nm_setting_match_get_kernel_command_line (s_match, i); - nm_gstring_add_space_delimiter (str); - nm_utils_escaped_tokens_escape_gstr (name, NM_ASCII_SPACES, str); - } - svSetValueStr (ifcfg, "MATCH_KERNEL_COMMAND_LINE", str->str); - } - - num = nm_setting_match_get_num_paths (s_match); - if (num > 0) { - nm_gstring_prepare (&str); - for (i = 0; i < num; i++) { - name = nm_setting_match_get_path (s_match, i); - nm_gstring_add_space_delimiter (str); - nm_utils_escaped_tokens_escape_gstr (name, NM_ASCII_SPACES, str); - } - svSetValueStr (ifcfg, "MATCH_PATH", str->str); - } + nm_auto_free_gstring GString *str = NULL; + NMSettingMatch * s_match; + guint i, num; + const char * name; + + s_match = (NMSettingMatch *) nm_connection_get_setting(connection, NM_TYPE_SETTING_MATCH); + if (!s_match) + return; + + num = nm_setting_match_get_num_drivers(s_match); + if (num > 0) { + nm_gstring_prepare(&str); + for (i = 0; i < num; i++) { + name = nm_setting_match_get_driver(s_match, i); + nm_gstring_add_space_delimiter(str); + nm_utils_escaped_tokens_escape_gstr(name, NM_ASCII_SPACES, str); + } + svSetValueStr(ifcfg, "MATCH_DRIVER", str->str); + } + + num = nm_setting_match_get_num_interface_names(s_match); + if (num > 0) { + nm_gstring_prepare(&str); + for (i = 0; i < num; i++) { + name = nm_setting_match_get_interface_name(s_match, i); + nm_gstring_add_space_delimiter(str); + nm_utils_escaped_tokens_escape_gstr(name, NM_ASCII_SPACES, str); + } + svSetValueStr(ifcfg, "MATCH_INTERFACE_NAME", str->str); + } + + num = nm_setting_match_get_num_kernel_command_lines(s_match); + if (num > 0) { + nm_gstring_prepare(&str); + for (i = 0; i < num; i++) { + name = nm_setting_match_get_kernel_command_line(s_match, i); + nm_gstring_add_space_delimiter(str); + nm_utils_escaped_tokens_escape_gstr(name, NM_ASCII_SPACES, str); + } + svSetValueStr(ifcfg, "MATCH_KERNEL_COMMAND_LINE", str->str); + } + + num = nm_setting_match_get_num_paths(s_match); + if (num > 0) { + nm_gstring_prepare(&str); + for (i = 0; i < num; i++) { + name = nm_setting_match_get_path(s_match, i); + nm_gstring_add_space_delimiter(str); + nm_utils_escaped_tokens_escape_gstr(name, NM_ASCII_SPACES, str); + } + svSetValueStr(ifcfg, "MATCH_PATH", str->str); + } } static void -write_res_options (shvarFile *ifcfg, NMSettingIPConfig *s_ip, const char *var) +write_res_options(shvarFile *ifcfg, NMSettingIPConfig *s_ip, const char *var) { - nm_auto_free_gstring GString *value = NULL; - guint i, num_options; + nm_auto_free_gstring GString *value = NULL; + guint i, num_options; - if (!nm_setting_ip_config_has_dns_options (s_ip)) - return; + if (!nm_setting_ip_config_has_dns_options(s_ip)) + return; - value = g_string_new (NULL); - num_options = nm_setting_ip_config_get_num_dns_options (s_ip); - for (i = 0; i < num_options; i++) { - if (i > 0) - g_string_append_c (value, ' '); - g_string_append (value, nm_setting_ip_config_get_dns_option (s_ip, i)); - } + value = g_string_new(NULL); + num_options = nm_setting_ip_config_get_num_dns_options(s_ip); + for (i = 0; i < num_options; i++) { + if (i > 0) + g_string_append_c(value, ' '); + g_string_append(value, nm_setting_ip_config_get_dns_option(s_ip, i)); + } - svSetValue (ifcfg, var, value->str); + svSetValue(ifcfg, var, value->str); } static void -write_dns_setting (shvarFile *ifcfg, - NMConnection *connection, - int addr_family) +write_dns_setting(shvarFile *ifcfg, NMConnection *connection, int addr_family) { - NMSettingIPConfig *s_ip; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6 = NULL; - guint num4; - guint num6 = 0; - guint num; - guint i; - guint offset; - - if (addr_family == AF_INET6) { - s_ip6 = nm_connection_get_setting_ip6_config (connection); - num6 = s_ip6 ? nm_setting_ip_config_get_num_dns (s_ip6) : 0u; - } - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - num4 = s_ip4 ? nm_setting_ip_config_get_num_dns (s_ip4) : 0u; - - if (addr_family == AF_INET6) { - num = num6; - offset = num4; - s_ip = s_ip6; - } else { - num = num4; - offset = 0; - s_ip = s_ip4; - } - - for (i = 0; i < num; i++) { - char tag[64]; - - svSetValueStr (ifcfg, - numbered_tag (tag, "DNS", offset + i + 1u), - nm_setting_ip_config_get_dns (s_ip, i)); - } + NMSettingIPConfig *s_ip; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6 = NULL; + guint num4; + guint num6 = 0; + guint num; + guint i; + guint offset; + + if (addr_family == AF_INET6) { + s_ip6 = nm_connection_get_setting_ip6_config(connection); + num6 = s_ip6 ? nm_setting_ip_config_get_num_dns(s_ip6) : 0u; + } + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + num4 = s_ip4 ? nm_setting_ip_config_get_num_dns(s_ip4) : 0u; + + if (addr_family == AF_INET6) { + num = num6; + offset = num4; + s_ip = s_ip6; + } else { + num = num4; + offset = 0; + s_ip = s_ip4; + } + + for (i = 0; i < num; i++) { + char tag[64]; + + svSetValueStr(ifcfg, + numbered_tag(tag, "DNS", offset + i + 1u), + nm_setting_ip_config_get_dns(s_ip, i)); + } } static gboolean -write_ip4_setting (NMConnection *connection, - shvarFile *ifcfg, - shvarFile **out_route_content_svformat, - GString **out_route_content, - GError **error) +write_ip4_setting(NMConnection *connection, + shvarFile * ifcfg, + shvarFile ** out_route_content_svformat, + GString ** out_route_content, + GError ** error) { - NMSettingIPConfig *s_ip4; - const char *value; - char *tmp; - char tag[64]; - int j; - guint i, num, n; - gint64 route_metric; - NMIPRouteTableSyncMode route_table; - int priority; - int timeout; - GString *searches; - const char *method = NULL; - gboolean has_netmask; - NMDhcpHostnameFlags flags; - - NM_SET_OUT (out_route_content_svformat, NULL); - NM_SET_OUT (out_route_content, NULL); - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (!s_ip4) - return TRUE; - - method = nm_setting_ip_config_get_method (s_ip4); - - /* Missing IP4 setting is assumed to be DHCP */ - if (!method) - method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; - - if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) - return TRUE; - - num = nm_setting_ip_config_get_num_addresses (s_ip4); - - if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) - svSetValueStr (ifcfg, "BOOTPROTO", "dhcp"); - else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { - /* Preserve the archaic form of "static" if there actually - * is static configuration. */ - if (g_strcmp0 (svGetValue (ifcfg, "BOOTPROTO", &tmp), "static") || !num) - svSetValueStr (ifcfg, "BOOTPROTO", "none"); - g_free (tmp); - } else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) - svSetValueStr (ifcfg, "BOOTPROTO", "autoip"); - else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) - svSetValueStr (ifcfg, "BOOTPROTO", "shared"); - - has_netmask = !!svFindFirstNumberedKey (ifcfg, "NETMASK"); - - /* Write out IPADDR, PREFIX, GATEWAY for current IP addresses - * without labels. Unset obsolete NETMASK. - */ - for (i = n = 0; i < num; i++) { - NMIPAddress *addr; - guint prefix; - - addr = nm_setting_ip_config_get_address (s_ip4, i); - - if (i > 0) { - GVariant *label; - - label = nm_ip_address_get_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); - if (label) - continue; - } - - if (n == 0) { - /* Instead of index 0 use un-numbered variables. - * It's needed for compatibility with ifup that only recognizes 'GATEAWAY' - * See https://bugzilla.redhat.com/show_bug.cgi?id=771673 - * and https://bugzilla.redhat.com/show_bug.cgi?id=1105770 - */ - j = -1; - } else - j = n; - - svSetValueStr (ifcfg, - numbered_tag (tag, "IPADDR", j), - nm_ip_address_get_address (addr)); - - prefix = nm_ip_address_get_prefix (addr); - svSetValueInt64 (ifcfg, numbered_tag (tag, "PREFIX", j), prefix); - - /* If the legacy "NETMASK" is present, keep it. */ - numbered_tag (tag, "NETMASK", j); - if (has_netmask) { - char buf[INET_ADDRSTRLEN]; - - svSetValueStr (ifcfg, tag, - _nm_utils_inet4_ntop (_nm_utils_ip4_prefix_to_netmask (prefix), buf)); - } - - n++; - } - - svSetValueStr (ifcfg, "GATEWAY", nm_setting_ip_config_get_gateway (s_ip4)); - - write_dns_setting (ifcfg, connection, AF_INET); - - num = nm_setting_ip_config_get_num_dns_searches (s_ip4); - if (num > 0) { - searches = g_string_new (NULL); - for (i = 0; i < num; i++) { - if (i > 0) - g_string_append_c (searches, ' '); - g_string_append (searches, nm_setting_ip_config_get_dns_search (s_ip4, i)); - } - svSetValueStr (ifcfg, "DOMAIN", searches->str); - g_string_free (searches, TRUE); - } - - /* DEFROUTE; remember that it has the opposite meaning from never-default */ - svSetValueBoolean (ifcfg, "DEFROUTE", !nm_setting_ip_config_get_never_default (s_ip4)); - - /* Missing PEERDNS means TRUE, so write it only when is FALSE */ - svSetValueStr (ifcfg, "PEERDNS", - nm_setting_ip_config_get_ignore_auto_dns (s_ip4) ? "no" : NULL); - /* Missing PEERROUTES means TRUE, so write it only when is FALSE */ - svSetValueStr (ifcfg, "PEERROUTES", - nm_setting_ip_config_get_ignore_auto_routes (s_ip4) ? "no" : NULL); - - value = nm_setting_ip_config_get_dhcp_hostname (s_ip4); - svSetValueStr (ifcfg, "DHCP_HOSTNAME", value); - - value = nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG (s_ip4)); - svSetValueStr (ifcfg, "DHCP_FQDN", value); - - flags = nm_setting_ip_config_get_dhcp_hostname_flags (s_ip4); - svSetValueInt64_cond (ifcfg, - "DHCP_HOSTNAME_FLAGS", - flags != NM_DHCP_HOSTNAME_FLAG_NONE, - flags); - - /* Missing DHCP_SEND_HOSTNAME means TRUE, and we prefer not write it explicitly - * in that case, because it is NM-specific variable - */ - svSetValueStr (ifcfg, "DHCP_SEND_HOSTNAME", - nm_setting_ip_config_get_dhcp_send_hostname (s_ip4) ? NULL : "no"); - - value = nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4)); - svSetValueStr (ifcfg, "DHCP_CLIENT_ID", value); - - value = nm_setting_ip_config_get_dhcp_iaid (s_ip4); - svSetValueStr (ifcfg, "DHCP_IAID", value); - - timeout = nm_setting_ip_config_get_dhcp_timeout (s_ip4); - svSetValueInt64_cond (ifcfg, - "IPV4_DHCP_TIMEOUT", - timeout != 0, - timeout); - - svSetValueBoolean (ifcfg, "IPV4_FAILURE_FATAL", !nm_setting_ip_config_get_may_fail (s_ip4)); - - route_metric = nm_setting_ip_config_get_route_metric (s_ip4); - svSetValueInt64_cond (ifcfg, - "IPV4_ROUTE_METRIC", - route_metric != -1, - route_metric); - - route_table = nm_setting_ip_config_get_route_table (s_ip4); - svSetValueInt64_cond (ifcfg, - "IPV4_ROUTE_TABLE", - route_table != 0, - route_table); - - NM_SET_OUT (out_route_content_svformat, write_route_file_svformat (svFileGetName (ifcfg), s_ip4)); - NM_SET_OUT (out_route_content, write_route_file (s_ip4)); - - timeout = nm_setting_ip_config_get_dad_timeout (s_ip4); - if (timeout < 0) { - /* pass */ - } else if (timeout == 0) { - svSetValueStr (ifcfg, "ACD_TIMEOUT", "0"); - svSetValueStr (ifcfg, "ARPING_WAIT", "0"); - } else { - svSetValueInt64 (ifcfg, "ACD_TIMEOUT", timeout); - /* Round the value up to next integer for initscripts */ - svSetValueInt64 (ifcfg, "ARPING_WAIT", (timeout - 1) / 1000 + 1); - } - - priority = nm_setting_ip_config_get_dns_priority (s_ip4); - if (priority) - svSetValueInt64 (ifcfg, "IPV4_DNS_PRIORITY", priority); - - write_res_options (ifcfg, s_ip4, "RES_OPTIONS"); - - return TRUE; + NMSettingIPConfig * s_ip4; + const char * value; + char * tmp; + char tag[64]; + int j; + guint i, num, n; + gint64 route_metric; + NMIPRouteTableSyncMode route_table; + int priority; + int timeout; + nm_auto_free_gstring GString *str = NULL; + const char * method = NULL; + gboolean has_netmask; + NMDhcpHostnameFlags flags; + const char *const * strv; + + NM_SET_OUT(out_route_content_svformat, NULL); + NM_SET_OUT(out_route_content, NULL); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + if (!s_ip4) + return TRUE; + + method = nm_setting_ip_config_get_method(s_ip4); + + /* Missing IP4 setting is assumed to be DHCP */ + if (!method) + method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + + if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) + return TRUE; + + num = nm_setting_ip_config_get_num_addresses(s_ip4); + + if (!strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) + svSetValueStr(ifcfg, "BOOTPROTO", "dhcp"); + else if (!strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + /* Preserve the archaic form of "static" if there actually + * is static configuration. */ + if (g_strcmp0(svGetValue(ifcfg, "BOOTPROTO", &tmp), "static") || !num) + svSetValueStr(ifcfg, "BOOTPROTO", "none"); + g_free(tmp); + } else if (!strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) + svSetValueStr(ifcfg, "BOOTPROTO", "autoip"); + else if (!strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) + svSetValueStr(ifcfg, "BOOTPROTO", "shared"); + + has_netmask = !!svFindFirstNumberedKey(ifcfg, "NETMASK"); + + /* Write out IPADDR, PREFIX, GATEWAY for current IP addresses + * without labels. Unset obsolete NETMASK. + */ + for (i = n = 0; i < num; i++) { + NMIPAddress *addr; + guint prefix; + + addr = nm_setting_ip_config_get_address(s_ip4, i); + + if (i > 0) { + GVariant *label; + + label = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + if (label) + continue; + } + + if (n == 0) { + /* Instead of index 0 use un-numbered variables. + * It's needed for compatibility with ifup that only recognizes 'GATEAWAY' + * See https://bugzilla.redhat.com/show_bug.cgi?id=771673 + * and https://bugzilla.redhat.com/show_bug.cgi?id=1105770 + */ + j = -1; + } else + j = n; + + svSetValueStr(ifcfg, numbered_tag(tag, "IPADDR", j), nm_ip_address_get_address(addr)); + + prefix = nm_ip_address_get_prefix(addr); + svSetValueInt64(ifcfg, numbered_tag(tag, "PREFIX", j), prefix); + + /* If the legacy "NETMASK" is present, keep it. */ + numbered_tag(tag, "NETMASK", j); + if (has_netmask) { + char buf[INET_ADDRSTRLEN]; + + svSetValueStr(ifcfg, + tag, + _nm_utils_inet4_ntop(_nm_utils_ip4_prefix_to_netmask(prefix), buf)); + } + + n++; + } + + svSetValueStr(ifcfg, "GATEWAY", nm_setting_ip_config_get_gateway(s_ip4)); + + write_dns_setting(ifcfg, connection, AF_INET); + + num = nm_setting_ip_config_get_num_dns_searches(s_ip4); + if (num > 0) { + nm_gstring_prepare(&str); + for (i = 0; i < num; i++) { + nm_gstring_add_space_delimiter(str); + g_string_append(str, nm_setting_ip_config_get_dns_search(s_ip4, i)); + } + svSetValueStr(ifcfg, "DOMAIN", str->str); + } + + /* DEFROUTE; remember that it has the opposite meaning from never-default */ + svSetValueBoolean(ifcfg, "DEFROUTE", !nm_setting_ip_config_get_never_default(s_ip4)); + + /* Missing PEERDNS means TRUE, so write it only when is FALSE */ + svSetValueStr(ifcfg, "PEERDNS", nm_setting_ip_config_get_ignore_auto_dns(s_ip4) ? "no" : NULL); + /* Missing PEERROUTES means TRUE, so write it only when is FALSE */ + svSetValueStr(ifcfg, + "PEERROUTES", + nm_setting_ip_config_get_ignore_auto_routes(s_ip4) ? "no" : NULL); + + value = nm_setting_ip_config_get_dhcp_hostname(s_ip4); + svSetValueStr(ifcfg, "DHCP_HOSTNAME", value); + + value = nm_setting_ip4_config_get_dhcp_fqdn(NM_SETTING_IP4_CONFIG(s_ip4)); + svSetValueStr(ifcfg, "DHCP_FQDN", value); + + flags = nm_setting_ip_config_get_dhcp_hostname_flags(s_ip4); + svSetValueInt64_cond(ifcfg, "DHCP_HOSTNAME_FLAGS", flags != NM_DHCP_HOSTNAME_FLAG_NONE, flags); + + /* Missing DHCP_SEND_HOSTNAME means TRUE, and we prefer not write it explicitly + * in that case, because it is NM-specific variable + */ + svSetValueStr(ifcfg, + "DHCP_SEND_HOSTNAME", + nm_setting_ip_config_get_dhcp_send_hostname(s_ip4) ? NULL : "no"); + + value = nm_setting_ip4_config_get_dhcp_client_id(NM_SETTING_IP4_CONFIG(s_ip4)); + svSetValueStr(ifcfg, "DHCP_CLIENT_ID", value); + + svSetValue( + ifcfg, + "DHCP_VENDOR_CLASS_IDENTIFIER", + nm_setting_ip4_config_get_dhcp_vendor_class_identifier(NM_SETTING_IP4_CONFIG(s_ip4))); + + value = nm_setting_ip_config_get_dhcp_iaid(s_ip4); + svSetValueStr(ifcfg, "DHCP_IAID", value); + + timeout = nm_setting_ip_config_get_dhcp_timeout(s_ip4); + svSetValueInt64_cond(ifcfg, "IPV4_DHCP_TIMEOUT", timeout != 0, timeout); + + svSetValueBoolean(ifcfg, "IPV4_FAILURE_FATAL", !nm_setting_ip_config_get_may_fail(s_ip4)); + + route_metric = nm_setting_ip_config_get_route_metric(s_ip4); + svSetValueInt64_cond(ifcfg, "IPV4_ROUTE_METRIC", route_metric != -1, route_metric); + + route_table = nm_setting_ip_config_get_route_table(s_ip4); + svSetValueInt64_cond(ifcfg, "IPV4_ROUTE_TABLE", route_table != 0, route_table); + + NM_SET_OUT(out_route_content_svformat, write_route_file_svformat(svFileGetName(ifcfg), s_ip4)); + NM_SET_OUT(out_route_content, write_route_file(s_ip4)); + + timeout = nm_setting_ip_config_get_dad_timeout(s_ip4); + if (timeout < 0) { + /* pass */ + } else if (timeout == 0) { + svSetValueStr(ifcfg, "ACD_TIMEOUT", "0"); + svSetValueStr(ifcfg, "ARPING_WAIT", "0"); + } else { + svSetValueInt64(ifcfg, "ACD_TIMEOUT", timeout); + /* Round the value up to next integer for initscripts */ + svSetValueInt64(ifcfg, "ARPING_WAIT", (timeout - 1) / 1000 + 1); + } + + priority = nm_setting_ip_config_get_dns_priority(s_ip4); + if (priority) + svSetValueInt64(ifcfg, "IPV4_DNS_PRIORITY", priority); + + write_res_options(ifcfg, s_ip4, "RES_OPTIONS"); + + strv = nm_setting_ip_config_get_dhcp_reject_servers(s_ip4, &num); + if (num > 0) { + nm_gstring_prepare(&str); + for (i = 0; i < num; i++) { + nm_gstring_add_space_delimiter(str); + nm_utils_escaped_tokens_escape_gstr(strv[i], NM_ASCII_SPACES, str); + } + svSetValueStr(ifcfg, "DHCP_REJECT_SERVERS", str->str); + } + + return TRUE; } static void -write_ip4_aliases (NMConnection *connection, const char *base_ifcfg_path) +write_ip4_aliases(NMConnection *connection, const char *base_ifcfg_path) { - NMSettingIPConfig *s_ip4; - gs_free char *base_ifcfg_dir = NULL, *base_ifcfg_name = NULL; - const char *base_name; - int i, num, base_ifcfg_name_len, base_name_len; - GDir *dir; - - base_ifcfg_dir = g_path_get_dirname (base_ifcfg_path); - base_ifcfg_name = g_path_get_basename (base_ifcfg_path); - base_ifcfg_name_len = strlen (base_ifcfg_name); - if (!g_str_has_prefix (base_ifcfg_name, IFCFG_TAG)) - g_return_if_reached (); - base_name = base_ifcfg_name + strlen (IFCFG_TAG); - base_name_len = strlen (base_name); - - /* Remove all existing aliases for this file first */ - dir = g_dir_open (base_ifcfg_dir, 0, NULL); - if (dir) { - const char *item; - - while ((item = g_dir_read_name (dir))) { - char *full_path; - - if ( strncmp (item, base_ifcfg_name, base_ifcfg_name_len) != 0 - || item[base_ifcfg_name_len] != ':') - continue; - - full_path = g_build_filename (base_ifcfg_dir, item, NULL); - unlink (full_path); - g_free (full_path); - } - - g_dir_close (dir); - } - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (!s_ip4) { - /* slave-type: no alias files */ - return; - } - - num = nm_setting_ip_config_get_num_addresses (s_ip4); - for (i = 0; i < num; i++) { - GVariant *label_var; - const char *label, *p; - char *path; - NMIPAddress *addr; - shvarFile *ifcfg; - - addr = nm_setting_ip_config_get_address (s_ip4, i); - - label_var = nm_ip_address_get_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); - if (!label_var) - continue; - label = g_variant_get_string (label_var, NULL); - if ( strncmp (label, base_name, base_name_len) != 0 - || label[base_name_len] != ':') - continue; - - for (p = label; *p; p++) { - if (!g_ascii_isalnum (*p) && *p != '_' && *p != ':') - break; - } - if (*p) - continue; - - path = g_strdup_printf ("%s%s", base_ifcfg_path, label + base_name_len); - ifcfg = svCreateFile (path); - g_free (path); - - svSetValueStr (ifcfg, "DEVICE", label); - - addr = nm_setting_ip_config_get_address (s_ip4, i); - svSetValueStr (ifcfg, "IPADDR", nm_ip_address_get_address (addr)); - - svSetValueInt64 (ifcfg, "PREFIX", nm_ip_address_get_prefix(addr)); - - svWriteFileWithoutDirtyWellknown (ifcfg, 0644, NULL); - svCloseFile (ifcfg); - } + NMSettingIPConfig *s_ip4; + gs_free char * base_ifcfg_dir = NULL, *base_ifcfg_name = NULL; + const char * base_name; + int i, num, base_ifcfg_name_len, base_name_len; + GDir * dir; + + base_ifcfg_dir = g_path_get_dirname(base_ifcfg_path); + base_ifcfg_name = g_path_get_basename(base_ifcfg_path); + base_ifcfg_name_len = strlen(base_ifcfg_name); + if (!g_str_has_prefix(base_ifcfg_name, IFCFG_TAG)) + g_return_if_reached(); + base_name = base_ifcfg_name + strlen(IFCFG_TAG); + base_name_len = strlen(base_name); + + /* Remove all existing aliases for this file first */ + dir = g_dir_open(base_ifcfg_dir, 0, NULL); + if (dir) { + const char *item; + + while ((item = g_dir_read_name(dir))) { + char *full_path; + + if (strncmp(item, base_ifcfg_name, base_ifcfg_name_len) != 0 + || item[base_ifcfg_name_len] != ':') + continue; + + full_path = g_build_filename(base_ifcfg_dir, item, NULL); + unlink(full_path); + g_free(full_path); + } + + g_dir_close(dir); + } + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + if (!s_ip4) { + /* slave-type: no alias files */ + return; + } + + num = nm_setting_ip_config_get_num_addresses(s_ip4); + for (i = 0; i < num; i++) { + GVariant * label_var; + const char * label, *p; + char * path; + NMIPAddress *addr; + shvarFile * ifcfg; + + addr = nm_setting_ip_config_get_address(s_ip4, i); + + label_var = nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + if (!label_var) + continue; + label = g_variant_get_string(label_var, NULL); + if (strncmp(label, base_name, base_name_len) != 0 || label[base_name_len] != ':') + continue; + + for (p = label; *p; p++) { + if (!g_ascii_isalnum(*p) && *p != '_' && *p != ':') + break; + } + if (*p) + continue; + + path = g_strdup_printf("%s%s", base_ifcfg_path, label + base_name_len); + ifcfg = svCreateFile(path); + g_free(path); + + svSetValueStr(ifcfg, "DEVICE", label); + + addr = nm_setting_ip_config_get_address(s_ip4, i); + svSetValueStr(ifcfg, "IPADDR", nm_ip_address_get_address(addr)); + + svSetValueInt64(ifcfg, "PREFIX", nm_ip_address_get_prefix(addr)); + + svWriteFileWithoutDirtyWellknown(ifcfg, 0644, NULL); + svCloseFile(ifcfg); + } } static gboolean -write_ip6_setting (NMConnection *connection, - shvarFile *ifcfg, - GString **out_route6_content, - GError **error) +write_ip6_setting(NMConnection *connection, + shvarFile * ifcfg, + GString ** out_route6_content, + GError ** error) { - NMSettingIPConfig *s_ip6; - const char *value; - guint i, num; - int priority; - NMIPAddress *addr; - gint64 route_metric; - NMIPRouteTableSyncMode route_table; - GString *ip_str1, *ip_str2, *ip_ptr; - NMSettingIP6ConfigAddrGenMode addr_gen_mode; - NMDhcpHostnameFlags flags; - const char *hostname; - int timeout; - - NM_SET_OUT (out_route6_content, NULL); - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (!s_ip6) - return TRUE; - - value = nm_setting_ip_config_get_method (s_ip6); - g_assert (value); - if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { - svSetValueStr (ifcfg, "IPV6INIT", "no"); - return TRUE; - } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { - svSetValueStr (ifcfg, "IPV6_DISABLED", "yes"); - svSetValueStr (ifcfg, "IPV6INIT", "no"); - return TRUE; - } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { - svSetValueStr (ifcfg, "IPV6INIT", "yes"); - svSetValueStr (ifcfg, "IPV6_AUTOCONF", "yes"); - } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { - svSetValueStr (ifcfg, "IPV6INIT", "yes"); - svSetValueStr (ifcfg, "IPV6_AUTOCONF", "no"); - svSetValueStr (ifcfg, "DHCPV6C", "yes"); - } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { - svSetValueStr (ifcfg, "IPV6INIT", "yes"); - svSetValueStr (ifcfg, "IPV6_AUTOCONF", "no"); - } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) { - svSetValueStr (ifcfg, "IPV6INIT", "yes"); - svSetValueStr (ifcfg, "IPV6_AUTOCONF", "no"); - } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { - svSetValueStr (ifcfg, "IPV6INIT", "yes"); - svSetValueStr (ifcfg, "IPV6_AUTOCONF", "shared"); - } - - svSetValueStr (ifcfg, "DHCPV6_DUID", - nm_setting_ip6_config_get_dhcp_duid (NM_SETTING_IP6_CONFIG (s_ip6))); - svSetValueStr (ifcfg, "DHCPV6_IAID", - nm_setting_ip_config_get_dhcp_iaid (s_ip6)); - - hostname = nm_setting_ip_config_get_dhcp_hostname (s_ip6); - svSetValueStr (ifcfg, "DHCPV6_HOSTNAME", hostname); - - /* Missing DHCPV6_SEND_HOSTNAME means TRUE, and we prefer not write it - * explicitly in that case, because it is NM-specific variable - */ - if (!nm_setting_ip_config_get_dhcp_send_hostname (s_ip6)) - svSetValueStr (ifcfg, "DHCPV6_SEND_HOSTNAME", "no"); - - timeout = nm_setting_ip6_config_get_ra_timeout (NM_SETTING_IP6_CONFIG (s_ip6)); - svSetValueInt64_cond (ifcfg, - "IPV6_RA_TIMEOUT", - timeout != 0, - timeout); - - timeout = nm_setting_ip_config_get_dhcp_timeout (s_ip6); - svSetValueInt64_cond (ifcfg, - "IPV6_DHCP_TIMEOUT", - timeout != 0, - timeout); - - flags = nm_setting_ip_config_get_dhcp_hostname_flags (s_ip6); - svSetValueInt64_cond (ifcfg, - "DHCPV6_HOSTNAME_FLAGS", - flags != NM_DHCP_HOSTNAME_FLAG_NONE, - flags); - - /* Write out IP addresses */ - num = nm_setting_ip_config_get_num_addresses (s_ip6); - ip_str1 = g_string_new (NULL); - ip_str2 = g_string_new (NULL); - for (i = 0; i < num; i++) { - if (i == 0) - ip_ptr = ip_str1; - else - ip_ptr = ip_str2; - - addr = nm_setting_ip_config_get_address (s_ip6, i); - - if (i > 1) - g_string_append_c (ip_ptr, ' '); /* separate addresses in IPV6ADDR_SECONDARIES */ - g_string_append_printf (ip_ptr, "%s/%u", - nm_ip_address_get_address (addr), - nm_ip_address_get_prefix (addr)); - } - svSetValueStr (ifcfg, "IPV6ADDR", ip_str1->str); - svSetValueStr (ifcfg, "IPV6ADDR_SECONDARIES", ip_str2->str); - svSetValueStr (ifcfg, "IPV6_DEFAULTGW", nm_setting_ip_config_get_gateway (s_ip6)); - g_string_free (ip_str1, TRUE); - g_string_free (ip_str2, TRUE); - - write_dns_setting (ifcfg, connection, AF_INET6); - - /* Write out DNS domains */ - num = nm_setting_ip_config_get_num_dns_searches (s_ip6); - if (num > 0) { - nm_auto_free_gstring GString *searches = NULL; - - searches = g_string_new (NULL); - for (i = 0; i < num; i++) { - if (searches->len > 0) - g_string_append_c (searches, ' '); - g_string_append (searches, nm_setting_ip_config_get_dns_search (s_ip6, i)); - } - svSetValueStr (ifcfg, "IPV6_DOMAIN", searches->str); - } - - /* handle IPV6_DEFROUTE */ - /* IPV6_DEFROUTE has the opposite meaning from 'never-default' */ - svSetValueBoolean (ifcfg, "IPV6_DEFROUTE", !nm_setting_ip_config_get_never_default (s_ip6)); - - svSetValueStr (ifcfg, "IPV6_PEERDNS", - nm_setting_ip_config_get_ignore_auto_dns (s_ip6) ? "no" : NULL); - - svSetValueStr (ifcfg, "IPV6_PEERROUTES", - nm_setting_ip_config_get_ignore_auto_routes (s_ip6) ? "no" : NULL); - - svSetValueStr (ifcfg, "IPV6_FAILURE_FATAL", - nm_setting_ip_config_get_may_fail (s_ip6) ? "no" : "yes"); - - route_metric = nm_setting_ip_config_get_route_metric (s_ip6); - svSetValueInt64_cond (ifcfg, - "IPV6_ROUTE_METRIC", - route_metric != -1, - route_metric); - - route_table = nm_setting_ip_config_get_route_table (s_ip6); - svSetValueInt64_cond (ifcfg, - "IPV6_ROUTE_TABLE", - route_table != 0, - route_table); - - /* IPv6 Privacy Extensions */ - switch (nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6))) { - case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: - svSetValueStr (ifcfg, "IPV6_PRIVACY", "no"); - break; - case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR: - svSetValueStr (ifcfg, "IPV6_PRIVACY", "rfc3041"); - svSetValueStr (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", "yes"); - break; - case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR: - svSetValueStr (ifcfg, "IPV6_PRIVACY", "rfc3041"); - break; - default: - break; - } - - /* IPv6 Address generation mode */ - addr_gen_mode = nm_setting_ip6_config_get_addr_gen_mode (NM_SETTING_IP6_CONFIG (s_ip6)); - if (addr_gen_mode != NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) { - svSetValueEnum (ifcfg, "IPV6_ADDR_GEN_MODE", nm_setting_ip6_config_addr_gen_mode_get_type (), - addr_gen_mode); - } - - /* IPv6 tokenized interface identifier */ - value = nm_setting_ip6_config_get_token (NM_SETTING_IP6_CONFIG (s_ip6)); - svSetValueStr (ifcfg, "IPV6_TOKEN", value); - - priority = nm_setting_ip_config_get_dns_priority (s_ip6); - if (priority) - svSetValueInt64 (ifcfg, "IPV6_DNS_PRIORITY", priority); - - write_res_options (ifcfg, s_ip6, "IPV6_RES_OPTIONS"); - - NM_SET_OUT (out_route6_content, write_route_file (s_ip6)); - - return TRUE; + NMSettingIPConfig * s_ip6; + const char * value; + guint i, num; + int priority; + NMIPAddress * addr; + gint64 route_metric; + NMIPRouteTableSyncMode route_table; + GString * ip_str1, *ip_str2, *ip_ptr; + NMSettingIP6ConfigAddrGenMode addr_gen_mode; + NMDhcpHostnameFlags flags; + const char * hostname; + int timeout; + + NM_SET_OUT(out_route6_content, NULL); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + if (!s_ip6) + return TRUE; + + value = nm_setting_ip_config_get_method(s_ip6); + g_assert(value); + if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { + svSetValueStr(ifcfg, "IPV6INIT", "no"); + return TRUE; + } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { + svSetValueStr(ifcfg, "IPV6_DISABLED", "yes"); + svSetValueStr(ifcfg, "IPV6INIT", "no"); + return TRUE; + } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { + svSetValueStr(ifcfg, "IPV6INIT", "yes"); + svSetValueStr(ifcfg, "IPV6_AUTOCONF", "yes"); + } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { + svSetValueStr(ifcfg, "IPV6INIT", "yes"); + svSetValueStr(ifcfg, "IPV6_AUTOCONF", "no"); + svSetValueStr(ifcfg, "DHCPV6C", "yes"); + } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + svSetValueStr(ifcfg, "IPV6INIT", "yes"); + svSetValueStr(ifcfg, "IPV6_AUTOCONF", "no"); + } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) { + svSetValueStr(ifcfg, "IPV6INIT", "yes"); + svSetValueStr(ifcfg, "IPV6_AUTOCONF", "no"); + } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { + svSetValueStr(ifcfg, "IPV6INIT", "yes"); + svSetValueStr(ifcfg, "IPV6_AUTOCONF", "shared"); + } + + svSetValueStr(ifcfg, + "DHCPV6_DUID", + nm_setting_ip6_config_get_dhcp_duid(NM_SETTING_IP6_CONFIG(s_ip6))); + svSetValueStr(ifcfg, "DHCPV6_IAID", nm_setting_ip_config_get_dhcp_iaid(s_ip6)); + + hostname = nm_setting_ip_config_get_dhcp_hostname(s_ip6); + svSetValueStr(ifcfg, "DHCPV6_HOSTNAME", hostname); + + /* Missing DHCPV6_SEND_HOSTNAME means TRUE, and we prefer not write it + * explicitly in that case, because it is NM-specific variable + */ + if (!nm_setting_ip_config_get_dhcp_send_hostname(s_ip6)) + svSetValueStr(ifcfg, "DHCPV6_SEND_HOSTNAME", "no"); + + timeout = nm_setting_ip6_config_get_ra_timeout(NM_SETTING_IP6_CONFIG(s_ip6)); + svSetValueInt64_cond(ifcfg, "IPV6_RA_TIMEOUT", timeout != 0, timeout); + + timeout = nm_setting_ip_config_get_dhcp_timeout(s_ip6); + svSetValueInt64_cond(ifcfg, "IPV6_DHCP_TIMEOUT", timeout != 0, timeout); + + flags = nm_setting_ip_config_get_dhcp_hostname_flags(s_ip6); + svSetValueInt64_cond(ifcfg, + "DHCPV6_HOSTNAME_FLAGS", + flags != NM_DHCP_HOSTNAME_FLAG_NONE, + flags); + + /* Write out IP addresses */ + num = nm_setting_ip_config_get_num_addresses(s_ip6); + ip_str1 = g_string_new(NULL); + ip_str2 = g_string_new(NULL); + for (i = 0; i < num; i++) { + if (i == 0) + ip_ptr = ip_str1; + else + ip_ptr = ip_str2; + + addr = nm_setting_ip_config_get_address(s_ip6, i); + + if (i > 1) + g_string_append_c(ip_ptr, ' '); /* separate addresses in IPV6ADDR_SECONDARIES */ + g_string_append_printf(ip_ptr, + "%s/%u", + nm_ip_address_get_address(addr), + nm_ip_address_get_prefix(addr)); + } + svSetValueStr(ifcfg, "IPV6ADDR", ip_str1->str); + svSetValueStr(ifcfg, "IPV6ADDR_SECONDARIES", ip_str2->str); + svSetValueStr(ifcfg, "IPV6_DEFAULTGW", nm_setting_ip_config_get_gateway(s_ip6)); + g_string_free(ip_str1, TRUE); + g_string_free(ip_str2, TRUE); + + write_dns_setting(ifcfg, connection, AF_INET6); + + /* Write out DNS domains */ + num = nm_setting_ip_config_get_num_dns_searches(s_ip6); + if (num > 0) { + nm_auto_free_gstring GString *searches = NULL; + + searches = g_string_new(NULL); + for (i = 0; i < num; i++) { + if (searches->len > 0) + g_string_append_c(searches, ' '); + g_string_append(searches, nm_setting_ip_config_get_dns_search(s_ip6, i)); + } + svSetValueStr(ifcfg, "IPV6_DOMAIN", searches->str); + } + + /* handle IPV6_DEFROUTE */ + /* IPV6_DEFROUTE has the opposite meaning from 'never-default' */ + svSetValueBoolean(ifcfg, "IPV6_DEFROUTE", !nm_setting_ip_config_get_never_default(s_ip6)); + + svSetValueStr(ifcfg, + "IPV6_PEERDNS", + nm_setting_ip_config_get_ignore_auto_dns(s_ip6) ? "no" : NULL); + + svSetValueStr(ifcfg, + "IPV6_PEERROUTES", + nm_setting_ip_config_get_ignore_auto_routes(s_ip6) ? "no" : NULL); + + svSetValueStr(ifcfg, + "IPV6_FAILURE_FATAL", + nm_setting_ip_config_get_may_fail(s_ip6) ? "no" : "yes"); + + route_metric = nm_setting_ip_config_get_route_metric(s_ip6); + svSetValueInt64_cond(ifcfg, "IPV6_ROUTE_METRIC", route_metric != -1, route_metric); + + route_table = nm_setting_ip_config_get_route_table(s_ip6); + svSetValueInt64_cond(ifcfg, "IPV6_ROUTE_TABLE", route_table != 0, route_table); + + /* IPv6 Privacy Extensions */ + switch (nm_setting_ip6_config_get_ip6_privacy(NM_SETTING_IP6_CONFIG(s_ip6))) { + case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: + svSetValueStr(ifcfg, "IPV6_PRIVACY", "no"); + break; + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR: + svSetValueStr(ifcfg, "IPV6_PRIVACY", "rfc3041"); + svSetValueStr(ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", "yes"); + break; + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR: + svSetValueStr(ifcfg, "IPV6_PRIVACY", "rfc3041"); + break; + default: + break; + } + + /* IPv6 Address generation mode */ + addr_gen_mode = nm_setting_ip6_config_get_addr_gen_mode(NM_SETTING_IP6_CONFIG(s_ip6)); + if (addr_gen_mode != NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) { + svSetValueEnum(ifcfg, + "IPV6_ADDR_GEN_MODE", + nm_setting_ip6_config_addr_gen_mode_get_type(), + addr_gen_mode); + } + + /* IPv6 tokenized interface identifier */ + value = nm_setting_ip6_config_get_token(NM_SETTING_IP6_CONFIG(s_ip6)); + svSetValueStr(ifcfg, "IPV6_TOKEN", value); + + priority = nm_setting_ip_config_get_dns_priority(s_ip6); + if (priority) + svSetValueInt64(ifcfg, "IPV6_DNS_PRIORITY", priority); + + write_res_options(ifcfg, s_ip6, "IPV6_RES_OPTIONS"); + + NM_SET_OUT(out_route6_content, write_route_file(s_ip6)); + + return TRUE; } static void -write_ip_routing_rules (NMConnection *connection, - shvarFile *ifcfg, - gboolean route_ignore) +write_ip_routing_rules(NMConnection *connection, shvarFile *ifcfg, gboolean route_ignore) { - gsize idx; - int is_ipv4; - - if (route_ignore) - return; - - idx = 0; - - for (is_ipv4 = 1; is_ipv4 >= 0; is_ipv4--) { - const int addr_family = is_ipv4 ? AF_INET : AF_INET6; - NMSettingIPConfig *s_ip; - guint i, num; - - s_ip = nm_connection_get_setting_ip_config (connection, addr_family); - if (!s_ip) - continue; - - num = nm_setting_ip_config_get_num_routing_rules (s_ip); - for (i = 0; i < num; i++) { - NMIPRoutingRule *rule = nm_setting_ip_config_get_routing_rule (s_ip, i); - gs_free const char *s = NULL; - char key[64]; - - s = nm_ip_routing_rule_to_string (rule, - NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE, - NULL, - NULL); - if (!s) - continue; - - if (is_ipv4) - numbered_tag (key, "ROUTING_RULE_", ++idx); - else - numbered_tag (key, "ROUTING_RULE6_", ++idx); - svSetValueStr (ifcfg, key, s); - } - } + gsize idx; + int is_ipv4; + + if (route_ignore) + return; + + idx = 0; + + for (is_ipv4 = 1; is_ipv4 >= 0; is_ipv4--) { + const int addr_family = is_ipv4 ? AF_INET : AF_INET6; + NMSettingIPConfig *s_ip; + guint i, num; + + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); + if (!s_ip) + continue; + + num = nm_setting_ip_config_get_num_routing_rules(s_ip); + for (i = 0; i < num; i++) { + NMIPRoutingRule * rule = nm_setting_ip_config_get_routing_rule(s_ip, i); + gs_free const char *s = NULL; + char key[64]; + + s = nm_ip_routing_rule_to_string(rule, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE, + NULL, + NULL); + if (!s) + continue; + + if (is_ipv4) + numbered_tag(key, "ROUTING_RULE_", ++idx); + else + numbered_tag(key, "ROUTING_RULE6_", ++idx); + svSetValueStr(ifcfg, key, s); + } + } } static char * -escape_id (const char *id) +escape_id(const char *id) { - char *escaped = g_strdup (id); - char *p = escaped; - - /* Escape random stuff */ - while (*p) { - if (*p == ' ') - *p = '_'; - else if (strchr ("\\][|/=()!:", *p)) - *p = '-'; - p++; - } - - return escaped; + char *escaped = g_strdup(id); + char *p = escaped; + + /* Escape random stuff */ + while (*p) { + if (*p == ' ') + *p = '_'; + else if (strchr("\\][|/=()!:", *p)) + *p = '-'; + p++; + } + + return escaped; } static gboolean -do_write_construct (NMConnection *connection, - const char *ifcfg_dir, - const char *filename, - NMSIfcfgRHWriterAllowFilenameCb allow_filename_cb, - gpointer allow_filename_user_data, - shvarFile **out_ifcfg, - GHashTable **out_blobs, - GHashTable **out_secrets, - gboolean *out_route_ignore, - shvarFile **out_route_content_svformat, - GString **out_route_content, - GString **out_route6_content, - GError **error) +do_write_construct(NMConnection * connection, + const char * ifcfg_dir, + const char * filename, + NMSIfcfgRHWriterAllowFilenameCb allow_filename_cb, + gpointer allow_filename_user_data, + shvarFile ** out_ifcfg, + GHashTable ** out_blobs, + GHashTable ** out_secrets, + gboolean * out_route_ignore, + shvarFile ** out_route_content_svformat, + GString ** out_route_content, + GString ** out_route6_content, + GError ** error) { - NMSettingConnection *s_con; - nm_auto_shvar_file_close shvarFile *ifcfg = NULL; - gs_free char *ifcfg_name = NULL; - gs_free char *route_path = NULL; - gs_free char *route6_path = NULL; - const char *type; - gs_unref_hashtable GHashTable *blobs = NULL; - gs_unref_hashtable GHashTable *secrets = NULL; - gboolean wired; - gboolean no_8021x; - gboolean route_path_is_svformat; - gboolean has_complex_routes_v4; - gboolean has_complex_routes_v6; - gboolean route_ignore; - nm_auto_shvar_file_close shvarFile *route_content_svformat = NULL; - nm_auto_free_gstring GString *route_content = NULL; - nm_auto_free_gstring GString *route6_content = NULL; - - nm_assert (NM_IS_CONNECTION (connection)); - nm_assert (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS); - - if (!nms_ifcfg_rh_writer_can_write_connection (connection, error)) - return FALSE; - - s_con = nm_connection_get_setting_connection (connection); - - if (filename) { - /* For existing connections, 'filename' should be full path to ifcfg file */ - ifcfg = svOpenFile (filename, error); - if (!ifcfg) - return FALSE; - - ifcfg_name = g_strdup (filename); - } else if (ifcfg_dir) { - gs_free char *escaped = NULL; - int i_path; - - escaped = escape_id (nm_setting_connection_get_id (s_con)); - - for (i_path = 0; i_path < 10000; i_path++) { - gs_free char *path_candidate = NULL; - - if (i_path == 0) - path_candidate = g_strdup_printf ("%s/ifcfg-%s", ifcfg_dir, escaped); - else - path_candidate = g_strdup_printf ("%s/ifcfg-%s-%d", ifcfg_dir, escaped, i_path); - - if ( allow_filename_cb - && !allow_filename_cb (path_candidate, allow_filename_user_data)) - continue; - - if (g_file_test (path_candidate, G_FILE_TEST_EXISTS)) - continue; - - ifcfg_name = g_steal_pointer (&path_candidate); - break; - } - - if (!ifcfg_name) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Failed to find usable ifcfg file name"); - return FALSE; - } - - ifcfg = svCreateFile (ifcfg_name); - } else - ifcfg = svCreateFile ("/tmp/ifcfg-dummy"); - - route_path = utils_get_route_path (svFileGetName (ifcfg)); - if (!route_path) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Could not get route file path for '%s'", svFileGetName (ifcfg)); - return FALSE; - } - - route6_path = utils_get_route6_path (svFileGetName (ifcfg)); - if (!route6_path) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Could not get route6 file path for '%s'", svFileGetName (ifcfg)); - return FALSE; - } - - type = nm_setting_connection_get_connection_type (s_con); - if (!type) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Missing connection type!"); - return FALSE; - } - - secrets = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); - - wired = FALSE; - no_8021x = FALSE; - if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) { - // FIXME: can't write PPPoE at this time - if (nm_connection_get_setting_pppoe (connection)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Can't write connection type '%s'", - NM_SETTING_PPPOE_SETTING_NAME); - return FALSE; - } - - if (!write_wired_setting (connection, ifcfg, error)) - return FALSE; - wired = TRUE; - } else if (!strcmp (type, NM_SETTING_VLAN_SETTING_NAME)) { - if (!write_vlan_setting (connection, ifcfg, &wired, error)) - return FALSE; - } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) { - if (!write_wireless_setting (connection, ifcfg, secrets, &no_8021x, error)) - return FALSE; - } else if (!strcmp (type, NM_SETTING_INFINIBAND_SETTING_NAME)) { - if (!write_infiniband_setting (connection, ifcfg, error)) - return FALSE; - } else if (!strcmp (type, NM_SETTING_BOND_SETTING_NAME)) { - if (!write_bond_setting (connection, ifcfg, &wired, error)) - return FALSE; - } else if (!strcmp (type, NM_SETTING_TEAM_SETTING_NAME)) { - if (!write_team_setting (connection, ifcfg, &wired, error)) - return FALSE; - } else if (!strcmp (type, NM_SETTING_BRIDGE_SETTING_NAME)) { - if (!write_bridge_setting (connection, ifcfg, &wired, error)) - return FALSE; - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Can't write connection type '%s'", type); - return FALSE; - } - - if (!no_8021x) { - blobs = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) g_bytes_unref); - if (!write_8021x_setting (connection, ifcfg, secrets, blobs, wired, error)) - return FALSE; - } - - if (!write_bridge_port_setting (connection, ifcfg, error)) - return FALSE; - - if (!write_team_port_setting (connection, ifcfg, error)) - return FALSE; - - if (!write_dcb_setting (connection, ifcfg, error)) - return FALSE; - - if (!write_proxy_setting (connection, ifcfg, error)) - return FALSE; - - if (!write_ethtool_setting (connection, ifcfg, error)) - return FALSE; - - if (!write_user_setting (connection, ifcfg, error)) - return FALSE; - - write_match_setting (connection, ifcfg); - - write_sriov_setting (connection, ifcfg); - - if (!write_tc_setting (connection, ifcfg, error)) - return FALSE; - - - route_path_is_svformat = utils_has_route_file_new_syntax (route_path); - - has_complex_routes_v4 = utils_has_complex_routes (ifcfg_name, AF_INET); - has_complex_routes_v6 = utils_has_complex_routes (ifcfg_name, AF_INET6); - - if (has_complex_routes_v4 || has_complex_routes_v6) { - NMSettingIPConfig *s_ip4, *s_ip6; - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if ( ( s_ip4 - && nm_setting_ip_config_get_num_routes (s_ip4) > 0) - || ( s_ip6 - && nm_setting_ip_config_get_num_routes (s_ip6) > 0)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Cannot configure static routes on a connection that has an associated 'rule%s-' file", - has_complex_routes_v4 ? "" : "6"); - return FALSE; - } - if ( ( s_ip4 - && nm_setting_ip_config_get_route_table (s_ip4) != 0) - || ( s_ip6 - && nm_setting_ip_config_get_route_table (s_ip6) != 0)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Cannot configure a route table for policy routing on a connection that has an associated 'rule%s-' file", - has_complex_routes_v4 ? "" : "6"); - return FALSE; - } - if ( ( s_ip4 - && nm_setting_ip_config_get_num_routing_rules (s_ip4) > 0) - || ( s_ip6 - && nm_setting_ip_config_get_num_routing_rules (s_ip6) > 0)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Cannot configure routing rules on a connection that has an associated 'rule%s-' file", - has_complex_routes_v4 ? "" : "6"); - return FALSE; - } - route_ignore = TRUE; - } else - route_ignore = FALSE; - - if (!write_ip4_setting (connection, - ifcfg, - !route_ignore && route_path_is_svformat ? &route_content_svformat : NULL, - !route_ignore && route_path_is_svformat ? NULL :&route_content, - error)) - return FALSE; - - if (!write_ip6_setting (connection, - ifcfg, - !route_ignore ? &route6_content : NULL, - error)) - return FALSE; - - write_ip_routing_rules (connection, - ifcfg, - route_ignore); - - write_connection_setting (s_con, ifcfg); - - NM_SET_OUT (out_ifcfg, g_steal_pointer (&ifcfg)); - NM_SET_OUT (out_blobs, g_steal_pointer (&blobs)); - NM_SET_OUT (out_secrets, g_steal_pointer (&secrets)); - NM_SET_OUT (out_route_ignore, route_ignore); - NM_SET_OUT (out_route_content_svformat, g_steal_pointer (&route_content_svformat)); - NM_SET_OUT (out_route_content, g_steal_pointer (&route_content)); - NM_SET_OUT (out_route6_content, g_steal_pointer (&route6_content)); - return TRUE; + NMSettingConnection * s_con; + nm_auto_shvar_file_close shvarFile *ifcfg = NULL; + gs_free char * ifcfg_name = NULL; + gs_free char * route_path = NULL; + gs_free char * route6_path = NULL; + const char * type; + gs_unref_hashtable GHashTable *blobs = NULL; + gs_unref_hashtable GHashTable *secrets = NULL; + gboolean wired; + gboolean no_8021x; + gboolean route_path_is_svformat; + gboolean has_complex_routes_v4; + gboolean has_complex_routes_v6; + gboolean route_ignore; + nm_auto_shvar_file_close shvarFile *route_content_svformat = NULL; + nm_auto_free_gstring GString *route_content = NULL; + nm_auto_free_gstring GString *route6_content = NULL; + + nm_assert(NM_IS_CONNECTION(connection)); + nm_assert(_nm_connection_verify(connection, NULL) == NM_SETTING_VERIFY_SUCCESS); + + if (!nms_ifcfg_rh_writer_can_write_connection(connection, error)) + return FALSE; + + s_con = nm_connection_get_setting_connection(connection); + + if (filename) { + /* For existing connections, 'filename' should be full path to ifcfg file */ + ifcfg = svOpenFile(filename, error); + if (!ifcfg) + return FALSE; + + ifcfg_name = g_strdup(filename); + } else if (ifcfg_dir) { + gs_free char *escaped = NULL; + int i_path; + + escaped = escape_id(nm_setting_connection_get_id(s_con)); + + for (i_path = 0; i_path < 10000; i_path++) { + gs_free char *path_candidate = NULL; + + if (i_path == 0) + path_candidate = g_strdup_printf("%s/ifcfg-%s", ifcfg_dir, escaped); + else + path_candidate = g_strdup_printf("%s/ifcfg-%s-%d", ifcfg_dir, escaped, i_path); + + if (allow_filename_cb && !allow_filename_cb(path_candidate, allow_filename_user_data)) + continue; + + if (g_file_test(path_candidate, G_FILE_TEST_EXISTS)) + continue; + + ifcfg_name = g_steal_pointer(&path_candidate); + break; + } + + if (!ifcfg_name) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Failed to find usable ifcfg file name"); + return FALSE; + } + + ifcfg = svCreateFile(ifcfg_name); + } else + ifcfg = svCreateFile("/tmp/ifcfg-dummy"); + + route_path = utils_get_route_path(svFileGetName(ifcfg)); + if (!route_path) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Could not get route file path for '%s'", + svFileGetName(ifcfg)); + return FALSE; + } + + route6_path = utils_get_route6_path(svFileGetName(ifcfg)); + if (!route6_path) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Could not get route6 file path for '%s'", + svFileGetName(ifcfg)); + return FALSE; + } + + type = nm_setting_connection_get_connection_type(s_con); + if (!type) { + g_set_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Missing connection type!"); + return FALSE; + } + + secrets = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); + + wired = FALSE; + no_8021x = FALSE; + if (!strcmp(type, NM_SETTING_WIRED_SETTING_NAME)) { + // FIXME: can't write PPPoE at this time + if (nm_connection_get_setting_pppoe(connection)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Can't write connection type '%s'", + NM_SETTING_PPPOE_SETTING_NAME); + return FALSE; + } + + if (!write_wired_setting(connection, ifcfg, error)) + return FALSE; + wired = TRUE; + } else if (!strcmp(type, NM_SETTING_VLAN_SETTING_NAME)) { + if (!write_vlan_setting(connection, ifcfg, &wired, error)) + return FALSE; + } else if (!strcmp(type, NM_SETTING_WIRELESS_SETTING_NAME)) { + if (!write_wireless_setting(connection, ifcfg, secrets, &no_8021x, error)) + return FALSE; + } else if (!strcmp(type, NM_SETTING_INFINIBAND_SETTING_NAME)) { + if (!write_infiniband_setting(connection, ifcfg, error)) + return FALSE; + } else if (!strcmp(type, NM_SETTING_BOND_SETTING_NAME)) { + if (!write_bond_setting(connection, ifcfg, &wired, error)) + return FALSE; + } else if (!strcmp(type, NM_SETTING_TEAM_SETTING_NAME)) { + if (!write_team_setting(connection, ifcfg, &wired, error)) + return FALSE; + } else if (!strcmp(type, NM_SETTING_BRIDGE_SETTING_NAME)) { + if (!write_bridge_setting(connection, ifcfg, &wired, error)) + return FALSE; + } else { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Can't write connection type '%s'", + type); + return FALSE; + } + + if (!no_8021x) { + blobs = + g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, (GDestroyNotify) g_bytes_unref); + if (!write_8021x_setting(connection, ifcfg, secrets, blobs, wired, error)) + return FALSE; + } + + if (!write_bridge_port_setting(connection, ifcfg, error)) + return FALSE; + + if (!write_team_port_setting(connection, ifcfg, error)) + return FALSE; + + if (!write_dcb_setting(connection, ifcfg, error)) + return FALSE; + + if (!write_proxy_setting(connection, ifcfg, error)) + return FALSE; + + if (!write_ethtool_setting(connection, ifcfg, error)) + return FALSE; + + if (!write_user_setting(connection, ifcfg, error)) + return FALSE; + + write_match_setting(connection, ifcfg); + + write_sriov_setting(connection, ifcfg); + + if (!write_tc_setting(connection, ifcfg, error)) + return FALSE; + + route_path_is_svformat = utils_has_route_file_new_syntax(route_path); + + has_complex_routes_v4 = utils_has_complex_routes(ifcfg_name, AF_INET); + has_complex_routes_v6 = utils_has_complex_routes(ifcfg_name, AF_INET6); + + if (has_complex_routes_v4 || has_complex_routes_v6) { + NMSettingIPConfig *s_ip4, *s_ip6; + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + s_ip6 = nm_connection_get_setting_ip6_config(connection); + if ((s_ip4 && nm_setting_ip_config_get_num_routes(s_ip4) > 0) + || (s_ip6 && nm_setting_ip_config_get_num_routes(s_ip6) > 0)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Cannot configure static routes on a connection that has an associated " + "'rule%s-' file", + has_complex_routes_v4 ? "" : "6"); + return FALSE; + } + if ((s_ip4 && nm_setting_ip_config_get_route_table(s_ip4) != 0) + || (s_ip6 && nm_setting_ip_config_get_route_table(s_ip6) != 0)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Cannot configure a route table for policy routing on a connection that " + "has an associated 'rule%s-' file", + has_complex_routes_v4 ? "" : "6"); + return FALSE; + } + if ((s_ip4 && nm_setting_ip_config_get_num_routing_rules(s_ip4) > 0) + || (s_ip6 && nm_setting_ip_config_get_num_routing_rules(s_ip6) > 0)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Cannot configure routing rules on a connection that has an associated " + "'rule%s-' file", + has_complex_routes_v4 ? "" : "6"); + return FALSE; + } + route_ignore = TRUE; + } else + route_ignore = FALSE; + + if (!write_ip4_setting(connection, + ifcfg, + !route_ignore && route_path_is_svformat ? &route_content_svformat : NULL, + !route_ignore && route_path_is_svformat ? NULL : &route_content, + error)) + return FALSE; + + if (!write_ip6_setting(connection, ifcfg, !route_ignore ? &route6_content : NULL, error)) + return FALSE; + + write_ip_routing_rules(connection, ifcfg, route_ignore); + + write_connection_setting(s_con, ifcfg); + + NM_SET_OUT(out_ifcfg, g_steal_pointer(&ifcfg)); + NM_SET_OUT(out_blobs, g_steal_pointer(&blobs)); + NM_SET_OUT(out_secrets, g_steal_pointer(&secrets)); + NM_SET_OUT(out_route_ignore, route_ignore); + NM_SET_OUT(out_route_content_svformat, g_steal_pointer(&route_content_svformat)); + NM_SET_OUT(out_route_content, g_steal_pointer(&route_content)); + NM_SET_OUT(out_route6_content, g_steal_pointer(&route6_content)); + return TRUE; } static gboolean -do_write_to_disk (NMConnection *connection, - shvarFile *ifcfg, - GHashTable *blobs, - GHashTable *secrets, - gboolean route_ignore, - shvarFile *route_content_svformat, - GString *route_content, - GString *route6_content, - GError **error) +do_write_to_disk(NMConnection *connection, + shvarFile * ifcfg, + GHashTable * blobs, + GHashTable * secrets, + gboolean route_ignore, + shvarFile * route_content_svformat, + GString * route_content, + GString * route6_content, + GError ** error) { - /* From here on, we persist data to disk. Before, it was all in-memory - * only. But we loaded the ifcfg files from disk, and managled our - * new settings (in-memory). */ - - if (!svWriteFileWithoutDirtyWellknown (ifcfg, 0644, error)) - return FALSE; - - write_ip4_aliases (connection, svFileGetName (ifcfg)); - - if (!write_blobs (blobs, error)) - return FALSE; - - if (!write_secrets (ifcfg, secrets, error)) - return FALSE; - - if (!route_ignore) { - gs_free char *route_path = utils_get_route_path (svFileGetName (ifcfg)); - - if (!route_content && !route_content_svformat) - (void) unlink (route_path); - else { - nm_assert (route_content_svformat || route_content); - if (route_content_svformat) { - if (!svWriteFileWithoutDirtyWellknown (route_content_svformat, 0644, error)) - return FALSE; - } else { - if (!g_file_set_contents (route_path, route_content->str, route_content->len, NULL)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Writing route file '%s' failed", route_path); - return FALSE; - } - } - } - } - - if (!route_ignore) { - gs_free char *route6_path = utils_get_route6_path (svFileGetName (ifcfg)); - - if (!route6_content) - (void) unlink (route6_path); - else { - if (!g_file_set_contents (route6_path, route6_content->str, route6_content->len, NULL)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Writing route6 file '%s' failed", route6_path); - return FALSE; - } - } - } - - return TRUE; + /* From here on, we persist data to disk. Before, it was all in-memory + * only. But we loaded the ifcfg files from disk, and managled our + * new settings (in-memory). */ + + if (!svWriteFileWithoutDirtyWellknown(ifcfg, 0644, error)) + return FALSE; + + write_ip4_aliases(connection, svFileGetName(ifcfg)); + + if (!write_blobs(blobs, error)) + return FALSE; + + if (!write_secrets(ifcfg, secrets, error)) + return FALSE; + + if (!route_ignore) { + gs_free char *route_path = utils_get_route_path(svFileGetName(ifcfg)); + + if (!route_content && !route_content_svformat) + (void) unlink(route_path); + else { + nm_assert(route_content_svformat || route_content); + if (route_content_svformat) { + if (!svWriteFileWithoutDirtyWellknown(route_content_svformat, 0644, error)) + return FALSE; + } else { + if (!g_file_set_contents(route_path, + route_content->str, + route_content->len, + NULL)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Writing route file '%s' failed", + route_path); + return FALSE; + } + } + } + } + + if (!route_ignore) { + gs_free char *route6_path = utils_get_route6_path(svFileGetName(ifcfg)); + + if (!route6_content) + (void) unlink(route6_path); + else { + if (!g_file_set_contents(route6_path, route6_content->str, route6_content->len, NULL)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "Writing route6 file '%s' failed", + route6_path); + return FALSE; + } + } + } + + return TRUE; } gboolean -nms_ifcfg_rh_writer_write_connection (NMConnection *connection, - const char *ifcfg_dir, - const char *filename, - NMSIfcfgRHWriterAllowFilenameCb allow_filename_cb, - gpointer allow_filename_user_data, - char **out_filename, - NMConnection **out_reread, - gboolean *out_reread_same, - GError **error) +nms_ifcfg_rh_writer_write_connection(NMConnection * connection, + const char * ifcfg_dir, + const char * filename, + NMSIfcfgRHWriterAllowFilenameCb allow_filename_cb, + gpointer allow_filename_user_data, + char ** out_filename, + NMConnection ** out_reread, + gboolean * out_reread_same, + GError ** error) { - nm_auto_shvar_file_close shvarFile *ifcfg = NULL; - nm_auto_free_gstring GString *route_content = NULL; - gboolean route_ignore = FALSE; - nm_auto_shvar_file_close shvarFile *route_content_svformat = NULL; - nm_auto_free_gstring GString *route6_content = NULL; - gs_unref_hashtable GHashTable *secrets = NULL; - gs_unref_hashtable GHashTable *blobs = NULL; - - nm_assert (!out_reread || !*out_reread); - - if (!do_write_construct (connection, - ifcfg_dir, - filename, - allow_filename_cb, - allow_filename_user_data, - &ifcfg, - &blobs, - &secrets, - &route_ignore, - &route_content_svformat, - &route_content, - &route6_content, - error)) - return FALSE; - - _LOGT ("write: write connection %s (%s) to file \"%s\"", - nm_connection_get_id (connection), - nm_connection_get_uuid (connection), - svFileGetName (ifcfg)); - - if (!do_write_to_disk (connection, - ifcfg, - blobs, - secrets, - route_ignore, - route_content_svformat, - route_content, - route6_content, - error)) - return FALSE; - - /* Note that we just wrote the connection to disk, and re-read it from there. - * That is racy if somebody else modifies the connection. - * That race is why we must not tread a failure to re-read the profile - * as an error. - * - * FIXME: a much better solution might be, to re-read the connection only based - * on the in-memory representation of what we collected above. But the reader - * does not yet allow to inject the configuration. */ - if ( out_reread - || out_reread_same) { - gs_unref_object NMConnection *reread = NULL; - gboolean reread_same = FALSE; - gs_free_error GError *local = NULL; - gs_free char *unhandled = NULL; - - reread = connection_from_file (svFileGetName (ifcfg), - &unhandled, - &local, - NULL); - nm_assert ((NM_IS_CONNECTION (reread) && !local) || (!reread && local)); - - if (!reread) { - _LOGW ("write: failure to re-read connection \"%s\": %s", - svFileGetName (ifcfg), local->message); - } else if (unhandled) { - g_clear_object (&reread); - _LOGW ("write: failure to re-read connection \"%s\": %s", - svFileGetName (ifcfg), "connection is unhandled"); - } else { - /* ifcfg-rh doesn't support the 'timestamp' property, let's add it here */ - g_object_set (nm_connection_get_setting_connection (reread), - NM_SETTING_CONNECTION_TIMESTAMP, - nm_setting_connection_get_timestamp (nm_connection_get_setting_connection (connection)), - NULL); - if (out_reread_same) { - reread_same = nm_connection_compare (reread, connection, NM_SETTING_COMPARE_FLAG_EXACT); - if (!reread_same) { - _LOGD ("write: connection %s (%s) was modified by persisting it to \"%s\" ", - nm_connection_get_id (connection), - nm_connection_get_uuid (connection), - svFileGetName (ifcfg)); - } - } - } - - NM_SET_OUT (out_reread, g_steal_pointer (&reread)); - NM_SET_OUT (out_reread_same, reread_same); - } - - /* Only return the filename if this was a newly written ifcfg */ - if (out_filename && !filename) - *out_filename = g_strdup (svFileGetName (ifcfg)); - - return TRUE; + nm_auto_shvar_file_close shvarFile *ifcfg = NULL; + nm_auto_free_gstring GString *route_content = NULL; + gboolean route_ignore = FALSE; + nm_auto_shvar_file_close shvarFile *route_content_svformat = NULL; + nm_auto_free_gstring GString *route6_content = NULL; + gs_unref_hashtable GHashTable *secrets = NULL; + gs_unref_hashtable GHashTable *blobs = NULL; + + nm_assert(!out_reread || !*out_reread); + + if (!do_write_construct(connection, + ifcfg_dir, + filename, + allow_filename_cb, + allow_filename_user_data, + &ifcfg, + &blobs, + &secrets, + &route_ignore, + &route_content_svformat, + &route_content, + &route6_content, + error)) + return FALSE; + + _LOGT("write: write connection %s (%s) to file \"%s\"", + nm_connection_get_id(connection), + nm_connection_get_uuid(connection), + svFileGetName(ifcfg)); + + if (!do_write_to_disk(connection, + ifcfg, + blobs, + secrets, + route_ignore, + route_content_svformat, + route_content, + route6_content, + error)) + return FALSE; + + /* Note that we just wrote the connection to disk, and re-read it from there. + * That is racy if somebody else modifies the connection. + * That race is why we must not tread a failure to re-read the profile + * as an error. + * + * FIXME: a much better solution might be, to re-read the connection only based + * on the in-memory representation of what we collected above. But the reader + * does not yet allow to inject the configuration. */ + if (out_reread || out_reread_same) { + gs_unref_object NMConnection *reread = NULL; + gboolean reread_same = FALSE; + gs_free_error GError *local = NULL; + gs_free char * unhandled = NULL; + + reread = connection_from_file(svFileGetName(ifcfg), &unhandled, &local, NULL); + nm_assert((NM_IS_CONNECTION(reread) && !local) || (!reread && local)); + + if (!reread) { + _LOGW("write: failure to re-read connection \"%s\": %s", + svFileGetName(ifcfg), + local->message); + } else if (unhandled) { + g_clear_object(&reread); + _LOGW("write: failure to re-read connection \"%s\": %s", + svFileGetName(ifcfg), + "connection is unhandled"); + } else { + /* ifcfg-rh doesn't support the 'timestamp' property, let's add it here */ + g_object_set(nm_connection_get_setting_connection(reread), + NM_SETTING_CONNECTION_TIMESTAMP, + nm_setting_connection_get_timestamp( + nm_connection_get_setting_connection(connection)), + NULL); + if (out_reread_same) { + reread_same = + nm_connection_compare(reread, connection, NM_SETTING_COMPARE_FLAG_EXACT); + if (!reread_same) { + _LOGD("write: connection %s (%s) was modified by persisting it to \"%s\" ", + nm_connection_get_id(connection), + nm_connection_get_uuid(connection), + svFileGetName(ifcfg)); + } + } + } + + NM_SET_OUT(out_reread, g_steal_pointer(&reread)); + NM_SET_OUT(out_reread_same, reread_same); + } + + /* Only return the filename if this was a newly written ifcfg */ + if (out_filename && !filename) + *out_filename = g_strdup(svFileGetName(ifcfg)); + + return TRUE; } gboolean -nms_ifcfg_rh_writer_can_write_connection (NMConnection *connection, GError **error) +nms_ifcfg_rh_writer_can_write_connection(NMConnection *connection, GError **error) { - const char *type, *id; - - type = nm_connection_get_connection_type (connection); - if (NM_IN_STRSET (type, - NM_SETTING_VLAN_SETTING_NAME, - NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_INFINIBAND_SETTING_NAME, - NM_SETTING_BOND_SETTING_NAME, - NM_SETTING_TEAM_SETTING_NAME, - NM_SETTING_BRIDGE_SETTING_NAME)) - return TRUE; - if ( nm_streq0 (type, NM_SETTING_WIRED_SETTING_NAME) - && !nm_connection_get_setting_pppoe (connection)) - return TRUE; - - id = nm_connection_get_id (connection); - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "The ifcfg-rh plugin cannot write the connection %s%s%s (type %s%s%s)", - NM_PRINT_FMT_QUOTE_STRING (id), - NM_PRINT_FMT_QUOTE_STRING (type)); - return FALSE; + const char *type, *id; + + type = nm_connection_get_connection_type(connection); + if (NM_IN_STRSET(type, + NM_SETTING_VLAN_SETTING_NAME, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_BOND_SETTING_NAME, + NM_SETTING_TEAM_SETTING_NAME, + NM_SETTING_BRIDGE_SETTING_NAME)) + return TRUE; + if (nm_streq0(type, NM_SETTING_WIRED_SETTING_NAME) + && !nm_connection_get_setting_pppoe(connection)) + return TRUE; + + id = nm_connection_get_id(connection); + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "The ifcfg-rh plugin cannot write the connection %s%s%s (type %s%s%s)", + NM_PRINT_FMT_QUOTE_STRING(id), + NM_PRINT_FMT_QUOTE_STRING(type)); + return FALSE; } diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h index c4903a46..1c58a346 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2009 Red Hat, Inc. */ @@ -8,21 +8,19 @@ #include "nm-connection.h" +typedef gboolean (*NMSIfcfgRHWriterAllowFilenameCb)(const char *check_filename, + gpointer allow_filename_user_data); -typedef gboolean (*NMSIfcfgRHWriterAllowFilenameCb) (const char *check_filename, - gpointer allow_filename_user_data); +gboolean nms_ifcfg_rh_writer_can_write_connection(NMConnection *connection, GError **error); -gboolean nms_ifcfg_rh_writer_can_write_connection (NMConnection *connection, - GError **error); - -gboolean nms_ifcfg_rh_writer_write_connection (NMConnection *connection, - const char *ifcfg_dir, - const char *filename, - NMSIfcfgRHWriterAllowFilenameCb allow_filename_cb, - gpointer allow_filename_user_data, - char **out_filename, - NMConnection **out_reread, - gboolean *out_reread_same, - GError **error); +gboolean nms_ifcfg_rh_writer_write_connection(NMConnection * connection, + const char * ifcfg_dir, + const char * filename, + NMSIfcfgRHWriterAllowFilenameCb allow_filename_cb, + gpointer allow_filename_user_data, + char ** out_filename, + NMConnection **out_reread, + gboolean * out_reread_same, + GError ** error); #endif /* __NMS_IFCFG_RH_WRITER_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index cd63661d..8f5be2cc 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 1999, 2000 Red Hat, Inc. */ @@ -24,69 +24,68 @@ /*****************************************************************************/ struct _shvarLine { - - const char *key; - - CList lst; - - /* We index variables by their key in shvarFile.lst_idx. One shell variable might - * occur multiple times in a file (in which case the last occurrence wins). - * Hence, we need to keep a list of all the same keys. - * - * This is a pointer to the next shadowed line. */ - struct _shvarLine *prev_shadowed; - - /* There are three cases: - * - * 1) the line is not a valid variable assignment (that is, it doesn't - * start with a "FOO=" with possible whitespace prefix). - * In that case, @key and @key_with_prefix are %NULL, and the entire - * original line is in @line. Such entries are ignored for the most part. - * - * 2) if the line can be parsed with a "FOO=" assignment, then @line contains - * the part after '=', @key_with_prefix contains the key "FOO" with possible - * whitespace prefix, and @key points into @key_with_prefix skipping over the - * whitespace. - * - * 3) like 2, but if the value was deleted via svSetValue(), the entry is not removed, - * but only marked for deletion. That is done by clearing @line but preserving - * @key/@key_with_prefix. - * */ - char *line; - char *key_with_prefix; - - /* svSetValue() will clear the dirty flag. */ - bool dirty:1; + const char *key; + + CList lst; + + /* We index variables by their key in shvarFile.lst_idx. One shell variable might + * occur multiple times in a file (in which case the last occurrence wins). + * Hence, we need to keep a list of all the same keys. + * + * This is a pointer to the next shadowed line. */ + struct _shvarLine *prev_shadowed; + + /* There are three cases: + * + * 1) the line is not a valid variable assignment (that is, it doesn't + * start with a "FOO=" with possible whitespace prefix). + * In that case, @key and @key_with_prefix are %NULL, and the entire + * original line is in @line. Such entries are ignored for the most part. + * + * 2) if the line can be parsed with a "FOO=" assignment, then @line contains + * the part after '=', @key_with_prefix contains the key "FOO" with possible + * whitespace prefix, and @key points into @key_with_prefix skipping over the + * whitespace. + * + * 3) like 2, but if the value was deleted via svSetValue(), the entry is not removed, + * but only marked for deletion. That is done by clearing @line but preserving + * @key/@key_with_prefix. + * */ + char *line; + char *key_with_prefix; + + /* svSetValue() will clear the dirty flag. */ + bool dirty : 1; }; typedef struct _shvarLine shvarLine; struct _shvarFile { - char *fileName; - CList lst_head; - GHashTable *lst_idx; - int fd; - bool modified:1; + char * fileName; + CList lst_head; + GHashTable *lst_idx; + int fd; + bool modified : 1; }; /*****************************************************************************/ -static void _line_link_parse (shvarFile *s, const char *value, gsize len); +static void _line_link_parse(shvarFile *s, const char *value, gsize len); /*****************************************************************************/ -#define ASSERT_key_is_well_known(key) \ - nm_assert ( ({ \ - const char *_key = (key); \ - gboolean _is_wellknown = TRUE; \ - \ - if (!nms_ifcfg_rh_utils_is_well_known_key (_key)) { \ - _is_wellknown = FALSE; \ - g_critical ("ifcfg-rh key \"%s\" is not well-known", _key); \ - } \ - \ - _is_wellknown; \ - }) ) +#define ASSERT_key_is_well_known(key) \ + nm_assert(({ \ + const char *_key = (key); \ + gboolean _is_wellknown = TRUE; \ + \ + if (!nms_ifcfg_rh_utils_is_well_known_key(_key)) { \ + _is_wellknown = FALSE; \ + g_critical("ifcfg-rh key \"%s\" is not well-known", _key); \ + } \ + \ + _is_wellknown; \ + })) /** * svParseBoolean: @@ -100,52 +99,46 @@ static void _line_link_parse (shvarFile *s, const char *value, gsize len); * Returns: the parsed boolean value or @fallback. */ int -svParseBoolean (const char *value, int fallback) +svParseBoolean(const char *value, int fallback) { - if (!value) - return fallback; - - if ( !g_ascii_strcasecmp ("yes", value) - || !g_ascii_strcasecmp ("true", value) - || !g_ascii_strcasecmp ("t", value) - || !g_ascii_strcasecmp ("y", value) - || !g_ascii_strcasecmp ("1", value)) - return TRUE; - else if ( !g_ascii_strcasecmp ("no", value) - || !g_ascii_strcasecmp ("false", value) - || !g_ascii_strcasecmp ("f", value) - || !g_ascii_strcasecmp ("n", value) - || !g_ascii_strcasecmp ("0", value)) - return FALSE; - - return fallback; + if (!value) + return fallback; + + if (!g_ascii_strcasecmp("yes", value) || !g_ascii_strcasecmp("true", value) + || !g_ascii_strcasecmp("t", value) || !g_ascii_strcasecmp("y", value) + || !g_ascii_strcasecmp("1", value)) + return TRUE; + else if (!g_ascii_strcasecmp("no", value) || !g_ascii_strcasecmp("false", value) + || !g_ascii_strcasecmp("f", value) || !g_ascii_strcasecmp("n", value) + || !g_ascii_strcasecmp("0", value)) + return FALSE; + + return fallback; } /*****************************************************************************/ static gboolean -_shell_is_name (const char *key, gssize len) +_shell_is_name(const char *key, gssize len) { - gssize i; - - /* whether @key is a valid identifier (name). */ - if (!key || len == 0) - return FALSE; - if ( !g_ascii_isalpha (key[0]) - && key[0] != '_') - return FALSE; - for (i = 1; TRUE; i++) { - if (len < 0) { - if (!key[i]) - return TRUE; - } else { - if (i >= len) - return TRUE; - } - if ( !g_ascii_isalnum (key[i]) - && key[i] != '_') - return FALSE; - } + gssize i; + + /* whether @key is a valid identifier (name). */ + if (!key || len == 0) + return FALSE; + if (!g_ascii_isalpha(key[0]) && key[0] != '_') + return FALSE; + for (i = 1; TRUE; i++) { + if (len < 0) { + if (!key[i]) + return TRUE; + } else { + if (i >= len) + return TRUE; + } + if (!g_ascii_isalnum(key[i]) && key[i] != '_') + return FALSE; + } } /*****************************************************************************/ @@ -154,959 +147,964 @@ _shell_is_name (const char *key, gssize len) * * While at it, add $''. */ static char * -_escape_ansic (const char *source) +_escape_ansic(const char *source) { - const char *p; - char *dest; - char *q; - - nm_assert (source); - - p = (const char *) source; - /* Each source byte needs maximally four destination chars (\777) */ - q = dest = g_malloc (strlen (source) * 4 + 1 + 3); - - *q++ = '$'; - *q++ = '\''; - - while (*p) { - switch (*p) { - case '\b': - *q++ = '\\'; - *q++ = 'b'; - break; - case '\f': - *q++ = '\\'; - *q++ = 'f'; - break; - case '\n': - *q++ = '\\'; - *q++ = 'n'; - break; - case '\r': - *q++ = '\\'; - *q++ = 'r'; - break; - case '\t': - *q++ = '\\'; - *q++ = 't'; - break; - case '\v': - *q++ = '\\'; - *q++ = 'v'; - break; - case '\\': - case '"': - case '\'': - *q++ = '\\'; - *q++ = *p; - break; - default: - if ((*p < ' ') || (*p >= 0177)) { - *q++ = '\\'; - *q++ = '0' + (((*p) >> 6) & 07); - *q++ = '0' + (((*p) >> 3) & 07); - *q++ = '0' + ((*p) & 07); - } else - *q++ = *p; - break; - } - p++; - } - *q++ = '\''; - *q++ = '\0'; - - nm_assert (q - dest <= strlen (source) * 4 + 1 + 3); - - return dest; + const char *p; + char * dest; + char * q; + + nm_assert(source); + + p = (const char *) source; + /* Each source byte needs maximally four destination chars (\777) */ + q = dest = g_malloc(strlen(source) * 4 + 1 + 3); + + *q++ = '$'; + *q++ = '\''; + + while (*p) { + switch (*p) { + case '\b': + *q++ = '\\'; + *q++ = 'b'; + break; + case '\f': + *q++ = '\\'; + *q++ = 'f'; + break; + case '\n': + *q++ = '\\'; + *q++ = 'n'; + break; + case '\r': + *q++ = '\\'; + *q++ = 'r'; + break; + case '\t': + *q++ = '\\'; + *q++ = 't'; + break; + case '\v': + *q++ = '\\'; + *q++ = 'v'; + break; + case '\\': + case '"': + case '\'': + *q++ = '\\'; + *q++ = *p; + break; + default: + if ((*p < ' ') || (*p >= 0177)) { + *q++ = '\\'; + *q++ = '0' + (((*p) >> 6) & 07); + *q++ = '0' + (((*p) >> 3) & 07); + *q++ = '0' + ((*p) & 07); + } else + *q++ = *p; + break; + } + p++; + } + *q++ = '\''; + *q++ = '\0'; + + nm_assert(q - dest <= strlen(source) * 4 + 1 + 3); + + return dest; } /*****************************************************************************/ -#define _char_req_escape(ch) NM_IN_SET (ch, '"', '\\', '$', '`') -#define _char_req_escape_old(ch) NM_IN_SET (ch, '"', '\\', '\'', '$', '`', '~') -#define _char_req_quotes(ch) NM_IN_SET (ch, ' ', '\'', '~', '\t', '|', '&', ';', '(', ')', '<', '>') +#define _char_req_escape(ch) NM_IN_SET(ch, '"', '\\', '$', '`') +#define _char_req_escape_old(ch) NM_IN_SET(ch, '"', '\\', '\'', '$', '`', '~') +#define _char_req_quotes(ch) NM_IN_SET(ch, ' ', '\'', '~', '\t', '|', '&', ';', '(', ')', '<', '>') const char * -svEscape (const char *s, char **to_free) +svEscape(const char *s, char **to_free) { - char *new; - gsize mangle = 0; - gboolean requires_quotes = FALSE; - int newlen; - size_t i, j, slen; - - for (slen = 0; s[slen]; slen++) { - if (_char_req_escape (s[slen])) - mangle++; - else if (_char_req_quotes (s[slen])) - requires_quotes = TRUE; - else if (s[slen] < ' ') { - /* if the string contains newline we can only express it using ANSI C quotation - * (as we don't support line continuation). - * Additionally, ANSI control characters look odd with regular quotation, so handle - * them too. */ - return (*to_free = _escape_ansic (s)); - } - } - if (!mangle && !requires_quotes) { - *to_free = NULL; - return s; - } - - newlen = slen + mangle + 3; /* 3 is extra ""\0 */ - new = g_malloc (newlen); - - j = 0; - new[j++] = '"'; - for (i = 0; i < slen; i++) { - if (_char_req_escape (s[i])) - new[j++] = '\\'; - new[j++] = s[i]; - } - new[j++] = '"'; - new[j++] = '\0'; - - nm_assert (j == slen + mangle + 3); - - *to_free = new; - return new; + char *new; + gsize mangle = 0; + gboolean requires_quotes = FALSE; + int newlen; + size_t i, j, slen; + + for (slen = 0; s[slen]; slen++) { + if (_char_req_escape(s[slen])) + mangle++; + else if (_char_req_quotes(s[slen])) + requires_quotes = TRUE; + else if (s[slen] < ' ') { + /* if the string contains newline we can only express it using ANSI C quotation + * (as we don't support line continuation). + * Additionally, ANSI control characters look odd with regular quotation, so handle + * them too. */ + return (*to_free = _escape_ansic(s)); + } + } + if (!mangle && !requires_quotes) { + *to_free = NULL; + return s; + } + + newlen = slen + mangle + 3; /* 3 is extra ""\0 */ + new = g_malloc(newlen); + + j = 0; + new[j++] = '"'; + for (i = 0; i < slen; i++) { + if (_char_req_escape(s[i])) + new[j++] = '\\'; + new[j++] = s[i]; + } + new[j++] = '"'; + new[j++] = '\0'; + + nm_assert(j == slen + mangle + 3); + + *to_free = new; + return new; } static gboolean -_looks_like_old_svescaped (const char *value) +_looks_like_old_svescaped(const char *value) { - gsize k; - - if (value[0] != '"') - return FALSE; - - for (k = 1; ; k++) { - if (value[k] == '\0') - return FALSE; - if (!_char_req_escape_old (value[k])) - continue; - - if (value[k] == '"') - return (value[k + 1] == '\0'); - else if (value[k] == '\\') { - k++; - if (!_char_req_escape_old (value[k])) - return FALSE; - } else - return FALSE; - } + gsize k; + + if (value[0] != '"') + return FALSE; + + for (k = 1;; k++) { + if (value[k] == '\0') + return FALSE; + if (!_char_req_escape_old(value[k])) + continue; + + if (value[k] == '"') + return (value[k + 1] == '\0'); + else if (value[k] == '\\') { + k++; + if (!_char_req_escape_old(value[k])) + return FALSE; + } else + return FALSE; + } } static gboolean -_ch_octal_is (char ch) +_ch_octal_is(char ch) { - return ch >= '0' && ch < '8'; + return ch >= '0' && ch < '8'; } static guint8 -_ch_octal_get (char ch) +_ch_octal_get(char ch) { - nm_assert (_ch_octal_is (ch)); - return (ch - '0'); + nm_assert(_ch_octal_is(ch)); + return (ch - '0'); } static gboolean -_ch_hex_is (char ch) +_ch_hex_is(char ch) { - return g_ascii_isxdigit (ch); + return g_ascii_isxdigit(ch); } static guint8 -_ch_hex_get (char ch) +_ch_hex_get(char ch) { - nm_assert (_ch_hex_is (ch)); - return ch <= '9' ? ch - '0' : (ch & 0x4F) - 'A' + 10; + nm_assert(_ch_hex_is(ch)); + return ch <= '9' ? ch - '0' : (ch & 0x4F) - 'A' + 10; } static void -_gstr_init (GString **str, const char *value, gsize i) +_gstr_init(GString **str, const char *value, gsize i) { - nm_assert (str); - nm_assert (value); - - if (!(*str)) { - /* if @str is not yet initialized, it allocates - * a new GString and copies @i characters from - * @value over. - * - * Unescaping usually does not extend the length of a string, - * so we might be tempted to allocate a fixed buffer of length - * (strlen(value)+CONST). - * However, due to $'\Ux' escapes, the maximum length is some - * (FACTOR*strlen(value) + CONST), which is non trivial to get - * right in all cases. Also, we would have to provision for the - * very unlikely extreme case. - * Instead, use a GString buffer which can grow as needed. But for an - * initial guess, strlen(value) is a good start */ - *str = g_string_new_len (NULL, strlen (value) + 3); - if (i) - g_string_append_len (*str, value, i); - } + nm_assert(str); + nm_assert(value); + + if (!(*str)) { + /* if @str is not yet initialized, it allocates + * a new GString and copies @i characters from + * @value over. + * + * Unescaping usually does not extend the length of a string, + * so we might be tempted to allocate a fixed buffer of length + * (strlen(value)+CONST). + * However, due to $'\Ux' escapes, the maximum length is some + * (FACTOR*strlen(value) + CONST), which is non trivial to get + * right in all cases. Also, we would have to provision for the + * very unlikely extreme case. + * Instead, use a GString buffer which can grow as needed. But for an + * initial guess, strlen(value) is a good start */ + *str = g_string_new_len(NULL, strlen(value) + 3); + if (i) + g_string_append_len(*str, value, i); + } } const char * -svUnescape (const char *value, char **to_free) +svUnescape(const char *value, char **to_free) { - gsize i, j; - GString *str = NULL; - int looks_like_old_svescaped = -1; - - /* we handle bash syntax here (note that ifup has #!/bin/bash. - * Thus, see https://www.gnu.org/software/bash/manual/html_node/Quoting.html#Quoting */ - - /* @value shall start with the first character after "FOO=" */ - - nm_assert (value); - nm_assert (to_free); - - /* we don't expect any newlines. They must be filtered out before-hand. - * We also don't support line continuation. */ - nm_assert (!NM_STRCHAR_ANY (value, ch, ch == '\n')); - - i = 0; - while (TRUE) { - - if (value[i] == '\0') - goto out_value; - - if ( g_ascii_isspace (value[i]) - || value[i] == ';') { - gboolean has_semicolon = (value[i] == ';'); - - /* starting with space is only allowed, if the entire - * string consists of spaces (possibly terminated by a comment). - * This disallows for example - * LANG=C ls -1 - * LANG= ls -1 - * but allows - * LANG= #comment - * - * As a special case, we also allow one trailing semicolon, as long - * it is only followed by whitespace or a #-comment. - * FOO=; - * FOO=a; - * FOO=b ; #hallo - */ - j = i + 1; - while ( g_ascii_isspace (value[j]) - || ( !has_semicolon - && (has_semicolon = (value[j] == ';')))) - j++; - if (!NM_IN_SET (value[j], '\0', '#')) - goto out_error; - goto out_value; - } - - if (value[i] == '\\') { - /* backslash escape */ - _gstr_init (&str, value, i); - i++; - if (G_UNLIKELY (value[i] == '\0')) { - /* we don't support line continuation */ - goto out_error; - } - g_string_append_c (str, value[i]); - i++; - goto loop1_next; - } - - if (value[i] == '\'') { - /* single quotes */ - _gstr_init (&str, value, i); - i++; - j = i; - while (TRUE) { - if (value[j] == '\0') { - /* unterminated single quote. We don't support line continuation */ - goto out_error; - } - if (value[j] == '\'') - break; - j++; - } - g_string_append_len (str, &value[i], j - i); - i = j + 1; - goto loop1_next; - } - - if (value[i] == '"') { - /* double quotes */ - _gstr_init (&str, value, i); - i++; - while (TRUE) { - if (value[i] == '"') { - i++; - break; - } - if (value[i] == '\0') { - /* unterminated double quote. We don't support line continuation. */ - goto out_error; - } - if (NM_IN_SET (value[i], '`', '$')) { - /* we don't support shell expansion. */ - goto out_error; - } - if (value[i] == '\\') { - i++; - if (value[i] == '\0') { - /* we don't support line continuation */ - goto out_error; - } - if (NM_IN_SET (value[i], '$', '`', '"', '\\')) { - /* Drop the backslash. */ - } else if (NM_IN_SET (value[i], '\'', '~')) { - /* '\'' and '~' in double quotes are not handled special by shell. - * However, old versions of svEscape() would wrongly use double-quoting - * with backslash escaping for these characters (expecting svUnescape() - * to remove the backslash). - * - * In order to preserve previous behavior, we continue to read such - * strings different then shell does. */ - - /* Actually, we can relax this. Old svEscape() escaped the entire value - * in a particular way with double quotes. - * If the value doesn't exactly look like something as created by svEscape(), - * don't do the compat hack and preserve the backslash. */ - if (looks_like_old_svescaped < 0) - looks_like_old_svescaped = _looks_like_old_svescaped (value); - if (!looks_like_old_svescaped) - g_string_append_c (str, '\\'); - } else - g_string_append_c (str, '\\'); - } - g_string_append_c (str, value[i]); - i++; - } - goto loop1_next; - } - - if ( value[i] == '$' - && value[i + 1] == '\'') { - /* ANSI-C Quoting */ - _gstr_init (&str, value, i); - i += 2; - while (TRUE) { - char ch; - - if (value[i] == '\'') { - i++; - break; - } - if (value[i] == '\0') { - /* unterminated double quote. We don't support line continuation. */ - goto out_error; - } - if (value[i] == '\\') { - - i++; - if (value[i] == '\0') { - /* we don't support line continuation */ - goto out_error; - } - switch (value[i]) { - case 'a': ch = '\a'; break; - case 'b': ch = '\b'; break; - case 'e': ch = '\e'; break; - case 'E': ch = '\E'; break; - case 'f': ch = '\f'; break; - case 'n': ch = '\n'; break; - case 'r': ch = '\r'; break; - case 't': ch = '\t'; break; - case 'v': ch = '\v'; break; - case '?': ch = '\?'; break; - case '"': ch = '"'; break; - case '\\': ch = '\\'; break; - case '\'': ch = '\''; break; - default: - if (_ch_octal_is (value[i])) { - guint v; - - v = _ch_octal_get (value[i]); - i++; - if (_ch_octal_is (value[i])) { - v = (v * 8) + _ch_octal_get (value[i]); - i++; - if (_ch_octal_is (value[i])) { - v = (v * 8) + _ch_octal_get (value[i]); - i++; - } - } - /* like bash, we cut too large numbers off. E.g. A=$'\772' becomes 0xfa */ - g_string_append_c (str, (guint8) v); - } else if (NM_IN_SET (value[i], 'x', 'u', 'U')) { - const char escape_type = value[i]; - int max_digits = escape_type == 'x' ? 2 : escape_type == 'u' ? 4 : 8; - guint64 v; - - i++; - if (!_ch_hex_is (value[i])) { - /* missing hex value after "\x" escape. This is treated like no escaping. */ - g_string_append_c (str, '\\'); - g_string_append_c (str, escape_type); - } else { - v = _ch_hex_get (value[i]); - i++; - - while (--max_digits > 0) { - if (!_ch_hex_is (value[i])) - break; - v = v * 16 + _ch_hex_get (value[i]); - i++; - } - if (escape_type == 'x') - g_string_append_c (str, v); - else { - /* we treat the unicode escapes as utf-8 encoded values. */ - g_string_append_unichar (str, v); - } - } - } else { - g_string_append_c (str, '\\'); - g_string_append_c (str, value[i]); - i++; - } - goto loop_ansic_next; - } - } else - ch = value[i]; - g_string_append_c (str, ch); - i++; -loop_ansic_next: ; - } - goto loop1_next; - } - - if (NM_IN_SET (value[i], '|', '&', '(', ')', '<', '>')) { - /* shell metacharacters are not supported without quoting. - * Note that ';' is already handled above. */ - goto out_error; - } - - /* an unquoted, regular character. Just consume it directly. */ - if (str) - g_string_append_c (str, value[i]); - i++; - -loop1_next: ; - } - - nm_assert_not_reached (); + gsize i, j; + GString *str = NULL; + int looks_like_old_svescaped = -1; + + /* we handle bash syntax here (note that ifup has #!/bin/bash. + * Thus, see https://www.gnu.org/software/bash/manual/html_node/Quoting.html#Quoting */ + + /* @value shall start with the first character after "FOO=" */ + + nm_assert(value); + nm_assert(to_free); + + /* we don't expect any newlines. They must be filtered out before-hand. + * We also don't support line continuation. */ + nm_assert(!NM_STRCHAR_ANY(value, ch, ch == '\n')); + + i = 0; + while (TRUE) { + if (value[i] == '\0') + goto out_value; + + if (g_ascii_isspace(value[i]) || value[i] == ';') { + gboolean has_semicolon = (value[i] == ';'); + + /* starting with space is only allowed, if the entire + * string consists of spaces (possibly terminated by a comment). + * This disallows for example + * LANG=C ls -1 + * LANG= ls -1 + * but allows + * LANG= #comment + * + * As a special case, we also allow one trailing semicolon, as long + * it is only followed by whitespace or a #-comment. + * FOO=; + * FOO=a; + * FOO=b ; #hallo + */ + j = i + 1; + while (g_ascii_isspace(value[j]) + || (!has_semicolon && (has_semicolon = (value[j] == ';')))) + j++; + if (!NM_IN_SET(value[j], '\0', '#')) + goto out_error; + goto out_value; + } + + if (value[i] == '\\') { + /* backslash escape */ + _gstr_init(&str, value, i); + i++; + if (G_UNLIKELY(value[i] == '\0')) { + /* we don't support line continuation */ + goto out_error; + } + g_string_append_c(str, value[i]); + i++; + goto loop1_next; + } + + if (value[i] == '\'') { + /* single quotes */ + _gstr_init(&str, value, i); + i++; + j = i; + while (TRUE) { + if (value[j] == '\0') { + /* unterminated single quote. We don't support line continuation */ + goto out_error; + } + if (value[j] == '\'') + break; + j++; + } + g_string_append_len(str, &value[i], j - i); + i = j + 1; + goto loop1_next; + } + + if (value[i] == '"') { + /* double quotes */ + _gstr_init(&str, value, i); + i++; + while (TRUE) { + if (value[i] == '"') { + i++; + break; + } + if (value[i] == '\0') { + /* unterminated double quote. We don't support line continuation. */ + goto out_error; + } + if (NM_IN_SET(value[i], '`', '$')) { + /* we don't support shell expansion. */ + goto out_error; + } + if (value[i] == '\\') { + i++; + if (value[i] == '\0') { + /* we don't support line continuation */ + goto out_error; + } + if (NM_IN_SET(value[i], '$', '`', '"', '\\')) { + /* Drop the backslash. */ + } else if (NM_IN_SET(value[i], '\'', '~')) { + /* '\'' and '~' in double quotes are not handled special by shell. + * However, old versions of svEscape() would wrongly use double-quoting + * with backslash escaping for these characters (expecting svUnescape() + * to remove the backslash). + * + * In order to preserve previous behavior, we continue to read such + * strings different then shell does. */ + + /* Actually, we can relax this. Old svEscape() escaped the entire value + * in a particular way with double quotes. + * If the value doesn't exactly look like something as created by svEscape(), + * don't do the compat hack and preserve the backslash. */ + if (looks_like_old_svescaped < 0) + looks_like_old_svescaped = _looks_like_old_svescaped(value); + if (!looks_like_old_svescaped) + g_string_append_c(str, '\\'); + } else + g_string_append_c(str, '\\'); + } + g_string_append_c(str, value[i]); + i++; + } + goto loop1_next; + } + + if (value[i] == '$' && value[i + 1] == '\'') { + /* ANSI-C Quoting */ + _gstr_init(&str, value, i); + i += 2; + while (TRUE) { + char ch; + + if (value[i] == '\'') { + i++; + break; + } + if (value[i] == '\0') { + /* unterminated double quote. We don't support line continuation. */ + goto out_error; + } + if (value[i] == '\\') { + i++; + if (value[i] == '\0') { + /* we don't support line continuation */ + goto out_error; + } + switch (value[i]) { + case 'a': + ch = '\a'; + break; + case 'b': + ch = '\b'; + break; + case 'e': + ch = '\e'; + break; + case 'E': + ch = '\E'; + break; + case 'f': + ch = '\f'; + break; + case 'n': + ch = '\n'; + break; + case 'r': + ch = '\r'; + break; + case 't': + ch = '\t'; + break; + case 'v': + ch = '\v'; + break; + case '?': + ch = '\?'; + break; + case '"': + ch = '"'; + break; + case '\\': + ch = '\\'; + break; + case '\'': + ch = '\''; + break; + default: + if (_ch_octal_is(value[i])) { + guint v; + + v = _ch_octal_get(value[i]); + i++; + if (_ch_octal_is(value[i])) { + v = (v * 8) + _ch_octal_get(value[i]); + i++; + if (_ch_octal_is(value[i])) { + v = (v * 8) + _ch_octal_get(value[i]); + i++; + } + } + /* like bash, we cut too large numbers off. E.g. A=$'\772' becomes 0xfa */ + g_string_append_c(str, (guint8) v); + } else if (NM_IN_SET(value[i], 'x', 'u', 'U')) { + const char escape_type = value[i]; + int max_digits = escape_type == 'x' ? 2 : escape_type == 'u' ? 4 : 8; + guint64 v; + + i++; + if (!_ch_hex_is(value[i])) { + /* missing hex value after "\x" escape. This is treated like no escaping. */ + g_string_append_c(str, '\\'); + g_string_append_c(str, escape_type); + } else { + v = _ch_hex_get(value[i]); + i++; + + while (--max_digits > 0) { + if (!_ch_hex_is(value[i])) + break; + v = v * 16 + _ch_hex_get(value[i]); + i++; + } + if (escape_type == 'x') + g_string_append_c(str, v); + else { + /* we treat the unicode escapes as utf-8 encoded values. */ + g_string_append_unichar(str, v); + } + } + } else { + g_string_append_c(str, '\\'); + g_string_append_c(str, value[i]); + i++; + } + goto loop_ansic_next; + } + } else + ch = value[i]; + g_string_append_c(str, ch); + i++; +loop_ansic_next:; + } + goto loop1_next; + } + + if (NM_IN_SET(value[i], '|', '&', '(', ')', '<', '>')) { + /* shell metacharacters are not supported without quoting. + * Note that ';' is already handled above. */ + goto out_error; + } + + /* an unquoted, regular character. Just consume it directly. */ + if (str) + g_string_append_c(str, value[i]); + i++; + +loop1_next:; + } + + nm_assert_not_reached(); out_value: - if (i == 0) { - nm_assert (!str); - *to_free = NULL; - return ""; - } - - if (str) { - if (str->len == 0 || str->str[0] == '\0') { - g_string_free (str, TRUE); - *to_free = NULL; - return ""; - } else { - *to_free = g_string_free (str, FALSE); - return *to_free; - } - } - - if (value[i] != '\0') { - *to_free = g_strndup (value, i); - return *to_free; - } - - *to_free = NULL; - return value; + if (i == 0) { + nm_assert(!str); + *to_free = NULL; + return ""; + } + + if (str) { + if (str->len == 0 || str->str[0] == '\0') { + g_string_free(str, TRUE); + *to_free = NULL; + return ""; + } else { + *to_free = g_string_free(str, FALSE); + return *to_free; + } + } + + if (value[i] != '\0') { + *to_free = g_strndup(value, i); + return *to_free; + } + + *to_free = NULL; + return value; out_error: - if (str) - g_string_free (str, TRUE); - *to_free = NULL; - return NULL; + if (str) + g_string_free(str, TRUE); + *to_free = NULL; + return NULL; } /*****************************************************************************/ shvarFile * -svFile_new (const char *name, - int fd, - const char *content) +svFile_new(const char *name, int fd, const char *content) { - shvarFile *s; - const char *p; - const char *q; - - nm_assert (name); - nm_assert (fd >= -1); - - s = g_slice_new (shvarFile); - *s = (shvarFile) { - .fileName = g_strdup (name), - .fd = fd, - .lst_head = C_LIST_INIT (s->lst_head), - .lst_idx = g_hash_table_new (nm_pstr_hash, nm_pstr_equal), - }; - - if (content) { - for (p = content; (q = strchr (p, '\n')) != NULL; p = q + 1) - _line_link_parse (s, p, q - p); - if (p[0]) - _line_link_parse (s, p, strlen (p)); - } - - return s; + shvarFile * s; + const char *p; + const char *q; + + nm_assert(name); + nm_assert(fd >= -1); + + s = g_slice_new(shvarFile); + *s = (shvarFile){ + .fileName = g_strdup(name), + .fd = fd, + .lst_head = C_LIST_INIT(s->lst_head), + .lst_idx = g_hash_table_new(nm_pstr_hash, nm_pstr_equal), + }; + + if (content) { + for (p = content; (q = strchr(p, '\n')) != NULL; p = q + 1) + _line_link_parse(s, p, q - p); + if (p[0]) + _line_link_parse(s, p, strlen(p)); + } + + return s; } const char * -svFileGetName (const shvarFile *s) +svFileGetName(const shvarFile *s) { - nm_assert (s); + nm_assert(s); - return s->fileName; + return s->fileName; } void -_nmtst_svFileSetName (shvarFile *s, const char *fileName) +_nmtst_svFileSetName(shvarFile *s, const char *fileName) { - /* changing the file name is not supported for regular - * operation. Only allowed to use in tests, otherwise, - * the filename is immutable. */ - g_free (s->fileName); - s->fileName = g_strdup (fileName); + /* changing the file name is not supported for regular + * operation. Only allowed to use in tests, otherwise, + * the filename is immutable. */ + g_free(s->fileName); + s->fileName = g_strdup(fileName); } void -_nmtst_svFileSetModified (shvarFile *s) +_nmtst_svFileSetModified(shvarFile *s) { - /* marking a file as modified is only for testing. */ - s->modified = TRUE; + /* marking a file as modified is only for testing. */ + s->modified = TRUE; } /*****************************************************************************/ static void -ASSERT_shvarLine (const shvarLine *line) +ASSERT_shvarLine(const shvarLine *line) { #if NM_MORE_ASSERTS > 5 - const char *s, *s2; - - nm_assert (line); - if (!line->key) { - nm_assert (line->line); - nm_assert (!line->key_with_prefix); - s = nm_str_skip_leading_spaces (line->line); - s2 = strchr (s, '='); - nm_assert (!s2 || !_shell_is_name (s, s2 - s)); - } else { - nm_assert (line->key_with_prefix); - nm_assert (line->key == nm_str_skip_leading_spaces (line->key_with_prefix)); - nm_assert (_shell_is_name (line->key, -1)); - } + const char *s, *s2; + + nm_assert(line); + if (!line->key) { + nm_assert(line->line); + nm_assert(!line->key_with_prefix); + s = nm_str_skip_leading_spaces(line->line); + s2 = strchr(s, '='); + nm_assert(!s2 || !_shell_is_name(s, s2 - s)); + } else { + nm_assert(line->key_with_prefix); + nm_assert(line->key == nm_str_skip_leading_spaces(line->key_with_prefix)); + nm_assert(_shell_is_name(line->key, -1)); + } #endif } static shvarLine * -line_new_parse (const char *value, gsize len) +line_new_parse(const char *value, gsize len) { - shvarLine *line; - gsize k, e; - - nm_assert (value); - - line = g_slice_new (shvarLine); - *line = (shvarLine) { - .lst = C_LIST_INIT (line->lst), - .dirty = TRUE, - }; - - for (k = 0; k < len; k++) { - if (g_ascii_isspace (value[k])) - continue; - - if ( g_ascii_isalpha (value[k]) - || value[k] == '_') { - for (e = k + 1; e < len; e++) { - if (value[e] == '=') { - nm_assert (_shell_is_name (&value[k], e - k)); - line->line = g_strndup (&value[e + 1], len - e - 1); - line->key_with_prefix = g_strndup (value, e); - line->key = &line->key_with_prefix[k]; - ASSERT_shvarLine (line); - return line; - } - if ( !g_ascii_isalnum (value[e]) - && value[e] != '_') - break; - } - } - break; - } - line->line = g_strndup (value, len); - ASSERT_shvarLine (line); - return line; + shvarLine *line; + gsize k, e; + + nm_assert(value); + + line = g_slice_new(shvarLine); + *line = (shvarLine){ + .lst = C_LIST_INIT(line->lst), + .dirty = TRUE, + }; + + for (k = 0; k < len; k++) { + if (g_ascii_isspace(value[k])) + continue; + + if (g_ascii_isalpha(value[k]) || value[k] == '_') { + for (e = k + 1; e < len; e++) { + if (value[e] == '=') { + nm_assert(_shell_is_name(&value[k], e - k)); + line->line = g_strndup(&value[e + 1], len - e - 1); + line->key_with_prefix = g_strndup(value, e); + line->key = &line->key_with_prefix[k]; + ASSERT_shvarLine(line); + return line; + } + if (!g_ascii_isalnum(value[e]) && value[e] != '_') + break; + } + } + break; + } + line->line = g_strndup(value, len); + ASSERT_shvarLine(line); + return line; } static shvarLine * -line_new_build (const char *key, const char *value) +line_new_build(const char *key, const char *value) { - char *value_escaped = NULL; - shvarLine *line; - char *new_key; - - value = svEscape (value, &value_escaped); - - line = g_slice_new (shvarLine); - new_key = g_strdup (key), - *line = (shvarLine) { - .lst = C_LIST_INIT (line->lst), - .line = value_escaped ?: g_strdup (value), - .key_with_prefix = new_key, - .key = new_key, - .dirty = FALSE, - }; - ASSERT_shvarLine (line); - return line; + char * value_escaped = NULL; + shvarLine *line; + char * new_key; + + value = svEscape(value, &value_escaped); + + line = g_slice_new(shvarLine); + new_key = g_strdup(key), *line = (shvarLine){ + .lst = C_LIST_INIT(line->lst), + .line = value_escaped ?: g_strdup(value), + .key_with_prefix = new_key, + .key = new_key, + .dirty = FALSE, + }; + ASSERT_shvarLine(line); + return line; } static gboolean -line_set (shvarLine *line, const char *value) +line_set(shvarLine *line, const char *value) { - char *value_escaped = NULL; - gboolean changed = FALSE; - - ASSERT_shvarLine (line); - nm_assert (line->key); - - line->dirty = FALSE; - - if (line->key != line->key_with_prefix) { - memmove (line->key_with_prefix, line->key, strlen (line->key) + 1); - line->key = line->key_with_prefix; - changed = TRUE; - ASSERT_shvarLine (line); - } - - value = svEscape (value, &value_escaped); - - if (line->line) { - if (nm_streq (value, line->line)) { - g_free (value_escaped); - return changed; - } - g_free (line->line); - } - - line->line = value_escaped ?: g_strdup (value); - ASSERT_shvarLine (line); - return TRUE; + char * value_escaped = NULL; + gboolean changed = FALSE; + + ASSERT_shvarLine(line); + nm_assert(line->key); + + line->dirty = FALSE; + + if (line->key != line->key_with_prefix) { + memmove(line->key_with_prefix, line->key, strlen(line->key) + 1); + line->key = line->key_with_prefix; + changed = TRUE; + ASSERT_shvarLine(line); + } + + value = svEscape(value, &value_escaped); + + if (line->line) { + if (nm_streq(value, line->line)) { + g_free(value_escaped); + return changed; + } + g_free(line->line); + } + + line->line = value_escaped ?: g_strdup(value); + ASSERT_shvarLine(line); + return TRUE; } static void -line_free (shvarLine *line) +line_free(shvarLine *line) { - ASSERT_shvarLine (line); - c_list_unlink_stale (&line->lst); - g_free (line->line); - g_free (line->key_with_prefix); - g_slice_free (shvarLine, line); + ASSERT_shvarLine(line); + c_list_unlink_stale(&line->lst); + g_free(line->line); + g_free(line->key_with_prefix); + g_slice_free(shvarLine, line); } /*****************************************************************************/ static void -_line_link_parse (shvarFile *s, const char *value, gsize len) +_line_link_parse(shvarFile *s, const char *value, gsize len) { - shvarLine *line; + shvarLine *line; - line = line_new_parse (value, len); - if (!line->key) - goto do_link; + line = line_new_parse(value, len); + if (!line->key) + goto do_link; - if (G_UNLIKELY (!g_hash_table_insert (s->lst_idx, line, line))) { - shvarLine *existing_key; - shvarLine *existing_val; + if (G_UNLIKELY(!g_hash_table_insert(s->lst_idx, line, line))) { + shvarLine *existing_key; + shvarLine *existing_val; - /* Slow-path: we have duplicate keys. Fix the mess we created. - * Unfortunately, g_hash_table_insert() now had to allocate an extra - * array to track the keys/values differently. I wish there was an - * GHashTable API to add a key only if it does not exist yet. */ + /* Slow-path: we have duplicate keys. Fix the mess we created. + * Unfortunately, g_hash_table_insert() now had to allocate an extra + * array to track the keys/values differently. I wish there was an + * GHashTable API to add a key only if it does not exist yet. */ - if (!g_hash_table_lookup_extended (s->lst_idx, line, (gpointer *) &existing_key, (gpointer *) &existing_val)) - nm_assert_not_reached (); + if (!g_hash_table_lookup_extended(s->lst_idx, + line, + (gpointer *) &existing_key, + (gpointer *) &existing_val)) + nm_assert_not_reached(); - nm_assert (existing_val == line); - nm_assert (existing_key != line); - line->prev_shadowed = existing_key; - g_hash_table_replace (s->lst_idx, line, line); - } + nm_assert(existing_val == line); + nm_assert(existing_key != line); + line->prev_shadowed = existing_key; + g_hash_table_replace(s->lst_idx, line, line); + } do_link: - c_list_link_tail (&s->lst_head, &line->lst); + c_list_link_tail(&s->lst_head, &line->lst); } /*****************************************************************************/ - /* Open the file , returning a shvarFile on success and NULL on failure. * Add a wrinkle to let the caller specify whether or not to create the file * (actually, return a structure anyway) if it doesn't exist. */ static shvarFile * -svOpenFileInternal (const char *name, gboolean create, GError **error) +svOpenFileInternal(const char *name, gboolean create, GError **error) { - gboolean closefd = FALSE; - int errsv = 0; - gs_free char *content = NULL; - gs_free_error GError *local = NULL; - nm_auto_close int fd = -1; - - if (create) - fd = open (name, O_RDWR | O_CLOEXEC); /* NOT O_CREAT */ - if (fd < 0) { - /* try read-only */ - fd = open (name, O_RDONLY | O_CLOEXEC); /* NOT O_CREAT */ - if (fd < 0) - errsv = errno; - else - closefd = TRUE; - } - - if (fd < 0) { - if (create) - return svFile_new (name, -1, NULL); - - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv), - "Could not read file '%s': %s", - name, nm_strerror_native (errsv)); - return NULL; - } - - if (!nm_utils_fd_get_contents (closefd ? nm_steal_fd (&fd) : fd, - closefd, - 10 * 1024 * 1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &content, - NULL, - NULL, - &local)) { - if (create) - return svFile_new (name, -1, NULL); - - g_set_error (error, G_FILE_ERROR, - local->domain == G_FILE_ERROR ? local->code : G_FILE_ERROR_FAILED, - "Could not read file '%s': %s", - name, local->message); - return NULL; - } - - /* closefd is set if we opened the file read-only, so go ahead and - * close it, because we can't write to it anyway */ - nm_assert (closefd || fd >= 0); - return svFile_new (name, - !closefd - ? nm_steal_fd (&fd) - : -1, - content); + gboolean closefd = FALSE; + int errsv = 0; + gs_free char *content = NULL; + gs_free_error GError *local = NULL; + nm_auto_close int fd = -1; + + if (create) + fd = open(name, O_RDWR | O_CLOEXEC); /* NOT O_CREAT */ + if (fd < 0) { + /* try read-only */ + fd = open(name, O_RDONLY | O_CLOEXEC); /* NOT O_CREAT */ + if (fd < 0) + errsv = errno; + else + closefd = TRUE; + } + + if (fd < 0) { + if (create) + return svFile_new(name, -1, NULL); + + g_set_error(error, + G_FILE_ERROR, + g_file_error_from_errno(errsv), + "Could not read file '%s': %s", + name, + nm_strerror_native(errsv)); + return NULL; + } + + if (!nm_utils_fd_get_contents(closefd ? nm_steal_fd(&fd) : fd, + closefd, + 10 * 1024 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, + &content, + NULL, + NULL, + &local)) { + if (create) + return svFile_new(name, -1, NULL); + + g_set_error(error, + G_FILE_ERROR, + local->domain == G_FILE_ERROR ? local->code : G_FILE_ERROR_FAILED, + "Could not read file '%s': %s", + name, + local->message); + return NULL; + } + + /* closefd is set if we opened the file read-only, so go ahead and + * close it, because we can't write to it anyway */ + nm_assert(closefd || fd >= 0); + return svFile_new(name, !closefd ? nm_steal_fd(&fd) : -1, content); } /* Open the file , return shvarFile on success, NULL on failure */ shvarFile * -svOpenFile (const char *name, GError **error) +svOpenFile(const char *name, GError **error) { - return svOpenFileInternal (name, FALSE, error); + return svOpenFileInternal(name, FALSE, error); } /* Create a new file structure, returning actual data if the file exists, * and a suitable starting point if it doesn't. */ shvarFile * -svCreateFile (const char *name) +svCreateFile(const char *name) { - return svOpenFileInternal (name, TRUE, NULL); + return svOpenFileInternal(name, TRUE, NULL); } /*****************************************************************************/ static gboolean -_svKeyMatchesType (const char *key, SvKeyType match_key_type) +_svKeyMatchesType(const char *key, SvKeyType match_key_type) { - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ANY)) - return TRUE; - -#define _IS_NUMBERED(key, tag) \ - ({ \ - gint64 _idx; \ - \ - NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, tag, &_idx) \ - && _idx >= 0; \ - }) - - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTE_SVFORMAT)) { - if ( _IS_NUMBERED (key, "ADDRESS") - || _IS_NUMBERED (key, "NETMASK") - || _IS_NUMBERED (key, "GATEWAY") - || _IS_NUMBERED (key, "METRIC") - || _IS_NUMBERED (key, "OPTIONS")) - return TRUE; - } - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_IP4_ADDRESS)) { - if ( _IS_NUMBERED (key, "IPADDR") - || _IS_NUMBERED (key, "PREFIX") - || _IS_NUMBERED (key, "NETMASK") - || _IS_NUMBERED (key, "GATEWAY")) - return TRUE; - } - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_USER)) { - if (g_str_has_prefix (key, "NM_USER_")) - return TRUE; - } - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_TC)) { - if ( _IS_NUMBERED (key, "QDISC") - || _IS_NUMBERED (key, "FILTER")) - return TRUE; - } - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_SRIOV_VF)) { - if (_IS_NUMBERED (key, "SRIOV_VF")) - return TRUE; - } - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTING_RULE4)) { - if (_IS_NUMBERED (key, "ROUTING_RULE_")) - return TRUE; - } - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTING_RULE6)) { - if (_IS_NUMBERED (key, "ROUTING_RULE6_")) - return TRUE; - } - - return FALSE; + if (NM_FLAGS_HAS(match_key_type, SV_KEY_TYPE_ANY)) + return TRUE; + +#define _IS_NUMBERED(key, tag) \ + ({ \ + gint64 _idx; \ + \ + NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG(key, tag, &_idx) \ + &&_idx >= 0; \ + }) + + if (NM_FLAGS_HAS(match_key_type, SV_KEY_TYPE_ROUTE_SVFORMAT)) { + if (_IS_NUMBERED(key, "ADDRESS") || _IS_NUMBERED(key, "NETMASK") + || _IS_NUMBERED(key, "GATEWAY") || _IS_NUMBERED(key, "METRIC") + || _IS_NUMBERED(key, "OPTIONS")) + return TRUE; + } + if (NM_FLAGS_HAS(match_key_type, SV_KEY_TYPE_IP4_ADDRESS)) { + if (_IS_NUMBERED(key, "IPADDR") || _IS_NUMBERED(key, "PREFIX") + || _IS_NUMBERED(key, "NETMASK") || _IS_NUMBERED(key, "GATEWAY")) + return TRUE; + } + if (NM_FLAGS_HAS(match_key_type, SV_KEY_TYPE_USER)) { + if (g_str_has_prefix(key, "NM_USER_")) + return TRUE; + } + if (NM_FLAGS_HAS(match_key_type, SV_KEY_TYPE_TC)) { + if (_IS_NUMBERED(key, "QDISC") || _IS_NUMBERED(key, "FILTER")) + return TRUE; + } + if (NM_FLAGS_HAS(match_key_type, SV_KEY_TYPE_SRIOV_VF)) { + if (_IS_NUMBERED(key, "SRIOV_VF")) + return TRUE; + } + if (NM_FLAGS_HAS(match_key_type, SV_KEY_TYPE_ROUTING_RULE4)) { + if (_IS_NUMBERED(key, "ROUTING_RULE_")) + return TRUE; + } + if (NM_FLAGS_HAS(match_key_type, SV_KEY_TYPE_ROUTING_RULE6)) { + if (_IS_NUMBERED(key, "ROUTING_RULE6_")) + return TRUE; + } + + return FALSE; } gint64 -svNumberedParseKey (const char *key) +svNumberedParseKey(const char *key) { - gint64 idx; + gint64 idx; - if ( NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "ROUTING_RULE_", &idx) - || NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG (key, "ROUTING_RULE6_", &idx)) - return idx; - return -1; + if (NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG(key, "ROUTING_RULE_", &idx) + || NMS_IFCFG_RH_UTIL_IS_NUMBERED_TAG(key, "ROUTING_RULE6_", &idx)) + return idx; + return -1; } GHashTable * -svGetKeys (shvarFile *s, SvKeyType match_key_type) +svGetKeys(shvarFile *s, SvKeyType match_key_type) { - GHashTable *keys = NULL; - CList *current; - const shvarLine *line; - - nm_assert (s); - - c_list_for_each (current, &s->lst_head) { - line = c_list_entry (current, shvarLine, lst); - if ( line->key - && line->line - && _svKeyMatchesType (line->key, match_key_type)) { - /* we don't clone the keys. The keys are only valid - * until @s gets modified. */ - if (!keys) - keys = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, NULL); - g_hash_table_add (keys, (gpointer) line->key); - } - } - return keys; + GHashTable * keys = NULL; + CList * current; + const shvarLine *line; + + nm_assert(s); + + c_list_for_each (current, &s->lst_head) { + line = c_list_entry(current, shvarLine, lst); + if (line->key && line->line && _svKeyMatchesType(line->key, match_key_type)) { + /* we don't clone the keys. The keys are only valid + * until @s gets modified. */ + if (!keys) + keys = g_hash_table_new_full(nm_str_hash, g_str_equal, NULL, NULL); + g_hash_table_add(keys, (gpointer) line->key); + } + } + return keys; } static int -_get_keys_sorted_cmp (gconstpointer a, - gconstpointer b, - gpointer user_data) +_get_keys_sorted_cmp(gconstpointer a, gconstpointer b, gpointer user_data) { - const char *k_a = *((const char *const*) a); - const char *k_b = *((const char *const*) b); - gint64 n_a; - gint64 n_b; - - n_a = svNumberedParseKey (k_a); - n_b = svNumberedParseKey (k_b); - NM_CMP_DIRECT (n_a, n_b); - NM_CMP_RETURN (strcmp (k_a, k_b)); - nm_assert_not_reached (); - return 0; + const char *k_a = *((const char *const *) a); + const char *k_b = *((const char *const *) b); + gint64 n_a; + gint64 n_b; + + n_a = svNumberedParseKey(k_a); + n_b = svNumberedParseKey(k_b); + NM_CMP_DIRECT(n_a, n_b); + NM_CMP_RETURN(strcmp(k_a, k_b)); + nm_assert_not_reached(); + return 0; } const char ** -svGetKeysSorted (shvarFile *s, - SvKeyType match_key_type, - guint *out_len) +svGetKeysSorted(shvarFile *s, SvKeyType match_key_type, guint *out_len) { - gs_unref_hashtable GHashTable *keys_hash = NULL; - - keys_hash = svGetKeys (s, match_key_type); - if (!keys_hash) { - NM_SET_OUT (out_len, 0); - return NULL; - } - return (const char **) nm_utils_hash_keys_to_array (keys_hash, - _get_keys_sorted_cmp, - NULL, - out_len); + gs_unref_hashtable GHashTable *keys_hash = NULL; + + keys_hash = svGetKeys(s, match_key_type); + if (!keys_hash) { + NM_SET_OUT(out_len, 0); + return NULL; + } + return ( + const char **) nm_utils_hash_keys_to_array(keys_hash, _get_keys_sorted_cmp, NULL, out_len); } /*****************************************************************************/ const char * -svFindFirstNumberedKey (shvarFile *s, const char *key_prefix) +svFindFirstNumberedKey(shvarFile *s, const char *key_prefix) { - const shvarLine *line; + const shvarLine *line; - g_return_val_if_fail (s, NULL); - g_return_val_if_fail (key_prefix, NULL); + g_return_val_if_fail(s, NULL); + g_return_val_if_fail(key_prefix, NULL); - c_list_for_each_entry (line, &s->lst_head, lst) { - if ( line->key - && line->line - && nms_ifcfg_rh_utils_is_numbered_tag (line->key, key_prefix, NULL)) - return line->key; - } + c_list_for_each_entry (line, &s->lst_head, lst) { + if (line->key && line->line + && nms_ifcfg_rh_utils_is_numbered_tag(line->key, key_prefix, NULL)) + return line->key; + } - return NULL; + return NULL; } /*****************************************************************************/ static const char * -_svGetValue (shvarFile *s, const char *key, char **to_free) +_svGetValue(shvarFile *s, const char *key, char **to_free) { - const shvarLine *line; - const char *v; - - nm_assert (s); - nm_assert (_shell_is_name (key, -1)); - nm_assert (to_free); - - ASSERT_key_is_well_known (key); - - line = g_hash_table_lookup (s->lst_idx, &key); - - if (line && line->line) { - v = svUnescape (line->line, to_free); - if (!v) { - /* a wrongly quoted value is treated like the empty string. - * See also svWriteFile(), which handles unparsable values - * that way. */ - nm_assert (!*to_free); - return ""; - } - return v; - } - *to_free = NULL; - return NULL; + const shvarLine *line; + const char * v; + + nm_assert(s); + nm_assert(_shell_is_name(key, -1)); + nm_assert(to_free); + + ASSERT_key_is_well_known(key); + + line = g_hash_table_lookup(s->lst_idx, &key); + + if (line && line->line) { + v = svUnescape(line->line, to_free); + if (!v) { + /* a wrongly quoted value is treated like the empty string. + * See also svWriteFile(), which handles unparsable values + * that way. */ + nm_assert(!*to_free); + return ""; + } + return v; + } + *to_free = NULL; + return NULL; } /* Returns the value for key. The value is either owned by @s @@ -1116,13 +1114,13 @@ _svGetValue (shvarFile *s, const char *key, char **to_free) * - like svGetValueStr(), but does not ignore empty string values. */ const char * -svGetValue (shvarFile *s, const char *key, char **to_free) +svGetValue(shvarFile *s, const char *key, char **to_free) { - g_return_val_if_fail (s, NULL); - g_return_val_if_fail (key, NULL); - g_return_val_if_fail (to_free, NULL); + g_return_val_if_fail(s, NULL); + g_return_val_if_fail(key, NULL); + g_return_val_if_fail(to_free, NULL); - return _svGetValue (s, key, to_free); + return _svGetValue(s, key, to_free); } /* Returns the value for key. The value is either owned by @s @@ -1132,20 +1130,20 @@ svGetValue (shvarFile *s, const char *key, char **to_free) * - like svGetValueStr_cp(), but avoids cloning the value if possible. */ const char * -svGetValueStr (shvarFile *s, const char *key, char **to_free) +svGetValueStr(shvarFile *s, const char *key, char **to_free) { - const char *value; - - g_return_val_if_fail (s, NULL); - g_return_val_if_fail (key, NULL); - g_return_val_if_fail (to_free, NULL); - - value = _svGetValue (s, key, to_free); - if (!value || !value[0]) { - nm_assert (!*to_free); - return NULL; - } - return value; + const char *value; + + g_return_val_if_fail(s, NULL); + g_return_val_if_fail(key, NULL); + g_return_val_if_fail(to_free, NULL); + + value = _svGetValue(s, key, to_free); + if (!value || !value[0]) { + nm_assert(!*to_free); + return NULL; + } + return value; } /* Returns the value for key. The returned value must be freed @@ -1155,20 +1153,20 @@ svGetValueStr (shvarFile *s, const char *key, char **to_free) * - like svGetValueStr_cp(), but does not ignore an empty string. */ char * -svGetValue_cp (shvarFile *s, const char *key) +svGetValue_cp(shvarFile *s, const char *key) { - char *to_free; - const char *value; - - g_return_val_if_fail (s, NULL); - g_return_val_if_fail (key, NULL); - - value = _svGetValue (s, key, &to_free); - if (!value) { - nm_assert (!to_free); - return NULL; - } - return to_free ?: g_strdup (value); + char * to_free; + const char *value; + + g_return_val_if_fail(s, NULL); + g_return_val_if_fail(key, NULL); + + value = _svGetValue(s, key, &to_free); + if (!value) { + nm_assert(!to_free); + return NULL; + } + return to_free ?: g_strdup(value); } /* Returns the value for key. The returned value must be freed @@ -1179,20 +1177,20 @@ svGetValue_cp (shvarFile *s, const char *key) * - like svGetValue_cp(), but returns NULL instead of an empty string. */ char * -svGetValueStr_cp (shvarFile *s, const char *key) +svGetValueStr_cp(shvarFile *s, const char *key) { - char *to_free; - const char *value; - - g_return_val_if_fail (s, NULL); - g_return_val_if_fail (key, NULL); - - value = _svGetValue (s, key, &to_free); - if (!value || !value[0]) { - nm_assert (!to_free); - return NULL; - } - return to_free ?: g_strdup (value); + char * to_free; + const char *value; + + g_return_val_if_fail(s, NULL); + g_return_val_if_fail(key, NULL); + + value = _svGetValue(s, key, &to_free); + if (!value || !value[0]) { + nm_assert(!to_free); + return NULL; + } + return to_free ?: g_strdup(value); } /* svGetValueBoolean: @@ -1205,13 +1203,27 @@ svGetValueStr_cp (shvarFile *s, const char *key) * Returns: the parsed boolean value or @fallback. */ int -svGetValueBoolean (shvarFile *s, const char *key, int fallback) +svGetValueBoolean(shvarFile *s, const char *key, int fallback) { - gs_free char *to_free = NULL; - const char *value; + gs_free char *to_free = NULL; + const char * value; - value = _svGetValue (s, key, &to_free); - return svParseBoolean (value, fallback); + value = _svGetValue(s, key, &to_free); + return svParseBoolean(value, fallback); +} + +/* svGetValueTernary: + * @s: fhe file + * @key: the name of the key to read + * + * Reads a value @key and converts it to a NMTernary value. + * + * Returns: the parsed NMTernary + */ +NMTernary +svGetValueTernary(shvarFile *s, const char *key) +{ + return svGetValueBoolean(s, key, NM_TERNARY_DEFAULT); } /* svGetValueInt64: @@ -1225,173 +1237,171 @@ svGetValueBoolean (shvarFile *s, const char *key, int fallback) * Reads a value @key and converts it to an integer using _nm_utils_ascii_str_to_int64(). * In case of error, @errno will be set and @fallback returned. */ gint64 -svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 max, gint64 fallback) +svGetValueInt64(shvarFile *s, const char *key, guint base, gint64 min, gint64 max, gint64 fallback) { - char *to_free; - const char *value; - gint64 result; - int errsv; - - value = _svGetValue (s, key, &to_free); - if (!value) { - nm_assert (!to_free); - /* indicate that the key does not exist (or has a syntax error - * and svUnescape() failed). */ - errno = ENOKEY; - return fallback; - } - - result = _nm_utils_ascii_str_to_int64 (value, base, min, max, fallback); - if (to_free) { - errsv = errno; - g_free (to_free); - errno = errsv; - } - return result; + char * to_free; + const char *value; + gint64 result; + int errsv; + + value = _svGetValue(s, key, &to_free); + if (!value) { + nm_assert(!to_free); + /* indicate that the key does not exist (or has a syntax error + * and svUnescape() failed). */ + errno = ENOKEY; + return fallback; + } + + result = _nm_utils_ascii_str_to_int64(value, base, min, max, fallback); + if (to_free) { + errsv = errno; + g_free(to_free); + errno = errsv; + } + return result; } gboolean -svGetValueEnum (shvarFile *s, const char *key, - GType gtype, int *out_value, - GError **error) +svGetValueEnum(shvarFile *s, const char *key, GType gtype, int *out_value, GError **error) { - gs_free char *to_free = NULL; - const char *svalue; - gs_free char *err_token = NULL; - int value; - - svalue = _svGetValue (s, key, &to_free); - if (!svalue) { - /* don't touch out_value. The caller is supposed - * to initialize it with the default value. */ - return TRUE; - } - - if (!nm_utils_enum_from_str (gtype, svalue, &value, &err_token)) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "Invalid token \"%s\" in \"%s\" for %s", - err_token, svalue, key); - return FALSE; - } - - NM_SET_OUT (out_value, value); - return TRUE; + gs_free char *to_free = NULL; + const char * svalue; + gs_free char *err_token = NULL; + int value; + + svalue = _svGetValue(s, key, &to_free); + if (!svalue) { + /* don't touch out_value. The caller is supposed + * to initialize it with the default value. */ + return TRUE; + } + + if (!nm_utils_enum_from_str(gtype, svalue, &value, &err_token)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "Invalid token \"%s\" in \"%s\" for %s", + err_token, + svalue, + key); + return FALSE; + } + + NM_SET_OUT(out_value, value); + return TRUE; } /*****************************************************************************/ gboolean -svUnsetAll (shvarFile *s, SvKeyType match_key_type) +svUnsetAll(shvarFile *s, SvKeyType match_key_type) { - shvarLine *line; - gboolean changed = FALSE; - - g_return_val_if_fail (s, FALSE); - - c_list_for_each_entry (line, &s->lst_head, lst) { - ASSERT_shvarLine (line); - if ( line->key - && _svKeyMatchesType (line->key, match_key_type)) { - if (nm_clear_g_free (&line->line)) { - ASSERT_shvarLine (line); - changed = TRUE; - } - } - } - - if (changed) - s->modified = TRUE; - return changed; + shvarLine *line; + gboolean changed = FALSE; + + g_return_val_if_fail(s, FALSE); + + c_list_for_each_entry (line, &s->lst_head, lst) { + ASSERT_shvarLine(line); + if (line->key && _svKeyMatchesType(line->key, match_key_type)) { + if (nm_clear_g_free(&line->line)) { + ASSERT_shvarLine(line); + changed = TRUE; + } + } + } + + if (changed) + s->modified = TRUE; + return changed; } gboolean -svUnsetDirtyWellknown (shvarFile *s, NMTernary new_dirty_value) +svUnsetDirtyWellknown(shvarFile *s, NMTernary new_dirty_value) { - shvarLine *line; - gboolean changed = FALSE; - - g_return_val_if_fail (s, FALSE); - - c_list_for_each_entry (line, &s->lst_head, lst) { - const NMSIfcfgKeyTypeInfo *ti; - - ASSERT_shvarLine (line); - - if ( line->dirty - && line->key - && line->line - && (ti = nms_ifcfg_rh_utils_is_well_known_key (line->key)) - && !NM_FLAGS_HAS (ti->key_flags, NMS_IFCFG_KEY_TYPE_KEEP_WHEN_DIRTY)) { - if (nm_clear_g_free (&line->line)) { - ASSERT_shvarLine (line); - changed = TRUE; - } - } - - if (new_dirty_value != NM_TERNARY_DEFAULT) - line->dirty = (new_dirty_value != NM_TERNARY_FALSE); - } - - if (changed) - s->modified = TRUE; - return changed; + shvarLine *line; + gboolean changed = FALSE; + + g_return_val_if_fail(s, FALSE); + + c_list_for_each_entry (line, &s->lst_head, lst) { + const NMSIfcfgKeyTypeInfo *ti; + + ASSERT_shvarLine(line); + + if (line->dirty && line->key && line->line + && (ti = nms_ifcfg_rh_utils_is_well_known_key(line->key)) + && !NM_FLAGS_HAS(ti->key_flags, NMS_IFCFG_KEY_TYPE_KEEP_WHEN_DIRTY)) { + if (nm_clear_g_free(&line->line)) { + ASSERT_shvarLine(line); + changed = TRUE; + } + } + + if (new_dirty_value != NM_TERNARY_DEFAULT) + line->dirty = (new_dirty_value != NM_TERNARY_FALSE); + } + + if (changed) + s->modified = TRUE; + return changed; } /* Same as svSetValueStr() but it preserves empty @value -- contrary to * svSetValueStr() for which "" effectively means to remove the value. */ gboolean -svSetValue (shvarFile *s, const char *key, const char *value) +svSetValue(shvarFile *s, const char *key, const char *value) { - shvarLine *line; - shvarLine *l_shadowed; - gboolean changed = FALSE; - - g_return_val_if_fail (s, FALSE); - g_return_val_if_fail (key, FALSE); - - nm_assert (_shell_is_name (key, -1)); - - ASSERT_key_is_well_known (key); - - line = g_hash_table_lookup (s->lst_idx, &key); - if ( line - && (l_shadowed = line->prev_shadowed)) { - /* if we find multiple entries for the same key, we can - * delete the shadowed ones. */ - line->prev_shadowed = NULL; - changed = TRUE; - do { - shvarLine *l = l_shadowed; - - l_shadowed = l_shadowed->prev_shadowed; - line_free (l); - } while (l_shadowed); - } - - if (!value) { - if (line) { - /* We only clear the value, but leave the line entry. This way, if we - * happen to re-add the value, we write it to the same line again. */ - if (nm_clear_g_free (&line->line)) { - changed = TRUE; - } - } - } else { - if (!line) { - line = line_new_build (key, value); - if (!g_hash_table_add (s->lst_idx, line)) - nm_assert_not_reached (); - c_list_link_tail (&s->lst_head, &line->lst); - changed = TRUE; - } else { - if (line_set (line, value)) - changed = TRUE; - } - } - - if (changed) - s->modified = TRUE; - return changed; + shvarLine *line; + shvarLine *l_shadowed; + gboolean changed = FALSE; + + g_return_val_if_fail(s, FALSE); + g_return_val_if_fail(key, FALSE); + + nm_assert(_shell_is_name(key, -1)); + + ASSERT_key_is_well_known(key); + + line = g_hash_table_lookup(s->lst_idx, &key); + if (line && (l_shadowed = line->prev_shadowed)) { + /* if we find multiple entries for the same key, we can + * delete the shadowed ones. */ + line->prev_shadowed = NULL; + changed = TRUE; + do { + shvarLine *l = l_shadowed; + + l_shadowed = l_shadowed->prev_shadowed; + line_free(l); + } while (l_shadowed); + } + + if (!value) { + if (line) { + /* We only clear the value, but leave the line entry. This way, if we + * happen to re-add the value, we write it to the same line again. */ + if (nm_clear_g_free(&line->line)) { + changed = TRUE; + } + } + } else { + if (!line) { + line = line_new_build(key, value); + if (!g_hash_table_add(s->lst_idx, line)) + nm_assert_not_reached(); + c_list_link_tail(&s->lst_head, &line->lst); + changed = TRUE; + } else { + if (line_set(line, value)) + changed = TRUE; + } + } + + if (changed) + s->modified = TRUE; + return changed; } /* Set the variable equal to the value . @@ -1400,53 +1410,62 @@ svSetValue (shvarFile *s, const char *key, const char *value) * to the bottom of the file. */ gboolean -svSetValueStr (shvarFile *s, const char *key, const char *value) +svSetValueStr(shvarFile *s, const char *key, const char *value) { - return svSetValue (s, key, value && value[0] ? value : NULL); + return svSetValue(s, key, value && value[0] ? value : NULL); } gboolean -svSetValueInt64 (shvarFile *s, const char *key, gint64 value) +svSetValueInt64(shvarFile *s, const char *key, gint64 value) { - char buf[NM_DECIMAL_STR_MAX (value)]; + char buf[NM_DECIMAL_STR_MAX(value)]; + + return svSetValue(s, key, nm_sprintf_buf(buf, "%" G_GINT64_FORMAT, value)); +} - return svSetValue (s, key, nm_sprintf_buf (buf, "%"G_GINT64_FORMAT, value)); +gboolean +svSetValueInt64_cond(shvarFile *s, const char *key, gboolean do_set, gint64 value) +{ + if (do_set) + return svSetValueInt64(s, key, value); + else + return svUnsetValue(s, key); } gboolean -svSetValueInt64_cond (shvarFile *s, const char *key, gboolean do_set, gint64 value) +svSetValueBoolean(shvarFile *s, const char *key, gboolean value) { - if (do_set) - return svSetValueInt64 (s, key, value); - else - return svUnsetValue (s, key); + return svSetValue(s, key, value ? "yes" : "no"); } gboolean -svSetValueBoolean (shvarFile *s, const char *key, gboolean value) +svSetValueTernary(shvarFile *s, const char *key, NMTernary value) { - return svSetValue (s, key, value ? "yes" : "no"); + if (NM_IN_SET(value, NM_TERNARY_TRUE, NM_TERNARY_FALSE)) + return svSetValueBoolean(s, key, (gboolean) value); + else + return svUnsetValue(s, key); } gboolean -svSetValueBoolean_cond_true (shvarFile *s, const char *key, gboolean value) +svSetValueBoolean_cond_true(shvarFile *s, const char *key, gboolean value) { - return svSetValue (s, key, value ? "yes" : NULL); + return svSetValue(s, key, value ? "yes" : NULL); } gboolean -svSetValueEnum (shvarFile *s, const char *key, GType gtype, int value) +svSetValueEnum(shvarFile *s, const char *key, GType gtype, int value) { - gs_free char *v = NULL; + gs_free char *v = NULL; - v = _nm_utils_enum_to_str_full (gtype, value, " ", NULL); - return svSetValueStr (s, key, v); + v = _nm_utils_enum_to_str_full(gtype, value, " ", NULL); + return svSetValueStr(s, key, v); } gboolean -svUnsetValue (shvarFile *s, const char *key) +svUnsetValue(shvarFile *s, const char *key) { - return svSetValue (s, key, NULL); + return svSetValue(s, key, NULL); } /*****************************************************************************/ @@ -1458,97 +1477,109 @@ svUnsetValue (shvarFile *s, const char *key) * open() syscall. */ gboolean -svWriteFile (shvarFile *s, int mode, GError **error) +svWriteFile(shvarFile *s, int mode, GError **error) { - FILE *f; - int tmpfd; - CList *current; - int errsv; - - if (s->modified) { - if (s->fd == -1) - s->fd = open (s->fileName, O_WRONLY | O_CREAT | O_CLOEXEC, mode); - if (s->fd == -1) { - errsv = errno; - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv), - "Could not open file '%s' for writing: %s", - s->fileName, nm_strerror_native (errsv)); - return FALSE; - } - if (ftruncate (s->fd, 0) < 0) { - errsv = errno; - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv), - "Could not overwrite file '%s': %s", - s->fileName, nm_strerror_native (errsv)); - return FALSE; - } - - tmpfd = fcntl (s->fd, F_DUPFD_CLOEXEC, 0); - if (tmpfd == -1) { - errsv = errno; - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv), - "Internal error writing file '%s': %s", - s->fileName, nm_strerror_native (errsv)); - return FALSE; - } - f = fdopen (tmpfd, "w"); - if (!f) { - errsv = errno; - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv), - "Internal error writing file '%s': %s", - s->fileName, nm_strerror_native (errsv)); - return FALSE; - } - fseek (f, 0, SEEK_SET); - c_list_for_each (current, &s->lst_head) { - const shvarLine *line = c_list_entry (current, shvarLine, lst); - const char *str; - char *s_tmp; - gboolean valid_value; - - ASSERT_shvarLine (line); - - if (!line->key) { - str = nm_str_skip_leading_spaces (line->line); - if (NM_IN_SET (str[0], '\0', '#')) - fprintf (f, "%s\n", line->line); - else - fprintf (f, "#NM: %s\n", line->line); - continue; - } - - if (!line->line) - continue; - - /* we check that the assignment can be properly unescaped. */ - valid_value = !!svUnescape (line->line, &s_tmp); - g_free (s_tmp); - - if (valid_value) - fprintf (f, "%s=%s\n", line->key_with_prefix, line->line); - else { - fprintf (f, "%s=\n", line->key); - fprintf (f, "#NM: %s=%s\n", line->key_with_prefix, line->line); - } - } - fclose (f); - } - - return TRUE; + FILE * f; + int tmpfd; + CList *current; + int errsv; + + if (s->modified) { + if (s->fd == -1) + s->fd = open(s->fileName, O_WRONLY | O_CREAT | O_CLOEXEC, mode); + if (s->fd == -1) { + errsv = errno; + g_set_error(error, + G_FILE_ERROR, + g_file_error_from_errno(errsv), + "Could not open file '%s' for writing: %s", + s->fileName, + nm_strerror_native(errsv)); + return FALSE; + } + if (ftruncate(s->fd, 0) < 0) { + errsv = errno; + g_set_error(error, + G_FILE_ERROR, + g_file_error_from_errno(errsv), + "Could not overwrite file '%s': %s", + s->fileName, + nm_strerror_native(errsv)); + return FALSE; + } + + tmpfd = fcntl(s->fd, F_DUPFD_CLOEXEC, 0); + if (tmpfd == -1) { + errsv = errno; + g_set_error(error, + G_FILE_ERROR, + g_file_error_from_errno(errsv), + "Internal error writing file '%s': %s", + s->fileName, + nm_strerror_native(errsv)); + return FALSE; + } + f = fdopen(tmpfd, "w"); + if (!f) { + errsv = errno; + g_set_error(error, + G_FILE_ERROR, + g_file_error_from_errno(errsv), + "Internal error writing file '%s': %s", + s->fileName, + nm_strerror_native(errsv)); + return FALSE; + } + fseek(f, 0, SEEK_SET); + c_list_for_each (current, &s->lst_head) { + const shvarLine *line = c_list_entry(current, shvarLine, lst); + const char * str; + char * s_tmp; + gboolean valid_value; + + ASSERT_shvarLine(line); + + if (!line->key) { + str = nm_str_skip_leading_spaces(line->line); + if (NM_IN_SET(str[0], '\0', '#')) + fprintf(f, "%s\n", line->line); + else + fprintf(f, "#NM: %s\n", line->line); + continue; + } + + if (!line->line) + continue; + + /* we check that the assignment can be properly unescaped. */ + valid_value = !!svUnescape(line->line, &s_tmp); + g_free(s_tmp); + + if (valid_value) + fprintf(f, "%s=%s\n", line->key_with_prefix, line->line); + else { + fprintf(f, "%s=\n", line->key); + fprintf(f, "#NM: %s=%s\n", line->key_with_prefix, line->line); + } + } + fclose(f); + } + + return TRUE; } void -svCloseFile (shvarFile *s) +svCloseFile(shvarFile *s) { - shvarLine *line; + shvarLine *line; - g_return_if_fail (s != NULL); + g_return_if_fail(s != NULL); - if (s->fd >= 0) - nm_close (s->fd); - g_free (s->fileName); - g_hash_table_destroy (s->lst_idx); - while ((line = c_list_first_entry (&s->lst_head, shvarLine, lst))) - line_free (line); - g_slice_free (shvarFile, s); + if (s->fd >= 0) + nm_close(s->fd); + g_free(s->fileName); + g_hash_table_destroy(s->lst_idx); + while ((line = c_list_first_entry(&s->lst_head, shvarLine, lst))) + line_free(line); + g_slice_free(shvarFile, s); } diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h index 410284f8..60324be0 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.h +++ b/src/settings/plugins/ifcfg-rh/shvar.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 1999 Red Hat, Inc. */ @@ -9,85 +9,83 @@ typedef struct _shvarFile shvarFile; typedef enum { - SV_KEY_TYPE_ANY = (1LL << 0), - SV_KEY_TYPE_ROUTE_SVFORMAT = (1LL << 1), - SV_KEY_TYPE_IP4_ADDRESS = (1LL << 2), - SV_KEY_TYPE_TC = (1LL << 3), - SV_KEY_TYPE_USER = (1LL << 4), - SV_KEY_TYPE_SRIOV_VF = (1LL << 5), - SV_KEY_TYPE_ROUTING_RULE4 = (1LL << 6), - SV_KEY_TYPE_ROUTING_RULE6 = (1LL << 7), + SV_KEY_TYPE_ANY = (1LL << 0), + SV_KEY_TYPE_ROUTE_SVFORMAT = (1LL << 1), + SV_KEY_TYPE_IP4_ADDRESS = (1LL << 2), + SV_KEY_TYPE_TC = (1LL << 3), + SV_KEY_TYPE_USER = (1LL << 4), + SV_KEY_TYPE_SRIOV_VF = (1LL << 5), + SV_KEY_TYPE_ROUTING_RULE4 = (1LL << 6), + SV_KEY_TYPE_ROUTING_RULE6 = (1LL << 7), } SvKeyType; -const char *svFileGetName (const shvarFile *s); +const char *svFileGetName(const shvarFile *s); -void _nmtst_svFileSetName (shvarFile *s, const char *fileName); -void _nmtst_svFileSetModified (shvarFile *s); +void _nmtst_svFileSetName(shvarFile *s, const char *fileName); +void _nmtst_svFileSetModified(shvarFile *s); /*****************************************************************************/ -shvarFile *svFile_new (const char *name, - int fd, - const char *content); +shvarFile *svFile_new(const char *name, int fd, const char *content); /* Create the file , return a shvarFile (never fails) */ -shvarFile *svCreateFile (const char *name); +shvarFile *svCreateFile(const char *name); /* Open the file , return shvarFile on success, NULL on failure */ -shvarFile *svOpenFile (const char *name, GError **error); +shvarFile *svOpenFile(const char *name, GError **error); /*****************************************************************************/ -const char *svFindFirstNumberedKey (shvarFile *s, const char *key_prefix); +const char *svFindFirstNumberedKey(shvarFile *s, const char *key_prefix); /* Get the value associated with the key, and leave the current pointer * pointing at the line containing the value. The char* returned MUST * be freed by the caller. */ -const char *svGetValue (shvarFile *s, const char *key, char **to_free); -char *svGetValue_cp (shvarFile *s, const char *key); +const char *svGetValue(shvarFile *s, const char *key, char **to_free); +char * svGetValue_cp(shvarFile *s, const char *key); -const char *svGetValueStr (shvarFile *s, const char *key, char **to_free); -char *svGetValueStr_cp (shvarFile *s, const char *key); +const char *svGetValueStr(shvarFile *s, const char *key, char **to_free); +char * svGetValueStr_cp(shvarFile *s, const char *key); -int svParseBoolean (const char *value, int def); +int svParseBoolean(const char *value, int def); -gint64 svNumberedParseKey (const char *key); +gint64 svNumberedParseKey(const char *key); -GHashTable *svGetKeys (shvarFile *s, SvKeyType match_key_type); +GHashTable *svGetKeys(shvarFile *s, SvKeyType match_key_type); -const char **svGetKeysSorted (shvarFile *s, - SvKeyType match_key_type, - guint *out_len); +const char **svGetKeysSorted(shvarFile *s, SvKeyType match_key_type, guint *out_len); /* return TRUE if resolves to any truth value (e.g. "yes", "y", "true") * return FALSE if resolves to any non-truth value (e.g. "no", "n", "false") * return otherwise */ -int svGetValueBoolean (shvarFile *s, const char *key, int def); +int svGetValueBoolean(shvarFile *s, const char *key, int def); -gint64 svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 max, gint64 fallback); +NMTernary svGetValueTernary(shvarFile *s, const char *key); -gboolean svGetValueEnum (shvarFile *s, const char *key, - GType gtype, int *out_value, - GError **error); +gint64 +svGetValueInt64(shvarFile *s, const char *key, guint base, gint64 min, gint64 max, gint64 fallback); + +gboolean svGetValueEnum(shvarFile *s, const char *key, GType gtype, int *out_value, GError **error); /* Set the variable equal to the value . * If does not exist, and the pointer is set, append * the key=value pair after that line. Otherwise, prepend the pair * to the top of the file. */ -gboolean svSetValue (shvarFile *s, const char *key, const char *value); -gboolean svSetValueStr (shvarFile *s, const char *key, const char *value); -gboolean svSetValueBoolean (shvarFile *s, const char *key, gboolean value); -gboolean svSetValueBoolean_cond_true (shvarFile *s, const char *key, gboolean value); -gboolean svSetValueInt64 (shvarFile *s, const char *key, gint64 value); -gboolean svSetValueInt64_cond (shvarFile *s, const char *key, gboolean do_set, gint64 value); -gboolean svSetValueEnum (shvarFile *s, const char *key, GType gtype, int value); - -gboolean svUnsetValue (shvarFile *s, const char *key); -gboolean svUnsetAll (shvarFile *s, SvKeyType match_key_type); -gboolean svUnsetDirtyWellknown (shvarFile *s, NMTernary new_dirty_value); +gboolean svSetValue(shvarFile *s, const char *key, const char *value); +gboolean svSetValueStr(shvarFile *s, const char *key, const char *value); +gboolean svSetValueBoolean(shvarFile *s, const char *key, gboolean value); +gboolean svSetValueBoolean_cond_true(shvarFile *s, const char *key, gboolean value); +gboolean svSetValueInt64(shvarFile *s, const char *key, gint64 value); +gboolean svSetValueInt64_cond(shvarFile *s, const char *key, gboolean do_set, gint64 value); +gboolean svSetValueEnum(shvarFile *s, const char *key, GType gtype, int value); +gboolean svSetValueTernary(shvarFile *s, const char *key, NMTernary value); + +gboolean svUnsetValue(shvarFile *s, const char *key); +gboolean svUnsetAll(shvarFile *s, SvKeyType match_key_type); +gboolean svUnsetDirtyWellknown(shvarFile *s, NMTernary new_dirty_value); /* Write the current contents iff modified. Returns FALSE on error * and TRUE on success. Do not write if no values have been modified. @@ -95,30 +93,30 @@ gboolean svUnsetDirtyWellknown (shvarFile *s, NMTernary new_dirty_value); * re-writing an existing file, and is passed unchanged to the * open() syscall. */ -gboolean svWriteFile (shvarFile *s, int mode, GError **error); +gboolean svWriteFile(shvarFile *s, int mode, GError **error); static inline gboolean -svWriteFileWithoutDirtyWellknown (shvarFile *s, int mode, GError **error) +svWriteFileWithoutDirtyWellknown(shvarFile *s, int mode, GError **error) { - svUnsetDirtyWellknown (s, NM_TERNARY_FALSE); - return svWriteFile (s, mode, error); + svUnsetDirtyWellknown(s, NM_TERNARY_FALSE); + return svWriteFile(s, mode, error); } /* Close the file descriptor (if open) and free the shvarFile. */ -void svCloseFile (shvarFile *s); +void svCloseFile(shvarFile *s); -const char *svEscape (const char *s, char **to_free); -const char *svUnescape (const char *s, char **to_free); +const char *svEscape(const char *s, char **to_free); +const char *svUnescape(const char *s, char **to_free); static inline void -_nm_auto_shvar_file_close (shvarFile **p_s) +_nm_auto_shvar_file_close(shvarFile **p_s) { - if (*p_s) { - int errsv = errno; + if (*p_s) { + int errsv = errno; - svCloseFile (*p_s); - errno = errsv; - } + svCloseFile(*p_s); + errno = errsv; + } } #define nm_auto_shvar_file_close nm_auto(_nm_auto_shvar_file_close) diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_AP_Mode.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_AP_Mode.cexpected new file mode 100644 index 00000000..ccec2b81 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_AP_Mode.cexpected @@ -0,0 +1,19 @@ +ESSID=MySSID +MODE=Ap +CHANNEL=196 +MAC_ADDRESS_RANDOMIZATION=default +AP_ISOLATION=yes +TYPE=Wireless +PROXY_METHOD=none +BROWSER_ONLY=no +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +IPV6_ADDR_GEN_MODE=stable-privacy +NAME="Test Write Wi-Fi AP Mode" +UUID=${UUID} +ONBOOT=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-1 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-1 index c927389e..2af1daf3 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-1 +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-1 @@ -3,6 +3,6 @@ FOO='val wrong line F2=b F3='b -XXX=adf' - XXX2=val2 +XXA=adf' + XXA2=val2 ' diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-1.expected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-1.expected index 568b2efc..7f154073 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-1.expected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-1.expected @@ -6,7 +6,7 @@ bar= F2=b F3= #NM: F3='b -XXX= -#NM: XXX=adf' - XXX2=val2 +XXA= +#NM: XXA=adf' + XXA2=val2 #NM: ' diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 40d1bb8c..a4e9d804 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 - 2011 Red Hat, Inc. */ @@ -15,6 +15,7 @@ #include #include +#include "nm-glib-aux/nm-json-aux.h" #include "nm-utils.h" #include "nm-setting-connection.h" #include "nm-setting-wired.h" @@ -45,64 +46,69 @@ #include "nm-test-utils-core.h" -#define TEST_IFCFG_DIR NM_BUILD_SRCDIR"/src/settings/plugins/ifcfg-rh/tests/network-scripts" -#define TEST_SCRATCH_DIR NM_BUILD_BUILDDIR"/src/settings/plugins/ifcfg-rh/tests/network-scripts" -#define TEST_SCRATCH_DIR_TMP TEST_SCRATCH_DIR"/tmp" +#define TEST_IFCFG_DIR NM_BUILD_SRCDIR "/src/settings/plugins/ifcfg-rh/tests/network-scripts" +#define TEST_SCRATCH_DIR NM_BUILD_BUILDDIR "/src/settings/plugins/ifcfg-rh/tests/network-scripts" +#define TEST_SCRATCH_DIR_TMP TEST_SCRATCH_DIR "/tmp" -#define TEST_SCRATCH_ALIAS_BASE TEST_SCRATCH_DIR"/ifcfg-alias0" +#define TEST_SCRATCH_ALIAS_BASE TEST_SCRATCH_DIR "/ifcfg-alias0" /*****************************************************************************/ -#define _svOpenFile(testfile) \ - ({ \ - shvarFile *_f; \ - GError *_error = NULL; \ - const char *_testfile = (testfile); \ - \ - g_assert (_testfile); \ - _f = svOpenFile (_testfile, &_error); \ - nmtst_assert_success (_f, _error); \ - _f; \ - }) +#define _svOpenFile(testfile) \ + ({ \ + shvarFile * _f; \ + GError * _error = NULL; \ + const char *_testfile = (testfile); \ + \ + g_assert(_testfile); \ + _f = svOpenFile(_testfile, &_error); \ + nmtst_assert_success(_f, _error); \ + _f; \ + }) -#define _svGetValue_check(f, key, expected_value) \ - G_STMT_START { \ - const char *_val; \ - gs_free char *_to_free = NULL; \ - gs_free char *_val_string = NULL; \ - shvarFile *const _f = (f); \ - const char *const _key = (key); \ - \ - _val_string = svGetValueStr_cp (_f, _key); \ - _val = svGetValue (_f, _key, &_to_free); \ - g_assert_cmpstr (_val, ==, (expected_value)); \ - g_assert ( (!_val_string && (!_val || !_val[0])) \ - || ( _val_string && nm_streq0 (_val, _val_string))); \ - } G_STMT_END +#define _svGetValue_check(f, key, expected_value) \ + G_STMT_START \ + { \ + const char * _val; \ + gs_free char * _to_free = NULL; \ + gs_free char * _val_string = NULL; \ + shvarFile *const _f = (f); \ + const char *const _key = (key); \ + \ + _val_string = svGetValueStr_cp(_f, _key); \ + _val = svGetValue(_f, _key, &_to_free); \ + g_assert_cmpstr(_val, ==, (expected_value)); \ + g_assert((!_val_string && (!_val || !_val[0])) \ + || (_val_string && nm_streq0(_val, _val_string))); \ + } \ + G_STMT_END static void -_assert_reread_same (NMConnection *connection, NMConnection *reread) +_assert_reread_same(NMConnection *connection, NMConnection *reread) { - nmtst_assert_connection_verifies_without_normalization (reread); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_verifies_without_normalization(reread); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -_assert_reread_same_FIXME (NMConnection *connection, NMConnection *reread) +_assert_reread_same_FIXME(NMConnection *connection, NMConnection *reread) { - gs_unref_object NMConnection *connection_normalized = NULL; - gs_unref_hashtable GHashTable *settings = NULL; + gs_unref_object NMConnection *connection_normalized = NULL; + gs_unref_hashtable GHashTable *settings = NULL; - /* FIXME: these assertion failures should not happen as we expect - * that re-reading a connection after write yields the same result. - * - * Needs investation and fixing. */ - nmtst_assert_connection_verifies_without_normalization (reread); + /* FIXME: these assertion failures should not happen as we expect + * that re-reading a connection after write yields the same result. + * + * Needs investigation and fixing. */ + nmtst_assert_connection_verifies_without_normalization(reread); - connection_normalized = nmtst_connection_duplicate_and_normalize (connection); + connection_normalized = nmtst_connection_duplicate_and_normalize(connection); - g_assert (!nm_connection_compare (connection_normalized, reread, NM_SETTING_COMPARE_FLAG_EXACT)); - g_assert (!nm_connection_diff (connection_normalized, reread, NM_SETTING_COMPARE_FLAG_EXACT, &settings)); + g_assert(!nm_connection_compare(connection_normalized, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + g_assert(!nm_connection_diff(connection_normalized, + reread, + NM_SETTING_COMPARE_FLAG_EXACT, + &settings)); } /* dummy path for an "expected" file, meaning: don't check for expected @@ -110,4801 +116,5252 @@ _assert_reread_same_FIXME (NMConnection *connection, NMConnection *reread) static const char NO_EXPECTED[1]; static void -_assert_expected_content (NMConnection *connection, const char *filename, const char *expected) -{ - gs_free char *content_expectd = NULL; - gs_free char *content_written = NULL; - GError *error = NULL; - gsize len_expectd = 0; - gsize len_written = 0; - gboolean success; - const char *uuid = NULL; - - g_assert (NM_IS_CONNECTION (connection)); - g_assert (filename); - g_assert (g_file_test (filename, G_FILE_TEST_EXISTS)); - - g_assert (expected); - if (expected == NO_EXPECTED) - return; - - success = g_file_get_contents (filename, &content_written, &len_written, &error); - nmtst_assert_success (success, error); - - success = g_file_get_contents (expected, &content_expectd, &len_expectd, &error); - nmtst_assert_success (success, error); - - { - gsize i, j; - - for (i = 0; i < len_expectd; ) { - if (content_expectd[i] != '$') { - i++; - continue; - } - if (g_str_has_prefix (&content_expectd[i], "${UUID}")) { - GString *str; - - if (!uuid) { - uuid = nm_connection_get_uuid (connection); - g_assert (uuid); - } - - j = strlen (uuid); - - str = g_string_new_len (content_expectd, len_expectd); - g_string_erase (str, i, NM_STRLEN ("${UUID}")); - g_string_insert_len (str, i, uuid, j); - - g_free (content_expectd); - len_expectd = str->len; - content_expectd = g_string_free (str, FALSE); - i += j; - continue; - } - - /* other '$' is not supported. If need be, support escaping of - * '$' via '$$'. */ - g_assert_not_reached (); - } - } - - if ( len_expectd != len_written - || memcmp (content_expectd, content_written, len_expectd) != 0) { - if ( g_getenv ("NMTST_IFCFG_RH_UPDATE_EXPECTED") - || nm_streq0 (g_getenv ("NM_TEST_REGENERATE"), "1")) { - if (uuid) { - gs_free char *search = g_strdup_printf ("UUID=%s\n", uuid); - const char *s; - gsize i; - GString *str; - - s = content_written; - while (TRUE) { - s = strstr (s, search); - g_assert (s); - if ( s == content_written - || s[-1] == '\n') - break; - s += strlen (search); - } - - i = s - content_written; - - str = g_string_new_len (content_written, len_written); - g_string_erase (str, i, strlen (search)); - g_string_insert (str, i, "UUID=${UUID}\n"); - - len_written = str->len; - content_written = g_string_free (str, FALSE); - } - success = g_file_set_contents (expected, content_written, len_written, &error); - nmtst_assert_success (success, error); - } else { - g_error ("The content of \"%s\" (%zu) differs from \"%s\" (%zu). Set NMTST_IFCFG_RH_UPDATE_EXPECTED=yes to update the files inplace\n\n>>>%s<<<\n\n>>>%s<<<\n", - filename, len_written, - expected, len_expectd, - content_written, - content_expectd); - } - } -} - -#define _writer_update_connection_reread(connection, ifcfg_dir, filename, expected, out_reread, out_reread_same) \ - G_STMT_START { \ - gs_unref_object NMConnection *_connection = nmtst_connection_duplicate_and_normalize (connection); \ - NMConnection **_out_reread = (out_reread); \ - gboolean *_out_reread_same = (out_reread_same); \ - const char *_ifcfg_dir = (ifcfg_dir); \ - const char *_filename = (filename); \ - const char *_expected = (expected); \ - GError *_error = NULL; \ - gboolean _success; \ - \ - g_assert (_ifcfg_dir && _ifcfg_dir[0]); \ - g_assert (_filename && _filename[0]); \ - \ - _success = nms_ifcfg_rh_writer_write_connection (_connection, _ifcfg_dir, _filename, NULL, NULL, NULL, _out_reread, _out_reread_same, &_error); \ - nmtst_assert_success (_success, _error); \ - _assert_expected_content (_connection, _filename, _expected); \ - } G_STMT_END +_assert_expected_content(NMConnection *connection, const char *filename, const char *expected) +{ + gs_free char *content_expectd = NULL; + gs_free char *content_written = NULL; + GError * error = NULL; + gsize len_expectd = 0; + gsize len_written = 0; + gboolean success; + const char * uuid = NULL; + + g_assert(NM_IS_CONNECTION(connection)); + g_assert(filename); + g_assert(g_file_test(filename, G_FILE_TEST_EXISTS)); + + g_assert(expected); + if (expected == NO_EXPECTED) + return; + + success = g_file_get_contents(filename, &content_written, &len_written, &error); + nmtst_assert_success(success, error); + + success = g_file_get_contents(expected, &content_expectd, &len_expectd, &error); + nmtst_assert_success(success, error); + + { + gsize i, j; + + for (i = 0; i < len_expectd;) { + if (content_expectd[i] != '$') { + i++; + continue; + } + if (g_str_has_prefix(&content_expectd[i], "${UUID}")) { + GString *str; + + if (!uuid) { + uuid = nm_connection_get_uuid(connection); + g_assert(uuid); + } + + j = strlen(uuid); + + str = g_string_new_len(content_expectd, len_expectd); + g_string_erase(str, i, NM_STRLEN("${UUID}")); + g_string_insert_len(str, i, uuid, j); + + g_free(content_expectd); + len_expectd = str->len; + content_expectd = g_string_free(str, FALSE); + i += j; + continue; + } + + /* other '$' is not supported. If need be, support escaping of + * '$' via '$$'. */ + g_assert_not_reached(); + } + } + + if (len_expectd != len_written || memcmp(content_expectd, content_written, len_expectd) != 0) { + if (g_getenv("NMTST_IFCFG_RH_UPDATE_EXPECTED") + || nm_streq0(g_getenv("NM_TEST_REGENERATE"), "1")) { + if (uuid) { + gs_free char *search = g_strdup_printf("UUID=%s\n", uuid); + const char * s; + gsize i; + GString * str; + + s = content_written; + while (TRUE) { + s = strstr(s, search); + g_assert(s); + if (s == content_written || s[-1] == '\n') + break; + s += strlen(search); + } + + i = s - content_written; + + str = g_string_new_len(content_written, len_written); + g_string_erase(str, i, strlen(search)); + g_string_insert(str, i, "UUID=${UUID}\n"); + + len_written = str->len; + content_written = g_string_free(str, FALSE); + } + success = g_file_set_contents(expected, content_written, len_written, &error); + nmtst_assert_success(success, error); + } else { + g_error("The content of \"%s\" (%zu) differs from \"%s\" (%zu). Set " + "NMTST_IFCFG_RH_UPDATE_EXPECTED=yes to update the files " + "inplace\n\n>>>%s<<<\n\n>>>%s<<<\n", + filename, + len_written, + expected, + len_expectd, + content_written, + content_expectd); + } + } +} + +#define _writer_update_connection_reread(connection, \ + ifcfg_dir, \ + filename, \ + expected, \ + out_reread, \ + out_reread_same) \ + G_STMT_START \ + { \ + gs_unref_object NMConnection *_connection = \ + nmtst_connection_duplicate_and_normalize(connection); \ + NMConnection **_out_reread = (out_reread); \ + gboolean * _out_reread_same = (out_reread_same); \ + const char * _ifcfg_dir = (ifcfg_dir); \ + const char * _filename = (filename); \ + const char * _expected = (expected); \ + GError * _error = NULL; \ + gboolean _success; \ + \ + g_assert(_ifcfg_dir &&_ifcfg_dir[0]); \ + g_assert(_filename &&_filename[0]); \ + \ + _success = nms_ifcfg_rh_writer_write_connection(_connection, \ + _ifcfg_dir, \ + _filename, \ + NULL, \ + NULL, \ + NULL, \ + _out_reread, \ + _out_reread_same, \ + &_error); \ + nmtst_assert_success(_success, _error); \ + _assert_expected_content(_connection, _filename, _expected); \ + } \ + G_STMT_END #define _writer_update_connection(connection, ifcfg_dir, filename, expected) \ - G_STMT_START { \ - gs_unref_object NMConnection *_reread = NULL; \ - NMConnection *_c = (connection); \ - gboolean _reread_same = FALSE; \ - \ - _writer_update_connection_reread (_c, ifcfg_dir, filename, expected, &_reread, &_reread_same); \ - _assert_reread_same (_c, _reread); \ - g_assert (_reread_same); \ - } G_STMT_END + G_STMT_START \ + { \ + gs_unref_object NMConnection *_reread = NULL; \ + NMConnection * _c = (connection); \ + gboolean _reread_same = FALSE; \ + \ + _writer_update_connection_reread(_c, \ + ifcfg_dir, \ + filename, \ + expected, \ + &_reread, \ + &_reread_same); \ + _assert_reread_same(_c, _reread); \ + g_assert(_reread_same); \ + } \ + G_STMT_END static NMConnection * -_connection_from_file (const char *filename, - const char *network_file, - const char *test_type, - char **out_unhandled) +_connection_from_file(const char *filename, + const char *network_file, + const char *test_type, + char ** out_unhandled) { - NMConnection *connection; - GError *error = NULL; - char *unhandled_fallback = NULL; + NMConnection *connection; + GError * error = NULL; + char * unhandled_fallback = NULL; - g_assert (!out_unhandled || !*out_unhandled); + g_assert(!out_unhandled || !*out_unhandled); - connection = nmtst_connection_from_file (filename, network_file, test_type, - out_unhandled ?: &unhandled_fallback, &error); - g_assert_no_error (error); - g_assert (!unhandled_fallback); + connection = nmtst_connection_from_file(filename, + network_file, + test_type, + out_unhandled ?: &unhandled_fallback, + &error); + g_assert_no_error(error); + g_assert(!unhandled_fallback); - if (out_unhandled && *out_unhandled) - nmtst_assert_connection_verifies (connection); - else - nmtst_assert_connection_verifies_without_normalization (connection); - return connection; + if (out_unhandled && *out_unhandled) + nmtst_assert_connection_verifies(connection); + else + nmtst_assert_connection_verifies_without_normalization(connection); + return connection; } static void -_connection_from_file_fail (const char *filename, - const char *network_file, - const char *test_type, - GError **error) +_connection_from_file_fail(const char *filename, + const char *network_file, + const char *test_type, + GError ** error) { - NMConnection *connection; - GError *local = NULL; - char *unhandled = NULL; + NMConnection *connection; + GError * local = NULL; + char * unhandled = NULL; - connection = nmtst_connection_from_file (filename, network_file, test_type, &unhandled, &local); + connection = nmtst_connection_from_file(filename, network_file, test_type, &unhandled, &local); - g_assert (!connection); - g_assert (local); - g_assert (!unhandled); - g_propagate_error (error, local); + g_assert(!connection); + g_assert(local); + g_assert(!unhandled); + g_propagate_error(error, local); } static void -_writer_new_connection_reread (NMConnection *connection, - const char *ifcfg_dir, - char **out_filename, - const char *expected, - NMConnection **out_reread, - gboolean *out_reread_same) +_writer_new_connection_reread(NMConnection * connection, + const char * ifcfg_dir, + char ** out_filename, + const char * expected, + NMConnection **out_reread, + gboolean * out_reread_same) { - gboolean success; - GError *error = NULL; - char *filename = NULL; - gs_unref_object NMConnection *con_verified = NULL; - gs_unref_object NMConnection *reread_copy = NULL; - NMConnection **reread = out_reread ?: ((nmtst_get_rand_uint32 () % 2) ? &reread_copy : NULL); + gboolean success; + GError * error = NULL; + char * filename = NULL; + gs_unref_object NMConnection *con_verified = NULL; + gs_unref_object NMConnection *reread_copy = NULL; + NMConnection **reread = out_reread ?: ((nmtst_get_rand_uint32() % 2) ? &reread_copy : NULL); - g_assert (NM_IS_CONNECTION (connection)); - g_assert (ifcfg_dir); + g_assert(NM_IS_CONNECTION(connection)); + g_assert(ifcfg_dir); - con_verified = nmtst_connection_duplicate_and_normalize (connection); + con_verified = nmtst_connection_duplicate_and_normalize(connection); - success = nms_ifcfg_rh_writer_write_connection (con_verified, - ifcfg_dir, - NULL, - NULL, - NULL, - &filename, - reread, - out_reread_same, - &error); - nmtst_assert_success (success, error); - g_assert (filename && filename[0]); + success = nms_ifcfg_rh_writer_write_connection(con_verified, + ifcfg_dir, + NULL, + NULL, + NULL, + &filename, + reread, + out_reread_same, + &error); + nmtst_assert_success(success, error); + g_assert(filename && filename[0]); - if (reread) - nmtst_assert_connection_verifies_without_normalization (*reread); + if (reread) + nmtst_assert_connection_verifies_without_normalization(*reread); - _assert_expected_content (con_verified, filename, expected); - - if (out_filename) - *out_filename = filename; - else - g_free (filename); + _assert_expected_content(con_verified, filename, expected); + if (out_filename) + *out_filename = filename; + else + g_free(filename); } static void -_writer_new_connec_exp (NMConnection *connection, - const char *ifcfg_dir, - const char *expected, - char **out_filename) +_writer_new_connec_exp(NMConnection *connection, + const char * ifcfg_dir, + const char * expected, + char ** out_filename) { - gs_unref_object NMConnection *reread = NULL; - gboolean reread_same = FALSE; + gs_unref_object NMConnection *reread = NULL; + gboolean reread_same = FALSE; - _writer_new_connection_reread (connection, ifcfg_dir, out_filename, expected, &reread, &reread_same); - _assert_reread_same (connection, reread); - g_assert (reread_same); + _writer_new_connection_reread(connection, + ifcfg_dir, + out_filename, + expected, + &reread, + &reread_same); + _assert_reread_same(connection, reread); + g_assert(reread_same); } static void -_writer_new_connection (NMConnection *connection, - const char *ifcfg_dir, - char **out_filename) +_writer_new_connection(NMConnection *connection, const char *ifcfg_dir, char **out_filename) { - _writer_new_connec_exp (connection, ifcfg_dir, NO_EXPECTED, out_filename); + _writer_new_connec_exp(connection, ifcfg_dir, NO_EXPECTED, out_filename); } static void -_writer_new_connection_FIXME (NMConnection *connection, - const char *ifcfg_dir, - char **out_filename) +_writer_new_connection_FIXME(NMConnection *connection, const char *ifcfg_dir, char **out_filename) { - gs_unref_object NMConnection *reread = NULL; - gboolean reread_same = FALSE; + gs_unref_object NMConnection *reread = NULL; + gboolean reread_same = FALSE; - /* FIXME: this should not happen. Fix it to use _writer_new_connection() instead. */ + /* FIXME: this should not happen. Fix it to use _writer_new_connection() instead. */ - _writer_new_connection_reread (connection, ifcfg_dir, out_filename, NO_EXPECTED, &reread, &reread_same); - _assert_reread_same_FIXME (connection, reread); - g_assert (!reread_same); + _writer_new_connection_reread(connection, + ifcfg_dir, + out_filename, + NO_EXPECTED, + &reread, + &reread_same); + _assert_reread_same_FIXME(connection, reread); + g_assert(!reread_same); } static void -_writer_new_connection_fail (NMConnection *connection, - const char *ifcfg_dir, - GError **error) +_writer_new_connection_fail(NMConnection *connection, const char *ifcfg_dir, GError **error) { - gs_unref_object NMConnection *connection_normalized = NULL; - gs_unref_object NMConnection *reread = NULL; - gboolean success; - GError *local = NULL; - char *filename = NULL; + gs_unref_object NMConnection *connection_normalized = NULL; + gs_unref_object NMConnection *reread = NULL; + gboolean success; + GError * local = NULL; + char * filename = NULL; - g_assert (NM_IS_CONNECTION (connection)); - g_assert (ifcfg_dir); + g_assert(NM_IS_CONNECTION(connection)); + g_assert(ifcfg_dir); - connection_normalized = nmtst_connection_duplicate_and_normalize (connection); + connection_normalized = nmtst_connection_duplicate_and_normalize(connection); - success = nms_ifcfg_rh_writer_write_connection (connection_normalized, - ifcfg_dir, - NULL, - NULL, - NULL, - &filename, - &reread, - NULL, - &local); - nmtst_assert_no_success (success, local); - g_assert (!filename); - g_assert (!reread); + success = nms_ifcfg_rh_writer_write_connection(connection_normalized, + ifcfg_dir, + NULL, + NULL, + NULL, + &filename, + &reread, + NULL, + &local); + nmtst_assert_no_success(success, local); + g_assert(!filename); + g_assert(!reread); - g_propagate_error (error, local); + g_propagate_error(error, local); } /*****************************************************************************/ static void -test_read_netmask_1 (void) +test_read_netmask_1(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_free char *content = NULL; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMIPAddress *ip4_addr; - const char *FILENAME = TEST_IFCFG_DIR"/ifcfg-netmask-1"; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_free char * content = NULL; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMIPAddress * ip4_addr; + const char * FILENAME = TEST_IFCFG_DIR "/ifcfg-netmask-1"; - connection = _connection_from_file (FILENAME, NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(FILENAME, NULL, TYPE_ETHERNET, NULL); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System netmask-1"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System netmask-1"); - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpuint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 1); - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); - g_assert (ip4_addr); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "102.0.2.2"); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 15); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpuint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "102.0.2.2"); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 15); - nmtst_assert_connection_verifies_without_normalization (connection); + nmtst_assert_connection_verifies_without_normalization(connection); - content = nmtst_file_get_contents (FILENAME); + content = nmtst_file_get_contents(FILENAME); - testfile = g_strdup (TEST_SCRATCH_DIR"/ifcfg-netmask-1.copy"); + testfile = g_strdup(TEST_SCRATCH_DIR "/ifcfg-netmask-1.copy"); - nmtst_file_set_contents (testfile, content); + nmtst_file_set_contents(testfile, content); - _writer_update_connection (connection, - TEST_SCRATCH_DIR, - testfile, - TEST_IFCFG_DIR"/ifcfg-netmask-1.cexpected"); + _writer_update_connection(connection, + TEST_SCRATCH_DIR, + testfile, + TEST_IFCFG_DIR "/ifcfg-netmask-1.cexpected"); } /*****************************************************************************/ static gboolean -verify_cert_or_key (NMSetting8021x *s_compare, - const char *file, - const char *privkey_password, - const char *property) -{ - NMSetting8021x *s_8021x; - GError *error = NULL; - gboolean success = FALSE; - const char *expected = NULL, *setting = NULL; - gboolean phase2 = FALSE; - NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_UNKNOWN; - - if (strstr (property, "phase2")) - phase2 = TRUE; - - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - - /* Load the certificate into an empty setting */ - if (strstr (property, "ca-cert")) { - if (phase2) - success = nm_setting_802_1x_set_phase2_ca_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); - else - success = nm_setting_802_1x_set_ca_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); - } else if (strstr (property, "client-cert")) { - if (phase2) - success = nm_setting_802_1x_set_phase2_client_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); - else - success = nm_setting_802_1x_set_client_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); - } else if (strstr (property, "private-key")) { - if (phase2) - success = nm_setting_802_1x_set_phase2_private_key (s_8021x, file, privkey_password, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); - else - success = nm_setting_802_1x_set_private_key (s_8021x, file, privkey_password, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error); - } - g_assert_no_error (error); - g_assert_cmpint (success, ==, TRUE); - - /* Ensure it was loaded using the PATH scheme */ - if (strstr (property, "ca-cert")) { - if (phase2) - scheme = nm_setting_802_1x_get_phase2_ca_cert_scheme (s_8021x); - else - scheme = nm_setting_802_1x_get_ca_cert_scheme (s_8021x); - } else if (strstr (property, "client-cert")) { - if (phase2) - scheme = nm_setting_802_1x_get_phase2_client_cert_scheme (s_8021x); - else - scheme = nm_setting_802_1x_get_client_cert_scheme (s_8021x); - } else if (strstr (property, "private-key")) { - if (phase2) - scheme = nm_setting_802_1x_get_phase2_private_key_scheme (s_8021x); - else - scheme = nm_setting_802_1x_get_private_key_scheme (s_8021x); - } - g_assert_cmpint (scheme, ==, NM_SETTING_802_1X_CK_SCHEME_PATH); - - /* Grab the path back out */ - if (strstr (property, "ca-cert")) { - if (phase2) - expected = nm_setting_802_1x_get_phase2_ca_cert_path (s_8021x); - else - expected = nm_setting_802_1x_get_ca_cert_path (s_8021x); - } else if (strstr (property, "client-cert")) { - if (phase2) - expected = nm_setting_802_1x_get_phase2_client_cert_path (s_8021x); - else - expected = nm_setting_802_1x_get_client_cert_path (s_8021x); - } else if (strstr (property, "private-key")) { - if (phase2) - expected = nm_setting_802_1x_get_phase2_private_key_path (s_8021x); - else - expected = nm_setting_802_1x_get_private_key_path (s_8021x); - } - g_assert_cmpstr (expected, ==, file); - - /* Compare the path with the expected path from the real setting */ - if (strstr (property, "ca-cert")) { - if (phase2) - setting = nm_setting_802_1x_get_phase2_ca_cert_path (s_compare); - else - setting = nm_setting_802_1x_get_ca_cert_path (s_compare); - } else if (strstr (property, "client-cert")) { - if (phase2) - setting = nm_setting_802_1x_get_phase2_client_cert_path (s_compare); - else - setting = nm_setting_802_1x_get_client_cert_path (s_compare); - } else if (strstr (property, "private-key")) { - if (phase2) - setting = nm_setting_802_1x_get_phase2_private_key_path (s_compare); - else - setting = nm_setting_802_1x_get_private_key_path (s_compare); - } - g_assert_cmpstr (setting, ==, expected); - - g_object_unref (s_8021x); - return TRUE; -} - -static void -test_read_basic (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - const char *mac; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-minimal", - NULL, TYPE_ETHERNET, NULL); - - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-minimal"); - g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); - g_assert (nm_setting_connection_get_autoconnect (s_con)); - g_assert_cmpint (nm_setting_connection_get_autoconnect_retries (s_con), ==, -1); - - /* UUID can't be tested if the ifcfg does not contain the UUID key, because - * the UUID is generated on the full path of the ifcfg file, which can change - * depending on where the tests are run. - */ - - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 0); - - /* MAC address */ - mac = nm_setting_wired_get_mac_address (s_wired); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, ETH_ALEN)); - - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - g_assert (nm_setting_ip_config_get_never_default (s_ip4) == FALSE); - - /* ===== IPv6 SETTING ===== */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); - g_assert (nm_setting_ip_config_get_never_default (s_ip6) == FALSE); - - g_object_unref (connection); -} - -static void -test_read_miscellaneous_variables (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - char *expected_mac_blacklist[3] = { "00:16:41:11:22:88", "00:16:41:11:22:99", "6a:5d:5a:fa:dd:f0" }; - int mac_blacklist_num, i; - guint64 expected_timestamp = 0; - - NMTST_EXPECT_NM_WARN ("*invalid MAC in HWADDR_BLACKLIST 'XX:aa:invalid'*"); - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-misc-variables", - NULL, TYPE_ETHERNET, NULL); - g_test_assert_expected_messages (); - - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, expected_timestamp); - g_assert (nm_setting_connection_get_autoconnect (s_con)); - g_assert_cmpint (nm_setting_connection_get_autoconnect_retries (s_con), ==, 100); - - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 0); - - /* MAC blacklist */ - mac_blacklist_num = nm_setting_wired_get_num_mac_blacklist_items (s_wired); - g_assert_cmpint (mac_blacklist_num, ==, 3); - for (i = 0; i < mac_blacklist_num; i++) - g_assert (nm_utils_hwaddr_matches (nm_setting_wired_get_mac_blacklist_item (s_wired, i), -1, expected_mac_blacklist[i], -1)); - - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - g_assert (nm_setting_ip_config_get_never_default (s_ip4) == FALSE); - - g_object_unref (connection); -} - -static void -test_read_variables_corner_cases (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - const char *mac; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-variables-corner-cases-1", - NULL, TYPE_ETHERNET, NULL); - - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-variables-corner-cases-1"); - g_assert_cmpstr (nm_setting_connection_get_zone (s_con), ==, NULL); - g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); - g_assert (nm_setting_connection_get_autoconnect (s_con)); - - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 0); - - /* MAC address */ - mac = nm_setting_wired_get_mac_address (s_wired); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, ETH_ALEN)); - - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - g_assert (nm_setting_ip_config_get_never_default (s_ip4) == FALSE); - - g_object_unref (connection); -} - -static void -test_read_unmanaged (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - char *unhandled_spec = NULL; - guint64 expected_timestamp = 0; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-nm-controlled", - NULL, TYPE_ETHERNET, - &unhandled_spec); - g_assert_cmpstr (unhandled_spec, ==, "unmanaged:mac:00:11:22:33:f8:9f"); - - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-nm-controlled"); - g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, expected_timestamp); - g_assert (nm_setting_connection_get_autoconnect (s_con)); - - g_free (unhandled_spec); - g_object_unref (connection); -} - -static void -test_read_unmanaged_unrecognized (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - gs_free char *unhandled_spec = NULL; - guint64 expected_timestamp = 0; +verify_cert_or_key(NMSetting8021x *s_compare, + const char * file, + const char * privkey_password, + const char * property) +{ + NMSetting8021x * s_8021x; + GError * error = NULL; + gboolean success = FALSE; + const char * expected = NULL, *setting = NULL; + gboolean phase2 = FALSE; + NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_UNKNOWN; + + if (strstr(property, "phase2")) + phase2 = TRUE; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + + /* Load the certificate into an empty setting */ + if (strstr(property, "ca-cert")) { + if (phase2) + success = nm_setting_802_1x_set_phase2_ca_cert(s_8021x, + file, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + else + success = nm_setting_802_1x_set_ca_cert(s_8021x, + file, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + } else if (strstr(property, "client-cert")) { + if (phase2) + success = nm_setting_802_1x_set_phase2_client_cert(s_8021x, + file, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + else + success = nm_setting_802_1x_set_client_cert(s_8021x, + file, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + } else if (strstr(property, "private-key")) { + if (phase2) + success = nm_setting_802_1x_set_phase2_private_key(s_8021x, + file, + privkey_password, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + else + success = nm_setting_802_1x_set_private_key(s_8021x, + file, + privkey_password, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + } + g_assert_no_error(error); + g_assert_cmpint(success, ==, TRUE); + + /* Ensure it was loaded using the PATH scheme */ + if (strstr(property, "ca-cert")) { + if (phase2) + scheme = nm_setting_802_1x_get_phase2_ca_cert_scheme(s_8021x); + else + scheme = nm_setting_802_1x_get_ca_cert_scheme(s_8021x); + } else if (strstr(property, "client-cert")) { + if (phase2) + scheme = nm_setting_802_1x_get_phase2_client_cert_scheme(s_8021x); + else + scheme = nm_setting_802_1x_get_client_cert_scheme(s_8021x); + } else if (strstr(property, "private-key")) { + if (phase2) + scheme = nm_setting_802_1x_get_phase2_private_key_scheme(s_8021x); + else + scheme = nm_setting_802_1x_get_private_key_scheme(s_8021x); + } + g_assert_cmpint(scheme, ==, NM_SETTING_802_1X_CK_SCHEME_PATH); + + /* Grab the path back out */ + if (strstr(property, "ca-cert")) { + if (phase2) + expected = nm_setting_802_1x_get_phase2_ca_cert_path(s_8021x); + else + expected = nm_setting_802_1x_get_ca_cert_path(s_8021x); + } else if (strstr(property, "client-cert")) { + if (phase2) + expected = nm_setting_802_1x_get_phase2_client_cert_path(s_8021x); + else + expected = nm_setting_802_1x_get_client_cert_path(s_8021x); + } else if (strstr(property, "private-key")) { + if (phase2) + expected = nm_setting_802_1x_get_phase2_private_key_path(s_8021x); + else + expected = nm_setting_802_1x_get_private_key_path(s_8021x); + } + g_assert_cmpstr(expected, ==, file); + + /* Compare the path with the expected path from the real setting */ + if (strstr(property, "ca-cert")) { + if (phase2) + setting = nm_setting_802_1x_get_phase2_ca_cert_path(s_compare); + else + setting = nm_setting_802_1x_get_ca_cert_path(s_compare); + } else if (strstr(property, "client-cert")) { + if (phase2) + setting = nm_setting_802_1x_get_phase2_client_cert_path(s_compare); + else + setting = nm_setting_802_1x_get_client_cert_path(s_compare); + } else if (strstr(property, "private-key")) { + if (phase2) + setting = nm_setting_802_1x_get_phase2_private_key_path(s_compare); + else + setting = nm_setting_802_1x_get_private_key_path(s_compare); + } + g_assert_cmpstr(setting, ==, expected); + + g_object_unref(s_8021x); + return TRUE; +} + +static void +test_read_basic(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + const char * mac; + char expected_mac_address[ETH_ALEN] = {0x00, 0x16, 0x41, 0x11, 0x22, 0x33}; + + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-minimal", NULL, TYPE_ETHERNET, NULL); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System test-minimal"); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + g_assert_cmpint(nm_setting_connection_get_autoconnect_retries(s_con), ==, -1); + + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 0); + + /* MAC address */ + mac = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, ETH_ALEN)); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + g_assert(nm_setting_ip_config_get_never_default(s_ip4) == FALSE); + + /* ===== IPv6 SETTING ===== */ + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE); + g_assert(nm_setting_ip_config_get_never_default(s_ip6) == FALSE); + + g_object_unref(connection); +} + +static void +test_read_miscellaneous_variables(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + char * expected_mac_blacklist[3] = {"00:16:41:11:22:88", + "00:16:41:11:22:99", + "6a:5d:5a:fa:dd:f0"}; + int mac_blacklist_num, i; + guint64 expected_timestamp = 0; + + NMTST_EXPECT_NM_WARN("*invalid MAC in HWADDR_BLACKLIST 'XX:aa:invalid'*"); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-misc-variables", + NULL, + TYPE_ETHERNET, + NULL); + g_test_assert_expected_messages(); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, expected_timestamp); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + g_assert_cmpint(nm_setting_connection_get_autoconnect_retries(s_con), ==, 100); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 0); + + /* MAC blacklist */ + mac_blacklist_num = nm_setting_wired_get_num_mac_blacklist_items(s_wired); + g_assert_cmpint(mac_blacklist_num, ==, 3); + for (i = 0; i < mac_blacklist_num; i++) + g_assert(nm_utils_hwaddr_matches(nm_setting_wired_get_mac_blacklist_item(s_wired, i), + -1, + expected_mac_blacklist[i], + -1)); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + g_assert(nm_setting_ip_config_get_never_default(s_ip4) == FALSE); + + g_object_unref(connection); +} + +static void +test_read_variables_corner_cases(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + const char * mac; + char expected_mac_address[ETH_ALEN] = {0x00, 0x16, 0x41, 0x11, 0x22, 0x33}; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-variables-corner-cases-1", + NULL, + TYPE_ETHERNET, + NULL); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System test-variables-corner-cases-1"); + g_assert_cmpstr(nm_setting_connection_get_zone(s_con), ==, NULL); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 0); + + /* MAC address */ + mac = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, ETH_ALEN)); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + g_assert(nm_setting_ip_config_get_never_default(s_ip4) == FALSE); - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-nm-controlled-unrecognized", - NULL, NULL, - &unhandled_spec); - g_assert_cmpstr (unhandled_spec, ==, "unmanaged:interface-name:=ipoac0"); - - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "PigeonNet"); - g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, expected_timestamp); - - g_object_unref (connection); + g_object_unref(connection); } - + static void -test_read_unrecognized (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - gs_free char *unhandled_spec = NULL; - guint64 expected_timestamp = 0; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-unrecognized", - NULL, NULL, - &unhandled_spec); - g_assert_cmpstr (unhandled_spec, ==, "unrecognized:mac:00:11:22:33"); - - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-unrecognized"); - g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, expected_timestamp); - - g_object_unref (connection); -} - +test_read_unmanaged(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + char * unhandled_spec = NULL; + guint64 expected_timestamp = 0; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-nm-controlled", + NULL, + TYPE_ETHERNET, + &unhandled_spec); + g_assert_cmpstr(unhandled_spec, ==, "unmanaged:mac:00:11:22:33:f8:9f"); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System test-nm-controlled"); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, expected_timestamp); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + g_free(unhandled_spec); + g_object_unref(connection); +} + +static void +test_read_unmanaged_unrecognized(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + gs_free char * unhandled_spec = NULL; + guint64 expected_timestamp = 0; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-nm-controlled-unrecognized", + NULL, + NULL, + &unhandled_spec); + g_assert_cmpstr(unhandled_spec, ==, "unmanaged:interface-name:=ipoac0"); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "PigeonNet"); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, expected_timestamp); + + g_object_unref(connection); +} + static void -test_read_wired_static (gconstpointer test_data) +test_read_unrecognized(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - char *unmanaged = NULL; - const char *mac; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee }; - NMIPAddress *ip4_addr; - NMIPAddress *ip6_addr; - const char *file, *expected_id; - gpointer expect_ip6_p; + NMConnection * connection; + NMSettingConnection *s_con; + gs_free char * unhandled_spec = NULL; + guint64 expected_timestamp = 0; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-unrecognized", + NULL, + NULL, + &unhandled_spec); + g_assert_cmpstr(unhandled_spec, ==, "unrecognized:mac:00:11:22:33"); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System test-unrecognized"); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, expected_timestamp); + + g_object_unref(connection); +} + +static void +test_read_wired_static(gconstpointer test_data) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + char * unmanaged = NULL; + const char * mac; + char expected_mac_address[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xee}; + NMIPAddress * ip4_addr; + NMIPAddress * ip6_addr; + const char * file, *expected_id; + gpointer expect_ip6_p; - nmtst_test_data_unpack (test_data, &file, &expected_id, &expect_ip6_p); + nmtst_test_data_unpack(test_data, &file, &expected_id, &expect_ip6_p); - g_assert (expected_id); + g_assert(expected_id); - connection = _connection_from_file (file, NULL, TYPE_ETHERNET, - &unmanaged); - g_assert_cmpstr (unmanaged, ==, NULL); + connection = _connection_from_file(file, NULL, TYPE_ETHERNET, &unmanaged); + g_assert_cmpstr(unmanaged, ==, NULL); - /* ===== 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_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); - g_assert (nm_setting_connection_get_autoconnect (s_con)); + /* ===== 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_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 1492); + + /* MAC address */ + mac = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, ETH_ALEN)); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + g_assert(nm_setting_ip_config_get_may_fail(s_ip4)); - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 1492); + g_assert(nm_setting_ip_config_has_dns_options(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns_options(s_ip4), ==, 0); - /* MAC address */ - mac = nm_setting_wired_get_mac_address (s_wired); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, ETH_ALEN)); + /* DNS Addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 0), ==, "4.2.2.1"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 1), ==, "4.2.2.2"); + + /* IP addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 24); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "192.168.1.5"); + + /* Gateway */ + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "192.168.1.1"); + + /* ===== IPv6 SETTING ===== */ + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + if (GPOINTER_TO_INT(expect_ip6_p)) { + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL); + g_assert(nm_setting_ip_config_get_may_fail(s_ip6)); + + g_assert(nm_setting_ip_config_has_dns_options(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns_options(s_ip6), ==, 0); + + /* DNS Addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 0), ==, "1:2:3:4::a"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 1), ==, "1:2:3:4::b"); + + /* IP addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 2); + + ip6_addr = nm_setting_ip_config_get_address(s_ip6, 0); + g_assert(ip6_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip6_addr), ==, 64); + g_assert_cmpstr(nm_ip_address_get_address(ip6_addr), ==, "dead:beaf::1"); + + ip6_addr = nm_setting_ip_config_get_address(s_ip6, 1); + g_assert(ip6_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip6_addr), ==, 56); + g_assert_cmpstr(nm_ip_address_get_address(ip6_addr), ==, "dead:beaf::2"); + } else { + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE); + g_assert(!nm_setting_ip_config_has_dns_options(s_ip6)); + } + + g_object_unref(connection); +} + +static void +test_read_wired_static_no_prefix(gconstpointer user_data) +{ + guint32 expected_prefix = GPOINTER_TO_UINT(user_data); + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4; + NMIPAddress * ip4_addr; + char * file, *expected_id; + + file = g_strdup_printf(TEST_IFCFG_DIR "/ifcfg-test-wired-static-no-prefix-%u", expected_prefix); + expected_id = g_strdup_printf("System test-wired-static-no-prefix-%u", expected_prefix); + + NMTST_EXPECT_NM_WARN("*missing PREFIX, assuming*"); + connection = _connection_from_file(file, NULL, TYPE_ETHERNET, NULL); + g_test_assert_expected_messages(); + + /* ===== 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); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + + g_assert(!nm_setting_ip_config_has_dns_options(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns_options(s_ip4), ==, 0); + + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, expected_prefix); + + g_free(file); + g_free(expected_id); + g_object_unref(connection); +} + +static void +test_read_wired_dhcp(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + char * unmanaged = NULL; + char expected_mac_address[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xee}; + const char * mac; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-dhcp", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert(unmanaged == NULL); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System test-wired-dhcp"); + g_assert_cmpuint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + /* MAC address */ + mac = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, sizeof(expected_mac_address))); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + g_assert_cmpstr(nm_setting_ip4_config_get_dhcp_fqdn(NM_SETTING_IP4_CONFIG(s_ip4)), + ==, + "foo.bar"); + g_assert(nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert_cmpuint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 0), ==, "4.2.2.1"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 1), ==, "4.2.2.2"); + g_assert_cmpuint(nm_setting_ip_config_get_dhcp_hostname_flags(s_ip4), + ==, + NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED | NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE); + + /* ===== IPv6 SETTING ===== */ + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_DHCP); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_hostname(s_ip6), ==, "foo.bar"); + g_assert_cmpuint(nm_setting_ip_config_get_dhcp_hostname_flags(s_ip6), + ==, + NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS); + + g_object_unref(connection); +} + +static void +test_read_wired_dhcp_plus_ip(void) +{ + NMConnection * connection; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + NMIPAddress * ip4_addr; + NMIPAddress * ip6_addr; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-dhcp-plus-ip", + NULL, + TYPE_ETHERNET, + NULL); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + g_assert(nm_setting_ip_config_get_may_fail(s_ip4)); + + /* DNS Addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 0), ==, "4.2.2.1"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 1), ==, "4.2.2.2"); + + /* IP addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 2); + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 24); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "1.2.3.4"); + + /* Gateway */ + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "1.1.1.1"); + + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 1); + g_assert(ip4_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 16); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "9.8.7.6"); + + /* ===== IPv6 SETTING ===== */ + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(nm_setting_ip_config_get_may_fail(s_ip6)); + + /* DNS Addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 0), ==, "1:2:3:4::a"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 1), ==, "1:2:3:4::b"); + + /* IP addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 3); + ip6_addr = nm_setting_ip_config_get_address(s_ip6, 0); + g_assert(ip6_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip6_addr), ==, 56); + g_assert_cmpstr(nm_ip_address_get_address(ip6_addr), ==, "1001:abba::1234"); + + ip6_addr = nm_setting_ip_config_get_address(s_ip6, 1); + g_assert(ip6_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip6_addr), ==, 64); + g_assert_cmpstr(nm_ip_address_get_address(ip6_addr), ==, "2001:abba::2234"); + + ip6_addr = nm_setting_ip_config_get_address(s_ip6, 2); + g_assert(ip6_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip6_addr), ==, 96); + g_assert_cmpstr(nm_ip_address_get_address(ip6_addr), ==, "3001:abba::3234"); + + g_object_unref(connection); +} + +static void +test_read_wired_shared_plus_ip(void) +{ + NMConnection * connection; + NMSettingIPConfig *s_ip4; + NMIPAddress * ip4_addr; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-shared-plus-ip", + NULL, + TYPE_ETHERNET, + NULL); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_SHARED); + g_assert(nm_setting_ip_config_get_may_fail(s_ip4)); - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - g_assert (nm_setting_ip_config_get_may_fail (s_ip4)); + /* IP addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 24); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "10.20.30.5"); - g_assert (nm_setting_ip_config_has_dns_options (s_ip4)); - g_assert_cmpint (nm_setting_ip_config_get_num_dns_options (s_ip4), ==, 0); + /* Gateway */ + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "1.1.1.1"); + + g_object_unref(connection); +} + +static void +test_read_wired_global_gateway(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMIPAddress * ip4_addr; + char * unmanaged = NULL; - /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "4.2.2.1"); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 1), ==, "4.2.2.2"); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-global-gateway", + TEST_IFCFG_DIR "/network-test-wired-global-gateway", + TYPE_ETHERNET, + &unmanaged); + g_assert(unmanaged == NULL); - /* IP addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); - g_assert (ip4_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.1.5"); - - /* Gateway */ - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1"); - - /* ===== IPv6 SETTING ===== */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - if (GPOINTER_TO_INT (expect_ip6_p)) { - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_MANUAL); - g_assert (nm_setting_ip_config_get_may_fail (s_ip6)); - - g_assert (nm_setting_ip_config_has_dns_options (s_ip6)); - g_assert_cmpint (nm_setting_ip_config_get_num_dns_options (s_ip6), ==, 0); + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System test-wired-global-gateway"); - /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip6), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 0), ==, "1:2:3:4::a"); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 1), ==, "1:2:3:4::b"); - - /* IP addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip6), ==, 2); - - ip6_addr = nm_setting_ip_config_get_address (s_ip6, 0); - g_assert (ip6_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 64); - g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "dead:beaf::1"); - - ip6_addr = nm_setting_ip_config_get_address (s_ip6, 1); - g_assert (ip6_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 56); - g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "dead:beaf::2"); - } else { - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); - g_assert (!nm_setting_ip_config_has_dns_options (s_ip6)); - } - - g_object_unref (connection); -} - -static void -test_read_wired_static_no_prefix (gconstpointer user_data) -{ - guint32 expected_prefix = GPOINTER_TO_UINT (user_data); - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMIPAddress *ip4_addr; - char *file, *expected_id; - - file = g_strdup_printf (TEST_IFCFG_DIR"/ifcfg-test-wired-static-no-prefix-%u", expected_prefix); - expected_id = g_strdup_printf ("System test-wired-static-no-prefix-%u", expected_prefix); - - NMTST_EXPECT_NM_WARN ("*missing PREFIX, assuming*"); - connection = _connection_from_file (file, NULL, TYPE_ETHERNET, NULL); - g_test_assert_expected_messages (); - - /* ===== 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); - - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - - g_assert (!nm_setting_ip_config_has_dns_options (s_ip4)); - g_assert_cmpint (nm_setting_ip_config_get_num_dns_options (s_ip4), ==, 0); - - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); - g_assert (ip4_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, expected_prefix); - - g_free (file); - g_free (expected_id); - g_object_unref (connection); -} - -static void -test_read_wired_dhcp (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - char *unmanaged = NULL; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee }; - const char *mac; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-dhcp", - NULL, TYPE_ETHERNET, - &unmanaged); - g_assert (unmanaged == NULL); - - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-dhcp"); - g_assert_cmpuint (nm_setting_connection_get_timestamp (s_con), ==, 0); - g_assert (nm_setting_connection_get_autoconnect (s_con)); - - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - - /* MAC address */ - mac = nm_setting_wired_get_mac_address (s_wired); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address))); - - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - g_assert_cmpstr (nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG (s_ip4)), ==, "foo.bar"); - g_assert (nm_setting_ip_config_get_ignore_auto_dns (s_ip4)); - g_assert_cmpuint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "4.2.2.1"); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 1), ==, "4.2.2.2"); - g_assert_cmpuint (nm_setting_ip_config_get_dhcp_hostname_flags (s_ip4), - ==, - NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED | NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE); - - /* ===== IPv6 SETTING ===== */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_DHCP); - g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip6), ==, "foo.bar"); - g_assert_cmpuint (nm_setting_ip_config_get_dhcp_hostname_flags (s_ip6), - ==, - NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS); - - g_object_unref (connection); -} - -static void -test_read_wired_dhcp_plus_ip (void) -{ - NMConnection *connection; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMIPAddress *ip4_addr; - NMIPAddress *ip6_addr; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-dhcp-plus-ip", - NULL, TYPE_ETHERNET, NULL); - - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - g_assert (nm_setting_ip_config_get_may_fail (s_ip4)); - - /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "4.2.2.1"); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 1), ==, "4.2.2.2"); - - /* IP addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 2); - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); - g_assert (ip4_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "1.2.3.4"); - - /* Gateway */ - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "1.1.1.1"); - - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 1); - g_assert (ip4_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 16); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "9.8.7.6"); - - /* ===== IPv6 SETTING ===== */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); - g_assert (nm_setting_ip_config_get_may_fail (s_ip6)); - - /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip6), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 0), ==, "1:2:3:4::a"); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 1), ==, "1:2:3:4::b"); - - /* IP addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip6), ==, 3); - ip6_addr = nm_setting_ip_config_get_address (s_ip6, 0); - g_assert (ip6_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 56); - g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "1001:abba::1234"); - - ip6_addr = nm_setting_ip_config_get_address (s_ip6, 1); - g_assert (ip6_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 64); - g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "2001:abba::2234"); - - ip6_addr = nm_setting_ip_config_get_address (s_ip6, 2); - g_assert (ip6_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 96); - g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "3001:abba::3234"); - - g_object_unref (connection); -} - -static void -test_read_wired_shared_plus_ip (void) -{ - NMConnection *connection; - NMSettingIPConfig *s_ip4; - NMIPAddress *ip4_addr; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-shared-plus-ip", - NULL, TYPE_ETHERNET, NULL); - - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_SHARED); - g_assert (nm_setting_ip_config_get_may_fail (s_ip4)); - - /* IP addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); - g_assert (ip4_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "10.20.30.5"); - - /* Gateway */ - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "1.1.1.1"); - - g_object_unref (connection); -} - -static void -test_read_wired_global_gateway (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMIPAddress *ip4_addr; - char *unmanaged = NULL; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-global-gateway", - TEST_IFCFG_DIR"/network-test-wired-global-gateway", - TYPE_ETHERNET, &unmanaged); - g_assert (unmanaged == NULL); - - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-global-gateway"); + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + /* Address #1 */ + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 24); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "192.168.1.5"); - /* Address #1 */ - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); - g_assert (ip4_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.1.5"); + /* Gateway */ + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "192.168.1.2"); - /* Gateway */ - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.2"); - - g_object_unref (connection); + g_object_unref(connection); } /* Ignore GATEWAY from /etc/sysconfig/network for automatic connections */ static void -test_read_wired_global_gateway_ignore (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - - NMTST_EXPECT_NM_WARN ("*ignoring GATEWAY (/etc/sysconfig/network) for * because the connection has no static addresses"); - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-global-gateway-ignore", - TEST_IFCFG_DIR"/network-test-wired-global-gateway-ignore", - TYPE_ETHERNET, &unmanaged); - g_test_assert_expected_messages (); - g_assert (unmanaged == NULL); - - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-global-gateway-ignore"); - - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - - /* Addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 0); - - /* Gateway */ - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, NULL); - - g_object_unref (connection); -} - -static void -test_read_wired_obsolete_gateway_n (void) +test_read_wired_global_gateway_ignore(void) { - NMConnection *connection; - NMSettingIPConfig *s_ip4; - NMIPAddress *ip4_addr; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-obsolete-gateway-n", - NULL, TYPE_ETHERNET, NULL); - - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + char * unmanaged = NULL; + + NMTST_EXPECT_NM_WARN("*ignoring GATEWAY (/etc/sysconfig/network) for * because the connection " + "has no static addresses"); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-global-gateway-ignore", + TEST_IFCFG_DIR "/network-test-wired-global-gateway-ignore", + TYPE_ETHERNET, + &unmanaged); + g_test_assert_expected_messages(); + g_assert(unmanaged == NULL); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System test-wired-global-gateway-ignore"); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - /* IP addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); - g_assert (ip4_addr); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "1.2.3.4"); + /* Addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 0); - /* Gateway */ - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "1.1.1.1"); + /* Gateway */ + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, NULL); - g_object_unref (connection); + g_object_unref(connection); } -static void -test_user_1 (void) +static void +test_read_wired_obsolete_gateway_n(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingUser *s_user; - - connection = nmtst_create_minimal_connection ("Test User 1", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); - s_user = NM_SETTING_USER (nm_setting_user_new ()); - -#define _USER_SET_DATA(s_user, key, val) \ - G_STMT_START { \ - GError *_error = NULL; \ - gboolean _success; \ - \ - _success = nm_setting_user_set_data ((s_user), (key), (val), &_error); \ - nmtst_assert_success (_success, _error); \ - } G_STMT_END - -#define _USER_SET_DATA_X(s_user, key) \ - _USER_SET_DATA (s_user, key, "val="key"") + NMConnection * connection; + NMSettingIPConfig *s_ip4; + NMIPAddress * ip4_addr; - _USER_SET_DATA (s_user, "my.val1", ""); - _USER_SET_DATA_X (s_user, "my.val2"); - _USER_SET_DATA_X (s_user, "my.v__al3"); - _USER_SET_DATA_X (s_user, "my._v"); - _USER_SET_DATA_X (s_user, "my.v+"); - _USER_SET_DATA_X (s_user, "my.Av"); - _USER_SET_DATA_X (s_user, "MY.AV"); - _USER_SET_DATA_X (s_user, "MY.8V"); - _USER_SET_DATA_X (s_user, "MY.8-V"); - _USER_SET_DATA_X (s_user, "MY.8_V"); - _USER_SET_DATA_X (s_user, "MY.8+V"); - _USER_SET_DATA_X (s_user, "MY.8/V"); - _USER_SET_DATA_X (s_user, "MY.8=V"); - _USER_SET_DATA_X (s_user, "MY.-"); - _USER_SET_DATA_X (s_user, "MY._"); - _USER_SET_DATA_X (s_user, "MY.+"); - _USER_SET_DATA_X (s_user, "MY./"); - _USER_SET_DATA_X (s_user, "MY.="); - _USER_SET_DATA_X (s_user, "my.keys.1"); - _USER_SET_DATA_X (s_user, "my.other.KEY.42"); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-obsolete-gateway-n", + NULL, + TYPE_ETHERNET, + NULL); - nm_connection_add_setting (connection, NM_SETTING (s_user)); + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + + /* IP addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 24); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "1.2.3.4"); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_User_1.cexpected", - &testfile); + /* Gateway */ + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "1.1.1.1"); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_object_unref(connection); } static void -test_read_wired_never_default (void) +test_user_1(void) { - NMConnection *connection; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-never-default", - TEST_IFCFG_DIR"/network-test-wired-never-default", - TYPE_ETHERNET, NULL); - - /* ===== WIRED SETTING ===== */ - g_assert (nm_connection_get_setting_wired (connection)); - - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - g_assert (nm_setting_ip_config_get_never_default (s_ip4)); - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 0); + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingUser * s_user; - /* ===== IPv6 SETTING ===== */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); - g_assert (nm_setting_ip_config_get_never_default (s_ip6)); + connection = + nmtst_create_minimal_connection("Test User 1", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_user = NM_SETTING_USER(nm_setting_user_new()); - g_object_unref (connection); -} - -static void -test_read_wired_defroute_no (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - char *unmanaged = NULL; +#define _USER_SET_DATA(s_user, key, val) \ + G_STMT_START \ + { \ + GError * _error = NULL; \ + gboolean _success; \ + \ + _success = nm_setting_user_set_data((s_user), (key), (val), &_error); \ + nmtst_assert_success(_success, _error); \ + } \ + G_STMT_END - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-defroute-no", - NULL, TYPE_ETHERNET, &unmanaged); - g_assert (unmanaged == NULL); +#define _USER_SET_DATA_X(s_user, key) _USER_SET_DATA(s_user, key, "val=" key "") - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-defroute-no"); - - g_assert (nm_connection_get_setting_wired (connection)); - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - g_assert (nm_setting_ip_config_get_never_default (s_ip4)); - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); - g_assert (nm_setting_ip_config_get_never_default (s_ip6)); - - g_object_unref (connection); -} - -static void -test_read_wired_defroute_no_gatewaydev_yes (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - char *unmanaged = NULL; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-defroute-no-gatewaydev-yes", - TEST_IFCFG_DIR"/network-test-wired-defroute-no-gatewaydev-yes", - TYPE_ETHERNET, - &unmanaged); - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-defroute-no-gatewaydev-yes"); + _USER_SET_DATA(s_user, "my.val1", ""); + _USER_SET_DATA_X(s_user, "my.val2"); + _USER_SET_DATA_X(s_user, "my.v__al3"); + _USER_SET_DATA_X(s_user, "my._v"); + _USER_SET_DATA_X(s_user, "my.v+"); + _USER_SET_DATA_X(s_user, "my.Av"); + _USER_SET_DATA_X(s_user, "MY.AV"); + _USER_SET_DATA_X(s_user, "MY.8V"); + _USER_SET_DATA_X(s_user, "MY.8-V"); + _USER_SET_DATA_X(s_user, "MY.8_V"); + _USER_SET_DATA_X(s_user, "MY.8+V"); + _USER_SET_DATA_X(s_user, "MY.8/V"); + _USER_SET_DATA_X(s_user, "MY.8=V"); + _USER_SET_DATA_X(s_user, "MY.-"); + _USER_SET_DATA_X(s_user, "MY._"); + _USER_SET_DATA_X(s_user, "MY.+"); + _USER_SET_DATA_X(s_user, "MY./"); + _USER_SET_DATA_X(s_user, "MY.="); + _USER_SET_DATA_X(s_user, "my.keys.1"); + _USER_SET_DATA_X(s_user, "my.other.KEY.42"); - g_assert (nm_connection_get_setting_wired (connection)); + nm_connection_add_setting(connection, NM_SETTING(s_user)); - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - g_assert (nm_setting_ip_config_get_never_default (s_ip4) == FALSE); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_User_1.cexpected", + &testfile); - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); - g_assert (nm_setting_ip_config_get_never_default (s_ip6) == FALSE); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - g_object_unref (connection); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_read_wired_static_routes (void) +test_read_wired_never_default(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMIPRoute *ip4_route; + NMConnection * connection; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-static-routes", - NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-never-default", + TEST_IFCFG_DIR "/network-test-wired-never-default", + TYPE_ETHERNET, + NULL); - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-static-routes"); + /* ===== WIRED SETTING ===== */ + g_assert(nm_connection_get_setting_wired(connection)); - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + g_assert(nm_setting_ip_config_get_never_default(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 0); - /* Routes */ - g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 4); - - ip4_route = nm_setting_ip_config_get_route (s_ip4, 0); - g_assert (ip4_route); - g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "11.22.33.0"); - g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 24); - g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "192.168.1.5"); - g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, -1); - - ip4_route = nm_setting_ip_config_get_route (s_ip4, 1); - g_assert (ip4_route); - g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "44.55.66.77"); - g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 32); - g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "192.168.1.7"); - g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 3); - nmtst_assert_route_attribute_byte (ip4_route, NM_IP_ROUTE_ATTRIBUTE_TOS, 0x28); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, 30000); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_CWND, 12); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITCWND, 13); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITRWND, 14); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 9000); - nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, TRUE); - nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, TRUE); - nmtst_assert_route_attribute_string (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "1.1.1.1"); - nmtst_assert_route_attribute_byte (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SCOPE, 10); - - ip4_route = nm_setting_ip_config_get_route (s_ip4, 2); - g_assert (ip4_route); - g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "44.55.66.78"); - g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 32); - g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "192.168.1.8"); - g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 3); - nmtst_assert_route_attribute_byte (ip4_route, NM_IP_ROUTE_ATTRIBUTE_TOS, 0x28); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, 30000); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_CWND, 12); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITCWND, 13); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITRWND, 14); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 9000); - nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, TRUE); - nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, TRUE); - nmtst_assert_route_attribute_string (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "1.1.1.1"); - nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, TRUE); - nmtst_assert_route_attribute_byte (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SCOPE, 253); - - ip4_route = nm_setting_ip_config_get_route (s_ip4, 3); - g_assert (ip4_route); - g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "1.2.3.4"); - g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 32); - nmtst_assert_route_attribute_string (ip4_route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "local"); - nmtst_assert_route_attribute_byte (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SCOPE, 254); - - g_object_unref (connection); -} - -static void -test_read_wired_static_routes_legacy (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - NMIPRoute *ip4_route; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-static-routes-legacy", - NULL, TYPE_ETHERNET, &unmanaged); - g_assert (!unmanaged); - - /* ===== CONNECTION SETTING ===== */ - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-static-routes-legacy"); - - /* ===== WIRED SETTING ===== */ - - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - - /* ===== IPv4 SETTING ===== */ - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - - /* Routes */ - g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 5); - - /* Route #1 */ - ip4_route = nm_setting_ip_config_get_route (s_ip4, 0); - g_assert (ip4_route != NULL); - g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "21.31.41.0"); - g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 24); - g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "9.9.9.9"); - g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 1); - - /* Route #2 */ - ip4_route = nm_setting_ip_config_get_route (s_ip4, 1); - g_assert (ip4_route != NULL); - g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "32.42.52.62"); - g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 32); - g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "8.8.8.8"); - g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, -1); - - /* Route #3 */ - ip4_route = nm_setting_ip_config_get_route (s_ip4, 2); - g_assert (ip4_route != NULL); - g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "43.53.0.0"); - g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 16); - g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "7.7.7.7"); - g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 3); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, 10000); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_CWND, 14); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITCWND, 42); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITRWND, 20); - nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 9000); - nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW, TRUE); - nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, TRUE); - nmtst_assert_route_attribute_string (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "1.2.3.4"); - - ip4_route = nm_setting_ip_config_get_route (s_ip4, 3); - g_assert (ip4_route != NULL); - g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "7.7.7.8"); - g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 32); - g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, NULL); - g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 18); - - - /* Route #5 */ - ip4_route = nm_setting_ip_config_get_route (s_ip4, 4); - g_assert (ip4_route != NULL); - g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "1.2.3.4"); - nmtst_assert_route_attribute_string (ip4_route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "local"); + /* ===== IPv6 SETTING ===== */ + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(nm_setting_ip_config_get_never_default(s_ip6)); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wired_ipv4_manual (gconstpointer data) +test_read_wired_defroute_no(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - NMIPAddress *ip4_addr; - const char *file, *expected_id; - - nmtst_test_data_unpack (data, &file, &expected_id); - - g_assert (expected_id); - - connection = _connection_from_file (file, - NULL, - TYPE_ETHERNET, - &unmanaged); - g_assert (!unmanaged); - - /* ===== 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); - - /* ===== WIRED SETTING ===== */ - - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - - /* ===== IPv4 SETTING ===== */ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + char * unmanaged = NULL; - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - g_assert_cmpint (nm_setting_ip_config_get_dad_timeout (s_ip4), ==, 2000); - - /* IP addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 3); - - /* Address #1 */ - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); - g_assert (ip4_addr != NULL); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "1.2.3.4"); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); - - /* Address #2 */ - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 1); - g_assert (ip4_addr != NULL); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "9.8.7.6"); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 16); - - /* Address #3 */ - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 2); - g_assert (ip4_addr != NULL); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "3.3.3.3"); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 8); - - g_object_unref (connection); -} - -static void -test_read_wired_ipv6_manual (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - char *unmanaged = NULL; - NMIPAddress *ip6_addr; - NMIPRoute *ip6_route; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-ipv6-manual", - NULL, TYPE_ETHERNET, &unmanaged); - g_assert (!unmanaged); - - /* ===== CONNECTION SETTING ===== */ - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-ipv6-manual"); - - /* ===== WIRED SETTING ===== */ - - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - - /* ===== IPv4 SETTING ===== */ - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - - /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 2); - - /* DNS search domains */ - g_assert_cmpint (nm_setting_ip_config_get_num_dns_searches (s_ip4), ==, 3); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 0), ==, "lorem.com"); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 1), ==, "ipsum.org"); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 2), ==, "dolor.edu"); - - /* ===== IPv6 SETTING ===== */ - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_MANUAL); - g_assert (!nm_setting_ip_config_get_never_default (s_ip6)); - g_assert (nm_setting_ip_config_get_may_fail (s_ip6)); - - /* IP addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip6), ==, 3); - - /* Address #1 */ - ip6_addr = nm_setting_ip_config_get_address (s_ip6, 0); - g_assert (ip6_addr != NULL); - g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "1001:abba::1234"); - g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 56); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-defroute-no", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert(unmanaged == NULL); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System test-wired-defroute-no"); + + g_assert(nm_connection_get_setting_wired(connection)); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + g_assert(nm_setting_ip_config_get_never_default(s_ip4)); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(nm_setting_ip_config_get_never_default(s_ip6)); + + g_object_unref(connection); +} + +static void +test_read_wired_defroute_no_gatewaydev_yes(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + char * unmanaged = NULL; + + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-defroute-no-gatewaydev-yes", + TEST_IFCFG_DIR "/network-test-wired-defroute-no-gatewaydev-yes", + TYPE_ETHERNET, + &unmanaged); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System test-wired-defroute-no-gatewaydev-yes"); + + g_assert(nm_connection_get_setting_wired(connection)); - /* Address #2 */ - ip6_addr = nm_setting_ip_config_get_address (s_ip6, 1); - g_assert (ip6_addr != NULL); - g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "2001:abba::2234"); - g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 64); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + g_assert(nm_setting_ip_config_get_never_default(s_ip4) == FALSE); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(nm_setting_ip_config_get_never_default(s_ip6) == FALSE); + + g_object_unref(connection); +} + +static void +test_read_wired_static_routes(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMIPRoute * ip4_route; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-static-routes", + NULL, + TYPE_ETHERNET, + NULL); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System test-wired-static-routes"); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + + /* Routes */ + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 4); + + ip4_route = nm_setting_ip_config_get_route(s_ip4, 0); + g_assert(ip4_route); + g_assert_cmpstr(nm_ip_route_get_dest(ip4_route), ==, "11.22.33.0"); + g_assert_cmpint(nm_ip_route_get_prefix(ip4_route), ==, 24); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip4_route), ==, "192.168.1.5"); + g_assert_cmpint(nm_ip_route_get_metric(ip4_route), ==, -1); + + ip4_route = nm_setting_ip_config_get_route(s_ip4, 1); + g_assert(ip4_route); + g_assert_cmpstr(nm_ip_route_get_dest(ip4_route), ==, "44.55.66.77"); + g_assert_cmpint(nm_ip_route_get_prefix(ip4_route), ==, 32); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip4_route), ==, "192.168.1.7"); + g_assert_cmpint(nm_ip_route_get_metric(ip4_route), ==, 3); + nmtst_assert_route_attribute_byte(ip4_route, NM_IP_ROUTE_ATTRIBUTE_TOS, 0x28); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, 30000); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_CWND, 12); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITCWND, 13); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITRWND, 14); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 9000); + nmtst_assert_route_attribute_boolean(ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, TRUE); + nmtst_assert_route_attribute_boolean(ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, TRUE); + nmtst_assert_route_attribute_string(ip4_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "1.1.1.1"); + nmtst_assert_route_attribute_byte(ip4_route, NM_IP_ROUTE_ATTRIBUTE_SCOPE, 10); + + ip4_route = nm_setting_ip_config_get_route(s_ip4, 2); + g_assert(ip4_route); + g_assert_cmpstr(nm_ip_route_get_dest(ip4_route), ==, "44.55.66.78"); + g_assert_cmpint(nm_ip_route_get_prefix(ip4_route), ==, 32); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip4_route), ==, "192.168.1.8"); + g_assert_cmpint(nm_ip_route_get_metric(ip4_route), ==, 3); + nmtst_assert_route_attribute_byte(ip4_route, NM_IP_ROUTE_ATTRIBUTE_TOS, 0x28); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, 30000); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_CWND, 12); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITCWND, 13); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITRWND, 14); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 9000); + nmtst_assert_route_attribute_boolean(ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, TRUE); + nmtst_assert_route_attribute_boolean(ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, TRUE); + nmtst_assert_route_attribute_string(ip4_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "1.1.1.1"); + nmtst_assert_route_attribute_boolean(ip4_route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, TRUE); + nmtst_assert_route_attribute_byte(ip4_route, NM_IP_ROUTE_ATTRIBUTE_SCOPE, 253); + + ip4_route = nm_setting_ip_config_get_route(s_ip4, 3); + g_assert(ip4_route); + g_assert_cmpstr(nm_ip_route_get_dest(ip4_route), ==, "1.2.3.4"); + g_assert_cmpint(nm_ip_route_get_prefix(ip4_route), ==, 32); + nmtst_assert_route_attribute_string(ip4_route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "local"); + nmtst_assert_route_attribute_byte(ip4_route, NM_IP_ROUTE_ATTRIBUTE_SCOPE, 254); + + g_object_unref(connection); +} + +static void +test_read_wired_static_routes_legacy(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + char * unmanaged = NULL; + NMIPRoute * ip4_route; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-static-routes-legacy", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert(!unmanaged); + + /* ===== CONNECTION SETTING ===== */ + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System test-wired-static-routes-legacy"); + + /* ===== WIRED SETTING ===== */ + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + + /* Routes */ + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 5); + + /* Route #1 */ + ip4_route = nm_setting_ip_config_get_route(s_ip4, 0); + g_assert(ip4_route != NULL); + g_assert_cmpstr(nm_ip_route_get_dest(ip4_route), ==, "21.31.41.0"); + g_assert_cmpint(nm_ip_route_get_prefix(ip4_route), ==, 24); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip4_route), ==, "9.9.9.9"); + g_assert_cmpint(nm_ip_route_get_metric(ip4_route), ==, 1); + + /* Route #2 */ + ip4_route = nm_setting_ip_config_get_route(s_ip4, 1); + g_assert(ip4_route != NULL); + g_assert_cmpstr(nm_ip_route_get_dest(ip4_route), ==, "32.42.52.62"); + g_assert_cmpint(nm_ip_route_get_prefix(ip4_route), ==, 32); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip4_route), ==, "8.8.8.8"); + g_assert_cmpint(nm_ip_route_get_metric(ip4_route), ==, -1); + + /* Route #3 */ + ip4_route = nm_setting_ip_config_get_route(s_ip4, 2); + g_assert(ip4_route != NULL); + g_assert_cmpstr(nm_ip_route_get_dest(ip4_route), ==, "43.53.0.0"); + g_assert_cmpint(nm_ip_route_get_prefix(ip4_route), ==, 16); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip4_route), ==, "7.7.7.7"); + g_assert_cmpint(nm_ip_route_get_metric(ip4_route), ==, 3); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, 10000); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_CWND, 14); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITCWND, 42); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITRWND, 20); + nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 9000); + nmtst_assert_route_attribute_boolean(ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW, TRUE); + nmtst_assert_route_attribute_boolean(ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, TRUE); + nmtst_assert_route_attribute_string(ip4_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "1.2.3.4"); + + ip4_route = nm_setting_ip_config_get_route(s_ip4, 3); + g_assert(ip4_route != NULL); + g_assert_cmpstr(nm_ip_route_get_dest(ip4_route), ==, "7.7.7.8"); + g_assert_cmpint(nm_ip_route_get_prefix(ip4_route), ==, 32); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip4_route), ==, NULL); + g_assert_cmpint(nm_ip_route_get_metric(ip4_route), ==, 18); + + /* Route #5 */ + ip4_route = nm_setting_ip_config_get_route(s_ip4, 4); + g_assert(ip4_route != NULL); + g_assert_cmpstr(nm_ip_route_get_dest(ip4_route), ==, "1.2.3.4"); + nmtst_assert_route_attribute_string(ip4_route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "local"); - /* Address #3 */ - ip6_addr = nm_setting_ip_config_get_address (s_ip6, 2); - g_assert (ip6_addr != NULL); - g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "3001:abba::3234"); - g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 96); - - /* Routes */ - g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip6), ==, 4); - /* Route #1 */ - ip6_route = nm_setting_ip_config_get_route (s_ip6, 0); - g_assert (ip6_route); - g_assert_cmpstr (nm_ip_route_get_dest (ip6_route), ==, "9876::1234"); - g_assert_cmpint (nm_ip_route_get_prefix (ip6_route), ==, 96); - g_assert_cmpstr (nm_ip_route_get_next_hop (ip6_route), ==, "9876::7777"); - g_assert_cmpint (nm_ip_route_get_metric (ip6_route), ==, 2); - /* Route #2 */ - ip6_route = nm_setting_ip_config_get_route (s_ip6, 1); - g_assert (ip6_route); - g_assert_cmpstr (nm_ip_route_get_dest (ip6_route), ==, "::"); - g_assert_cmpint (nm_ip_route_get_prefix (ip6_route), ==, 0); - g_assert_cmpstr (nm_ip_route_get_next_hop (ip6_route), ==, "dead::beaf"); - g_assert_cmpint (nm_ip_route_get_metric (ip6_route), ==, -1); - /* Route #3 */ - ip6_route = nm_setting_ip_config_get_route (s_ip6, 2); - g_assert (ip6_route); - g_assert_cmpstr (nm_ip_route_get_dest (ip6_route), ==, "abbe::cafe"); - g_assert_cmpint (nm_ip_route_get_prefix (ip6_route), ==, 64); - g_assert_cmpstr (nm_ip_route_get_next_hop (ip6_route), ==, NULL); - g_assert_cmpint (nm_ip_route_get_metric (ip6_route), ==, 777); - /* Route #4 */ - ip6_route = nm_setting_ip_config_get_route (s_ip6, 3); - g_assert (ip6_route); - g_assert_cmpstr (nm_ip_route_get_dest (ip6_route), ==, "aaaa::cccc"); - g_assert_cmpint (nm_ip_route_get_prefix (ip6_route), ==, 64); - g_assert_cmpstr (nm_ip_route_get_next_hop (ip6_route), ==, "3333::4444"); - nmtst_assert_route_attribute_uint32 (ip6_route, NM_IP_ROUTE_ATTRIBUTE_CWND, 13); - nmtst_assert_route_attribute_uint32 (ip6_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 1450); - nmtst_assert_route_attribute_boolean (ip6_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, TRUE); - nmtst_assert_route_attribute_string (ip6_route, NM_IP_ROUTE_ATTRIBUTE_FROM, "1111::2222/48"); - nmtst_assert_route_attribute_string (ip6_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "5555::6666"); - - /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip6), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 0), ==, "1:2:3:4::a"); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 1), ==, "1:2:3:4::b"); - - /* DNS domains - none as domains are stuffed to 'ipv4' setting */ - g_assert_cmpint (nm_setting_ip_config_get_num_dns_searches (s_ip6), ==, 0); - - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wired_ipv6_only (gconstpointer test_data) +test_read_wired_ipv4_manual(gconstpointer data) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - char *unmanaged = NULL; - NMIPAddress *ip6_addr; - const char *method; - const char *file, *expected_id; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + char * unmanaged = NULL; + NMIPAddress * ip4_addr; + const char * file, *expected_id; - nmtst_test_data_unpack (test_data, &file, &expected_id); + nmtst_test_data_unpack(data, &file, &expected_id); + + g_assert(expected_id); + + connection = _connection_from_file(file, NULL, TYPE_ETHERNET, &unmanaged); + g_assert(!unmanaged); + + /* ===== 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); + + /* ===== WIRED SETTING ===== */ + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + g_assert_cmpint(nm_setting_ip_config_get_dad_timeout(s_ip4), ==, 2000); + + /* IP addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 3); + + /* Address #1 */ + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr != NULL); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "1.2.3.4"); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 24); + + /* Address #2 */ + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 1); + g_assert(ip4_addr != NULL); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "9.8.7.6"); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 16); + + /* Address #3 */ + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 2); + g_assert(ip4_addr != NULL); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "3.3.3.3"); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 8); + + g_object_unref(connection); +} + +static void +test_read_wired_ipv6_manual(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + char * unmanaged = NULL; + NMIPAddress * ip6_addr; + NMIPRoute * ip6_route; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-ipv6-manual", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert(!unmanaged); + + /* ===== CONNECTION SETTING ===== */ + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System test-wired-ipv6-manual"); + + /* ===== WIRED SETTING ===== */ + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + + /* DNS Addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 2); + + /* DNS search domains */ + g_assert_cmpint(nm_setting_ip_config_get_num_dns_searches(s_ip4), ==, 3); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip4, 0), ==, "lorem.com"); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip4, 1), ==, "ipsum.org"); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip4, 2), ==, "dolor.edu"); + + /* ===== IPv6 SETTING ===== */ + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL); + g_assert(!nm_setting_ip_config_get_never_default(s_ip6)); + g_assert(nm_setting_ip_config_get_may_fail(s_ip6)); + + /* IP addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 3); + + /* Address #1 */ + ip6_addr = nm_setting_ip_config_get_address(s_ip6, 0); + g_assert(ip6_addr != NULL); + g_assert_cmpstr(nm_ip_address_get_address(ip6_addr), ==, "1001:abba::1234"); + g_assert_cmpint(nm_ip_address_get_prefix(ip6_addr), ==, 56); + + /* Address #2 */ + ip6_addr = nm_setting_ip_config_get_address(s_ip6, 1); + g_assert(ip6_addr != NULL); + g_assert_cmpstr(nm_ip_address_get_address(ip6_addr), ==, "2001:abba::2234"); + g_assert_cmpint(nm_ip_address_get_prefix(ip6_addr), ==, 64); + + /* Address #3 */ + ip6_addr = nm_setting_ip_config_get_address(s_ip6, 2); + g_assert(ip6_addr != NULL); + g_assert_cmpstr(nm_ip_address_get_address(ip6_addr), ==, "3001:abba::3234"); + g_assert_cmpint(nm_ip_address_get_prefix(ip6_addr), ==, 96); + + /* Routes */ + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 4); + /* Route #1 */ + ip6_route = nm_setting_ip_config_get_route(s_ip6, 0); + g_assert(ip6_route); + g_assert_cmpstr(nm_ip_route_get_dest(ip6_route), ==, "9876::1234"); + g_assert_cmpint(nm_ip_route_get_prefix(ip6_route), ==, 96); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip6_route), ==, "9876::7777"); + g_assert_cmpint(nm_ip_route_get_metric(ip6_route), ==, 2); + /* Route #2 */ + ip6_route = nm_setting_ip_config_get_route(s_ip6, 1); + g_assert(ip6_route); + g_assert_cmpstr(nm_ip_route_get_dest(ip6_route), ==, "::"); + g_assert_cmpint(nm_ip_route_get_prefix(ip6_route), ==, 0); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip6_route), ==, "dead::beaf"); + g_assert_cmpint(nm_ip_route_get_metric(ip6_route), ==, -1); + /* Route #3 */ + ip6_route = nm_setting_ip_config_get_route(s_ip6, 2); + g_assert(ip6_route); + g_assert_cmpstr(nm_ip_route_get_dest(ip6_route), ==, "abbe::cafe"); + g_assert_cmpint(nm_ip_route_get_prefix(ip6_route), ==, 64); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip6_route), ==, NULL); + g_assert_cmpint(nm_ip_route_get_metric(ip6_route), ==, 777); + /* Route #4 */ + ip6_route = nm_setting_ip_config_get_route(s_ip6, 3); + g_assert(ip6_route); + g_assert_cmpstr(nm_ip_route_get_dest(ip6_route), ==, "aaaa::cccc"); + g_assert_cmpint(nm_ip_route_get_prefix(ip6_route), ==, 64); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip6_route), ==, "3333::4444"); + nmtst_assert_route_attribute_uint32(ip6_route, NM_IP_ROUTE_ATTRIBUTE_CWND, 13); + nmtst_assert_route_attribute_uint32(ip6_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 1450); + nmtst_assert_route_attribute_boolean(ip6_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, TRUE); + nmtst_assert_route_attribute_string(ip6_route, NM_IP_ROUTE_ATTRIBUTE_FROM, "1111::2222/48"); + nmtst_assert_route_attribute_string(ip6_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "5555::6666"); + + /* DNS Addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 0), ==, "1:2:3:4::a"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 1), ==, "1:2:3:4::b"); + + /* DNS domains - none as domains are stuffed to 'ipv4' setting */ + g_assert_cmpint(nm_setting_ip_config_get_num_dns_searches(s_ip6), ==, 0); + + g_object_unref(connection); +} + +static void +test_read_wired_ipv6_only(gconstpointer test_data) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + char * unmanaged = NULL; + NMIPAddress * ip6_addr; + const char * method; + const char * file, *expected_id; + + nmtst_test_data_unpack(test_data, &file, &expected_id); - g_assert (expected_id); + g_assert(expected_id); - connection = _connection_from_file (file, NULL, TYPE_ETHERNET, &unmanaged); - g_assert (!unmanaged); + connection = _connection_from_file(file, NULL, TYPE_ETHERNET, &unmanaged); + g_assert(!unmanaged); - /* ===== CONNECTION SETTING ===== */ + /* ===== 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); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, expected_id); + + /* ===== WIRED SETTING ===== */ - /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + /* ===== IPv4 SETTING ===== */ - /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); + method = nm_setting_ip_config_get_method(s_ip4); + g_assert_cmpstr(method, ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - method = nm_setting_ip_config_get_method (s_ip4); - g_assert_cmpstr (method, ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + /* ===== IPv6 SETTING ===== */ - /* ===== IPv6 SETTING ===== */ + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL); - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_MANUAL); + /* IP addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 1); - /* IP addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip6), ==, 1); + /* Address #1 */ + ip6_addr = nm_setting_ip_config_get_address(s_ip6, 0); + g_assert(ip6_addr != NULL); + g_assert_cmpstr(nm_ip_address_get_address(ip6_addr), ==, "1001:abba::1234"); + g_assert_cmpint(nm_ip_address_get_prefix(ip6_addr), ==, 56); - /* Address #1 */ - ip6_addr = nm_setting_ip_config_get_address (s_ip6, 0); - g_assert (ip6_addr != NULL); - g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "1001:abba::1234"); - g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 56); + /* DNS Addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 1); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 0), ==, "1:2:3:4::a"); - /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip6), ==, 1); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 0), ==, "1:2:3:4::a"); + /* DNS domains should be in IPv6, because IPv4 is disabled */ + g_assert_cmpint(nm_setting_ip_config_get_num_dns_searches(s_ip6), ==, 3); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 0), ==, "lorem.com"); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 1), ==, "ipsum.org"); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 2), ==, "dolor.edu"); - /* DNS domains should be in IPv6, because IPv4 is disabled */ - g_assert_cmpint (nm_setting_ip_config_get_num_dns_searches (s_ip6), ==, 3); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 0), ==, "lorem.com"); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 1), ==, "ipsum.org"); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 2), ==, "dolor.edu"); - - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wired_dhcp6_only (void) +test_read_wired_dhcp6_only(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - char *unmanaged = NULL; - const char *method; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + char * unmanaged = NULL; + const char * method; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-dhcp6-only", NULL, TYPE_ETHERNET, &unmanaged); - g_assert (!unmanaged); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-dhcp6-only", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert(!unmanaged); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-dhcp6-only"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System test-wired-dhcp6-only"); - /* ===== WIRED SETTING ===== */ + /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - /* ===== IPv4 SETTING ===== */ + /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); - method = nm_setting_ip_config_get_method (s_ip4); - g_assert_cmpstr (method, ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + method = nm_setting_ip_config_get_method(s_ip4); + g_assert_cmpstr(method, ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - /* ===== IPv6 SETTING ===== */ + /* ===== IPv6 SETTING ===== */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_DHCP); + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_DHCP); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wired_autoip (void) +test_read_wired_autoip(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + char * unmanaged = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-autoip", - NULL, TYPE_ETHERNET, - &unmanaged); - g_assert (unmanaged == NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-autoip", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert(unmanaged == NULL); - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL); - g_assert (!nm_setting_ip_config_get_may_fail (s_ip4)); - g_assert (nm_setting_ip_config_get_ignore_auto_dns (s_ip4)); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL); + g_assert(!nm_setting_ip_config_get_may_fail(s_ip4)); + g_assert(nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); - s_con = nm_connection_get_setting_connection (connection); - g_assert_cmpint (nm_setting_connection_get_wait_device_timeout (s_con), ==, 2600); + s_con = nm_connection_get_setting_connection(connection); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), ==, 2600); } static void -test_read_onboot_no (void) +test_read_onboot_no(void) { - NMConnection *connection; - NMSettingConnection *s_con; - char *unmanaged = NULL; + NMConnection * connection; + NMSettingConnection *s_con; + char * unmanaged = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-onboot-no", NULL, TYPE_ETHERNET, &unmanaged); - g_assert (!unmanaged); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-onboot-no", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert(!unmanaged); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); - g_assert (!nm_setting_connection_get_autoconnect (s_con)); + g_assert(!nm_setting_connection_get_autoconnect(s_con)); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_noip (void) +test_read_noip(void) { - NMConnection *connection; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; + NMConnection * connection; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-noip", NULL, TYPE_ETHERNET, NULL); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-noip", NULL, TYPE_ETHERNET, NULL); - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - g_assert (nm_setting_ip_config_get_never_default (s_ip4) == FALSE); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + g_assert(nm_setting_ip_config_get_never_default(s_ip4) == FALSE); - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); - g_assert (nm_setting_ip_config_get_never_default (s_ip6) == FALSE); + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE); + g_assert(nm_setting_ip_config_get_never_default(s_ip6) == FALSE); - g_object_unref (connection); + g_object_unref(connection); } -#define TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT TEST_IFCFG_DIR"/test_ca_cert.pem" - -static void -test_read_wired_8021x_peap_mschapv2 (void) -{ - NMConnection *connection; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSetting8021x *s_8021x; - NMSetting8021x *tmp_8021x; - char *unmanaged = NULL; - GError *error = NULL; - gboolean success = FALSE; - const char *expected_ca_cert_path; - const char *read_ca_cert_path; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-8021x-peap-mschapv2", - NULL, TYPE_ETHERNET, &unmanaged); - g_assert (!unmanaged); - - /* ===== WIRED SETTING ===== */ - - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - - /* ===== IPv4 SETTING ===== */ - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - - /* ===== 802.1x SETTING ===== */ - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x); - - g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); - g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "peap"); - g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "David Smith"); - g_assert_cmpstr (nm_setting_802_1x_get_anonymous_identity (s_8021x), ==, "somebody"); - g_assert_cmpstr (nm_setting_802_1x_get_password (s_8021x), ==, "foobar baz"); - g_assert_cmpstr (nm_setting_802_1x_get_phase1_peapver (s_8021x), ==, "1"); - g_assert_cmpstr (nm_setting_802_1x_get_phase1_peaplabel (s_8021x), ==, "1"); - - /* CA Cert */ - tmp_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - - success = nm_setting_802_1x_set_ca_cert (tmp_8021x, - TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error); - g_assert_no_error (error); - g_assert (success == TRUE); - - expected_ca_cert_path = nm_setting_802_1x_get_ca_cert_path (tmp_8021x); - g_assert (expected_ca_cert_path); - - read_ca_cert_path = nm_setting_802_1x_get_ca_cert_path (s_8021x); - g_assert (read_ca_cert_path); - - g_assert_cmpstr (read_ca_cert_path, ==, expected_ca_cert_path); - - g_object_unref (tmp_8021x); - - g_object_unref (connection); -} +#define TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT TEST_IFCFG_DIR "/test_ca_cert.pem" static void -test_read_wired_8021x_tls_secret_flags (gconstpointer test_data) +test_read_wired_8021x_peap_mschapv2(void) { - NMConnection *connection; - NMSettingWired *s_wired; - NMSetting8021x *s_8021x; - char *dirname, *tmp; - const char *ifcfg; - gpointer expected_flags_p; - - nmtst_test_data_unpack (test_data, &ifcfg, &expected_flags_p); - - connection = _connection_from_file (ifcfg, NULL, TYPE_ETHERNET, NULL); - - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + NMConnection * connection; + NMSettingWired * s_wired; + NMSettingIPConfig *s_ip4; + NMSetting8021x * s_8021x; + NMSetting8021x * tmp_8021x; + char * unmanaged = NULL; + GError * error = NULL; + gboolean success = FALSE; + const char * expected_ca_cert_path; + const char * read_ca_cert_path; - /* ===== 802.1x SETTING ===== */ - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x); - g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); - g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "tls"); - g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "David Smith"); - g_assert_cmpint (nm_setting_802_1x_get_private_key_password_flags (s_8021x), ==, GPOINTER_TO_INT (expected_flags_p)); - - dirname = g_path_get_dirname (ifcfg); - tmp = g_build_path ("/", dirname, "test_ca_cert.pem", NULL); - g_assert_cmpstr (nm_setting_802_1x_get_ca_cert_path (s_8021x), ==, tmp); - g_free (tmp); - - tmp = g_build_path ("/", dirname, "test1_key_and_cert.pem", NULL); - g_assert_cmpstr (nm_setting_802_1x_get_client_cert_path (s_8021x), ==, tmp); - g_assert_cmpstr (nm_setting_802_1x_get_private_key_path (s_8021x), ==, tmp); - g_free (tmp); - - g_free (dirname); - - g_object_unref (connection); -} - -static void -test_read_write_802_1X_subj_matches (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSetting8021x *s_8021x; + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-8021x-peap-mschapv2", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert(!unmanaged); - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-802-1X-subj-matches", - NULL, TYPE_ETHERNET, NULL); + /* ===== WIRED SETTING ===== */ - /* ===== 802.1x SETTING ===== */ - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x); - g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); - g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "peap"); - g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "Jara Cimrman"); - g_assert_cmpstr (nm_setting_802_1x_get_subject_match (s_8021x), ==, "server1.yourdomain.tld"); - g_assert_cmpstr (nm_setting_802_1x_get_phase2_subject_match (s_8021x), ==, "server2.yourdomain.tld"); - g_assert_cmpint (nm_setting_802_1x_get_num_altsubject_matches (s_8021x), ==, 3); - g_assert_cmpstr (nm_setting_802_1x_get_altsubject_match (s_8021x, 0), ==, "a.yourdomain.tld"); - g_assert_cmpstr (nm_setting_802_1x_get_altsubject_match (s_8021x, 1), ==, "b.yourdomain.tld"); - g_assert_cmpstr (nm_setting_802_1x_get_altsubject_match (s_8021x, 2), ==, "c.yourdomain.tld"); - g_assert_cmpint (nm_setting_802_1x_get_num_phase2_altsubject_matches (s_8021x), ==, 2); - g_assert_cmpstr (nm_setting_802_1x_get_phase2_altsubject_match (s_8021x, 0), ==, "x.yourdomain.tld"); - g_assert_cmpstr (nm_setting_802_1x_get_phase2_altsubject_match (s_8021x, 1), ==, "y.yourdomain.tld"); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-System_test-wired-802-1X-subj-matches.cexpected", - &testfile); + /* ===== IPv4 SETTING ===== */ - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + /* ===== 802.1x SETTING ===== */ + s_8021x = nm_connection_get_setting_802_1x(connection); + g_assert(s_8021x); - /* Check 802.1X stuff of the re-read connection. */ - s_8021x = nm_connection_get_setting_802_1x (reread); - g_assert (s_8021x); - g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); - g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "peap"); - g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "Jara Cimrman"); - g_assert_cmpstr (nm_setting_802_1x_get_subject_match (s_8021x), ==, "server1.yourdomain.tld"); - g_assert_cmpstr (nm_setting_802_1x_get_phase2_subject_match (s_8021x), ==, "server2.yourdomain.tld"); - g_assert_cmpint (nm_setting_802_1x_get_num_altsubject_matches (s_8021x), ==, 3); - g_assert_cmpstr (nm_setting_802_1x_get_altsubject_match (s_8021x, 0), ==, "a.yourdomain.tld"); - g_assert_cmpstr (nm_setting_802_1x_get_altsubject_match (s_8021x, 1), ==, "b.yourdomain.tld"); - g_assert_cmpstr (nm_setting_802_1x_get_altsubject_match (s_8021x, 2), ==, "c.yourdomain.tld"); - g_assert_cmpint (nm_setting_802_1x_get_num_phase2_altsubject_matches (s_8021x), ==, 2); - g_assert_cmpstr (nm_setting_802_1x_get_phase2_altsubject_match (s_8021x, 0), ==, "x.yourdomain.tld"); - g_assert_cmpstr (nm_setting_802_1x_get_phase2_altsubject_match (s_8021x, 1), ==, "y.yourdomain.tld"); -} + g_assert_cmpint(nm_setting_802_1x_get_num_eap_methods(s_8021x), ==, 1); + g_assert_cmpstr(nm_setting_802_1x_get_eap_method(s_8021x, 0), ==, "peap"); + g_assert_cmpstr(nm_setting_802_1x_get_identity(s_8021x), ==, "David Smith"); + g_assert_cmpstr(nm_setting_802_1x_get_anonymous_identity(s_8021x), ==, "somebody"); + g_assert_cmpstr(nm_setting_802_1x_get_password(s_8021x), ==, "foobar baz"); + g_assert_cmpstr(nm_setting_802_1x_get_phase1_peapver(s_8021x), ==, "1"); + g_assert_cmpstr(nm_setting_802_1x_get_phase1_peaplabel(s_8021x), ==, "1"); -static void -test_read_802_1x_ttls_eapgtc (void) -{ - NMConnection *connection; - NMSetting8021x *s_8021x; + /* CA Cert */ + tmp_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); - /* Test that EAP-* inner methods are correctly read into the - * NMSetting8021x::autheap property. - */ + success = nm_setting_802_1x_set_ca_cert(tmp_8021x, + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + g_assert_no_error(error); + g_assert(success == TRUE); - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-802-1x-ttls-eapgtc", - NULL, TYPE_WIRELESS, NULL); + expected_ca_cert_path = nm_setting_802_1x_get_ca_cert_path(tmp_8021x); + g_assert(expected_ca_cert_path); - /* ===== 802.1x SETTING ===== */ - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x); + read_ca_cert_path = nm_setting_802_1x_get_ca_cert_path(s_8021x); + g_assert(read_ca_cert_path); - /* EAP methods */ - g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); - g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "ttls"); + g_assert_cmpstr(read_ca_cert_path, ==, expected_ca_cert_path); - /* Auth methods */ - g_assert_cmpstr (nm_setting_802_1x_get_phase2_auth (s_8021x), ==, NULL); - g_assert_cmpstr (nm_setting_802_1x_get_phase2_autheap (s_8021x), ==, "gtc"); + g_object_unref(tmp_8021x); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_802_1x_tls_p12_no_client_cert (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSetting8021x *s_8021x; - const char *path; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-8021x-tls-p12-no-client-cert", - NULL, TYPE_ETHERNET, NULL); - - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x); - - g_assert_cmpint (nm_setting_802_1x_get_private_key_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH); - path = nm_setting_802_1x_get_private_key_path (s_8021x); - g_assert (path); - - g_assert_cmpint (nm_setting_802_1x_get_client_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH); - g_assert_cmpstr (path, ==, nm_setting_802_1x_get_client_cert_path (s_8021x)); -} +test_read_wired_8021x_tls_secret_flags(gconstpointer test_data) +{ + NMConnection * connection; + NMSettingWired *s_wired; + NMSetting8021x *s_8021x; + char * dirname, *tmp; + const char * ifcfg; + gpointer expected_flags_p; + + nmtst_test_data_unpack(test_data, &ifcfg, &expected_flags_p); + + connection = _connection_from_file(ifcfg, NULL, TYPE_ETHERNET, NULL); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + /* ===== 802.1x SETTING ===== */ + s_8021x = nm_connection_get_setting_802_1x(connection); + g_assert(s_8021x); + g_assert_cmpint(nm_setting_802_1x_get_num_eap_methods(s_8021x), ==, 1); + g_assert_cmpstr(nm_setting_802_1x_get_eap_method(s_8021x, 0), ==, "tls"); + g_assert_cmpstr(nm_setting_802_1x_get_identity(s_8021x), ==, "David Smith"); + g_assert_cmpint(nm_setting_802_1x_get_private_key_password_flags(s_8021x), + ==, + GPOINTER_TO_INT(expected_flags_p)); + + dirname = g_path_get_dirname(ifcfg); + tmp = g_build_path("/", dirname, "test_ca_cert.pem", NULL); + g_assert_cmpstr(nm_setting_802_1x_get_ca_cert_path(s_8021x), ==, tmp); + g_free(tmp); + + tmp = g_build_path("/", dirname, "test1_key_and_cert.pem", NULL); + g_assert_cmpstr(nm_setting_802_1x_get_client_cert_path(s_8021x), ==, tmp); + g_assert_cmpstr(nm_setting_802_1x_get_private_key_path(s_8021x), ==, tmp); + g_free(tmp); + + g_free(dirname); + + g_object_unref(connection); +} static void -test_read_write_802_1x_password_raw (void) +test_read_write_802_1X_subj_matches(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSetting8021x *s_8021x; - GBytes *bytes; - gconstpointer data; - gsize size; - - /* Test that the 802-1x.password-raw is correctly read and written. */ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSetting8021x * s_8021x; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-802-1x-password-raw", - NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-802-1X-subj-matches", + NULL, + TYPE_ETHERNET, + NULL); - /* ===== 802.1x SETTING ===== */ - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x); + /* ===== 802.1x SETTING ===== */ + s_8021x = nm_connection_get_setting_802_1x(connection); + g_assert(s_8021x); + g_assert_cmpint(nm_setting_802_1x_get_num_eap_methods(s_8021x), ==, 1); + g_assert_cmpstr(nm_setting_802_1x_get_eap_method(s_8021x, 0), ==, "peap"); + g_assert_cmpstr(nm_setting_802_1x_get_identity(s_8021x), ==, "Jara Cimrman"); + g_assert_cmpstr(nm_setting_802_1x_get_subject_match(s_8021x), ==, "server1.yourdomain.tld"); + g_assert_cmpstr(nm_setting_802_1x_get_phase2_subject_match(s_8021x), + ==, + "server2.yourdomain.tld"); + g_assert_cmpint(nm_setting_802_1x_get_num_altsubject_matches(s_8021x), ==, 3); + g_assert_cmpstr(nm_setting_802_1x_get_altsubject_match(s_8021x, 0), ==, "a.yourdomain.tld"); + g_assert_cmpstr(nm_setting_802_1x_get_altsubject_match(s_8021x, 1), ==, "b.yourdomain.tld"); + g_assert_cmpstr(nm_setting_802_1x_get_altsubject_match(s_8021x, 2), ==, "c.yourdomain.tld"); + g_assert_cmpint(nm_setting_802_1x_get_num_phase2_altsubject_matches(s_8021x), ==, 2); + g_assert_cmpstr(nm_setting_802_1x_get_phase2_altsubject_match(s_8021x, 0), + ==, + "x.yourdomain.tld"); + g_assert_cmpstr(nm_setting_802_1x_get_phase2_altsubject_match(s_8021x, 1), + ==, + "y.yourdomain.tld"); - bytes = nm_setting_802_1x_get_password_raw (s_8021x); - g_assert (bytes); - data = g_bytes_get_data (bytes, &size); - g_assert_cmpmem (data, size, "\x04\x08\x15\x16\x23\x42\x00\x01", 8); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-System_test-wired-802-1X-subj-matches.cexpected", + &testfile); - g_assert_cmpint (nm_setting_802_1x_get_password_raw_flags (s_8021x), - ==, - NM_SETTING_SECRET_FLAG_NONE); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - g_assert_cmpstr (nm_setting_802_1x_get_pin (s_8021x), ==, "hallo2"); - g_assert_cmpint (nm_setting_802_1x_get_pin_flags (s_8021x), ==, NM_SETTING_SECRET_FLAG_NONE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - keyfile = utils_get_keys_path (testfile); - g_assert (g_file_test (keyfile, G_FILE_TEST_EXISTS)); + /* Check 802.1X stuff of the re-read connection. */ + s_8021x = nm_connection_get_setting_802_1x(reread); + g_assert(s_8021x); + g_assert_cmpint(nm_setting_802_1x_get_num_eap_methods(s_8021x), ==, 1); + g_assert_cmpstr(nm_setting_802_1x_get_eap_method(s_8021x, 0), ==, "peap"); + g_assert_cmpstr(nm_setting_802_1x_get_identity(s_8021x), ==, "Jara Cimrman"); + g_assert_cmpstr(nm_setting_802_1x_get_subject_match(s_8021x), ==, "server1.yourdomain.tld"); + g_assert_cmpstr(nm_setting_802_1x_get_phase2_subject_match(s_8021x), + ==, + "server2.yourdomain.tld"); + g_assert_cmpint(nm_setting_802_1x_get_num_altsubject_matches(s_8021x), ==, 3); + g_assert_cmpstr(nm_setting_802_1x_get_altsubject_match(s_8021x, 0), ==, "a.yourdomain.tld"); + g_assert_cmpstr(nm_setting_802_1x_get_altsubject_match(s_8021x, 1), ==, "b.yourdomain.tld"); + g_assert_cmpstr(nm_setting_802_1x_get_altsubject_match(s_8021x, 2), ==, "c.yourdomain.tld"); + g_assert_cmpint(nm_setting_802_1x_get_num_phase2_altsubject_matches(s_8021x), ==, 2); + g_assert_cmpstr(nm_setting_802_1x_get_phase2_altsubject_match(s_8021x, 0), + ==, + "x.yourdomain.tld"); + g_assert_cmpstr(nm_setting_802_1x_get_phase2_altsubject_match(s_8021x, 1), + ==, + "y.yourdomain.tld"); +} + +static void +test_read_802_1x_ttls_eapgtc(void) +{ + NMConnection * connection; + NMSetting8021x *s_8021x; + + /* Test that EAP-* inner methods are correctly read into the + * NMSetting8021x::autheap property. + */ + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-802-1x-ttls-eapgtc", + NULL, + TYPE_WIRELESS, + NULL); + + /* ===== 802.1x SETTING ===== */ + s_8021x = nm_connection_get_setting_802_1x(connection); + g_assert(s_8021x); + + /* EAP methods */ + g_assert_cmpint(nm_setting_802_1x_get_num_eap_methods(s_8021x), ==, 1); + g_assert_cmpstr(nm_setting_802_1x_get_eap_method(s_8021x, 0), ==, "ttls"); + + /* Auth methods */ + g_assert_cmpstr(nm_setting_802_1x_get_phase2_auth(s_8021x), ==, NULL); + g_assert_cmpstr(nm_setting_802_1x_get_phase2_autheap(s_8021x), ==, "gtc"); + + g_object_unref(connection); +} + +static void +test_read_802_1x_tls_p12_no_client_cert(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSetting8021x * s_8021x; + const char * path; + + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-8021x-tls-p12-no-client-cert", + NULL, + TYPE_ETHERNET, + NULL); + + s_8021x = nm_connection_get_setting_802_1x(connection); + g_assert(s_8021x); + + g_assert_cmpint(nm_setting_802_1x_get_private_key_scheme(s_8021x), + ==, + NM_SETTING_802_1X_CK_SCHEME_PATH); + path = nm_setting_802_1x_get_private_key_path(s_8021x); + g_assert(path); + + g_assert_cmpint(nm_setting_802_1x_get_client_cert_scheme(s_8021x), + ==, + NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert_cmpstr(path, ==, nm_setting_802_1x_get_client_cert_path(s_8021x)); +} + +static void +test_read_write_802_1x_password_raw(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSetting8021x * s_8021x; + GBytes * bytes; + gconstpointer data; + gsize size; + + /* Test that the 802-1x.password-raw is correctly read and written. */ + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-802-1x-password-raw", + NULL, + TYPE_ETHERNET, + NULL); + + /* ===== 802.1x SETTING ===== */ + s_8021x = nm_connection_get_setting_802_1x(connection); + g_assert(s_8021x); + + bytes = nm_setting_802_1x_get_password_raw(s_8021x); + g_assert(bytes); + data = g_bytes_get_data(bytes, &size); + g_assert_cmpmem(data, size, "\x04\x08\x15\x16\x23\x42\x00\x01", 8); + + g_assert_cmpint(nm_setting_802_1x_get_password_raw_flags(s_8021x), + ==, + NM_SETTING_SECRET_FLAG_NONE); + + g_assert_cmpstr(nm_setting_802_1x_get_pin(s_8021x), ==, "hallo2"); + g_assert_cmpint(nm_setting_802_1x_get_pin_flags(s_8021x), ==, NM_SETTING_SECRET_FLAG_NONE); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + keyfile = utils_get_keys_path(testfile); + g_assert(g_file_test(keyfile, G_FILE_TEST_EXISTS)); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_read_wired_aliases_good (gconstpointer test_data) +test_read_wired_aliases_good(gconstpointer test_data) { - const int N = GPOINTER_TO_INT (test_data); - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - int expected_num_addresses; - const char *expected_address_0[] = { "192.168.1.5", "192.168.1.6", "192.168.1.9", "192.168.1.99", NULL }; - const char *expected_address_3[] = { "192.168.1.5", "192.168.1.6", NULL }; - const char *expected_label_0[] = { NULL, "aliasem0:1", "aliasem0:2", "aliasem0:99", NULL, }; - const char *expected_label_3[] = { NULL, "aliasem3:1", NULL, }; - const char **expected_address; - const char **expected_label; - int i, j; - char path[256]; + const int N = GPOINTER_TO_INT(test_data); + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4; + int expected_num_addresses; + const char * expected_address_0[] = {"192.168.1.5", + "192.168.1.6", + "192.168.1.9", + "192.168.1.99", + NULL}; + const char * expected_address_3[] = {"192.168.1.5", "192.168.1.6", NULL}; + const char * expected_label_0[] = { + NULL, + "aliasem0:1", + "aliasem0:2", + "aliasem0:99", + NULL, + }; + const char *expected_label_3[] = { + NULL, + "aliasem3:1", + NULL, + }; + const char **expected_address; + const char **expected_label; + int i, j; + char path[256]; + + expected_address = N == 0 ? expected_address_0 : expected_address_3; + expected_label = N == 0 ? expected_label_0 : expected_label_3; + expected_num_addresses = g_strv_length((char **) expected_address); - expected_address = N == 0 ? expected_address_0 : expected_address_3; - expected_label = N == 0 ? expected_label_0 : expected_label_3; - expected_num_addresses = g_strv_length ((char **) expected_address); + nm_sprintf_buf(path, TEST_IFCFG_DIR "/ifcfg-aliasem%d", N); - nm_sprintf_buf (path, TEST_IFCFG_DIR"/ifcfg-aliasem%d", N); + connection = _connection_from_file(path, NULL, TYPE_ETHERNET, NULL); - connection = _connection_from_file (path, NULL, TYPE_ETHERNET, NULL); + /* ===== CONNECTION SETTING ===== */ - /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + if (N == 0) + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System aliasem0"); + else + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System aliasem3"); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - if (N == 0) - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System aliasem0"); - else - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System aliasem3"); + /* ===== IPv4 SETTING ===== */ - /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, expected_num_addresses); - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, expected_num_addresses); + /* Addresses */ + for (i = 0; i < expected_num_addresses; i++) { + NMIPAddress *ip4_addr; + const char * addr; + GVariant * label; - /* Addresses */ - for (i = 0; i < expected_num_addresses; i++) { - NMIPAddress *ip4_addr; - const char *addr; - GVariant *label; + ip4_addr = nm_setting_ip_config_get_address(s_ip4, i); + g_assert(ip4_addr != NULL); - ip4_addr = nm_setting_ip_config_get_address (s_ip4, i); - g_assert (ip4_addr != NULL); + addr = nm_ip_address_get_address(ip4_addr); + g_assert(nm_utils_ipaddr_is_valid(AF_INET, addr)); - addr = nm_ip_address_get_address (ip4_addr); - g_assert (nm_utils_ipaddr_is_valid (AF_INET, addr)); + for (j = 0; j < expected_num_addresses; j++) { + if (!g_strcmp0(addr, expected_address[j])) + break; + } + g_assert(j < expected_num_addresses); - for (j = 0; j < expected_num_addresses; j++) { - if (!g_strcmp0 (addr, expected_address[j])) - break; - } - g_assert (j < expected_num_addresses); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 24); + label = nm_ip_address_get_attribute(ip4_addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + if (expected_label[j]) + g_assert_cmpstr(g_variant_get_string(label, NULL), ==, expected_label[j]); + else + g_assert(label == NULL); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); - label = nm_ip_address_get_attribute (ip4_addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); - if (expected_label[j]) - g_assert_cmpstr (g_variant_get_string (label, NULL), ==, expected_label[j]); - else - g_assert (label == NULL); + expected_address[j] = NULL; + expected_label[j] = NULL; + } - expected_address[j] = NULL; - expected_label[j] = NULL; - } + /* Gateway */ + g_assert(!nm_setting_ip_config_get_never_default(s_ip4)); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "192.168.1.1"); - /* Gateway */ - g_assert (!nm_setting_ip_config_get_never_default (s_ip4)); - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1"); + for (i = 0; i < expected_num_addresses; i++) + g_assert(!expected_address[i]); - for (i = 0; i < expected_num_addresses; i++) - g_assert (!expected_address[i]); - - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wired_aliases_bad (const char *base, const char *expected_id) +test_read_wired_aliases_bad(const char *base, const char *expected_id) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMIPAddress *ip4_addr; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4; + NMIPAddress * ip4_addr; - g_assert (expected_id); + g_assert(expected_id); - connection = _connection_from_file (base, NULL, TYPE_ETHERNET, NULL); - g_test_assert_expected_messages (); + connection = _connection_from_file(base, NULL, TYPE_ETHERNET, NULL); + g_test_assert_expected_messages(); - /* ===== CONNECTION SETTING ===== */ + /* ===== 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); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, expected_id); - /* ===== IPv4 SETTING ===== */ + /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); - /* Addresses */ - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); - g_assert (ip4_addr != NULL); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.1.5"); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); - g_assert (nm_ip_address_get_attribute (ip4_addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL) == NULL); + /* Addresses */ + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr != NULL); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "192.168.1.5"); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 24); + g_assert(nm_ip_address_get_attribute(ip4_addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL) == NULL); - /* Gateway */ - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1"); + /* Gateway */ + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "192.168.1.1"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wired_aliases_bad_1 (void) +test_read_wired_aliases_bad_1(void) { - NMTST_EXPECT_NM_WARN ("*aliasem1:1*has no DEVICE*"); - test_read_wired_aliases_bad (TEST_IFCFG_DIR"/ifcfg-aliasem1", "System aliasem1"); + NMTST_EXPECT_NM_WARN("*aliasem1:1*has no DEVICE*"); + test_read_wired_aliases_bad(TEST_IFCFG_DIR "/ifcfg-aliasem1", "System aliasem1"); } static void -test_read_wired_aliases_bad_2 (void) +test_read_wired_aliases_bad_2(void) { - NMTST_EXPECT_NM_WARN ("*aliasem2:1*has invalid DEVICE*"); - test_read_wired_aliases_bad (TEST_IFCFG_DIR"/ifcfg-aliasem2", "System aliasem2"); + NMTST_EXPECT_NM_WARN("*aliasem2:1*has invalid DEVICE*"); + test_read_wired_aliases_bad(TEST_IFCFG_DIR "/ifcfg-aliasem2", "System aliasem2"); } static void -test_read_dns_options (void) +test_read_dns_options(void) { - NMConnection *connection; - NMSettingIPConfig *s_ip4, *s_ip6; - char *unmanaged = NULL; - const char *option; - const char *options4[] = { "ndots:3", "single-request-reopen" }; - const char *options6[] = { "inet6" }; - guint32 i, num; + NMConnection * connection; + NMSettingIPConfig *s_ip4, *s_ip6; + char * unmanaged = NULL; + const char * option; + const char * options4[] = {"ndots:3", "single-request-reopen"}; + const char * options6[] = {"inet6"}; + guint32 i, num; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-dns-options", - NULL, TYPE_ETHERNET, &unmanaged); - g_assert_cmpstr (unmanaged, ==, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-dns-options", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert_cmpstr(unmanaged, ==, NULL); - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); - num = nm_setting_ip_config_get_num_dns_options (s_ip4); - g_assert_cmpint (num, ==, G_N_ELEMENTS (options4)); + num = nm_setting_ip_config_get_num_dns_options(s_ip4); + g_assert_cmpint(num, ==, G_N_ELEMENTS(options4)); - for (i = 0; i < num; i++) { - option = nm_setting_ip_config_get_dns_option (s_ip4, i); - g_assert_cmpstr (options4[i], ==, option); - } + for (i = 0; i < num; i++) { + option = nm_setting_ip_config_get_dns_option(s_ip4, i); + g_assert_cmpstr(options4[i], ==, option); + } - num = nm_setting_ip_config_get_num_dns_options (s_ip6); - g_assert_cmpint (num, ==, G_N_ELEMENTS (options6)); + num = nm_setting_ip_config_get_num_dns_options(s_ip6); + g_assert_cmpint(num, ==, G_N_ELEMENTS(options6)); - for (i = 0; i < num; i++) { - option = nm_setting_ip_config_get_dns_option (s_ip6, i); - g_assert_cmpstr (options6[i], ==, option); - } + for (i = 0; i < num; i++) { + option = nm_setting_ip_config_get_dns_option(s_ip6, i); + g_assert_cmpstr(options6[i], ==, option); + } - g_object_unref (connection); + g_object_unref(connection); } static void -test_clear_master (void) +test_clear_master(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_free char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - char *unmanaged = NULL; - shvarFile *f; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_free char * keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + char * unmanaged = NULL; + shvarFile * f; - /* 1. load the bridge slave connection from disk */ - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bridge-component", - NULL, TYPE_ETHERNET, &unmanaged); - g_assert_cmpstr (unmanaged, ==, NULL); + /* 1. load the bridge slave connection from disk */ + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-bridge-component", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert_cmpstr(unmanaged, ==, NULL); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); - g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, "br0"); - g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, "bridge"); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, "br0"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, "bridge"); - /* 2. write the connection to a new file */ - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-System_test-bridge-component-a.cexpected", - &testfile); + /* 2. write the connection to a new file */ + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-System_test-bridge-component-a.cexpected", + &testfile); - /* 3. clear master and slave-type */ - g_object_set (s_con, - NM_SETTING_CONNECTION_MASTER, NULL, - NM_SETTING_CONNECTION_SLAVE_TYPE, NULL, - NULL); + /* 3. clear master and slave-type */ + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + NULL, + NM_SETTING_CONNECTION_SLAVE_TYPE, + NULL, + NULL); - g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, NULL); - g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NULL); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, NULL); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NULL); - nmtst_assert_connection_verifies_after_normalization (connection, 0, 0); + nmtst_assert_connection_verifies_after_normalization(connection, 0, 0); - /* 4. update the connection on disk */ - _writer_update_connection (connection, - TEST_SCRATCH_DIR, - testfile, - TEST_IFCFG_DIR"/ifcfg-System_test-bridge-component-b.cexpected"); - keyfile = utils_get_keys_path (testfile); - g_assert (!g_file_test (keyfile, G_FILE_TEST_EXISTS)); + /* 4. update the connection on disk */ + _writer_update_connection(connection, + TEST_SCRATCH_DIR, + testfile, + TEST_IFCFG_DIR "/ifcfg-System_test-bridge-component-b.cexpected"); + keyfile = utils_get_keys_path(testfile); + g_assert(!g_file_test(keyfile, G_FILE_TEST_EXISTS)); - /* 5. check that BRIDGE variable has been removed */ - f = _svOpenFile (testfile); - _svGetValue_check (f, "BRIDGE", NULL); - svCloseFile (f); + /* 5. check that BRIDGE variable has been removed */ + f = _svOpenFile(testfile); + _svGetValue_check(f, "BRIDGE", NULL); + svCloseFile(f); } static void -test_write_dns_options (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - static const char *mac = "31:33:33:37:be:cd"; - guint32 mtu = 1492; - NMIPAddress *addr; - NMIPAddress *addr6; - GError *error = NULL; +test_write_dns_options(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + static const char * mac = "31:33:33:37:be:cd"; + guint32 mtu = 1492; + NMIPAddress * addr; + NMIPAddress * addr6; + GError * error = NULL; - connection = nm_simple_connection_new (); + connection = nm_simple_connection_new(); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test DNS options", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test DNS options", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, mtu, NULL); - g_object_set (s_wired, - NM_SETTING_WIRED_MAC_ADDRESS, mac, - NM_SETTING_WIRED_MTU, mtu, - NULL); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NM_SETTING_IP_CONFIG_ROUTE_METRIC, + (gint64) 204, + NULL); + + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, &error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + nm_setting_ip_config_add_dns_option(s_ip4, "debug"); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) 204, - NULL); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP_CONFIG_ROUTE_METRIC, + (gint64) 206, + NULL); - nm_setting_ip_config_add_dns_option (s_ip4, "debug"); + /* Add addresses */ + addr6 = nm_ip_address_new(AF_INET6, "1003:1234:abcd::1", 11, &error); + nm_setting_ip_config_add_address(s_ip6, addr6); + nm_ip_address_unref(addr6); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + nm_setting_ip_config_add_dns_option(s_ip6, "timeout:3"); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) 206, - NULL); + nmtst_assert_connection_verifies(connection); - /* Add addresses */ - addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, &error); - nm_setting_ip_config_add_address (s_ip6, addr6); - nm_ip_address_unref (addr6); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - nm_setting_ip_config_add_dns_option (s_ip6, "timeout:3"); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_verifies (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_read_wifi_open (void) +test_read_wifi_open(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4, *s_ip6; - GBytes *ssid; - const char *mac; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; - const char *expected_ssid = "blahblah"; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIPConfig * s_ip4, *s_ip6; + GBytes * ssid; + const char * mac; + char expected_mac_address[ETH_ALEN] = {0x00, 0x16, 0x41, 0x11, 0x22, 0x33}; + const char *expected_ssid = "blahblah"; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-open", - NULL, TYPE_WIRELESS, NULL); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-open", NULL, TYPE_WIRELESS, NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-open)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System blahblah (test-wifi-open)"); - /* UUID can't be tested if the ifcfg does not contain the UUID key, because - * the UUID is generated on the full path of the ifcfg file, which can change - * depending on where the tests are run. - */ + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ - g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); - g_assert (nm_setting_connection_get_autoconnect (s_con)); - g_assert_cmpint (nm_setting_connection_get_autoconnect_priority (s_con), ==, -1); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + g_assert_cmpint(nm_setting_connection_get_autoconnect_priority(s_con), ==, -1); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* MAC address */ - mac = nm_setting_wireless_get_mac_address (s_wireless); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address))); + /* MAC address */ + mac = nm_setting_wireless_get_mac_address(s_wireless); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, sizeof(expected_mac_address))); - g_assert_cmpint (nm_setting_wireless_get_mtu (s_wireless), ==, 0); + g_assert_cmpint(nm_setting_wireless_get_mtu(s_wireless), ==, 0); - ssid = nm_setting_wireless_get_ssid (s_wireless); - g_assert (ssid); - g_assert_cmpmem (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), expected_ssid, strlen (expected_ssid)); + ssid = nm_setting_wireless_get_ssid(s_wireless); + g_assert(ssid); + g_assert_cmpmem(g_bytes_get_data(ssid, NULL), + g_bytes_get_size(ssid), + expected_ssid, + strlen(expected_ssid)); - g_assert (!nm_setting_wireless_get_bssid (s_wireless)); - g_assert_cmpstr (nm_setting_wireless_get_mode (s_wireless), ==, "infrastructure"); - g_assert_cmpint (nm_setting_wireless_get_channel (s_wireless), ==, 1); + g_assert(!nm_setting_wireless_get_bssid(s_wireless)); + g_assert_cmpstr(nm_setting_wireless_get_mode(s_wireless), ==, "infrastructure"); + g_assert_cmpint(nm_setting_wireless_get_channel(s_wireless), ==, 1); - /* ===== Wi-Fi SECURITY SETTING ===== */ - s_wsec = nm_connection_get_setting_wireless_security (connection); - g_assert (s_wsec == NULL); + /* ===== Wi-Fi SECURITY SETTING ===== */ + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec == NULL); - /* ===== IPv4 SETTING ===== */ + /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpint (nm_setting_ip_config_get_route_metric (s_ip4), ==, 104); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpint(nm_setting_ip_config_get_route_metric(s_ip4), ==, 104); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert( s_ip6); - g_assert_cmpint (nm_setting_ip_config_get_route_metric (s_ip6), ==, 106); + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpint(nm_setting_ip_config_get_route_metric(s_ip6), ==, 106); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_open_auto (void) +test_read_wifi_open_auto(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWireless * s_wireless; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-open-auto", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-open-auto", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-open-auto)"); + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System blahblah (test-wifi-open-auto)"); - /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); - g_assert_cmpstr (nm_setting_wireless_get_mode (s_wireless), ==, "infrastructure"); + /* ===== WIRELESS SETTING ===== */ + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); + g_assert_cmpstr(nm_setting_wireless_get_mode(s_wireless), ==, "infrastructure"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_open_ssid_hex (void) +test_read_wifi_open_ssid_hex(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - GBytes *ssid; - const char *expected_ssid = "blahblah"; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWireless * s_wireless; + GBytes * ssid; + const char * expected_ssid = "blahblah"; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-open-ssid-hex", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-open-ssid-hex", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-open-ssid-hex)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System blahblah (test-wifi-open-ssid-hex)"); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - ssid = nm_setting_wireless_get_ssid (s_wireless); - g_assert (ssid); - g_assert_cmpmem (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), expected_ssid, strlen (expected_ssid)); + ssid = nm_setting_wireless_get_ssid(s_wireless); + g_assert(ssid); + g_assert_cmpmem(g_bytes_get_data(ssid, NULL), + g_bytes_get_size(ssid), + expected_ssid, + strlen(expected_ssid)); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_open_ssid_hex_bad (void) +test_read_wifi_open_ssid_hex_bad(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - GBytes *ssid; - const char *expected_ssid = "0x626cxx"; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + GBytes * ssid; + const char * expected_ssid = "0x626cxx"; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-open-ssid-bad-hex", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-open-ssid-bad-hex", + NULL, + TYPE_WIRELESS, + NULL); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System 0x626cxx (test-wifi-open-ssid-bad-hex)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System 0x626cxx (test-wifi-open-ssid-bad-hex)"); - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - ssid = nm_setting_wireless_get_ssid (s_wireless); - g_assert (ssid); - g_assert_cmpmem (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), expected_ssid, strlen (expected_ssid)); + ssid = nm_setting_wireless_get_ssid(s_wireless); + g_assert(ssid); + g_assert_cmpmem(g_bytes_get_data(ssid, NULL), + g_bytes_get_size(ssid), + expected_ssid, + strlen(expected_ssid)); } static void -test_read_wifi_open_ssid_bad (gconstpointer data) +test_read_wifi_open_ssid_bad(gconstpointer data) { - _connection_from_file_fail ((const char *) data, NULL, TYPE_WIRELESS, NULL); + _connection_from_file_fail((const char *) data, NULL, TYPE_WIRELESS, NULL); } static void -test_read_wifi_open_ssid_quoted (void) +test_read_wifi_open_ssid_quoted(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - GBytes *ssid; - const char *expected_ssid = "foo\"bar\\"; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWireless * s_wireless; + GBytes * ssid; + const char * expected_ssid = "foo\"bar\\"; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-open-ssid-quoted", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-open-ssid-quoted", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System foo\"bar\\ (test-wifi-open-ssid-quoted)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System foo\"bar\\ (test-wifi-open-ssid-quoted)"); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - ssid = nm_setting_wireless_get_ssid (s_wireless); - g_assert (ssid); - g_assert_cmpmem (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), expected_ssid, strlen (expected_ssid)); + ssid = nm_setting_wireless_get_ssid(s_wireless); + g_assert(ssid); + g_assert_cmpmem(g_bytes_get_data(ssid, NULL), + g_bytes_get_size(ssid), + expected_ssid, + strlen(expected_ssid)); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_wep (void) +test_read_wifi_wep(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - GBytes *ssid; - const char *mac; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; - const char *expected_ssid = "blahblah"; - NMWepKeyType key_type; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIPConfig * s_ip4; + GBytes * ssid; + const char * mac; + char expected_mac_address[ETH_ALEN] = {0x00, 0x16, 0x41, 0x11, 0x22, 0x33}; + const char * expected_ssid = "blahblah"; + NMWepKeyType key_type; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep", - NULL, TYPE_WIRELESS, NULL); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wep", NULL, TYPE_WIRELESS, NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-wep)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System blahblah (test-wifi-wep)"); - /* UUID can't be tested if the ifcfg does not contain the UUID key, because - * the UUID is generated on the full path of the ifcfg file, which can change - * depending on where the tests are run. - */ + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ - g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); - g_assert (nm_setting_connection_get_autoconnect (s_con)); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* MAC address */ - mac = nm_setting_wireless_get_mac_address (s_wireless); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address))); + /* MAC address */ + mac = nm_setting_wireless_get_mac_address(s_wireless); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, sizeof(expected_mac_address))); - /* MTU */ - g_assert_cmpint (nm_setting_wireless_get_mtu (s_wireless), ==, 0); + /* MTU */ + g_assert_cmpint(nm_setting_wireless_get_mtu(s_wireless), ==, 0); - ssid = nm_setting_wireless_get_ssid (s_wireless); - g_assert (ssid); - g_assert_cmpmem (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), expected_ssid, strlen (expected_ssid)); + ssid = nm_setting_wireless_get_ssid(s_wireless); + g_assert(ssid); + g_assert_cmpmem(g_bytes_get_data(ssid, NULL), + g_bytes_get_size(ssid), + expected_ssid, + strlen(expected_ssid)); - g_assert (!nm_setting_wireless_get_bssid (s_wireless)); - g_assert_cmpstr (nm_setting_wireless_get_mode (s_wireless), ==, "infrastructure"); - g_assert_cmpint (nm_setting_wireless_get_channel (s_wireless), ==, 1); + g_assert(!nm_setting_wireless_get_bssid(s_wireless)); + g_assert_cmpstr(nm_setting_wireless_get_mode(s_wireless), ==, "infrastructure"); + g_assert_cmpint(nm_setting_wireless_get_channel(s_wireless), ==, 1); - /* ===== WIRELESS SECURITY SETTING ===== */ + /* ===== WIRELESS 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), ==, "none"); - g_assert_cmpstr (nm_setting_wireless_security_get_auth_alg (s_wsec), ==, "shared"); - g_assert_cmpint (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec), ==, 0); + 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), ==, "none"); + g_assert_cmpstr(nm_setting_wireless_security_get_auth_alg(s_wsec), ==, "shared"); + g_assert_cmpint(nm_setting_wireless_security_get_wep_tx_keyidx(s_wsec), ==, 0); - key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); - g_assert (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); + key_type = nm_setting_wireless_security_get_wep_key_type(s_wsec); + g_assert(key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); - g_assert_cmpstr (nm_setting_wireless_security_get_wep_key (s_wsec, 0), ==, "0123456789abcdef0123456789"); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 1)); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 2)); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 3)); + g_assert_cmpstr(nm_setting_wireless_security_get_wep_key(s_wsec, 0), + ==, + "0123456789abcdef0123456789"); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 1)); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 2)); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 3)); - /* ===== IPv4 SETTING ===== */ + /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_wep_adhoc (void) +test_read_wifi_wep_adhoc(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - GBytes *ssid; - const char *expected_ssid = "blahblah"; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIPConfig * s_ip4; + GBytes * ssid; + const char * expected_ssid = "blahblah"; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-adhoc", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wep-adhoc", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-wep-adhoc)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System blahblah (test-wifi-wep-adhoc)"); - /* UUID can't be tested if the ifcfg does not contain the UUID key, because - * the UUID is generated on the full path of the ifcfg file, which can change - * depending on where the tests are run. - */ + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ - g_assert (!nm_setting_connection_get_autoconnect (s_con)); + g_assert(!nm_setting_connection_get_autoconnect(s_con)); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - ssid = nm_setting_wireless_get_ssid (s_wireless); - g_assert (ssid); - g_assert_cmpmem (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), expected_ssid, strlen (expected_ssid)); + ssid = nm_setting_wireless_get_ssid(s_wireless); + g_assert(ssid); + g_assert_cmpmem(g_bytes_get_data(ssid, NULL), + g_bytes_get_size(ssid), + expected_ssid, + strlen(expected_ssid)); - g_assert (!nm_setting_wireless_get_bssid (s_wireless)); - g_assert_cmpstr (nm_setting_wireless_get_mode (s_wireless), ==, "adhoc"); - g_assert_cmpint (nm_setting_wireless_get_channel (s_wireless), ==, 11); + g_assert(!nm_setting_wireless_get_bssid(s_wireless)); + g_assert_cmpstr(nm_setting_wireless_get_mode(s_wireless), ==, "adhoc"); + g_assert_cmpint(nm_setting_wireless_get_channel(s_wireless), ==, 11); - /* ===== WIRELESS SECURITY SETTING ===== */ + /* ===== WIRELESS 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), ==, "none"); - g_assert (!nm_setting_wireless_security_get_auth_alg (s_wsec)); - g_assert_cmpint (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec), ==, 0); + 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), ==, "none"); + g_assert(!nm_setting_wireless_security_get_auth_alg(s_wsec)); + g_assert_cmpint(nm_setting_wireless_security_get_wep_tx_keyidx(s_wsec), ==, 0); - g_assert_cmpstr (nm_setting_wireless_security_get_wep_key (s_wsec, 0), ==, "0123456789abcdef0123456789"); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 1)); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 2)); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 3)); + g_assert_cmpstr(nm_setting_wireless_security_get_wep_key(s_wsec, 0), + ==, + "0123456789abcdef0123456789"); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 1)); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 2)); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 3)); - /* ===== IPv4 SETTING ===== */ + /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - /* Ignore auto DNS */ - g_assert (nm_setting_ip_config_get_ignore_auto_dns (s_ip4)); + /* Ignore auto DNS */ + g_assert(nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); - /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "4.2.2.1"); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 1), ==, "4.2.2.2"); + /* DNS Addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 0), ==, "4.2.2.1"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 1), ==, "4.2.2.2"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_wep_passphrase (void) +test_read_wifi_wep_passphrase(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-passphrase", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wep-passphrase", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* ===== WIRELESS SECURITY SETTING ===== */ + /* ===== WIRELESS 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), ==, "none"); - g_assert_cmpint (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec), ==, 0); - g_assert_cmpint (nm_setting_wireless_security_get_wep_key_type (s_wsec), ==, NM_WEP_KEY_TYPE_UNKNOWN); - g_assert_cmpstr (nm_setting_wireless_security_get_wep_key (s_wsec, 0), ==, "foobar222blahblah"); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 1)); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 2)); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 3)); + 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), ==, "none"); + g_assert_cmpint(nm_setting_wireless_security_get_wep_tx_keyidx(s_wsec), ==, 0); + g_assert_cmpint(nm_setting_wireless_security_get_wep_key_type(s_wsec), + ==, + NM_WEP_KEY_TYPE_UNKNOWN); + g_assert_cmpstr(nm_setting_wireless_security_get_wep_key(s_wsec, 0), ==, "foobar222blahblah"); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 1)); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 2)); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 3)); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_wep_40_ascii (void) +test_read_wifi_wep_40_ascii(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - NMWepKeyType key_type; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMWepKeyType key_type; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-40-ascii", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wep-40-ascii", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* ===== WIRELESS SECURITY SETTING ===== */ + /* ===== WIRELESS 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), ==, "none"); - g_assert_cmpint (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec), ==, 0); + 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), ==, "none"); + g_assert_cmpint(nm_setting_wireless_security_get_wep_tx_keyidx(s_wsec), ==, 0); - key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); - g_assert (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); + key_type = nm_setting_wireless_security_get_wep_key_type(s_wsec); + g_assert(key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); - g_assert_cmpstr (nm_setting_wireless_security_get_wep_key (s_wsec, 0), ==, "Lorem"); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 1)); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 2)); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 3)); + g_assert_cmpstr(nm_setting_wireless_security_get_wep_key(s_wsec, 0), ==, "Lorem"); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 1)); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 2)); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 3)); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_wep_104_ascii (void) +test_read_wifi_wep_104_ascii(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - NMWepKeyType key_type; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMWepKeyType key_type; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-104-ascii", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wep-104-ascii", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* ===== WIRELESS SECURITY SETTING ===== */ + /* ===== WIRELESS 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), ==, "none"); - g_assert_cmpint (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec), ==, 0); + 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), ==, "none"); + g_assert_cmpint(nm_setting_wireless_security_get_wep_tx_keyidx(s_wsec), ==, 0); - key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); - g_assert (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); + key_type = nm_setting_wireless_security_get_wep_key_type(s_wsec); + g_assert(key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); - g_assert_cmpstr (nm_setting_wireless_security_get_wep_key (s_wsec, 0), ==, "LoremIpsumSit"); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 1)); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 2)); - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 3)); + g_assert_cmpstr(nm_setting_wireless_security_get_wep_key(s_wsec, 0), ==, "LoremIpsumSit"); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 1)); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 2)); + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 3)); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_leap (void) +test_read_wifi_leap(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-leap", - NULL, TYPE_WIRELESS, NULL); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-leap", NULL, TYPE_WIRELESS, NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-leap)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System blahblah (test-wifi-leap)"); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* ===== WIRELESS SECURITY SETTING ===== */ + /* ===== WIRELESS 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), ==, "ieee8021x"); - g_assert_cmpstr (nm_setting_wireless_security_get_auth_alg (s_wsec), ==, "leap"); - g_assert_cmpstr (nm_setting_wireless_security_get_leap_username (s_wsec), ==, "Bill Smith"); - g_assert_cmpstr (nm_setting_wireless_security_get_leap_password (s_wsec), ==, "foobarblah"); + 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), ==, "ieee8021x"); + g_assert_cmpstr(nm_setting_wireless_security_get_auth_alg(s_wsec), ==, "leap"); + g_assert_cmpstr(nm_setting_wireless_security_get_leap_username(s_wsec), ==, "Bill Smith"); + g_assert_cmpstr(nm_setting_wireless_security_get_leap_password(s_wsec), ==, "foobarblah"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_leap_secret_flags (gconstpointer test_data) +test_read_wifi_leap_secret_flags(gconstpointer test_data) { - NMConnection *connection; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - const char *file; - gpointer expected_flags_p; - - nmtst_test_data_unpack (test_data, &file, &expected_flags_p); + NMConnection * connection; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity *s_wsec; + const char * file; + gpointer expected_flags_p; - connection = _connection_from_file (file, NULL, TYPE_WIRELESS, NULL); + nmtst_test_data_unpack(test_data, &file, &expected_flags_p); - /* ===== WIRELESS SETTING ===== */ - s_wifi = nm_connection_get_setting_wireless (connection); - g_assert (s_wifi); + connection = _connection_from_file(file, NULL, TYPE_WIRELESS, NULL); - /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = nm_connection_get_setting_wireless_security (connection); - g_assert (s_wsec); + /* ===== WIRELESS SETTING ===== */ + s_wifi = nm_connection_get_setting_wireless(connection); + g_assert(s_wifi); - g_assert (g_strcmp0 (nm_setting_wireless_security_get_key_mgmt (s_wsec), "ieee8021x") == 0); - g_assert (g_strcmp0 (nm_setting_wireless_security_get_auth_alg (s_wsec), "leap") == 0); - g_assert (g_strcmp0 (nm_setting_wireless_security_get_leap_username (s_wsec), "Bill Smith") == 0); - /* password blank as it's not system-owned */ - g_assert (nm_setting_wireless_security_get_leap_password_flags (s_wsec) == GPOINTER_TO_INT (expected_flags_p)); - g_assert (nm_setting_wireless_security_get_leap_password (s_wsec) == NULL); + /* ===== WIRELESS SECURITY SETTING ===== */ + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec); - g_object_unref (connection); -} - -static void -test_ifcfg_no_trailing_newline (void) -{ - shvarFile *sv; + g_assert(g_strcmp0(nm_setting_wireless_security_get_key_mgmt(s_wsec), "ieee8021x") == 0); + g_assert(g_strcmp0(nm_setting_wireless_security_get_auth_alg(s_wsec), "leap") == 0); + g_assert(g_strcmp0(nm_setting_wireless_security_get_leap_username(s_wsec), "Bill Smith") == 0); + /* password blank as it's not system-owned */ + g_assert(nm_setting_wireless_security_get_leap_password_flags(s_wsec) + == GPOINTER_TO_INT(expected_flags_p)); + g_assert(nm_setting_wireless_security_get_leap_password(s_wsec) == NULL); - sv = _svOpenFile (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk"); - _svGetValue_check (sv, "CTCPROT", "no-newline"); - svCloseFile (sv); + g_object_unref(connection); } static void -test_read_wifi_wpa_psk (void) +test_ifcfg_no_trailing_newline(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - GBytes *ssid; - const char *mac; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; - const char *expected_ssid = "blahblah"; - guint32 n, i; - gboolean found_pair_tkip = FALSE; - gboolean found_pair_ccmp = FALSE; - gboolean found_group_tkip = FALSE; - gboolean found_group_ccmp = FALSE; - gboolean found_group_wep40 = FALSE; - gboolean found_group_wep104 = FALSE; - gboolean found_proto_wpa = FALSE; - gboolean found_proto_rsn = FALSE; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk", - NULL, TYPE_WIRELESS, NULL); - - /* ===== CONNECTION SETTING ===== */ - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-wpa-psk)"); - - /* UUID can't be tested if the ifcfg does not contain the UUID key, because - * the UUID is generated on the full path of the ifcfg file, which can change - * depending on where the tests are run. - */ - - g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); - g_assert (nm_setting_connection_get_autoconnect (s_con)); - - /* ===== WIRELESS SETTING ===== */ - - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); - - mac = nm_setting_wireless_get_mac_address (s_wireless); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address))); - - g_assert_cmpint (nm_setting_wireless_get_mtu (s_wireless), ==, 0); - - ssid = nm_setting_wireless_get_ssid (s_wireless); - g_assert (ssid); - g_assert_cmpmem (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), expected_ssid, strlen (expected_ssid)); - - g_assert (!nm_setting_wireless_get_bssid (s_wireless)); - g_assert_cmpstr (nm_setting_wireless_get_mode (s_wireless), ==, "infrastructure"); - g_assert_cmpint (nm_setting_wireless_get_channel (s_wireless), ==, 1); - - /* ===== WIRELESS 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), ==, "I wonder what the king is doing tonight?"); - g_assert (!nm_setting_wireless_security_get_auth_alg (s_wsec)); - - /* Pairwise ciphers */ - n = nm_setting_wireless_security_get_num_pairwise (s_wsec); - g_assert_cmpint (n, ==, 2); - for (i = 0; i < n; i++) { - const char * tmp = nm_setting_wireless_security_get_pairwise (s_wsec, i); - g_assert (tmp); - if (strcmp (tmp, "tkip") == 0) - found_pair_tkip = TRUE; - else if (strcmp (tmp, "ccmp") == 0) - found_pair_ccmp = TRUE; - } - g_assert (found_pair_tkip); - g_assert (found_pair_ccmp); - - /* Group ciphers */ - n = nm_setting_wireless_security_get_num_groups (s_wsec); - g_assert_cmpint (n, ==, 4); - for (i = 0; i < n; i++) { - const char *tmp = nm_setting_wireless_security_get_group (s_wsec, i); - g_assert (tmp); - if (strcmp (tmp, "tkip") == 0) - found_group_tkip = TRUE; - else if (strcmp (tmp, "ccmp") == 0) - found_group_ccmp = TRUE; - else if (strcmp (tmp, "wep40") == 0) - found_group_wep40 = TRUE; - else if (strcmp (tmp, "wep104") == 0) - found_group_wep104 = TRUE; - } - g_assert (found_group_tkip); - g_assert (found_group_ccmp); - g_assert (found_group_wep40); - g_assert (found_group_wep104); - - /* Protocols */ - n = nm_setting_wireless_security_get_num_protos (s_wsec); - g_assert_cmpint (n, ==, 2); - for (i = 0; i < n; i++) { - const char *tmp = nm_setting_wireless_security_get_proto (s_wsec, i); - g_assert (tmp); - if (strcmp (tmp, "wpa") == 0) - found_proto_wpa = TRUE; - else if (strcmp (tmp, "rsn") == 0) - found_proto_rsn = TRUE; - } - g_assert (found_proto_wpa); - g_assert (found_proto_rsn); - - /* ===== IPv4 SETTING ===== */ + shvarFile *sv; - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - - g_object_unref (connection); + sv = _svOpenFile(TEST_IFCFG_DIR "/ifcfg-test-wifi-wpa-psk"); + _svGetValue_check(sv, "CTCPROT", "no-newline"); + svCloseFile(sv); } static void -test_read_wifi_sae (void) +test_read_wifi_wpa_psk(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - GBytes *ssid; - const char *expected_ssid = "blahblah"; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-sae", - NULL, TYPE_WIRELESS, NULL); - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-sae)"); - - g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); - g_assert (nm_setting_connection_get_autoconnect (s_con)); + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIPConfig * s_ip4; + GBytes * ssid; + const char * mac; + char expected_mac_address[ETH_ALEN] = {0x00, 0x16, 0x41, 0x11, 0x22, 0x33}; + const char *expected_ssid = "blahblah"; + guint32 n, i; + gboolean found_pair_tkip = FALSE; + gboolean found_pair_ccmp = FALSE; + gboolean found_group_tkip = FALSE; + gboolean found_group_ccmp = FALSE; + gboolean found_group_wep40 = FALSE; + gboolean found_group_wep104 = FALSE; + gboolean found_proto_wpa = FALSE; + gboolean found_proto_rsn = FALSE; + + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wpa-psk", NULL, TYPE_WIRELESS, NULL); + + /* ===== CONNECTION SETTING ===== */ + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System blahblah (test-wifi-wpa-psk)"); - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ + + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); + + mac = nm_setting_wireless_get_mac_address(s_wireless); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, sizeof(expected_mac_address))); + + g_assert_cmpint(nm_setting_wireless_get_mtu(s_wireless), ==, 0); + + ssid = nm_setting_wireless_get_ssid(s_wireless); + g_assert(ssid); + g_assert_cmpmem(g_bytes_get_data(ssid, NULL), + g_bytes_get_size(ssid), + expected_ssid, + strlen(expected_ssid)); + + g_assert(!nm_setting_wireless_get_bssid(s_wireless)); + g_assert_cmpstr(nm_setting_wireless_get_mode(s_wireless), ==, "infrastructure"); + g_assert_cmpint(nm_setting_wireless_get_channel(s_wireless), ==, 1); + + /* ===== WIRELESS 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), + ==, + "I wonder what the king is doing tonight?"); + g_assert(!nm_setting_wireless_security_get_auth_alg(s_wsec)); + + /* Pairwise ciphers */ + n = nm_setting_wireless_security_get_num_pairwise(s_wsec); + g_assert_cmpint(n, ==, 2); + for (i = 0; i < n; i++) { + const char *tmp = nm_setting_wireless_security_get_pairwise(s_wsec, i); + g_assert(tmp); + if (strcmp(tmp, "tkip") == 0) + found_pair_tkip = TRUE; + else if (strcmp(tmp, "ccmp") == 0) + found_pair_ccmp = TRUE; + } + g_assert(found_pair_tkip); + g_assert(found_pair_ccmp); + + /* Group ciphers */ + n = nm_setting_wireless_security_get_num_groups(s_wsec); + g_assert_cmpint(n, ==, 4); + for (i = 0; i < n; i++) { + const char *tmp = nm_setting_wireless_security_get_group(s_wsec, i); + g_assert(tmp); + if (strcmp(tmp, "tkip") == 0) + found_group_tkip = TRUE; + else if (strcmp(tmp, "ccmp") == 0) + found_group_ccmp = TRUE; + else if (strcmp(tmp, "wep40") == 0) + found_group_wep40 = TRUE; + else if (strcmp(tmp, "wep104") == 0) + found_group_wep104 = TRUE; + } + g_assert(found_group_tkip); + g_assert(found_group_ccmp); + g_assert(found_group_wep40); + g_assert(found_group_wep104); + + /* Protocols */ + n = nm_setting_wireless_security_get_num_protos(s_wsec); + g_assert_cmpint(n, ==, 2); + for (i = 0; i < n; i++) { + const char *tmp = nm_setting_wireless_security_get_proto(s_wsec, i); + g_assert(tmp); + if (strcmp(tmp, "wpa") == 0) + found_proto_wpa = TRUE; + else if (strcmp(tmp, "rsn") == 0) + found_proto_rsn = TRUE; + } + g_assert(found_proto_wpa); + g_assert(found_proto_rsn); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + g_object_unref(connection); +} + +static void +test_read_wifi_sae(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity * s_wsec; + GBytes * ssid; + const char * expected_ssid = "blahblah"; + + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-sae", NULL, TYPE_WIRELESS, NULL); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System blahblah (test-wifi-sae)"); + + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); - g_assert_cmpint (nm_setting_wireless_get_mtu (s_wireless), ==, 0); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); + + g_assert_cmpint(nm_setting_wireless_get_mtu(s_wireless), ==, 0); + + ssid = nm_setting_wireless_get_ssid(s_wireless); + g_assert(ssid); + g_assert_cmpmem(g_bytes_get_data(ssid, NULL), + g_bytes_get_size(ssid), + expected_ssid, + strlen(expected_ssid)); - ssid = nm_setting_wireless_get_ssid (s_wireless); - g_assert (ssid); - g_assert_cmpmem (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), expected_ssid, strlen (expected_ssid)); + g_assert(!nm_setting_wireless_get_bssid(s_wireless)); + g_assert_cmpstr(nm_setting_wireless_get_mode(s_wireless), ==, "infrastructure"); - g_assert (!nm_setting_wireless_get_bssid (s_wireless)); - g_assert_cmpstr (nm_setting_wireless_get_mode (s_wireless), ==, "infrastructure"); - - 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), ==, "sae"); - g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, "The king is dead."); - g_assert (!nm_setting_wireless_security_get_auth_alg (s_wsec)); + 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), ==, "sae"); + g_assert_cmpstr(nm_setting_wireless_security_get_psk(s_wsec), ==, "The king is dead."); + g_assert(!nm_setting_wireless_security_get_auth_alg(s_wsec)); } static void -test_read_wifi_owe (void) +test_read_wifi_owe(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - GBytes *ssid; - const char *expected_ssid = "blahblah_owe"; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity * s_wsec; + GBytes * ssid; + const char * expected_ssid = "blahblah_owe"; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-owe", - NULL, TYPE_WIRELESS, NULL); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-owe", NULL, TYPE_WIRELESS, NULL); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah_owe (test-wifi-owe)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System blahblah_owe (test-wifi-owe)"); - g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); - g_assert (nm_setting_connection_get_autoconnect (s_con)); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - g_assert_cmpint (nm_setting_wireless_get_mtu (s_wireless), ==, 0); + g_assert_cmpint(nm_setting_wireless_get_mtu(s_wireless), ==, 0); - ssid = nm_setting_wireless_get_ssid (s_wireless); - g_assert (ssid); - g_assert_cmpmem (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), expected_ssid, strlen (expected_ssid)); + ssid = nm_setting_wireless_get_ssid(s_wireless); + g_assert(ssid); + g_assert_cmpmem(g_bytes_get_data(ssid, NULL), + g_bytes_get_size(ssid), + expected_ssid, + strlen(expected_ssid)); - g_assert (!nm_setting_wireless_get_bssid (s_wireless)); - g_assert_cmpstr (nm_setting_wireless_get_mode (s_wireless), ==, "infrastructure"); + g_assert(!nm_setting_wireless_get_bssid(s_wireless)); + g_assert_cmpstr(nm_setting_wireless_get_mode(s_wireless), ==, "infrastructure"); - 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), ==, "owe"); - g_assert (!nm_setting_wireless_security_get_psk (s_wsec)); - g_assert (!nm_setting_wireless_security_get_auth_alg (s_wsec)); + 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), ==, "owe"); + g_assert(!nm_setting_wireless_security_get_psk(s_wsec)); + g_assert(!nm_setting_wireless_security_get_auth_alg(s_wsec)); } static void -test_read_wifi_wpa_psk_2 (void) +test_read_wifi_wpa_psk_2(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk-2", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wpa-psk-2", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System ipsum (test-wifi-wpa-psk-2)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System ipsum (test-wifi-wpa-psk-2)"); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* ===== WIRELESS SECURITY SETTING ===== */ + /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = nm_connection_get_setting_wireless_security (connection); - g_assert (s_wsec); - g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, "They're really saying I love you. >>`<< '"); + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec); + g_assert_cmpstr(nm_setting_wireless_security_get_psk(s_wsec), + ==, + "They're really saying I love you. >>`<< '"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_wpa_psk_unquoted (void) +test_read_wifi_wpa_psk_unquoted(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk-unquoted", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wpa-psk-unquoted", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-wpa-psk-unquoted)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System blahblah (test-wifi-wpa-psk-unquoted)"); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* ===== WIRELESS SECURITY SETTING ===== */ + /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = nm_connection_get_setting_wireless_security (connection); - g_assert (s_wsec); - g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, "54336845e2f3f321c4c7"); + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec); + g_assert_cmpstr(nm_setting_wireless_security_get_psk(s_wsec), ==, "54336845e2f3f321c4c7"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_wpa_psk_unquoted2 (void) +test_read_wifi_wpa_psk_unquoted2(void) { - gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *connection = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk-unquoted2", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wpa-psk-unquoted2", + NULL, + TYPE_WIRELESS, + NULL); } static void -test_read_wifi_wpa_psk_adhoc (void) +test_read_wifi_wpa_psk_adhoc(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIPConfig * s_ip4; - connection = _connection_from_file(TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk-adhoc", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wpa-psk-adhoc", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-wpa-psk-adhoc)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System blahblah (test-wifi-wpa-psk-adhoc)"); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - g_assert_cmpstr (nm_setting_wireless_get_mode (s_wireless), ==, "adhoc"); + g_assert_cmpstr(nm_setting_wireless_get_mode(s_wireless), ==, "adhoc"); - /* ===== WIRELESS SECURITY SETTING ===== */ + /* ===== WIRELESS 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), ==, "I wonder what the king is doing tonight?"); + 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), + ==, + "I wonder what the king is doing tonight?"); - g_assert_cmpint (nm_setting_wireless_security_get_num_pairwise (s_wsec), ==, 1); - g_assert_cmpstr (nm_setting_wireless_security_get_pairwise (s_wsec, 0), ==, "ccmp"); + g_assert_cmpint(nm_setting_wireless_security_get_num_pairwise(s_wsec), ==, 1); + g_assert_cmpstr(nm_setting_wireless_security_get_pairwise(s_wsec, 0), ==, "ccmp"); - g_assert_cmpint (nm_setting_wireless_security_get_num_groups (s_wsec), ==, 1); - g_assert_cmpstr (nm_setting_wireless_security_get_group (s_wsec, 0), ==, "ccmp"); + g_assert_cmpint(nm_setting_wireless_security_get_num_groups(s_wsec), ==, 1); + g_assert_cmpstr(nm_setting_wireless_security_get_group(s_wsec, 0), ==, "ccmp"); - g_assert_cmpint (nm_setting_wireless_security_get_num_protos (s_wsec), ==, 1); - g_assert_cmpstr (nm_setting_wireless_security_get_proto (s_wsec, 0), ==, "rsn"); + g_assert_cmpint(nm_setting_wireless_security_get_num_protos(s_wsec), ==, 1); + g_assert_cmpstr(nm_setting_wireless_security_get_proto(s_wsec, 0), ==, "rsn"); - /* ===== IPv4 SETTING ===== */ + /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_wpa_psk_hex (void) +test_read_wifi_wpa_psk_hex(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - GBytes *ssid; - const char *expected_ssid = "blahblah"; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIPConfig * s_ip4; + GBytes * ssid; + const char * expected_ssid = "blahblah"; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk-hex", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wpa-psk-hex", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-wpa-psk-hex)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System blahblah (test-wifi-wpa-psk-hex)"); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - ssid = nm_setting_wireless_get_ssid (s_wireless); - g_assert (ssid); - g_assert (nm_utils_gbytes_equal_mem (ssid, expected_ssid, strlen (expected_ssid))); + ssid = nm_setting_wireless_get_ssid(s_wireless); + g_assert(ssid); + g_assert(nm_utils_gbytes_equal_mem(ssid, expected_ssid, strlen(expected_ssid))); - /* ===== WIRELESS SECURITY SETTING ===== */ + /* ===== WIRELESS 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), ==, "1da190379817bc360dda52e85c388c439a21ea5c7bf819c64e9da051807deae6"); + 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), + ==, + "1da190379817bc360dda52e85c388c439a21ea5c7bf819c64e9da051807deae6"); - /* ===== IPv4 SETTING ===== */ + /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - g_object_unref (connection); + g_object_unref(connection); } -#define TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT TEST_IFCFG_DIR"/test_ca_cert.pem" -#define TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT TEST_IFCFG_DIR"/test1_key_and_cert.pem" -#define TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY TEST_IFCFG_DIR"/test1_key_and_cert.pem" +#define TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT TEST_IFCFG_DIR "/test_ca_cert.pem" +#define TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT TEST_IFCFG_DIR "/test1_key_and_cert.pem" +#define TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY TEST_IFCFG_DIR "/test1_key_and_cert.pem" static void -test_read_wifi_wpa_eap_tls (void) +test_read_wifi_wpa_eap_tls(void) { - NMConnection *connection; - NMSettingWireless *s_wireless; - NMSettingIPConfig *s_ip4; - NMSetting8021x *s_8021x; - char *unmanaged = NULL; - const char *expected_privkey_password = "test1"; + NMConnection * connection; + NMSettingWireless *s_wireless; + NMSettingIPConfig *s_ip4; + NMSetting8021x * s_8021x; + char * unmanaged = NULL; + const char * expected_privkey_password = "test1"; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-eap-tls", - NULL, TYPE_ETHERNET, &unmanaged); - g_assert (!unmanaged); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wpa-eap-tls", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert(!unmanaged); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* ===== IPv4 SETTING ===== */ + /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - /* ===== 802.1x SETTING ===== */ - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x); - g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); - g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "tls"); - g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "Bill Smith"); + /* ===== 802.1x SETTING ===== */ + s_8021x = nm_connection_get_setting_802_1x(connection); + g_assert(s_8021x); + g_assert_cmpint(nm_setting_802_1x_get_num_eap_methods(s_8021x), ==, 1); + g_assert_cmpstr(nm_setting_802_1x_get_eap_method(s_8021x, 0), ==, "tls"); + g_assert_cmpstr(nm_setting_802_1x_get_identity(s_8021x), ==, "Bill Smith"); - /* CA Cert */ - verify_cert_or_key (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, - NULL, - NM_SETTING_802_1X_CA_CERT); + /* CA Cert */ + verify_cert_or_key(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NULL, + NM_SETTING_802_1X_CA_CERT); - /* Client Cert */ - verify_cert_or_key (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, - NULL, - NM_SETTING_802_1X_CLIENT_CERT); + /* Client Cert */ + verify_cert_or_key(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, + NULL, + NM_SETTING_802_1X_CLIENT_CERT); - /* Private Key Password */ - g_assert_cmpstr (nm_setting_802_1x_get_private_key_password (s_8021x), ==, expected_privkey_password); + /* Private Key Password */ + g_assert_cmpstr(nm_setting_802_1x_get_private_key_password(s_8021x), + ==, + expected_privkey_password); - /* Private key */ - verify_cert_or_key (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, - expected_privkey_password, - NM_SETTING_802_1X_PRIVATE_KEY); + /* Private key */ + verify_cert_or_key(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, + expected_privkey_password, + NM_SETTING_802_1X_PRIVATE_KEY); - g_object_unref (connection); + g_object_unref(connection); } /* Also use TLS defines from the previous test */ static void -test_read_wifi_wpa_eap_ttls_tls (void) +test_read_wifi_wpa_eap_ttls_tls(void) { - NMConnection *connection; - NMSettingWireless *s_wireless; - NMSettingIPConfig *s_ip4; - NMSetting8021x *s_8021x; - char *unmanaged = NULL; - const char *expected_privkey_password = "test1"; + NMConnection * connection; + NMSettingWireless *s_wireless; + NMSettingIPConfig *s_ip4; + NMSetting8021x * s_8021x; + char * unmanaged = NULL; + const char * expected_privkey_password = "test1"; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-eap-ttls-tls", - NULL, TYPE_WIRELESS, &unmanaged); - g_assert (!unmanaged); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wpa-eap-ttls-tls", + NULL, + TYPE_WIRELESS, + &unmanaged); + g_assert(!unmanaged); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* ===== IPv4 SETTING ===== */ + /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - /* ===== 802.1x SETTING ===== */ - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x); - g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); - g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "ttls"); - g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "Chuck Shumer"); + /* ===== 802.1x SETTING ===== */ + s_8021x = nm_connection_get_setting_802_1x(connection); + g_assert(s_8021x); + g_assert_cmpint(nm_setting_802_1x_get_num_eap_methods(s_8021x), ==, 1); + g_assert_cmpstr(nm_setting_802_1x_get_eap_method(s_8021x, 0), ==, "ttls"); + g_assert_cmpstr(nm_setting_802_1x_get_identity(s_8021x), ==, "Chuck Shumer"); - /* CA Cert */ - verify_cert_or_key (s_8021x, - TEST_IFCFG_DIR"/test_ca_cert.pem", - NULL, - NM_SETTING_802_1X_CA_CERT); + /* CA Cert */ + verify_cert_or_key(s_8021x, + TEST_IFCFG_DIR "/test_ca_cert.pem", + NULL, + NM_SETTING_802_1X_CA_CERT); - /* Inner auth method */ - g_assert_cmpstr (nm_setting_802_1x_get_phase2_autheap (s_8021x), ==, "tls"); + /* Inner auth method */ + g_assert_cmpstr(nm_setting_802_1x_get_phase2_autheap(s_8021x), ==, "tls"); - /* Inner CA Cert */ - verify_cert_or_key (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, - NULL, - NM_SETTING_802_1X_PHASE2_CA_CERT); + /* Inner CA Cert */ + verify_cert_or_key(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NULL, + NM_SETTING_802_1X_PHASE2_CA_CERT); - /* Inner Client Cert */ - verify_cert_or_key (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, - NULL, - NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + /* Inner Client Cert */ + verify_cert_or_key(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, + NULL, + NM_SETTING_802_1X_PHASE2_CLIENT_CERT); - /* Inner Private Key Password */ - g_assert_cmpstr (nm_setting_802_1x_get_phase2_private_key_password (s_8021x), ==, expected_privkey_password); + /* Inner Private Key Password */ + g_assert_cmpstr(nm_setting_802_1x_get_phase2_private_key_password(s_8021x), + ==, + expected_privkey_password); - /* Inner private key */ - verify_cert_or_key (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, - expected_privkey_password, - NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + /* Inner private key */ + verify_cert_or_key(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, + expected_privkey_password, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_dynamic_wep_leap (void) +test_read_wifi_dynamic_wep_leap(void) { - NMConnection *connection; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSetting8021x *s_8021x; + NMConnection * connection; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSetting8021x * s_8021x; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-dynamic-wep-leap", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-dynamic-wep-leap", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wifi = nm_connection_get_setting_wireless (connection); - g_assert (s_wifi); + s_wifi = nm_connection_get_setting_wireless(connection); + g_assert(s_wifi); - /* ===== Wi-Fi SECURITY SETTING ===== */ - s_wsec = nm_connection_get_setting_wireless_security (connection); - g_assert (s_wsec); + /* ===== Wi-Fi SECURITY SETTING ===== */ + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec); - /* Key management */ - g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "ieee8021x"); + /* Key management */ + g_assert_cmpstr(nm_setting_wireless_security_get_key_mgmt(s_wsec), ==, "ieee8021x"); - /* Auth alg should be NULL (open) for dynamic WEP with LEAP as the EAP method; - * only "old-school" LEAP uses 'leap' for the auth alg. - */ - g_assert_cmpstr (nm_setting_wireless_security_get_auth_alg (s_wsec), ==, NULL); + /* Auth alg should be NULL (open) for dynamic WEP with LEAP as the EAP method; + * only "old-school" LEAP uses 'leap' for the auth alg. + */ + g_assert_cmpstr(nm_setting_wireless_security_get_auth_alg(s_wsec), ==, NULL); - /* Expect no old-school LEAP username/password, that'll be in the 802.1x setting */ - g_assert_cmpstr (nm_setting_wireless_security_get_leap_username (s_wsec), ==, NULL); - g_assert_cmpstr (nm_setting_wireless_security_get_leap_password (s_wsec), ==, NULL); + /* Expect no old-school LEAP username/password, that'll be in the 802.1x setting */ + g_assert_cmpstr(nm_setting_wireless_security_get_leap_username(s_wsec), ==, NULL); + g_assert_cmpstr(nm_setting_wireless_security_get_leap_password(s_wsec), ==, NULL); - /* ===== 802.1x SETTING ===== */ - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x); + /* ===== 802.1x SETTING ===== */ + s_8021x = nm_connection_get_setting_802_1x(connection); + g_assert(s_8021x); - /* EAP method should be "leap" */ - g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); - g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "leap"); + /* EAP method should be "leap" */ + g_assert_cmpint(nm_setting_802_1x_get_num_eap_methods(s_8021x), ==, 1); + g_assert_cmpstr(nm_setting_802_1x_get_eap_method(s_8021x, 0), ==, "leap"); - /* username & password */ - g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "bill smith"); - g_assert_cmpstr (nm_setting_802_1x_get_password (s_8021x), ==, "foobar baz"); + /* username & password */ + g_assert_cmpstr(nm_setting_802_1x_get_identity(s_8021x), ==, "bill smith"); + g_assert_cmpstr(nm_setting_802_1x_get_password(s_8021x), ==, "foobar baz"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_wep_eap_ttls_chap (void) +test_read_wifi_wep_eap_ttls_chap(void) { - NMConnection *connection; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSetting8021x *s_8021x; - char *unmanaged = NULL; + NMConnection * connection; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMSettingIPConfig * s_ip4; + NMSetting8021x * s_8021x; + char * unmanaged = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-eap-ttls-chap", - NULL, TYPE_WIRELESS, &unmanaged); - g_assert (!unmanaged); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wep-eap-ttls-chap", + NULL, + TYPE_WIRELESS, + &unmanaged); + g_assert(!unmanaged); - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* ===== IPv4 SETTING ===== */ + /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - /* ===== 802.1x 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), ==, "ieee8021x"); + /* ===== 802.1x 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), ==, "ieee8021x"); - /* ===== 802.1x SETTING ===== */ - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x); + /* ===== 802.1x SETTING ===== */ + s_8021x = nm_connection_get_setting_802_1x(connection); + g_assert(s_8021x); - /* EAP methods */ - g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1); - g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "ttls"); + /* EAP methods */ + g_assert_cmpint(nm_setting_802_1x_get_num_eap_methods(s_8021x), ==, 1); + g_assert_cmpstr(nm_setting_802_1x_get_eap_method(s_8021x, 0), ==, "ttls"); - /* CA Cert */ - verify_cert_or_key (s_8021x, - TEST_IFCFG_DIR"/test_ca_cert.pem", - NULL, - NM_SETTING_802_1X_CA_CERT); + /* CA Cert */ + verify_cert_or_key(s_8021x, + TEST_IFCFG_DIR "/test_ca_cert.pem", + NULL, + NM_SETTING_802_1X_CA_CERT); - g_assert_cmpstr (nm_setting_802_1x_get_phase2_auth (s_8021x), ==, "chap"); - g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "David Smith"); - g_assert_cmpstr (nm_setting_802_1x_get_password (s_8021x), ==, "foobar baz"); + g_assert_cmpstr(nm_setting_802_1x_get_phase2_auth(s_8021x), ==, "chap"); + g_assert_cmpstr(nm_setting_802_1x_get_identity(s_8021x), ==, "David Smith"); + g_assert_cmpstr(nm_setting_802_1x_get_password(s_8021x), ==, "foobar baz"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wired_wake_on_lan (void) +test_read_wired_wake_on_lan(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-wake-on-lan", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-wake-on-lan", + NULL, + TYPE_WIRELESS, + NULL); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - g_assert_cmpint (nm_setting_wired_get_wake_on_lan (s_wired), - ==, - NM_SETTING_WIRED_WAKE_ON_LAN_ARP | - NM_SETTING_WIRED_WAKE_ON_LAN_PHY | - NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert_cmpint(nm_setting_wired_get_wake_on_lan(s_wired), + ==, + NM_SETTING_WIRED_WAKE_ON_LAN_ARP | NM_SETTING_WIRED_WAKE_ON_LAN_PHY + | NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC); - g_assert_cmpstr (nm_setting_wired_get_wake_on_lan_password (s_wired), - ==, - "00:11:22:33:44:55"); + g_assert_cmpstr(nm_setting_wired_get_wake_on_lan_password(s_wired), ==, "00:11:22:33:44:55"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wired_auto_negotiate_off (void) +test_read_wired_auto_negotiate_off(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-wake-on-lan", - NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-wake-on-lan", + NULL, + TYPE_ETHERNET, + NULL); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - g_assert (!nm_setting_wired_get_auto_negotiate (s_wired)); - g_assert_cmpint (nm_setting_wired_get_speed (s_wired), ==, 100); - g_assert_cmpstr (nm_setting_wired_get_duplex (s_wired), ==, "full"); + g_assert(!nm_setting_wired_get_auto_negotiate(s_wired)); + g_assert_cmpint(nm_setting_wired_get_speed(s_wired), ==, 100); + g_assert_cmpstr(nm_setting_wired_get_duplex(s_wired), ==, "full"); } static void -test_read_wired_auto_negotiate_on (void) +test_read_wired_auto_negotiate_on(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-auto-negotiate-on", - NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-auto-negotiate-on", + NULL, + TYPE_ETHERNET, + NULL); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - g_assert (nm_setting_wired_get_auto_negotiate (s_wired)); - g_assert_cmpint (nm_setting_wired_get_speed (s_wired), ==, 0); - g_assert_cmpstr (nm_setting_wired_get_duplex (s_wired), ==, NULL); + g_assert(nm_setting_wired_get_auto_negotiate(s_wired)); + g_assert_cmpint(nm_setting_wired_get_speed(s_wired), ==, 0); + g_assert_cmpstr(nm_setting_wired_get_duplex(s_wired), ==, NULL); } static void -test_read_wired_unknown_ethtool_opt (void) +test_read_wired_unknown_ethtool_opt(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-unknown-ethtool-opt", - NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-unknown-ethtool-opt", + NULL, + TYPE_ETHERNET, + NULL); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - g_assert (!nm_setting_wired_get_auto_negotiate (s_wired)); - g_assert (!nm_setting_wired_get_speed (s_wired)); - g_assert (!nm_setting_wired_get_duplex (s_wired)); + g_assert(!nm_setting_wired_get_auto_negotiate(s_wired)); + g_assert(!nm_setting_wired_get_speed(s_wired)); + g_assert(!nm_setting_wired_get_duplex(s_wired)); - g_assert_cmpint (nm_setting_wired_get_wake_on_lan (s_wired), - ==, - NM_SETTING_WIRED_WAKE_ON_LAN_ARP | - NM_SETTING_WIRED_WAKE_ON_LAN_PHY | - NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC); - g_assert_cmpstr (nm_setting_wired_get_wake_on_lan_password (s_wired), - ==, - "00:11:22:33:44:55"); + g_assert_cmpint(nm_setting_wired_get_wake_on_lan(s_wired), + ==, + NM_SETTING_WIRED_WAKE_ON_LAN_ARP | NM_SETTING_WIRED_WAKE_ON_LAN_PHY + | NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC); + g_assert_cmpstr(nm_setting_wired_get_wake_on_lan_password(s_wired), ==, "00:11:22:33:44:55"); } static void -test_read_wifi_hidden (void) +test_read_wifi_hidden(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWireless * s_wifi; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-hidden", - NULL, TYPE_WIRELESS, NULL); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-hidden", NULL, TYPE_WIRELESS, NULL); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRELESS_SETTING_NAME); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRELESS_SETTING_NAME); - s_wifi = nm_connection_get_setting_wireless (connection); - g_assert (s_wifi); - g_assert (nm_setting_wireless_get_hidden (s_wifi) == TRUE); + s_wifi = nm_connection_get_setting_wireless(connection); + g_assert(s_wifi); + g_assert(nm_setting_wireless_get_hidden(s_wifi) == TRUE); - g_object_unref (connection); + g_object_unref(connection); } static void -test_write_wifi_hidden (void) +test_write_wifi_hidden(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - shvarFile *f; - GBytes *ssid; - const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + shvarFile * f; + GBytes * ssid; + const unsigned char ssid_data[] = {0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44}; - connection = nm_simple_connection_new (); + connection = nm_simple_connection_new(); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wi-Fi Hidden", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wi-Fi Hidden", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new(ssid_data, sizeof(ssid_data)); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_HIDDEN, TRUE, - NULL); + g_object_set(s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); - g_bytes_unref (ssid); + g_bytes_unref(ssid); - nmtst_assert_connection_verifies (connection); + nmtst_assert_connection_verifies(connection); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_WiFi_Hidden.cexpected", - &testfile); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_WiFi_Hidden.cexpected", + &testfile); - f = _svOpenFile (testfile); - _svGetValue_check (f, "SSID_HIDDEN", "yes"); - svCloseFile (f); + f = _svOpenFile(testfile); + _svGetValue_check(f, "SSID_HIDDEN", "yes"); + svCloseFile(f); - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_read_wifi_mac_random (gconstpointer user_data) +test_read_wifi_mac_random(gconstpointer user_data) { - gs_unref_object NMConnection *connection = NULL; - gs_free char *path = NULL; - NMSettingWireless *s_wifi; - const char *name; - gpointer value_p; - NMSettingMacRandomization value; + gs_unref_object NMConnection *connection = NULL; + gs_free char * path = NULL; + NMSettingWireless * s_wifi; + const char * name; + gpointer value_p; + NMSettingMacRandomization value; - nmtst_test_data_unpack (user_data, &name, &value_p); - value = GPOINTER_TO_INT (value_p); + nmtst_test_data_unpack(user_data, &name, &value_p); + value = GPOINTER_TO_INT(value_p); - path = g_strdup_printf (TEST_IFCFG_DIR"/ifcfg-test-wifi-mac-random-%s", name); - connection = _connection_from_file (path, NULL, TYPE_WIRELESS, NULL); + path = g_strdup_printf(TEST_IFCFG_DIR "/ifcfg-test-wifi-mac-random-%s", name); + connection = _connection_from_file(path, NULL, TYPE_WIRELESS, NULL); - s_wifi = nm_connection_get_setting_wireless (connection); - g_assert (s_wifi); - g_assert_cmpint (nm_setting_wireless_get_mac_address_randomization (s_wifi), ==, value); + s_wifi = nm_connection_get_setting_wireless(connection); + g_assert(s_wifi); + g_assert_cmpint(nm_setting_wireless_get_mac_address_randomization(s_wifi), ==, value); } static void -test_write_wifi_mac_random (gconstpointer user_data) +test_write_wifi_mac_random(gconstpointer user_data) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - char *val; - shvarFile *f; - GBytes *ssid; - const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; - const char *name, *write_expected; - gpointer value_p; - NMSettingMacRandomization value; - char cexpected[NM_STRLEN (TEST_IFCFG_DIR) + 100]; - - nmtst_test_data_unpack (user_data, &name, &value_p, &write_expected); - value = GPOINTER_TO_INT (value_p); - - g_assert (write_expected); - - connection = nm_simple_connection_new (); + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + char * val; + shvarFile * f; + GBytes * ssid; + const unsigned char ssid_data[] = {0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44}; + const char * name, *write_expected; + gpointer value_p; + NMSettingMacRandomization value; + char cexpected[NM_STRLEN(TEST_IFCFG_DIR) + 100]; - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + nmtst_test_data_unpack(user_data, &name, &value_p, &write_expected); + value = GPOINTER_TO_INT(value_p); - val = g_strdup_printf ("Test Write Wi-Fi MAC %s", name); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, val, - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); - g_free (val); + g_assert(write_expected); - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + connection = nm_simple_connection_new(); - ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, value, - NULL); - g_bytes_unref (ssid); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - nmtst_assert_connection_verifies (connection); + val = g_strdup_printf("Test Write Wi-Fi MAC %s", name); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + val, + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free(val); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - nm_sprintf_buf (cexpected, TEST_IFCFG_DIR"/ifcfg-Test_Write_WiFi_MAC_%s.cexpected", name), - &testfile); + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - f = _svOpenFile (testfile); - _svGetValue_check (f, "MAC_ADDRESS_RANDOMIZATION", write_expected); - svCloseFile (f); + ssid = g_bytes_new(ssid_data, sizeof(ssid_data)); + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION, + value, + NULL); + g_bytes_unref(ssid); - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + nmtst_assert_connection_verifies(connection); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} + _writer_new_connec_exp( + connection, + TEST_SCRATCH_DIR, + nm_sprintf_buf(cexpected, TEST_IFCFG_DIR "/ifcfg-Test_Write_WiFi_MAC_%s.cexpected", name), + &testfile); -static void -test_write_wired_wake_on_lan (void) + f = _svOpenFile(testfile); + _svGetValue_check(f, "MAC_ADDRESS_RANDOMIZATION", write_expected); + svCloseFile(f); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wired_wake_on_lan(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingWiredWakeOnLan wol; - char *val; - shvarFile *f; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingWiredWakeOnLan wol; + char * val; + shvarFile * f; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired Wake-on-LAN", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + wol = NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST | NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST + | NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC; + + g_object_set(s_wired, + NM_SETTING_WIRED_WAKE_ON_LAN, + wol, + NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, + "00:00:00:11:22:33", + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected", + &testfile); + + f = _svOpenFile(testfile); + val = svGetValueStr_cp(f, "ETHTOOL_OPTS"); + g_assert(val); + g_assert(strstr(val, "wol")); + g_assert(strstr(val, "sopass 00:00:00:11:22:33")); + g_free(val); + svCloseFile(f); + + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wired_auto_negotiate_off(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingWired * s_wired; + char * val; + shvarFile * f; + + connection = nmtst_create_minimal_connection("Test Write Wired Auto-Negotiate", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + s_wired = nm_connection_get_setting_wired(connection); + g_object_set(s_wired, + NM_SETTING_WIRED_AUTO_NEGOTIATE, + FALSE, + NM_SETTING_WIRED_DUPLEX, + "half", + NM_SETTING_WIRED_SPEED, + 10, + NULL); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired Wake-on-LAN", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected", + &testfile); - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + f = _svOpenFile(testfile); + val = svGetValueStr_cp(f, "ETHTOOL_OPTS"); + g_assert(val); + g_assert(strstr(val, "autoneg off")); + g_assert(strstr(val, "speed 10")); + g_assert(strstr(val, "duplex half")); + g_free(val); + svCloseFile(f); - wol = NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST | - NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST | - NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC; + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wired_auto_negotiate_on(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingWired * s_wired; + NMSettingEthtool * s_ethtool; + char * val; + shvarFile * f; + + connection = nmtst_create_minimal_connection("Test Write Wired Auto-Negotiate", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + s_wired = nm_connection_get_setting_wired(connection); + g_object_set(s_wired, NM_SETTING_WIRED_AUTO_NEGOTIATE, TRUE, NULL); + + s_ethtool = NM_SETTING_ETHTOOL(nm_setting_ethtool_new()); + nm_setting_ethtool_set_feature(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TX, NM_TERNARY_TRUE); + nm_setting_ethtool_set_feature(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN, NM_TERNARY_FALSE); + nm_connection_add_setting(connection, NM_SETTING(s_ethtool)); + + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-test_write_wired_auto_negotiate_on.cexpected", + &testfile); + + f = _svOpenFile(testfile); + val = svGetValueStr_cp(f, "ETHTOOL_OPTS"); + g_assert(val); + g_assert(strstr(val, "autoneg on")); + g_assert(!strstr(val, "speed")); + g_assert(!strstr(val, "duplex")); + g_free(val); + svCloseFile(f); - g_object_set (s_wired, - NM_SETTING_WIRED_WAKE_ON_LAN, wol, - NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, "00:00:00:11:22:33", - NULL); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_verifies (connection); - - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected", - &testfile); + nmtst_assert_connection_verifies_without_normalization(reread); - f = _svOpenFile (testfile); - val = svGetValueStr_cp (f, "ETHTOOL_OPTS"); - g_assert (val); - g_assert (strstr (val, "wol")); - g_assert (strstr (val, "sopass 00:00:00:11:22:33")); - g_free (val); - svCloseFile (f); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + s_ethtool = NM_SETTING_ETHTOOL(nm_connection_get_setting(reread, NM_TYPE_SETTING_ETHTOOL)); + g_assert(s_ethtool); + g_assert_cmpint(nm_setting_ethtool_get_feature(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TX), + ==, + NM_TERNARY_TRUE); + g_assert_cmpint(nm_setting_ethtool_get_feature(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN), + ==, + NM_TERNARY_FALSE); + g_assert_cmpint(nm_setting_ethtool_get_feature(s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN), + ==, + NM_TERNARY_DEFAULT); } static void -test_write_wired_auto_negotiate_off (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingWired *s_wired; - char *val; - shvarFile *f; - - connection = nmtst_create_minimal_connection ("Test Write Wired Auto-Negotiate", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); - s_wired = nm_connection_get_setting_wired (connection); - g_object_set (s_wired, - NM_SETTING_WIRED_AUTO_NEGOTIATE, FALSE, - NM_SETTING_WIRED_DUPLEX, "half", - NM_SETTING_WIRED_SPEED, 10, - NULL); - - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected", - &testfile); +test_read_wifi_band_a(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWireless * s_wifi; + + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-band-a", NULL, TYPE_WIRELESS, NULL); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRELESS_SETTING_NAME); - f = _svOpenFile (testfile); - val = svGetValueStr_cp (f, "ETHTOOL_OPTS"); - g_assert (val); - g_assert (strstr (val, "autoneg off")); - g_assert (strstr (val, "speed 10")); - g_assert (strstr (val, "duplex half")); - g_free (val); - svCloseFile (f); + s_wifi = nm_connection_get_setting_wireless(connection); + g_assert(s_wifi); + g_assert_cmpstr(nm_setting_wireless_get_band(s_wifi), ==, "a"); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_object_unref(connection); } static void -test_write_wired_auto_negotiate_on (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingWired *s_wired; - NMSettingEthtool *s_ethtool; - char *val; - shvarFile *f; +test_write_wifi_band_a(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + shvarFile * f; + GBytes * ssid; + const unsigned char ssid_data[] = {0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44}; - connection = nmtst_create_minimal_connection ("Test Write Wired Auto-Negotiate", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); - s_wired = nm_connection_get_setting_wired (connection); - g_object_set (s_wired, - NM_SETTING_WIRED_AUTO_NEGOTIATE, TRUE, - NULL); + connection = nm_simple_connection_new(); - s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ()); - nm_setting_ethtool_set_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TX, NM_TERNARY_TRUE); - nm_setting_ethtool_set_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN, NM_TERNARY_FALSE); - nm_connection_add_setting (connection, NM_SETTING (s_ethtool)); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-test_write_wired_auto_negotiate_on.cexpected", - &testfile); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wi-Fi Band A", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); - f = _svOpenFile (testfile); - val = svGetValueStr_cp (f, "ETHTOOL_OPTS"); - g_assert (val); - g_assert (strstr (val, "autoneg on")); - g_assert (!strstr (val, "speed")); - g_assert (!strstr (val, "duplex")); - g_free (val); - svCloseFile (f); + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + ssid = g_bytes_new(ssid_data, sizeof(ssid_data)); - nmtst_assert_connection_verifies_without_normalization (reread); + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NM_SETTING_WIRELESS_BAND, + "a", + NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); - - s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (reread, NM_TYPE_SETTING_ETHTOOL)); - g_assert (s_ethtool); - g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TX), ==, NM_TERNARY_TRUE); - g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN), ==, NM_TERNARY_FALSE); - g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN), ==, NM_TERNARY_DEFAULT); -} + g_bytes_unref(ssid); -static void -test_read_wifi_band_a (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; + nmtst_assert_connection_verifies(connection); - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-band-a", - NULL, TYPE_WIRELESS, NULL); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_WiFi_Band_A.cexpected", + &testfile); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRELESS_SETTING_NAME); + f = _svOpenFile(testfile); + _svGetValue_check(f, "BAND", "a"); + svCloseFile(f); - s_wifi = nm_connection_get_setting_wireless (connection); - g_assert (s_wifi); - g_assert_cmpstr (nm_setting_wireless_get_band (s_wifi), ==, "a"); + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); - g_object_unref (connection); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_write_wifi_band_a (void) +test_write_wifi_ap_mode(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - shvarFile *f; - GBytes *ssid; - const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + gs_unref_bytes GBytes *ssid = NULL; - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wi-Fi Band A", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + connection = nm_simple_connection_new(); - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wi-Fi AP Mode", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NM_SETTING_WIRELESS_BAND, "a", - NULL); + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - g_bytes_unref (ssid); + ssid = g_bytes_new("MySSID", NM_STRLEN("MySSID")); - nmtst_assert_connection_verifies (connection); + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "ap", + NM_SETTING_WIRELESS_BAND, + "a", + NM_SETTING_WIRELESS_CHANNEL, + (guint) 196, + NM_SETTING_WIRELESS_AP_ISOLATION, + NM_TERNARY_TRUE, + NULL); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_WiFi_Band_A.cexpected", - &testfile); + nmtst_assert_connection_verifies(connection); - f = _svOpenFile (testfile); - _svGetValue_check (f, "BAND", "a"); - svCloseFile (f); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_WiFi_AP_Mode.cexpected", + &testfile); - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_read_wifi_band_a_channel_mismatch (void) +test_read_wifi_band_a_channel_mismatch(void) { - gs_free_error GError *error = NULL; + gs_free_error GError *error = NULL; - _connection_from_file_fail (TEST_IFCFG_DIR"/ifcfg-test-wifi-band-a-channel-mismatch", - NULL, TYPE_WIRELESS, &error); - g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + _connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-wifi-band-a-channel-mismatch", + NULL, + TYPE_WIRELESS, + &error); + g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); } static void -test_read_wifi_band_bg_channel_mismatch (void) +test_read_wifi_band_bg_channel_mismatch(void) { - gs_free_error GError *error = NULL; + gs_free_error GError *error = NULL; - _connection_from_file_fail (TEST_IFCFG_DIR"/ifcfg-test-wifi-band-bg-channel-mismatch", - NULL, TYPE_WIRELESS, &error); - g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + _connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-wifi-band-bg-channel-mismatch", + NULL, + TYPE_WIRELESS, + &error); + g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); } static void -test_read_wired_qeth_static (void) +test_read_wired_qeth_static(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - char *unmanaged = NULL; - const char * const *subchannels; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + char * unmanaged = NULL; + const char *const * subchannels; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-qeth-static", - NULL, TYPE_ETHERNET, &unmanaged); - g_assert (!unmanaged); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-qeth-static", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert(!unmanaged); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-qeth-static"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System test-wired-qeth-static"); - /* ===== WIRED SETTING ===== */ + /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - g_assert (!nm_setting_wired_get_mac_address (s_wired)); + g_assert(!nm_setting_wired_get_mac_address(s_wired)); - /* Subchannels */ - subchannels = nm_setting_wired_get_s390_subchannels (s_wired); - g_assert (subchannels); - g_assert (subchannels[0] && subchannels[1] && subchannels[2] && !subchannels[3]); + /* Subchannels */ + subchannels = nm_setting_wired_get_s390_subchannels(s_wired); + g_assert(subchannels); + g_assert(subchannels[0] && subchannels[1] && subchannels[2] && !subchannels[3]); - g_assert_cmpstr (subchannels[0], ==, "0.0.0600"); - g_assert_cmpstr (subchannels[1], ==, "0.0.0601"); - g_assert_cmpstr (subchannels[2], ==, "0.0.0602"); + g_assert_cmpstr(subchannels[0], ==, "0.0.0600"); + g_assert_cmpstr(subchannels[1], ==, "0.0.0601"); + g_assert_cmpstr(subchannels[2], ==, "0.0.0602"); - g_assert_cmpstr (nm_setting_wired_get_s390_nettype (s_wired), ==, "qeth"); - g_assert_cmpstr (nm_setting_wired_get_s390_option_by_key (s_wired, "portname"), ==, "OSAPORT"); - g_assert_cmpstr (nm_setting_wired_get_s390_option_by_key (s_wired, "portno"), ==, "0"); - g_assert_cmpstr (nm_setting_wired_get_s390_option_by_key (s_wired, "layer2"), ==, "1"); + g_assert_cmpstr(nm_setting_wired_get_s390_nettype(s_wired), ==, "qeth"); + g_assert_cmpstr(nm_setting_wired_get_s390_option_by_key(s_wired, "portname"), ==, "OSAPORT"); + g_assert_cmpstr(nm_setting_wired_get_s390_option_by_key(s_wired, "portno"), ==, "0"); + g_assert_cmpstr(nm_setting_wired_get_s390_option_by_key(s_wired, "layer2"), ==, "1"); - /* ===== IPv4 SETTING ===== */ + /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wired_ctc_static (void) +test_read_wired_ctc_static(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - char *unmanaged = NULL; - const char * const *subchannels; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + char * unmanaged = NULL; + const char *const * subchannels; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-ctc-static", - NULL, TYPE_ETHERNET, &unmanaged); - g_assert (unmanaged == NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-ctc-static", + NULL, + TYPE_ETHERNET, + &unmanaged); + g_assert(unmanaged == NULL); - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con != NULL); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-ctc-static"); + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con != NULL); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "System test-wired-ctc-static"); - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired != NULL); + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired != NULL); - g_assert (nm_setting_wired_get_mac_address (s_wired) == NULL); + g_assert(nm_setting_wired_get_mac_address(s_wired) == NULL); - /* Subchannels */ - subchannels = nm_setting_wired_get_s390_subchannels (s_wired); - g_assert (subchannels != NULL); - g_assert (subchannels[0] && subchannels[1] && !subchannels[2]); + /* Subchannels */ + subchannels = nm_setting_wired_get_s390_subchannels(s_wired); + g_assert(subchannels != NULL); + g_assert(subchannels[0] && subchannels[1] && !subchannels[2]); - g_assert_cmpstr (subchannels[0], ==, "0.0.1b00"); - g_assert_cmpstr (subchannels[1], ==, "0.0.1b01"); + g_assert_cmpstr(subchannels[0], ==, "0.0.1b00"); + g_assert_cmpstr(subchannels[1], ==, "0.0.1b01"); - g_assert_cmpstr (nm_setting_wired_get_s390_nettype (s_wired), ==, "ctc"); - g_assert_cmpstr (nm_setting_wired_get_s390_option_by_key (s_wired, "ctcprot"), ==, "0"); + g_assert_cmpstr(nm_setting_wired_get_s390_nettype(s_wired), ==, "ctc"); + g_assert_cmpstr(nm_setting_wired_get_s390_option_by_key(s_wired, "ctcprot"), ==, "0"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_wep_no_keys (void) +test_read_wifi_wep_no_keys(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wsec; - NMWepKeyType key_type; + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wsec; + NMWepKeyType key_type; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-no-keys", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wep-no-keys", + NULL, + TYPE_WIRELESS, + NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System foobar (test-wifi-wep-no-keys)"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), + ==, + "System foobar (test-wifi-wep-no-keys)"); - /* UUID can't be tested if the ifcfg does not contain the UUID key, because - * the UUID is generated on the full path of the ifcfg file, which can change - * depending on where the tests are run. - */ + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ - /* ===== WIRELESS SETTING ===== */ + /* ===== WIRELESS SETTING ===== */ - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - /* ===== WIRELESS SECURITY SETTING ===== */ + /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = nm_connection_get_setting_wireless_security (connection); - g_assert (s_wsec); + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec); - /* Key management */ - g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "none"); + /* Key management */ + g_assert_cmpstr(nm_setting_wireless_security_get_key_mgmt(s_wsec), ==, "none"); - /* WEP key index */ - g_assert_cmpint (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec), ==, 0); + /* WEP key index */ + g_assert_cmpint(nm_setting_wireless_security_get_wep_tx_keyidx(s_wsec), ==, 0); - /* WEP key type */ - key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); - g_assert (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); + /* WEP key type */ + key_type = nm_setting_wireless_security_get_wep_key_type(s_wsec); + g_assert(key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); - /* WEP key index 0; we don't expect it to be filled */ - g_assert (!nm_setting_wireless_security_get_wep_key (s_wsec, 0)); + /* WEP key index 0; we don't expect it to be filled */ + g_assert(!nm_setting_wireless_security_get_wep_key(s_wsec, 0)); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_permissions (void) +test_read_permissions(void) { - NMConnection *connection; - NMSettingConnection *s_con; - gboolean success; - guint32 num; - const char *tmp; + NMConnection * connection; + NMSettingConnection *s_con; + gboolean success; + guint32 num; + const char * tmp; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-permissions", - NULL, TYPE_ETHERNET, NULL); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-permissions", NULL, TYPE_ETHERNET, NULL); - /* ===== CONNECTION SETTING ===== */ + /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); - num = nm_setting_connection_get_num_permissions (s_con); - g_assert_cmpint (num, ==, 3); + num = nm_setting_connection_get_num_permissions(s_con); + g_assert_cmpint(num, ==, 3); - /* verify each permission */ - tmp = NULL; - success = nm_setting_connection_get_permission (s_con, 0, NULL, &tmp, NULL); - g_assert (success); - g_assert_cmpstr (tmp, ==, "dcbw"); + /* verify each permission */ + tmp = NULL; + success = nm_setting_connection_get_permission(s_con, 0, NULL, &tmp, NULL); + g_assert(success); + g_assert_cmpstr(tmp, ==, "dcbw"); - tmp = NULL; - success = nm_setting_connection_get_permission (s_con, 1, NULL, &tmp, NULL); - g_assert (success); - g_assert_cmpstr (tmp, ==, "ssmith"); + tmp = NULL; + success = nm_setting_connection_get_permission(s_con, 1, NULL, &tmp, NULL); + g_assert(success); + g_assert_cmpstr(tmp, ==, "ssmith"); - tmp = NULL; - success = nm_setting_connection_get_permission (s_con, 2, NULL, &tmp, NULL); - g_assert (success); - g_assert_cmpstr (tmp, ==, "johnny5"); + tmp = NULL; + success = nm_setting_connection_get_permission(s_con, 2, NULL, &tmp, NULL); + g_assert(success); + g_assert_cmpstr(tmp, ==, "johnny5"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_read_wifi_wep_agent_keys (void) +test_read_wifi_wep_agent_keys(void) { - NMConnection *connection; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMWepKeyType key_type; - NMSettingSecretFlags flags; + NMConnection * connection; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMWepKeyType key_type; + NMSettingSecretFlags flags; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-agent-keys", - NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-wep-agent-keys", + NULL, + TYPE_WIRELESS, + NULL); - /* Ensure the connection is still marked for wifi security even though - * we don't have any WEP keys because they are agent owned. - */ + /* Ensure the connection is still marked for wifi security even though + * we don't have any WEP keys because they are agent owned. + */ - /* ===== WIRELESS SETTING ===== */ - s_wifi = nm_connection_get_setting_wireless (connection); - g_assert (s_wifi); + /* ===== WIRELESS SETTING ===== */ + s_wifi = nm_connection_get_setting_wireless(connection); + g_assert(s_wifi); - /* ===== WIRELESS SECURITY SETTING ===== */ - s_wsec = nm_connection_get_setting_wireless_security (connection); - g_assert (s_wsec); + /* ===== WIRELESS SECURITY SETTING ===== */ + s_wsec = nm_connection_get_setting_wireless_security(connection); + g_assert(s_wsec); - g_assert (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0); - g_assert (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0); + g_assert(strcmp(nm_setting_wireless_security_get_key_mgmt(s_wsec), "none") == 0); + g_assert(nm_setting_wireless_security_get_wep_tx_keyidx(s_wsec) == 0); - key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); - g_assert (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); + key_type = nm_setting_wireless_security_get_wep_key_type(s_wsec); + g_assert(key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY); - /* We don't expect WEP key0 to be filled */ - g_assert (nm_setting_wireless_security_get_wep_key (s_wsec, 0) == NULL); + /* We don't expect WEP key0 to be filled */ + g_assert(nm_setting_wireless_security_get_wep_key(s_wsec, 0) == NULL); - flags = nm_setting_wireless_security_get_wep_key_flags (s_wsec); - g_assert (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED); + flags = nm_setting_wireless_security_get_wep_key_flags(s_wsec); + g_assert(flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED); - g_object_unref (connection); + g_object_unref(connection); } static void -test_write_wired_static (void) +test_write_wired_static(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *route6file = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4, *reread_s_ip4; - NMSettingIPConfig *s_ip6, *reread_s_ip6; - NMIPAddress *addr; - NMIPAddress *addr6; - NMIPRoute *route6; - GError *error = NULL; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired Static", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, 1, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - g_object_set (s_wired, - NM_SETTING_WIRED_MAC_ADDRESS, "31:33:33:37:be:cd", - NM_SETTING_WIRED_MTU, (guint32) 1492, - NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) 204, - NULL); - - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - addr = nm_ip_address_new (AF_INET, "1.1.1.5", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - nm_setting_ip_config_add_dns (s_ip4, "4.2.2.1"); - nm_setting_ip_config_add_dns (s_ip4, "4.2.2.2"); - - nm_setting_ip_config_add_dns_search (s_ip4, "foobar.com"); - nm_setting_ip_config_add_dns_search (s_ip4, "lab.foobar.com"); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) 206, - NULL); - - /* Add addresses */ - addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip6, addr6); - nm_ip_address_unref (addr6); - - addr6 = nm_ip_address_new (AF_INET6, "2003:1234:abcd::2", 22, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip6, addr6); - nm_ip_address_unref (addr6); - - addr6 = nm_ip_address_new (AF_INET6, "3003:1234:abcd::3", 33, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip6, addr6); - nm_ip_address_unref (addr6); - - /* Add routes */ - route6 = nm_ip_route_new (AF_INET6, - "2222:aaaa:bbbb:cccc::", 64, - "2222:aaaa:bbbb:cccc:dddd:eeee:5555:6666", 99, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_route (s_ip6, route6); - nm_ip_route_unref (route6); - - route6 = nm_ip_route_new (AF_INET6, "::", 128, "2222:aaaa::9999", 1, &error); - g_assert_no_error (error); - nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32 (100)); - nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32 (1280)); - nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, g_variant_new_boolean (TRUE)); - nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_FROM, g_variant_new_string ("2222::bbbb/32")); - nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_SRC, g_variant_new_string ("::42")); - nm_setting_ip_config_add_route (s_ip6, route6); - nm_ip_route_unref (route6); - - /* DNS servers */ - nm_setting_ip_config_add_dns (s_ip6, "fade:0102:0103::face"); - nm_setting_ip_config_add_dns (s_ip6, "cafe:ffff:eeee:dddd:cccc:bbbb:aaaa:feed"); - - /* DNS domains */ - nm_setting_ip_config_add_dns_search (s_ip6, "foobar6.com"); - nm_setting_ip_config_add_dns_search (s_ip6, "lab6.foobar.com"); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - route6file = utils_get_route6_path (testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - reread_s_ip4 = nm_connection_get_setting_ip4_config (reread); - reread_s_ip6 = nm_connection_get_setting_ip6_config (reread); - - g_assert_cmpint (nm_setting_ip_config_get_route_metric (reread_s_ip4), ==, 204); - g_assert_cmpint (nm_setting_ip_config_get_route_metric (reread_s_ip6), ==, 206); - - nm_connection_add_setting (connection, nm_setting_proxy_new ()); - - nmtst_assert_connection_equals (connection, FALSE, reread, FALSE); -} - -static void -test_write_wired_static_with_generic (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *route6file = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4, *reread_s_ip4; - NMSettingIPConfig *s_ip6, *reread_s_ip6; - NMIPAddress *addr; - NMIPAddress *addr6; - NMIPRoute *route6; - GError *error = NULL; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired Static", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, 1, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - g_object_set (s_wired, - NM_SETTING_WIRED_MAC_ADDRESS, "31:33:33:37:be:cd", - NM_SETTING_WIRED_MTU, (guint32) 1492, - NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) 204, - NULL); - - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - addr = nm_ip_address_new (AF_INET, "1.1.1.5", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - nm_setting_ip_config_add_dns (s_ip4, "4.2.2.1"); - nm_setting_ip_config_add_dns (s_ip4, "4.2.2.2"); - - nm_setting_ip_config_add_dns_search (s_ip4, "foobar.com"); - nm_setting_ip_config_add_dns_search (s_ip4, "lab.foobar.com"); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) 206, - NULL); - - /* Add addresses */ - addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip6, addr6); - nm_ip_address_unref (addr6); - - addr6 = nm_ip_address_new (AF_INET6, "2003:1234:abcd::2", 22, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip6, addr6); - nm_ip_address_unref (addr6); - - addr6 = nm_ip_address_new (AF_INET6, "3003:1234:abcd::3", 33, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip6, addr6); - nm_ip_address_unref (addr6); - - /* Add routes */ - route6 = nm_ip_route_new (AF_INET6, - "2222:aaaa:bbbb:cccc::", 64, - "2222:aaaa:bbbb:cccc:dddd:eeee:5555:6666", 99, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_route (s_ip6, route6); - nm_ip_route_unref (route6); - - route6 = nm_ip_route_new (AF_INET6, "::", 128, "2222:aaaa::9999", 1, &error); - g_assert_no_error (error); - nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32 (100)); - nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32 (1280)); - nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, g_variant_new_boolean (TRUE)); - nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_FROM, g_variant_new_string ("2222::bbbb/32")); - nm_ip_route_set_attribute (route6, NM_IP_ROUTE_ATTRIBUTE_SRC, g_variant_new_string ("::42")); - nm_setting_ip_config_add_route (s_ip6, route6); - nm_ip_route_unref (route6); - - /* DNS servers */ - nm_setting_ip_config_add_dns (s_ip6, "fade:0102:0103::face"); - nm_setting_ip_config_add_dns (s_ip6, "cafe:ffff:eeee:dddd:cccc:bbbb:aaaa:feed"); - - /* DNS domains */ - nm_setting_ip_config_add_dns_search (s_ip6, "foobar6.com"); - nm_setting_ip_config_add_dns_search (s_ip6, "lab6.foobar.com"); - - nm_connection_add_setting (connection, nm_setting_generic_new ()); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection_FIXME (connection, - TEST_SCRATCH_DIR, - &testfile); - route6file = utils_get_route6_path (testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - reread_s_ip4 = nm_connection_get_setting_ip4_config (reread); - reread_s_ip6 = nm_connection_get_setting_ip6_config (reread); - - g_assert_cmpint (nm_setting_ip_config_get_route_metric (reread_s_ip4), ==, 204); - g_assert_cmpint (nm_setting_ip_config_get_route_metric (reread_s_ip6), ==, 206); - - nm_connection_add_setting (connection, nm_setting_proxy_new ()); - - { - gs_unref_hashtable GHashTable *diffs = NULL; - - g_assert (!nm_connection_diff (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT, &diffs)); - g_assert (diffs); - g_assert (g_hash_table_size (diffs) == 1); - g_assert (g_hash_table_lookup (diffs, "generic")); - g_assert (!nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); - } - g_assert (!nm_connection_get_setting (reread, NM_TYPE_SETTING_GENERIC)); - nm_connection_add_setting (reread, nm_setting_generic_new ()); - { - gs_unref_hashtable GHashTable *diffs = NULL; - - g_assert (nm_connection_diff (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT, &diffs)); - g_assert (!diffs); - g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); - } -} - -static void -test_write_wired_dhcp (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired DHCP", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, "random-client-id-00:22:33", - NM_SETTING_IP4_CONFIG_DHCP_FQDN, "awesome.hostname", - NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, (guint) NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED, - NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, TRUE, - NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE, - NM_SETTING_IP_CONFIG_DHCP_IAID, "2864434397", - NULL); - - nmtst_assert_connection_verifies (connection); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_DHCP, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, "awesome.hostname", - NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, (guint) NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE, - NULL); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *route6file = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4, *reread_s_ip4; + NMSettingIPConfig * s_ip6, *reread_s_ip6; + NMIPAddress * addr; + NMIPAddress * addr6; + NMIPRoute * route6; + GError * error = NULL; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired Static", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, + 1, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + g_object_set(s_wired, + NM_SETTING_WIRED_MAC_ADDRESS, + "31:33:33:37:be:cd", + NM_SETTING_WIRED_MTU, + (guint32) 1492, + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NM_SETTING_IP_CONFIG_ROUTE_METRIC, + (gint64) 204, + NULL); + + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + addr = nm_ip_address_new(AF_INET, "1.1.1.5", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + nm_setting_ip_config_add_dns(s_ip4, "4.2.2.1"); + nm_setting_ip_config_add_dns(s_ip4, "4.2.2.2"); + + nm_setting_ip_config_add_dns_search(s_ip4, "foobar.com"); + nm_setting_ip_config_add_dns_search(s_ip4, "lab.foobar.com"); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP_CONFIG_ROUTE_METRIC, + (gint64) 206, + NULL); + + /* Add addresses */ + addr6 = nm_ip_address_new(AF_INET6, "1003:1234:abcd::1", 11, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip6, addr6); + nm_ip_address_unref(addr6); + + addr6 = nm_ip_address_new(AF_INET6, "2003:1234:abcd::2", 22, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip6, addr6); + nm_ip_address_unref(addr6); + + addr6 = nm_ip_address_new(AF_INET6, "3003:1234:abcd::3", 33, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip6, addr6); + nm_ip_address_unref(addr6); + + /* Add routes */ + route6 = nm_ip_route_new(AF_INET6, + "2222:aaaa:bbbb:cccc::", + 64, + "2222:aaaa:bbbb:cccc:dddd:eeee:5555:6666", + 99, + &error); + g_assert_no_error(error); + nm_setting_ip_config_add_route(s_ip6, route6); + nm_ip_route_unref(route6); + + route6 = nm_ip_route_new(AF_INET6, "::", 128, "2222:aaaa::9999", 1, &error); + g_assert_no_error(error); + nm_ip_route_set_attribute(route6, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32(100)); + nm_ip_route_set_attribute(route6, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32(1280)); + nm_ip_route_set_attribute(route6, NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, g_variant_new_boolean(TRUE)); + nm_ip_route_set_attribute(route6, + NM_IP_ROUTE_ATTRIBUTE_FROM, + g_variant_new_string("2222::bbbb/32")); + nm_ip_route_set_attribute(route6, NM_IP_ROUTE_ATTRIBUTE_SRC, g_variant_new_string("::42")); + nm_setting_ip_config_add_route(s_ip6, route6); + nm_ip_route_unref(route6); + + /* DNS servers */ + nm_setting_ip_config_add_dns(s_ip6, "fade:0102:0103::face"); + nm_setting_ip_config_add_dns(s_ip6, "cafe:ffff:eeee:dddd:cccc:bbbb:aaaa:feed"); + + /* DNS domains */ + nm_setting_ip_config_add_dns_search(s_ip6, "foobar6.com"); + nm_setting_ip_config_add_dns_search(s_ip6, "lab6.foobar.com"); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + route6file = utils_get_route6_path(testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + + reread_s_ip4 = nm_connection_get_setting_ip4_config(reread); + reread_s_ip6 = nm_connection_get_setting_ip6_config(reread); + + g_assert_cmpint(nm_setting_ip_config_get_route_metric(reread_s_ip4), ==, 204); + g_assert_cmpint(nm_setting_ip_config_get_route_metric(reread_s_ip6), ==, 206); + + nm_connection_add_setting(connection, nm_setting_proxy_new()); + + nmtst_assert_connection_equals(connection, FALSE, reread, FALSE); +} + +static void +test_write_wired_static_with_generic(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *route6file = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4, *reread_s_ip4; + NMSettingIPConfig * s_ip6, *reread_s_ip6; + NMIPAddress * addr; + NMIPAddress * addr6; + NMIPRoute * route6; + GError * error = NULL; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired Static", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, + 1, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + g_object_set(s_wired, + NM_SETTING_WIRED_MAC_ADDRESS, + "31:33:33:37:be:cd", + NM_SETTING_WIRED_MTU, + (guint32) 1492, + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NM_SETTING_IP_CONFIG_ROUTE_METRIC, + (gint64) 204, + NULL); + + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + addr = nm_ip_address_new(AF_INET, "1.1.1.5", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + nm_setting_ip_config_add_dns(s_ip4, "4.2.2.1"); + nm_setting_ip_config_add_dns(s_ip4, "4.2.2.2"); + + nm_setting_ip_config_add_dns_search(s_ip4, "foobar.com"); + nm_setting_ip_config_add_dns_search(s_ip4, "lab.foobar.com"); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP_CONFIG_ROUTE_METRIC, + (gint64) 206, + NULL); + + /* Add addresses */ + addr6 = nm_ip_address_new(AF_INET6, "1003:1234:abcd::1", 11, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip6, addr6); + nm_ip_address_unref(addr6); + + addr6 = nm_ip_address_new(AF_INET6, "2003:1234:abcd::2", 22, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip6, addr6); + nm_ip_address_unref(addr6); + + addr6 = nm_ip_address_new(AF_INET6, "3003:1234:abcd::3", 33, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip6, addr6); + nm_ip_address_unref(addr6); + + /* Add routes */ + route6 = nm_ip_route_new(AF_INET6, + "2222:aaaa:bbbb:cccc::", + 64, + "2222:aaaa:bbbb:cccc:dddd:eeee:5555:6666", + 99, + &error); + g_assert_no_error(error); + nm_setting_ip_config_add_route(s_ip6, route6); + nm_ip_route_unref(route6); + + route6 = nm_ip_route_new(AF_INET6, "::", 128, "2222:aaaa::9999", 1, &error); + g_assert_no_error(error); + nm_ip_route_set_attribute(route6, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32(100)); + nm_ip_route_set_attribute(route6, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32(1280)); + nm_ip_route_set_attribute(route6, NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, g_variant_new_boolean(TRUE)); + nm_ip_route_set_attribute(route6, + NM_IP_ROUTE_ATTRIBUTE_FROM, + g_variant_new_string("2222::bbbb/32")); + nm_ip_route_set_attribute(route6, NM_IP_ROUTE_ATTRIBUTE_SRC, g_variant_new_string("::42")); + nm_setting_ip_config_add_route(s_ip6, route6); + nm_ip_route_unref(route6); + + /* DNS servers */ + nm_setting_ip_config_add_dns(s_ip6, "fade:0102:0103::face"); + nm_setting_ip_config_add_dns(s_ip6, "cafe:ffff:eeee:dddd:cccc:bbbb:aaaa:feed"); + + /* DNS domains */ + nm_setting_ip_config_add_dns_search(s_ip6, "foobar6.com"); + nm_setting_ip_config_add_dns_search(s_ip6, "lab6.foobar.com"); + + nm_connection_add_setting(connection, nm_setting_generic_new()); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection_FIXME(connection, TEST_SCRATCH_DIR, &testfile); + route6file = utils_get_route6_path(testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + reread_s_ip4 = nm_connection_get_setting_ip4_config(reread); + reread_s_ip6 = nm_connection_get_setting_ip6_config(reread); + + g_assert_cmpint(nm_setting_ip_config_get_route_metric(reread_s_ip4), ==, 204); + g_assert_cmpint(nm_setting_ip_config_get_route_metric(reread_s_ip6), ==, 206); + + nm_connection_add_setting(connection, nm_setting_proxy_new()); + + { + gs_unref_hashtable GHashTable *diffs = NULL; + + g_assert(!nm_connection_diff(connection, reread, NM_SETTING_COMPARE_FLAG_EXACT, &diffs)); + g_assert(diffs); + g_assert(g_hash_table_size(diffs) == 1); + g_assert(g_hash_table_lookup(diffs, "generic")); + g_assert(!nm_connection_compare(connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + } + g_assert(!nm_connection_get_setting(reread, NM_TYPE_SETTING_GENERIC)); + nm_connection_add_setting(reread, nm_setting_generic_new()); + { + gs_unref_hashtable GHashTable *diffs = NULL; + + g_assert(nm_connection_diff(connection, reread, NM_SETTING_COMPARE_FLAG_EXACT, &diffs)); + g_assert(!diffs); + g_assert(nm_connection_compare(connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + } +} + +static void +test_write_wired_dhcp(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired DHCP", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, + "random-client-id-00:22:33", + NM_SETTING_IP4_CONFIG_DHCP_FQDN, + "awesome.hostname", + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, + (guint) NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, + TRUE, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, + TRUE, + NM_SETTING_IP_CONFIG_DHCP_IAID, + "2864434397", + NULL); + + nmtst_assert_connection_verifies(connection); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_DHCP, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, + "awesome.hostname", + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, + (guint) NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE, + NULL); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static NMIPRoutingRule * -_ip_routing_rule_new (int addr_family, - const char *str) +_ip_routing_rule_new(int addr_family, const char *str) { - NMIPRoutingRuleAsStringFlags flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE; - gs_free_error GError *local = NULL; - NMIPRoutingRule *rule; + NMIPRoutingRuleAsStringFlags flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE; + gs_free_error GError *local = NULL; + NMIPRoutingRule * rule; - if (addr_family != AF_UNSPEC) { - if (addr_family == AF_INET) - flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET; - else { - g_assert (addr_family == AF_INET6); - flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6; - } - } + if (addr_family != AF_UNSPEC) { + if (addr_family == AF_INET) + flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET; + else { + g_assert(addr_family == AF_INET6); + flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6; + } + } - rule = nm_ip_routing_rule_from_string (str, - NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE - | flags, - NULL, - nmtst_get_rand_bool () ? &local : NULL); - nmtst_assert_success (rule, local); + rule = nm_ip_routing_rule_from_string(str, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE | flags, + NULL, + nmtst_get_rand_bool() ? &local : NULL); + nmtst_assert_success(rule, local); - if (addr_family != AF_UNSPEC) - g_assert_cmpint (nm_ip_routing_rule_get_addr_family (rule), ==, addr_family); - return rule; + if (addr_family != AF_UNSPEC) + g_assert_cmpint(nm_ip_routing_rule_get_addr_family(rule), ==, addr_family); + return rule; } static void -_ip_routing_rule_add_to_setting (NMSettingIPConfig *s_ip, - const char *str) +_ip_routing_rule_add_to_setting(NMSettingIPConfig *s_ip, const char *str) { - nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL; + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL; - rule = _ip_routing_rule_new (nm_setting_ip_config_get_addr_family (s_ip), str); - nm_setting_ip_config_add_routing_rule (s_ip, rule); + rule = _ip_routing_rule_new(nm_setting_ip_config_get_addr_family(s_ip), str); + nm_setting_ip_config_add_routing_rule(s_ip, rule); } static void -test_write_routing_rules (void) +test_write_routing_rules(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; - connection = nm_simple_connection_new (); + connection = nm_simple_connection_new(); - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Routing Rules", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Routing Rules", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NULL); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); - _ip_routing_rule_add_to_setting (s_ip4, "pref 10 from 0.0.0.0/0 table 1"); - _ip_routing_rule_add_to_setting (s_ip4, "priority 10 to 192.167.8.0/24 table 2"); - _ip_routing_rule_add_to_setting (s_ip6, "pref 10 from ::/0 table 10"); - _ip_routing_rule_add_to_setting (s_ip6, "pref 10 from ::/0 to 1:2:3::5/24 table 22"); - _ip_routing_rule_add_to_setting (s_ip6, "pref 10 from ::/0 to 1:3:3::5/128 table 55"); + _ip_routing_rule_add_to_setting(s_ip4, "pref 10 from 0.0.0.0/0 table 1"); + _ip_routing_rule_add_to_setting(s_ip4, "priority 10 to 192.167.8.0/24 table 2"); + _ip_routing_rule_add_to_setting(s_ip6, "pref 10 from ::/0 table 10"); + _ip_routing_rule_add_to_setting(s_ip6, "pref 10 from ::/0 to 1:2:3::5/24 table 22"); + _ip_routing_rule_add_to_setting(s_ip6, "pref 10 from ::/0 to 1:3:3::5/128 table 55"); - nmtst_assert_connection_verifies (connection); + nmtst_assert_connection_verifies(connection); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Routing_Rules.cexpected", - &testfile); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Routing_Rules.cexpected", + &testfile); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_write_wired_match (void) +test_write_wired_match(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingMatch *s_match; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingMatch * s_match; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; - connection = nm_simple_connection_new (); + connection = nm_simple_connection_new(); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired with Match setting", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired with Match setting", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NULL); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); - /* Match setting */ - s_match = (NMSettingMatch *) nm_setting_match_new (); - nm_setting_match_add_interface_name (s_match, "ens*"); - nm_setting_match_add_interface_name (s_match, "eth 1?"); - nm_setting_match_add_interface_name (s_match, "!veth*"); - nm_setting_match_add_driver (s_match, "!virtio"); - nm_setting_match_add_driver (s_match, "e1000e"); - nm_setting_match_add_kernel_command_line (s_match, "!ip="); - nm_connection_add_setting (connection, NM_SETTING (s_match)); + /* Match setting */ + s_match = (NMSettingMatch *) nm_setting_match_new(); + nm_setting_match_add_interface_name(s_match, "ens*"); + nm_setting_match_add_interface_name(s_match, "eth 1?"); + nm_setting_match_add_interface_name(s_match, "!veth*"); + nm_setting_match_add_driver(s_match, "!virtio"); + nm_setting_match_add_driver(s_match, "e1000e"); + nm_setting_match_add_kernel_command_line(s_match, "!ip="); + nm_connection_add_setting(connection, NM_SETTING(s_match)); - nmtst_assert_connection_verifies (connection); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Wired_match.cexpected", - &testfile); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_verifies(connection); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Wired_match.cexpected", + &testfile); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_write_wired_dhcp_plus_ip (void) +test_write_wired_dhcp_plus_ip(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-dhcp-plus-ip", - NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-dhcp-plus-ip", + NULL, + TYPE_ETHERNET, + NULL); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_read_write_wired_dhcp_send_hostname (void) +test_read_write_wired_dhcp_send_hostname(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - const char * dhcp_hostname = "kamil-patka"; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + const char * dhcp_hostname = "kamil-patka"; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-dhcp-send-hostname", - NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-dhcp-send-hostname", + NULL, + TYPE_ETHERNET, + NULL); - /* Check dhcp-hostname and dhcp-send-hostname */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip4); - g_assert (s_ip6); - g_assert (nm_setting_ip_config_get_dhcp_send_hostname (s_ip4) == TRUE); - g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip4), ==, "svata-pulec"); - g_assert (!nm_setting_ip_config_get_dhcp_hostname (s_ip6)); + /* Check dhcp-hostname and dhcp-send-hostname */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip4); + g_assert(s_ip6); + g_assert(nm_setting_ip_config_get_dhcp_send_hostname(s_ip4) == TRUE); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_hostname(s_ip4), ==, "svata-pulec"); + g_assert(!nm_setting_ip_config_get_dhcp_hostname(s_ip6)); - /* Set dhcp-send-hostname=false dhcp-hostname="kamil-patka" and write the connection. */ - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, FALSE, NULL); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, dhcp_hostname, NULL); - g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, dhcp_hostname, NULL); + /* Set dhcp-send-hostname=false dhcp-hostname="kamil-patka" and write the connection. */ + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, FALSE, NULL); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, dhcp_hostname, NULL); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, dhcp_hostname, NULL); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); - /* Check dhcp-hostname and dhcp-send-hostname from the re-read connection. */ - s_ip4 = nm_connection_get_setting_ip4_config (reread); - s_ip6 = nm_connection_get_setting_ip6_config (reread); - g_assert (s_ip4); - g_assert (s_ip6); - g_assert (nm_setting_ip_config_get_dhcp_send_hostname (s_ip4) == FALSE); - g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip4), ==, dhcp_hostname); - g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip6), ==, dhcp_hostname); + /* Check dhcp-hostname and dhcp-send-hostname from the re-read connection. */ + s_ip4 = nm_connection_get_setting_ip4_config(reread); + s_ip6 = nm_connection_get_setting_ip6_config(reread); + g_assert(s_ip4); + g_assert(s_ip6); + g_assert(nm_setting_ip_config_get_dhcp_send_hostname(s_ip4) == FALSE); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_hostname(s_ip4), ==, dhcp_hostname); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_hostname(s_ip6), ==, dhcp_hostname); } static void -test_read_wired_dhcpv6_hostname_fallback (void) +test_read_wired_dhcpv6_hostname_fallback(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingIPConfig *s_ip6; + gs_unref_object NMConnection *connection = NULL; + NMSettingIPConfig * s_ip6; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-dhcpv6-hostname-fallback", - NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wired-dhcpv6-hostname-fallback", + NULL, + TYPE_ETHERNET, + NULL); - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert (nm_setting_ip_config_get_dhcp_send_hostname (s_ip6) == TRUE); - g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip6), ==, "fully.qualified.domain"); + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert(nm_setting_ip_config_get_dhcp_send_hostname(s_ip6) == TRUE); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_hostname(s_ip6), ==, "fully.qualified.domain"); } static void -test_write_wired_static_ip6_only (void) +test_write_wired_static_ip6_only(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMIPAddress *addr6; - GError *error = NULL; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMIPAddress * addr6; + GError * error = NULL; - connection = nm_simple_connection_new (); + connection = nm_simple_connection_new(); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired Static IP6 Only", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired Static IP6 Only", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, "31:33:33:37:be:cd", NULL); + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, "31:33:33:37:be:cd", NULL); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, - NULL); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NULL); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NULL); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NULL); - /* Add addresses */ - addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip6, addr6); - nm_ip_address_unref (addr6); + /* Add addresses */ + addr6 = nm_ip_address_new(AF_INET6, "1003:1234:abcd::1", 11, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip6, addr6); + nm_ip_address_unref(addr6); - /* DNS server */ - nm_setting_ip_config_add_dns (s_ip6, "fade:0102:0103::face"); + /* DNS server */ + nm_setting_ip_config_add_dns(s_ip6, "fade:0102:0103::face"); - nmtst_assert_connection_verifies (connection); + nmtst_assert_connection_verifies(connection); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_write_ip6_disabled (void) +test_write_ip6_disabled(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; - connection = nmtst_create_minimal_connection ("Test Write Wired Disabled IP6", - NULL, - NM_SETTING_WIRED_SETTING_NAME, - &s_con); + connection = nmtst_create_minimal_connection("Test Write Wired Disabled IP6", + NULL, + NM_SETTING_WIRED_SETTING_NAME, + &s_con); - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_DISABLED, - NULL); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_DISABLED, NULL); - nmtst_assert_connection_verifies (connection); + nmtst_assert_connection_verifies(connection); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR_TMP, - TEST_IFCFG_DIR"/ifcfg-test-ip6-disabled.cexpected", - &testfile); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR_TMP, + TEST_IFCFG_DIR "/ifcfg-test-ip6-disabled.cexpected", + &testfile); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } /* Test writing an IPv6 config with varying gateway address. @@ -4916,5821 +5373,6452 @@ test_write_ip6_disabled (void) * That way, the gateway actually defaults to "::". */ static void -test_write_wired_static_ip6_only_gw (gconstpointer user_data) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMIPAddress *addr6; - GError *error = NULL; - char *id = NULL; - gs_free char *written_ifcfg_gateway = NULL; - const char *gateway6 = user_data; - shvarFile *ifcfg; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - id = g_strdup_printf ("Test Write Wired Static IP6 Only With Gateway %s", gateway6 ?: "NULL"); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, id, - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - g_free (id); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, "31:33:33:37:be:cd", NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, - NULL); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, gateway6, - NULL); - - /* Add addresses */ - addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip6, addr6); - nm_ip_address_unref (addr6); +test_write_wired_static_ip6_only_gw(gconstpointer user_data) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMIPAddress * addr6; + GError * error = NULL; + char * id = NULL; + gs_free char * written_ifcfg_gateway = NULL; + const char * gateway6 = user_data; + shvarFile * ifcfg; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + id = g_strdup_printf("Test Write Wired Static IP6 Only With Gateway %s", gateway6 ?: "NULL"); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + id, + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free(id); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - /* DNS server */ - nm_setting_ip_config_add_dns (s_ip6, "fade:0102:0103::face"); + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, "31:33:33:37:be:cd", NULL); - nmtst_assert_connection_verifies (connection); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + gateway6, + NULL); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + /* Add addresses */ + addr6 = nm_ip_address_new(AF_INET6, "1003:1234:abcd::1", 11, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip6, addr6); + nm_ip_address_unref(addr6); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + /* DNS server */ + nm_setting_ip_config_add_dns(s_ip6, "fade:0102:0103::face"); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); + + ifcfg = _svOpenFile(testfile); + written_ifcfg_gateway = svGetValueStr_cp(ifcfg, "IPV6_DEFAULTGW"); + svCloseFile(ifcfg); + + /* access the gateway from the loaded connection. */ + s_ip6 = nm_connection_get_setting_ip6_config(reread); + g_assert(s_ip6 && nm_setting_ip_config_get_num_addresses(s_ip6) == 1); + addr6 = nm_setting_ip_config_get_address(s_ip6, 0); + g_assert(addr6); + + /* assert that the gateway was written and reloaded as expected */ + if (!gateway6 || !strcmp(gateway6, "::")) { + g_assert(nm_setting_ip_config_get_gateway(s_ip6) == NULL); + g_assert(written_ifcfg_gateway == NULL); + } else { + g_assert(nm_setting_ip_config_get_gateway(s_ip6) != NULL); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip6), ==, gateway6); + g_assert_cmpstr(written_ifcfg_gateway, ==, gateway6); + } +} + +static void +test_read_write_static_routes_legacy(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *routefile = NULL; + gs_free char * route6file = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + const char * tmp; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-static-routes-legacy", + NULL, + TYPE_ETHERNET, + NULL); + + /* ===== CONNECTION SETTING ===== */ + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + + /* ID */ + tmp = nm_setting_connection_get_id(s_con); + g_assert(tmp); + + /* Autoconnect */ + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + /* ===== WIRED SETTING ===== */ + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + g_assert(!nm_setting_ip_config_get_never_default(s_ip4)); + + /* Save the ifcfg; use a special different scratch dir to ensure that + * we can clean up after the written connection in both the original + * source tree and for 'make distcheck'. + */ + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR_TMP, + TEST_IFCFG_DIR "/ifcfg-test-static-routes-legacy.cexpected", + &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + routefile = utils_get_route_path(testfile); + route6file = utils_get_route6_path(testfile); + g_assert(!g_file_test(route6file, G_FILE_TEST_EXISTS)); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wired_static_routes(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *routefile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMIPAddress * addr; + NMIPRoute * route; + GError * error = NULL; + gboolean reread_same = FALSE; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired Static Routes", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + g_object_set(s_wired, + NM_SETTING_WIRED_MAC_ADDRESS, + "31:33:33:37:be:cd", + NM_SETTING_WIRED_MTU, + (guint32) 1492, + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NM_SETTING_IP_CONFIG_DAD_TIMEOUT, + 400, + NULL); + + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + addr = nm_ip_address_new(AF_INET, "1.1.1.5", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + /* Write out routes */ + route = nm_ip_route_new(AF_INET, "1.2.3.0", 24, "222.173.190.239", 0, &error); + nm_ip_route_set_attribute(route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, g_variant_new_uint32(3455)); + nm_ip_route_set_attribute(route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, g_variant_new_boolean(TRUE)); + g_assert_no_error(error); + nm_setting_ip_config_add_route(s_ip4, route); + nm_ip_route_unref(route); + + route = nm_ip_route_new(AF_INET, "3.2.1.0", 24, "202.254.186.190", 77, &error); + nm_ip_route_set_attribute(route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, g_variant_new_uint32(30000)); + nm_ip_route_set_attribute(route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, g_variant_new_boolean(FALSE)); + g_assert_no_error(error); + nm_setting_ip_config_add_route(s_ip4, route); + nm_ip_route_unref(route); + + nm_setting_ip_config_add_dns(s_ip4, "4.2.2.1"); + nm_setting_ip_config_add_dns(s_ip4, "4.2.2.2"); + + nm_setting_ip_config_add_dns_search(s_ip4, "foobar.com"); + nm_setting_ip_config_add_dns_search(s_ip4, "lab.foobar.com"); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection_reread(connection, + TEST_SCRATCH_DIR, + &testfile, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Wired_Static_Routes.cexpected", + &reread, + &reread_same); + /* ifcfg does not support setting onlink=0. It gets lost during write+re-read. + * Assert that it's missing, and patch it to check whether the rest of the + * connection equals. */ + g_assert(!reread_same); + nmtst_assert_connection_verifies_without_normalization(reread); + s_ip4 = nm_connection_get_setting_ip4_config(reread); + g_assert(s_ip4); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 2); + route = nm_setting_ip_config_get_route(s_ip4, 1); + g_assert(route); + g_assert(!nm_ip_route_get_attribute(route, NM_IP_ROUTE_ATTRIBUTE_ONLINK)); + nm_ip_route_set_attribute(route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, g_variant_new_boolean(FALSE)); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); + + routefile = utils_get_route_path(testfile); +} + +static void +test_write_wired_dhcp_8021x_peap_mschapv2(void) +{ + nmtst_auto_unlinkfile char *keyfile = NULL; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSetting8021x * s_8021x; + gboolean success; + GError * error = NULL; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired DHCP 802.1x PEAP MSCHAPv2", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + /* 802.1x setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + g_object_set(s_8021x, + NM_SETTING_802_1X_IDENTITY, + "Bob Saget", + NM_SETTING_802_1X_ANONYMOUS_IDENTITY, + "barney", + NM_SETTING_802_1X_PASSWORD, + "Kids, it was back in October 2008...", + NM_SETTING_802_1X_PHASE1_PEAPVER, + "1", + NM_SETTING_802_1X_PHASE1_PEAPLABEL, + "1", + NM_SETTING_802_1X_PHASE2_AUTH, + "mschapv2", + NULL); + + nm_setting_802_1x_add_eap_method(s_8021x, "peap"); + + success = nm_setting_802_1x_set_ca_cert(s_8021x, + TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + nmtst_assert_success(success, error); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); + + keyfile = utils_get_keys_path(testfile); +} + +static void +test_write_wired_8021x_tls(gconstpointer test_data) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_free char * keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSetting8021x * s_8021x; + gboolean success; + GError * error = NULL; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + const char * pw; + char * tmp; + gpointer scheme_p, flags_p; + NMSetting8021xCKScheme scheme; + NMSettingSecretFlags flags; + + nmtst_test_data_unpack(test_data, &scheme_p, &flags_p); + scheme = GPOINTER_TO_INT(scheme_p); + flags = GPOINTER_TO_INT(flags_p); + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired 802.1x TLS Blobs", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + /* 802.1x setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + g_object_set(s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + nm_setting_802_1x_add_eap_method(s_8021x, "tls"); + + /* CA cert */ + success = nm_setting_802_1x_set_ca_cert(s_8021x, + TEST_IFCFG_DIR "/test_ca_cert.pem", + scheme, + &format, + &error); + g_assert_no_error(error); + g_assert(success); + g_assert(format == NM_SETTING_802_1X_CK_FORMAT_X509); + + /* Client cert */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_client_cert(s_8021x, + TEST_IFCFG_DIR "/test1_key_and_cert.pem", + scheme, + &format, + &error); + g_assert_no_error(error); + g_assert(success); + g_assert(format == NM_SETTING_802_1X_CK_FORMAT_X509); + + /* Private key */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_private_key(s_8021x, + TEST_IFCFG_DIR "/test1_key_and_cert.pem", + "test1", + scheme, + &format, + &error); + g_assert_no_error(error); + g_assert(success); + g_assert(format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY); + + /* Set secret flags */ + g_object_set(s_8021x, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, flags, NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection_FIXME(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + keyfile = utils_get_keys_path(testfile); + nmtst_file_unlink_if_exists(keyfile); + + /* Ensure the reread connection's certificates and private key are paths; no + * matter what scheme was used in the original connection they will be read + * back in as paths. + */ + s_8021x = nm_connection_get_setting_802_1x(reread); + g_assert(s_8021x); + g_assert_cmpint(nm_setting_802_1x_get_ca_cert_scheme(s_8021x), + ==, + NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert_cmpint(nm_setting_802_1x_get_client_cert_scheme(s_8021x), + ==, + NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert_cmpint(nm_setting_802_1x_get_private_key_scheme(s_8021x), + ==, + NM_SETTING_802_1X_CK_SCHEME_PATH); + + g_assert_cmpint(nm_setting_802_1x_get_private_key_password_flags(s_8021x), ==, flags); + pw = nm_setting_802_1x_get_private_key_password(s_8021x); + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + /* Ensure the private key password is still set */ + g_assert(pw != NULL); + g_assert_cmpstr(pw, ==, "test1"); + } else { + /* If the secret isn't owned by system settings, make sure its no longer there */ + g_assert(pw == NULL); + } + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + /* Do a direct compare if using the path scheme since then the + * certificate and key properties should be the same. If using blob + * scheme the original connection cert/key properties will be blobs + * but the re-read connection is always path scheme, so we wouldn't + * expect it to compare successfully. + */ + if (flags != NM_SETTING_SECRET_FLAG_NONE) { + /* Clear original connection's private key password because flags + * say it's not system-owned, and therefore it should not show up + * in the re-read connection. + */ + s_8021x = nm_connection_get_setting_802_1x(connection); + g_object_set(s_8021x, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL); + } + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); + } + + /* Clean up created certs and keys */ + tmp = utils_cert_path(testfile, "ca-cert", "der"); + nmtst_file_unlink_if_exists(tmp); + g_free(tmp); + + tmp = utils_cert_path(testfile, "client-cert", "der"); + nmtst_file_unlink_if_exists(tmp); + g_free(tmp); + + tmp = utils_cert_path(testfile, "private-key", "pem"); + nmtst_file_unlink_if_exists(tmp); + g_free(tmp); +} + +static void +test_write_wired_aliases(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + int num_addresses = 4; + const char * ip[] = {"1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4"}; + const char * label[] = {NULL, "alias0:2", NULL, "alias0:3"}; + NMIPAddress * addr; + GError * error = NULL; + shvarFile * ifcfg; + int i, j; + + nmtst_file_unlink_if_exists(TEST_SCRATCH_ALIAS_BASE ":2"); + nmtst_file_unlink_if_exists(TEST_SCRATCH_ALIAS_BASE ":3"); + nmtst_file_unlink_if_exists(TEST_SCRATCH_ALIAS_BASE ":5"); + + connection = nm_simple_connection_new(); + g_assert(connection); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "alias0", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + for (i = 0; i < num_addresses; i++) { + addr = nm_ip_address_new(AF_INET, ip[i], 24, &error); + g_assert_no_error(error); + if (label[i]) + nm_ip_address_set_attribute(addr, + NM_IP_ADDRESS_ATTRIBUTE_LABEL, + g_variant_new_string(label[i])); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + } + + nmtst_assert_connection_verifies(connection); + + /* Create some pre-existing alias files, to make sure they get overwritten / deleted. */ + ifcfg = svCreateFile(TEST_SCRATCH_ALIAS_BASE ":2"); + svSetValueStr(ifcfg, "DEVICE", "alias0:2"); + svSetValueStr(ifcfg, "IPADDR", "192.168.1.2"); + svWriteFile(ifcfg, 0644, NULL); + svCloseFile(ifcfg); + g_assert(g_file_test(TEST_SCRATCH_ALIAS_BASE ":2", G_FILE_TEST_EXISTS)); + + ifcfg = svCreateFile(TEST_SCRATCH_ALIAS_BASE ":5"); + svSetValueStr(ifcfg, "DEVICE", "alias0:5"); + svSetValueStr(ifcfg, "IPADDR", "192.168.1.5"); + svWriteFile(ifcfg, 0644, NULL); + svCloseFile(ifcfg); + g_assert(g_file_test(TEST_SCRATCH_ALIAS_BASE ":5", G_FILE_TEST_EXISTS)); + + _writer_new_connection_FIXME(connection, TEST_SCRATCH_DIR, &testfile); + + /* Re-check the alias files */ + g_assert(g_file_test(TEST_SCRATCH_ALIAS_BASE ":2", G_FILE_TEST_EXISTS)); + g_assert(g_file_test(TEST_SCRATCH_ALIAS_BASE ":3", G_FILE_TEST_EXISTS)); + g_assert(!g_file_test(TEST_SCRATCH_ALIAS_BASE ":5", G_FILE_TEST_EXISTS)); + + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + nmtst_file_unlink(TEST_SCRATCH_ALIAS_BASE ":2"); + nmtst_file_unlink(TEST_SCRATCH_ALIAS_BASE ":3"); + + /* nm_connection_compare() is not guaranteed to succeed, because the + * aliases get read back in essentially random order. So just + * verify the aliases manually. + */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(nm_setting_ip_config_get_num_addresses(s_ip4) == num_addresses); + + /* Addresses */ + for (i = 0; i < num_addresses; i++) { + const char *addrstr; + + addr = nm_setting_ip_config_get_address(s_ip4, i); + g_assert(addr != NULL); + + addrstr = nm_ip_address_get_address(addr); + for (j = 0; j < num_addresses; j++) { + if (!g_strcmp0(addrstr, ip[j])) + break; + } + if (j >= num_addresses) + g_assert_not_reached(); + else { + g_assert_cmpint(nm_ip_address_get_prefix(addr), ==, 24); + if (label[j]) + g_assert_cmpstr( + g_variant_get_string( + nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL), + NULL), + ==, + label[j]); + else + g_assert(nm_ip_address_get_attribute(addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL) == NULL); + ip[j] = NULL; + } + } + + for (i = 0; i < num_addresses; i++) + g_assert(!ip[i]); + + /* Gateway */ + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "1.1.1.1"); +} + +static void +test_write_gateway(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + GError * error = NULL; + shvarFile * f; + NMIPAddress * addr; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Static Addresses Gateway", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.254", + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + addr = nm_ip_address_new(AF_INET, "2.2.2.5", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + f = _svOpenFile(testfile); + _svGetValue_check(f, "IPADDR", "1.1.1.3"); + _svGetValue_check(f, "IPADDR1", "2.2.2.5"); + _svGetValue_check(f, "IPADDR0", NULL); + _svGetValue_check(f, "PREFIX", "24"); + _svGetValue_check(f, "PREFIX1", "24"); + _svGetValue_check(f, "PREFIX0", NULL); + _svGetValue_check(f, "GATEWAY", "1.1.1.254"); + _svGetValue_check(f, "GATEWAY0", NULL); + _svGetValue_check(f, "GATEWAY1", NULL); + svCloseFile(f); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_open(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GBytes * ssid; + const unsigned char ssid_data[] = {0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44}; + shvarFile * ifcfg; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi Open", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, sizeof(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_BSSID, + "11:22:33:44:55:66", + NM_SETTING_WIRELESS_MAC_ADDRESS, + "aa:bb:cc:dd:ee:ff", + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NM_SETTING_WIRELESS_BAND, + "bg", + NM_SETTING_WIRELESS_CHANNEL, + (guint32) 9, + NM_SETTING_WIRELESS_MTU, + (guint32) 1345, + NULL); + + g_bytes_unref(ssid); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - ifcfg = _svOpenFile (testfile); - written_ifcfg_gateway = svGetValueStr_cp (ifcfg, "IPV6_DEFAULTGW"); - svCloseFile (ifcfg); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - /* access the gateway from the loaded connection. */ - s_ip6 = nm_connection_get_setting_ip6_config (reread); - g_assert (s_ip6 && nm_setting_ip_config_get_num_addresses (s_ip6)==1); - addr6 = nm_setting_ip_config_get_address (s_ip6, 0); - g_assert (addr6); - - /* assert that the gateway was written and reloaded as expected */ - if (!gateway6 || !strcmp (gateway6, "::")) { - g_assert (nm_setting_ip_config_get_gateway (s_ip6) == NULL); - g_assert (written_ifcfg_gateway == NULL); - } else { - g_assert (nm_setting_ip_config_get_gateway (s_ip6) != NULL); - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, gateway6); - g_assert_cmpstr (written_ifcfg_gateway, ==, gateway6); - } -} + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); -static void -test_read_write_static_routes_legacy (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *routefile = NULL; - gs_free char *route6file = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - const char *tmp; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-static-routes-legacy", - NULL, TYPE_ETHERNET, NULL); - - /* ===== CONNECTION SETTING ===== */ - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - - /* ID */ - tmp = nm_setting_connection_get_id (s_con); - g_assert (tmp); - - /* Autoconnect */ - g_assert (nm_setting_connection_get_autoconnect (s_con)); - - /* ===== WIRED SETTING ===== */ - - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - - /* ===== IPv4 SETTING ===== */ - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - - g_assert (!nm_setting_ip_config_get_never_default (s_ip4)); + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); - /* Save the ifcfg; use a special different scratch dir to ensure that - * we can clean up after the written connection in both the original - * source tree and for 'make distcheck'. - */ - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR_TMP, - TEST_IFCFG_DIR"/ifcfg-test-static-routes-legacy.cexpected", - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - routefile = utils_get_route_path (testfile); - route6file = utils_get_route6_path (testfile); - g_assert (!g_file_test (route6file, G_FILE_TEST_EXISTS)); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_write_wired_static_routes (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *routefile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMIPAddress *addr; - NMIPRoute *route; - GError *error = NULL; - gboolean reread_same = FALSE; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired Static Routes", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - g_object_set (s_wired, - NM_SETTING_WIRED_MAC_ADDRESS, "31:33:33:37:be:cd", - NM_SETTING_WIRED_MTU, (guint32) 1492, - NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NM_SETTING_IP_CONFIG_DAD_TIMEOUT, 400, - NULL); - - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - addr = nm_ip_address_new (AF_INET, "1.1.1.5", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - /* Write out routes */ - route = nm_ip_route_new (AF_INET, "1.2.3.0", 24, "222.173.190.239", 0, &error); - nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, g_variant_new_uint32 (3455)); - nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, g_variant_new_boolean (TRUE)); - g_assert_no_error (error); - nm_setting_ip_config_add_route (s_ip4, route); - nm_ip_route_unref (route); - - route = nm_ip_route_new (AF_INET, "3.2.1.0", 24, "202.254.186.190", 77, &error); - nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, g_variant_new_uint32 (30000)); - nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, g_variant_new_boolean (FALSE)); - g_assert_no_error (error); - nm_setting_ip_config_add_route (s_ip4, route); - nm_ip_route_unref (route); - - nm_setting_ip_config_add_dns (s_ip4, "4.2.2.1"); - nm_setting_ip_config_add_dns (s_ip4, "4.2.2.2"); - - nm_setting_ip_config_add_dns_search (s_ip4, "foobar.com"); - nm_setting_ip_config_add_dns_search (s_ip4, "lab.foobar.com"); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection_reread (connection, - TEST_SCRATCH_DIR, - &testfile, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Wired_Static_Routes.cexpected", - &reread, - &reread_same); - /* ifcfg does not support setting onlink=0. It gets lost during write+re-read. - * Assert that it's missing, and patch it to check whether the rest of the - * connection equals. */ - g_assert (!reread_same); - nmtst_assert_connection_verifies_without_normalization (reread); - s_ip4 = nm_connection_get_setting_ip4_config (reread); - g_assert (s_ip4); - g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 2); - route = nm_setting_ip_config_get_route (s_ip4, 1); - g_assert (route); - g_assert (!nm_ip_route_get_attribute (route, NM_IP_ROUTE_ATTRIBUTE_ONLINK)); - nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, g_variant_new_boolean (FALSE)); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); - - routefile = utils_get_route_path (testfile); -} - -static void -test_write_wired_dhcp_8021x_peap_mschapv2 (void) -{ - nmtst_auto_unlinkfile char *keyfile = NULL; - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMSetting8021x *s_8021x; - gboolean success; - GError *error = NULL; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired DHCP 802.1x PEAP MSCHAPv2", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - /* 802.1x setting */ - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - g_object_set (s_8021x, - NM_SETTING_802_1X_IDENTITY, "Bob Saget", - NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "barney", - NM_SETTING_802_1X_PASSWORD, "Kids, it was back in October 2008...", - NM_SETTING_802_1X_PHASE1_PEAPVER, "1", - NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1", - NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", - NULL); - - nm_setting_802_1x_add_eap_method (s_8021x, "peap"); - - success = nm_setting_802_1x_set_ca_cert (s_8021x, - TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error); - nmtst_assert_success (success, error); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); - - keyfile = utils_get_keys_path (testfile); -} - -static void -test_write_wired_8021x_tls (gconstpointer test_data) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_free char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMSetting8021x *s_8021x; - gboolean success; - GError *error = NULL; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - const char *pw; - char *tmp; - gpointer scheme_p, flags_p; - NMSetting8021xCKScheme scheme; - NMSettingSecretFlags flags; - - nmtst_test_data_unpack (test_data, &scheme_p, &flags_p); - scheme = GPOINTER_TO_INT (scheme_p); - flags = GPOINTER_TO_INT (flags_p); - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired 802.1x TLS Blobs", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - /* 802.1x setting */ - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); - nm_setting_802_1x_add_eap_method (s_8021x, "tls"); - - /* CA cert */ - success = nm_setting_802_1x_set_ca_cert (s_8021x, - TEST_IFCFG_DIR"/test_ca_cert.pem", - scheme, - &format, - &error); - g_assert_no_error (error); - g_assert (success); - g_assert (format == NM_SETTING_802_1X_CK_FORMAT_X509); - - /* Client cert */ - format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - success = nm_setting_802_1x_set_client_cert (s_8021x, - TEST_IFCFG_DIR"/test1_key_and_cert.pem", - scheme, - &format, - &error); - g_assert_no_error (error); - g_assert (success); - g_assert (format == NM_SETTING_802_1X_CK_FORMAT_X509); - - /* Private key */ - format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - success = nm_setting_802_1x_set_private_key (s_8021x, - TEST_IFCFG_DIR"/test1_key_and_cert.pem", - "test1", - scheme, - &format, - &error); - g_assert_no_error (error); - g_assert (success); - g_assert (format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY); - - /* Set secret flags */ - g_object_set (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, flags, NULL); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection_FIXME (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); - - keyfile = utils_get_keys_path (testfile); - nmtst_file_unlink_if_exists (keyfile); - - /* Ensure the reread connection's certificates and private key are paths; no - * matter what scheme was used in the original connection they will be read - * back in as paths. - */ - s_8021x = nm_connection_get_setting_802_1x (reread); - g_assert (s_8021x); - g_assert_cmpint (nm_setting_802_1x_get_ca_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH); - g_assert_cmpint (nm_setting_802_1x_get_client_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH); - g_assert_cmpint (nm_setting_802_1x_get_private_key_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH); - - g_assert_cmpint (nm_setting_802_1x_get_private_key_password_flags (s_8021x), ==, flags); - pw = nm_setting_802_1x_get_private_key_password (s_8021x); - if (flags == NM_SETTING_SECRET_FLAG_NONE) { - /* Ensure the private key password is still set */ - g_assert (pw != NULL); - g_assert_cmpstr (pw, ==, "test1"); - } else { - /* If the secret isn't owned by system settings, make sure its no longer there */ - g_assert (pw == NULL); - } - - if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { - /* Do a direct compare if using the path scheme since then the - * certificate and key properties should be the same. If using blob - * scheme the original connection cert/key properties will be blobs - * but the re-read connection is always path scheme, so we wouldn't - * expect it to compare successfully. - */ - if (flags != NM_SETTING_SECRET_FLAG_NONE) { - /* Clear original connection's private key password because flags - * say it's not system-owned, and therefore it should not show up - * in the re-read connection. - */ - s_8021x = nm_connection_get_setting_802_1x (connection); - g_object_set (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL); - } - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); - } - - /* Clean up created certs and keys */ - tmp = utils_cert_path (testfile, "ca-cert", "der"); - nmtst_file_unlink_if_exists (tmp); - g_free (tmp); - - tmp = utils_cert_path (testfile, "client-cert", "der"); - nmtst_file_unlink_if_exists (tmp); - g_free (tmp); - - tmp = utils_cert_path (testfile, "private-key", "pem"); - nmtst_file_unlink_if_exists (tmp); - g_free (tmp); -} - -static void -test_write_wired_aliases (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - int num_addresses = 4; - const char *ip[] = { "1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4" }; - const char *label[] = { NULL, "alias0:2", NULL, "alias0:3" }; - NMIPAddress *addr; - GError *error = NULL; - shvarFile *ifcfg; - int i, j; - - nmtst_file_unlink_if_exists (TEST_SCRATCH_ALIAS_BASE ":2"); - nmtst_file_unlink_if_exists (TEST_SCRATCH_ALIAS_BASE ":3"); - nmtst_file_unlink_if_exists (TEST_SCRATCH_ALIAS_BASE ":5"); - - connection = nm_simple_connection_new (); - g_assert (connection); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "alias0", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - for (i = 0; i < num_addresses; i++) { - addr = nm_ip_address_new (AF_INET, ip[i], 24, &error); - g_assert_no_error (error); - if (label[i]) - nm_ip_address_set_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL, g_variant_new_string (label[i])); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - } - - nmtst_assert_connection_verifies (connection); - - /* Create some pre-existing alias files, to make sure they get overwritten / deleted. */ - ifcfg = svCreateFile (TEST_SCRATCH_ALIAS_BASE ":2"); - svSetValueStr (ifcfg, "DEVICE", "alias0:2"); - svSetValueStr (ifcfg, "IPADDR", "192.168.1.2"); - svWriteFile (ifcfg, 0644, NULL); - svCloseFile (ifcfg); - g_assert (g_file_test (TEST_SCRATCH_ALIAS_BASE ":2", G_FILE_TEST_EXISTS)); - - ifcfg = svCreateFile (TEST_SCRATCH_ALIAS_BASE ":5"); - svSetValueStr (ifcfg, "DEVICE", "alias0:5"); - svSetValueStr (ifcfg, "IPADDR", "192.168.1.5"); - svWriteFile (ifcfg, 0644, NULL); - svCloseFile (ifcfg); - g_assert (g_file_test (TEST_SCRATCH_ALIAS_BASE ":5", G_FILE_TEST_EXISTS)); - - _writer_new_connection_FIXME (connection, - TEST_SCRATCH_DIR, - &testfile); - - /* Re-check the alias files */ - g_assert (g_file_test (TEST_SCRATCH_ALIAS_BASE ":2", G_FILE_TEST_EXISTS)); - g_assert (g_file_test (TEST_SCRATCH_ALIAS_BASE ":3", G_FILE_TEST_EXISTS)); - g_assert (!g_file_test (TEST_SCRATCH_ALIAS_BASE ":5", G_FILE_TEST_EXISTS)); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_file_unlink (TEST_SCRATCH_ALIAS_BASE ":2"); - nmtst_file_unlink (TEST_SCRATCH_ALIAS_BASE ":3"); - - /* nm_connection_compare() is not guaranteed to succeed, because the - * aliases get read back in essentially random order. So just - * verify the aliases manually. - */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (nm_setting_ip_config_get_num_addresses (s_ip4) == num_addresses); - - /* Addresses */ - for (i = 0; i < num_addresses; i++) { - const char *addrstr; - - addr = nm_setting_ip_config_get_address (s_ip4, i); - g_assert (addr != NULL); - - addrstr = nm_ip_address_get_address (addr); - for (j = 0; j < num_addresses; j++) { - if (!g_strcmp0 (addrstr, ip[j])) - break; - } - if (j >= num_addresses) - g_assert_not_reached (); - else { - g_assert_cmpint (nm_ip_address_get_prefix (addr), ==, 24); - if (label[j]) - g_assert_cmpstr (g_variant_get_string (nm_ip_address_get_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL), NULL), ==, label[j]); - else - g_assert (nm_ip_address_get_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL) == NULL); - ip[j] = NULL; - } - } - - for (i = 0; i < num_addresses; i++) - g_assert (!ip[i]); - - /* Gateway */ - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "1.1.1.1"); -} - -static void -test_write_gateway (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - GError *error = NULL; - shvarFile *f; - NMIPAddress *addr; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Static Addresses Gateway", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.254", - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - addr = nm_ip_address_new (AF_INET, "2.2.2.5", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - f = _svOpenFile (testfile); - _svGetValue_check (f, "IPADDR", "1.1.1.3"); - _svGetValue_check (f, "IPADDR1", "2.2.2.5"); - _svGetValue_check (f, "IPADDR0", NULL); - _svGetValue_check (f, "PREFIX", "24"); - _svGetValue_check (f, "PREFIX1", "24"); - _svGetValue_check (f, "PREFIX0", NULL); - _svGetValue_check (f, "GATEWAY", "1.1.1.254"); - _svGetValue_check (f, "GATEWAY0", NULL); - _svGetValue_check (f, "GATEWAY1", NULL); - svCloseFile (f); - - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_write_wifi_open (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GBytes *ssid; - const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; - shvarFile *ifcfg; + ifcfg = _svOpenFile(testfile); + _svGetValue_check(ifcfg, "ESSID", "Test SSID"); + svCloseFile(ifcfg); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_open_hex_ssid(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GBytes * ssid; + const unsigned char ssid_data[] = + {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd}; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi Open Hex SSID", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, sizeof(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + + g_bytes_unref(ssid); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); - connection = nm_simple_connection_new (); + nmtst_assert_connection_verifies(connection); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi Open", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_BSSID, "11:22:33:44:55:66", - NM_SETTING_WIRELESS_MAC_ADDRESS, "aa:bb:cc:dd:ee:ff", - NM_SETTING_WIRELESS_MODE, "infrastructure", - NM_SETTING_WIRELESS_BAND, "bg", - NM_SETTING_WIRELESS_CHANNEL, (guint32) 9, - NM_SETTING_WIRELESS_MTU, (guint32) 1345, - NULL); +static void +test_write_wifi_wep(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GBytes * ssid; + const char * ssid_data = "blahblah"; + struct stat statbuf; - g_bytes_unref (ssid); + connection = nm_simple_connection_new(); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi WEP", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + + g_bytes_unref(ssid); + + /* Wireless 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, + "none", + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, + 2, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "shared", + NULL); + nm_setting_wireless_security_set_wep_key(s_wsec, 0, "0123456789abcdef0123456789"); + nm_setting_wireless_security_set_wep_key(s_wsec, 1, "11111111111111111111111111"); + nm_setting_wireless_security_set_wep_key(s_wsec, 2, "aaaaaaaaaaaaaaaaaaaaaaaaaa"); + nm_setting_wireless_security_set_wep_key(s_wsec, 3, "BBBBBBBBBBBBBBBBBBBBBBBBBB"); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + keyfile = utils_get_keys_path(testfile); + g_assert_cmpint(stat(keyfile, &statbuf), ==, 0); + g_assert(S_ISREG(statbuf.st_mode)); + g_assert_cmpint((statbuf.st_mode & 0077), ==, 0); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} - nmtst_assert_connection_verifies (connection); +static void +test_write_wifi_wep_adhoc(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GError * error = NULL; + GBytes * ssid; + const char * ssid_data = "blahblah"; + struct stat statbuf; + NMIPAddress * addr; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi WEP AdHoc", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "adhoc", NULL); + + g_bytes_unref(ssid); + + /* Wireless 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, "none", NULL); + nm_setting_wireless_security_set_wep_key(s_wsec, 0, "0123456789abcdef0123456789"); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NULL); + + /* IP Address */ + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + nm_setting_ip_config_add_dns(s_ip4, "4.2.2.1"); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); - ifcfg = _svOpenFile (testfile); - _svGetValue_check (ifcfg, "ESSID", "Test SSID"); - svCloseFile (ifcfg); + keyfile = utils_get_keys_path(testfile); + g_assert_cmpint(stat(keyfile, &statbuf), ==, 0); + g_assert(S_ISREG(statbuf.st_mode)); + g_assert_cmpint((statbuf.st_mode & 0077), ==, 0); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_write_wifi_open_hex_ssid (void) +test_write_wifi_wep_passphrase(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GBytes *ssid; - const unsigned char ssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd }; + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GBytes * ssid; + const char * ssid_data = "blahblah"; + struct stat statbuf; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi WEP Passphrase", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + + g_bytes_unref(ssid); + + /* Wireless 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, + "none", + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, + 0, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "shared", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + NM_WEP_KEY_TYPE_PASSPHRASE, + NULL); + nm_setting_wireless_security_set_wep_key(s_wsec, 0, "asdfdjaslfjasd;flasjdfl;aksdf"); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + keyfile = utils_get_keys_path(testfile); + g_assert_cmpint(stat(keyfile, &statbuf), ==, 0); + g_assert(S_ISREG(statbuf.st_mode)); + g_assert_cmpint((statbuf.st_mode & 0077), ==, 0); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_wep_40_ascii(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GBytes * ssid; + const char * ssid_data = "blahblah40"; + struct stat statbuf; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi WEP 40 ASCII", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + + g_bytes_unref(ssid); + + /* Wireless 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, + "none", + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, + 2, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + NM_WEP_KEY_TYPE_KEY, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "shared", + NULL); + nm_setting_wireless_security_set_wep_key(s_wsec, 0, "lorem"); + nm_setting_wireless_security_set_wep_key(s_wsec, 1, "ipsum"); + nm_setting_wireless_security_set_wep_key(s_wsec, 2, "dolor"); + nm_setting_wireless_security_set_wep_key(s_wsec, 3, "donec"); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + keyfile = utils_get_keys_path(testfile); + g_assert_cmpint(stat(keyfile, &statbuf), ==, 0); + g_assert(S_ISREG(statbuf.st_mode)); + g_assert_cmpint((statbuf.st_mode & 0077), ==, 0); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_wep_104_ascii(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GBytes * ssid; + const char * ssid_data = "blahblah104"; + struct stat statbuf; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi WEP 104 ASCII", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + + g_bytes_unref(ssid); + + /* Wireless 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, + "none", + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, + 0, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + NM_WEP_KEY_TYPE_UNKNOWN, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", + NULL); + nm_setting_wireless_security_set_wep_key(s_wsec, 0, "LoremIpsumSit"); + nm_setting_wireless_security_set_wep_key(s_wsec, 1, "AlfaBetaGamma"); + nm_setting_wireless_security_set_wep_key(s_wsec, 2, "WEP-104 ASCII"); + nm_setting_wireless_security_set_wep_key(s_wsec, 3, "thisismyascii"); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Wifi_WEP_104_ASCII.cexpected", + &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + keyfile = utils_get_keys_path(testfile); + g_assert_cmpint(stat(keyfile, &statbuf), ==, 0); + g_assert(S_ISREG(statbuf.st_mode)); + g_assert_cmpint((statbuf.st_mode & 0077), ==, 0); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_leap(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GBytes * ssid; + const char * ssid_data = "blahblah"; + struct stat statbuf; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi LEAP", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + + g_bytes_unref(ssid); + + /* Wireless 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, + "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "leap", + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "Bill Smith", + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, + "foobar22", + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Wifi_LEAP.cexpected", + &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + keyfile = utils_get_keys_path(testfile); + g_assert_cmpint(stat(keyfile, &statbuf), ==, 0); + g_assert(S_ISREG(statbuf.st_mode)); + g_assert_cmpint((statbuf.st_mode & 0077), ==, 0); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_leap_secret_flags(gconstpointer data) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_free char * keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GBytes * ssid; + const char * ssid_data = "blahblah"; + NMSettingSecretFlags flags = GPOINTER_TO_UINT(data); + + connection = nm_simple_connection_new(); + g_assert(connection); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi LEAP Secret Flags", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + g_bytes_unref(ssid); + + /* Wireless 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, + "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "leap", + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "Bill Smith", + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, + "foobar22", + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, + flags, + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection_FIXME(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + /* No key should be written out since the secret is not system owned */ + keyfile = utils_get_keys_path(testfile); + g_assert(g_file_test(keyfile, G_FILE_TEST_EXISTS) == FALSE); + + /* Remove the LEAP password from the original connection since it wont' be + * in the reread connection, as the password is not system owned. + */ + g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, NULL, NULL); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_wpa_psk(gconstpointer test_data) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GBytes * ssid; + const char * ssid_data = "blahblah"; + struct { + const char *name, *psk; + gpointer wep_group_p, wpa_p, wpa2_p; + } args; + + nmtst_test_data_unpack(test_data, + &args.name, + &args.wep_group_p, + &args.wpa_p, + &args.wpa2_p, + &args.psk); + + g_assert(args.psk); + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + args.name, + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + + g_bytes_unref(ssid); + + /* Wireless 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, + args.psk, + NM_SETTING_WIRELESS_SECURITY_PMF, + (int) NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED, + NULL); + + if (GPOINTER_TO_INT(args.wep_group_p)) { + nm_setting_wireless_security_add_group(s_wsec, "wep40"); + nm_setting_wireless_security_add_group(s_wsec, "wep104"); + } + if (GPOINTER_TO_INT(args.wpa_p)) { + nm_setting_wireless_security_add_proto(s_wsec, "wpa"); + nm_setting_wireless_security_add_pairwise(s_wsec, "tkip"); + nm_setting_wireless_security_add_group(s_wsec, "tkip"); + } + if (GPOINTER_TO_INT(args.wpa2_p)) { + nm_setting_wireless_security_add_proto(s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise(s_wsec, "ccmp"); + nm_setting_wireless_security_add_group(s_wsec, "ccmp"); + } + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + keyfile = utils_get_keys_path(testfile); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_wpa_psk_adhoc(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GError * error = NULL; + GBytes * ssid; + const char * ssid_data = "blahblah"; + NMIPAddress * addr; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi WPA PSK", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "adhoc", + NM_SETTING_WIRELESS_CHANNEL, + 11, + NM_SETTING_WIRELESS_BAND, + "bg", + NULL); + + g_bytes_unref(ssid); + + /* Wireless 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, + "7d308b11df1b4243b0f78e5f3fc68cdbb9a264ed0edf4c188edf329ff5b467f0", + NULL); + + nm_setting_wireless_security_add_proto(s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise(s_wsec, "ccmp"); + nm_setting_wireless_security_add_group(s_wsec, "ccmp"); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NULL); + + /* IP Address */ + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 25, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + nm_setting_ip_config_add_dns(s_ip4, "4.2.2.1"); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + keyfile = utils_get_keys_path(testfile); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_wpa_eap_tls(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSetting8021x * s_8021x; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + gboolean success; + GError * error = NULL; + GBytes * ssid; + const char * ssid_data = "blahblah"; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi WPA EAP-TLS", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + + g_bytes_unref(ssid); + + /* Wireless 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-eap", + NM_SETTING_WIRELESS_SECURITY_FILS, + (int) NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED, + NULL); + nm_setting_wireless_security_add_proto(s_wsec, "wpa"); + nm_setting_wireless_security_add_pairwise(s_wsec, "tkip"); + nm_setting_wireless_security_add_group(s_wsec, "tkip"); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + g_object_set(s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + g_object_set(s_8021x, + NM_SETTING_802_1X_PHASE1_AUTH_FLAGS, + (guint)(NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_0_DISABLE + | NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_1_DISABLE), + NULL); + + nm_setting_802_1x_add_eap_method(s_8021x, "tls"); + + success = nm_setting_802_1x_set_ca_cert(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + nmtst_assert_success(success, error); + + success = nm_setting_802_1x_set_client_cert(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + nmtst_assert_success(success, error); + + success = nm_setting_802_1x_set_private_key(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, + "test1", + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + nmtst_assert_success(success, error); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + keyfile = utils_get_keys_path(testfile); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_wpa_eap_ttls_tls(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSetting8021x * s_8021x; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + gboolean success; + GError * error = NULL; + GBytes * ssid; + const char * ssid_data = "blahblah"; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi WPA EAP-TTLS (TLS)", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + + g_bytes_unref(ssid); + + /* Wireless 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-eap", NULL); + nm_setting_wireless_security_add_proto(s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise(s_wsec, "ccmp"); + nm_setting_wireless_security_add_group(s_wsec, "ccmp"); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + nm_setting_802_1x_add_eap_method(s_8021x, "ttls"); + + g_object_set(s_8021x, + NM_SETTING_802_1X_IDENTITY, + "Bill Smith", + NM_SETTING_802_1X_ANONYMOUS_IDENTITY, + "foobar22", + NM_SETTING_802_1X_PHASE2_AUTHEAP, + "tls", + NULL); + + success = nm_setting_802_1x_set_ca_cert(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + nmtst_assert_success(success, error); + + /* Phase 2 TLS stuff */ + + /* phase2 CA cert */ + success = nm_setting_802_1x_set_phase2_ca_cert(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + nmtst_assert_success(success, error); + + /* phase2 client cert */ + success = nm_setting_802_1x_set_phase2_client_cert(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + nmtst_assert_success(success, error); + + /* phase2 private key */ + success = nm_setting_802_1x_set_phase2_private_key(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, + "test1", + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + nmtst_assert_success(success, error); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + keyfile = utils_get_keys_path(testfile); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_wpa_eap_ttls_mschapv2(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSetting8021x * s_8021x; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + gboolean success; + GError * error = NULL; + GBytes * ssid; + const char * ssid_data = "blahblah"; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi WPA EAP-TTLS (MSCHAPv2)", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + + g_bytes_unref(ssid); + + /* Wireless 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-eap", NULL); + nm_setting_wireless_security_add_proto(s_wsec, "wpa"); + nm_setting_wireless_security_add_proto(s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise(s_wsec, "tkip"); + nm_setting_wireless_security_add_pairwise(s_wsec, "ccmp"); + nm_setting_wireless_security_add_group(s_wsec, "tkip"); + nm_setting_wireless_security_add_group(s_wsec, "ccmp"); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + nm_setting_802_1x_add_eap_method(s_8021x, "ttls"); + + g_object_set(s_8021x, + NM_SETTING_802_1X_IDENTITY, + "Bill Smith", + NM_SETTING_802_1X_PASSWORD, + ";alkdfja;dslkfjsad;lkfjsadf", + NM_SETTING_802_1X_ANONYMOUS_IDENTITY, + "foobar22", + NM_SETTING_802_1X_PHASE2_AUTHEAP, + "mschapv2", + NULL); + + success = nm_setting_802_1x_set_ca_cert(s_8021x, + TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error); + nmtst_assert_success(success, error); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); + + keyfile = utils_get_keys_path(testfile); +} + +static void +test_write_wifi_wpa_then_open(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_free char * keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GBytes * ssid; + const char * ssid_data = "blahblah"; - connection = nm_simple_connection_new (); + /* Test that writing out a WPA config then changing that to an open + * config doesn't leave various WPA-related keys lying around in the ifcfg. + */ - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + connection = nm_simple_connection_new(); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi Open Hex SSID", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "random wifi connection", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); + + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + + g_bytes_unref(ssid); + + /* Wireless 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, + "some cool PSK", + NULL); + + nm_setting_wireless_security_add_proto(s_wsec, "wpa"); + nm_setting_wireless_security_add_pairwise(s_wsec, "tkip"); + nm_setting_wireless_security_add_group(s_wsec, "tkip"); + + nm_setting_wireless_security_add_proto(s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise(s_wsec, "ccmp"); + nm_setting_wireless_security_add_group(s_wsec, "ccmp"); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); + + g_object_unref(reread); + + nmtst_connection_normalize(connection); + + /* Now change the connection to open and recheck */ + nm_connection_remove_setting(connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + + /* Write it back out */ + _writer_update_connection(connection, + TEST_SCRATCH_DIR, + testfile, + TEST_IFCFG_DIR "/ifcfg-random_wifi_connection.cexpected"); + keyfile = utils_get_keys_path(testfile); + g_assert(!g_file_test(keyfile, G_FILE_TEST_EXISTS)); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wifi_wpa_then_wep_with_perms(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + gboolean success; + GBytes * ssid; + char ** perms; + const char * ssid_data = "SomeSSID"; + + /* Test that writing out a WPA config then changing that to a WEP + * config works and doesn't cause infinite loop or other issues. + */ - ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); + connection = nm_simple_connection_new(); + g_assert(connection); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + perms = g_strsplit("user:superman:", ",", -1); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "random wifi connection 2", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_PERMISSIONS, + perms, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_strfreev(perms); + g_assert_cmpint(nm_setting_connection_get_num_permissions(s_con), ==, 1); - g_bytes_unref (ssid); + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_bytes_unref(ssid); + + /* Wireless 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, + "My cool PSK", + NULL); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + nm_setting_wireless_security_add_proto(s_wsec, "wpa"); + nm_setting_wireless_security_add_pairwise(s_wsec, "tkip"); + nm_setting_wireless_security_add_group(s_wsec, "tkip"); - nmtst_assert_connection_verifies (connection); + nm_setting_wireless_security_add_proto(s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise(s_wsec, "ccmp"); + nm_setting_wireless_security_add_group(s_wsec, "ccmp"); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); + + g_object_unref(reread); + + nmtst_connection_normalize(connection); + + /* Now change the connection to WEP and recheck */ + 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, "none", NULL); + nm_setting_wireless_security_set_wep_key(s_wsec, 0, "abraka dabra"); + + /* Write it back out */ + _writer_update_connection(connection, + TEST_SCRATCH_DIR, + testfile, + TEST_IFCFG_DIR "/ifcfg-random_wifi_connection_2.cexpected"); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + nmtst_connection_normalize(connection); + success = nm_connection_compare(connection, + reread, + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS + | NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS); + g_assert(success); + + keyfile = utils_get_keys_path(testfile); +} + +static void +test_write_wifi_dynamic_wep_leap(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + nmtst_auto_unlinkfile char *keyfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSetting8021x * s_8021x; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GBytes * ssid; + const char * ssid_data = "blahblah"; + shvarFile * ifcfg; - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + connection = nm_simple_connection_new(); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi Dynamic WEP LEAP", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); -static void -test_write_wifi_wep (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GBytes *ssid; - const char *ssid_data = "blahblah"; - struct stat statbuf; + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - connection = nm_simple_connection_new (); + ssid = g_bytes_new(ssid_data, strlen(ssid_data)); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + g_bytes_unref(ssid); - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wsec)); - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); + g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); - g_bytes_unref (ssid); + nm_setting_802_1x_add_eap_method(s_8021x, "leap"); - /* Wireless security setting */ - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + g_object_set(s_8021x, + NM_SETTING_802_1X_IDENTITY, + "Bill Smith", + NM_SETTING_802_1X_PASSWORD, + ";alkdfja;dslkfjsad;lkfjsadf", + NULL); - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", - NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 2, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", - NULL); - nm_setting_wireless_security_set_wep_key (s_wsec, 0, "0123456789abcdef0123456789"); - nm_setting_wireless_security_set_wep_key (s_wsec, 1, "11111111111111111111111111"); - nm_setting_wireless_security_set_wep_key (s_wsec, 2, "aaaaaaaaaaaaaaaaaaaaaaaaaa"); - nm_setting_wireless_security_set_wep_key (s_wsec, 3, "BBBBBBBBBBBBBBBBBBBBBBBBBB"); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nmtst_assert_connection_verifies(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + keyfile = utils_get_keys_path(testfile); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); + + /* Check and make sure that an "old-school" LEAP (Network EAP) connection + * did not get written. Check first that the auth alg is not set to "LEAP" + * and next that the only IEEE 802.1x EAP method is "LEAP". + */ + ifcfg = _svOpenFile(testfile); + _svGetValue_check(ifcfg, "SECURITYMODE", NULL); + _svGetValue_check(ifcfg, "IEEE_8021X_EAP_METHODS", "LEAP"); + svCloseFile(ifcfg); +} + +static void +test_write_wired_qeth_dhcp(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + char ** subchans; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired qeth Static", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + subchans = g_strsplit("0.0.600,0.0.601,0.0.602", ",", -1); + g_object_set(s_wired, + NM_SETTING_WIRED_S390_SUBCHANNELS, + subchans, + NM_SETTING_WIRED_S390_NETTYPE, + "qeth", + NULL); + g_strfreev(subchans); - nmtst_assert_connection_verifies (connection); + nm_setting_wired_add_s390_option(s_wired, "portname", "FOOBAR"); + nm_setting_wired_add_s390_option(s_wired, "portno", "1"); + nm_setting_wired_add_s390_option(s_wired, "layer2", "0"); + nm_setting_wired_add_s390_option(s_wired, "protocol", "blahbalh"); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - keyfile = utils_get_keys_path (testfile); - g_assert_cmpint (stat (keyfile, &statbuf), ==, 0); - g_assert (S_ISREG (statbuf.st_mode)); - g_assert_cmpint ((statbuf.st_mode & 0077), ==, 0); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); -static void -test_write_wifi_wep_adhoc (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GError *error = NULL; - GBytes *ssid; - const char *ssid_data = "blahblah"; - struct stat statbuf; - NMIPAddress *addr; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + nmtst_assert_connection_verifies(connection); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP AdHoc", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "adhoc", - NULL); +static void +test_write_wired_ctc_dhcp(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + char ** subchans; + shvarFile * ifcfg; - g_bytes_unref (ssid); + connection = nm_simple_connection_new(); - /* Wireless security setting */ - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL); - nm_setting_wireless_security_set_wep_key (s_wsec, 0, "0123456789abcdef0123456789"); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired ctc Static", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + subchans = g_strsplit("0.0.600,0.0.601", ",", -1); + g_object_set(s_wired, + NM_SETTING_WIRED_S390_SUBCHANNELS, + subchans, + NM_SETTING_WIRED_S390_NETTYPE, + "ctc", + NULL); + g_strfreev(subchans); + nm_setting_wired_add_s390_option(s_wired, "ctcprot", "0"); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NULL); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - /* IP Address */ - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); - nm_setting_ip_config_add_dns (s_ip4, "4.2.2.1"); + nmtst_assert_connection_verifies(connection); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + /* Ensure the CTCPROT item gets written out as its own option */ + ifcfg = _svOpenFile(testfile); - nmtst_assert_connection_verifies (connection); + _svGetValue_check(ifcfg, "CTCPROT", "0"); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + /* And that it's not in the generic OPTIONS string */ + _svGetValue_check(ifcfg, "OPTIONS", NULL); - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + svCloseFile(ifcfg); - keyfile = utils_get_keys_path (testfile); - g_assert_cmpint (stat (keyfile, &statbuf), ==, 0); - g_assert (S_ISREG (statbuf.st_mode)); - g_assert_cmpint ((statbuf.st_mode & 0077), ==, 0); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_write_wifi_wep_passphrase (void) +test_write_permissions(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GBytes *ssid; - const char *ssid_data = "blahblah"; - struct stat statbuf; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - connection = nm_simple_connection_new (); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Permissions", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + nm_setting_connection_add_permission(s_con, "user", "blahblah", NULL); + nm_setting_connection_add_permission(s_con, "user", "foobar", NULL); + nm_setting_connection_add_permission(s_con, "user", "asdfasdf", NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + nmtst_assert_connection_verifies(connection); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Permissions.cexpected", + &testfile); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP Passphrase", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); +static void +test_write_wifi_wep_agent_keys(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + const char * str_ssid = "foobarbaz"; + GBytes * ssid; - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); + connection = nm_simple_connection_new(); + g_assert(connection != NULL); - g_bytes_unref (ssid); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wifi WEP Agent Owned", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(str_ssid, strlen(str_ssid)); + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + "infrastructure", + NULL); + g_bytes_unref(ssid); + + /* Wifi security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wsec)); - /* Wireless 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, + "none", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + NM_WEP_KEY_TYPE_PASSPHRASE, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + NM_SETTING_SECRET_FLAG_AGENT_OWNED, + NULL); + nm_setting_wireless_security_set_wep_key(s_wsec, 0, "asdfdjaslfjasd;flasjdfl;aksdf"); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection_FIXME(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL); + + /* Remove the WEP key from the original, because it should not have been + * written out to disk as it was agent-owned. The new connection should + * not have any WEP keys set. + * Also the new connection should not have WEP key type set. + */ + nm_setting_wireless_security_set_wep_key(s_wsec, 0, NULL); + g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_UNKNOWN, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_write_wired_pppoe(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingPppoe * s_pppoe; + NMSettingPpp * s_ppp; + GError * error = NULL; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Wired PPPoE", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", - NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 0, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", - NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_PASSPHRASE, - NULL); - nm_setting_wireless_security_set_wep_key (s_wsec, 0, "asdfdjaslfjasd;flasjdfl;aksdf"); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + /* PPPoE setting */ + s_pppoe = (NMSettingPppoe *) nm_setting_pppoe_new(); + nm_connection_add_setting(connection, NM_SETTING(s_pppoe)); + + g_object_set(G_OBJECT(s_pppoe), + NM_SETTING_PPPOE_SERVICE, + "stupid-service", + NM_SETTING_PPPOE_USERNAME, + "Bill Smith", + NM_SETTING_PPPOE_PASSWORD, + "test1", + NULL); + + /* PPP setting */ + s_ppp = (NMSettingPpp *) nm_setting_ppp_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ppp)); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection_fail(connection, TEST_SCRATCH_DIR, NULL); + + g_object_unref(connection); + g_clear_error(&error); +} + +static void +test_write_vpn(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4; + NMSettingVpn * s_vpn; + GError * error = NULL; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write VPN", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_VPN_SETTING_NAME, + NULL); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + /* VPN setting */ + s_vpn = (NMSettingVpn *) nm_setting_vpn_new(); + nm_connection_add_setting(connection, NM_SETTING(s_vpn)); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_object_set(s_vpn, + NM_SETTING_VPN_SERVICE_TYPE, + "awesomevpn", + NM_SETTING_VPN_USER_NAME, + "Bill Smith", + NULL); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + nm_setting_vpn_add_data_item(s_vpn, "server", "vpn.somewhere.com"); + nm_setting_vpn_add_secret(s_vpn, "password", "sup3rs3cr3t"); - nmtst_assert_connection_verifies (connection); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + nmtst_assert_connection_verifies(connection); - keyfile = utils_get_keys_path (testfile); - g_assert_cmpint (stat (keyfile, &statbuf), ==, 0); - g_assert (S_ISREG (statbuf.st_mode)); - g_assert_cmpint ((statbuf.st_mode & 0077), ==, 0); + _writer_new_connection_fail(connection, TEST_SCRATCH_DIR, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_object_unref(connection); + g_clear_error(&error); } -static void -test_write_wifi_wep_40_ascii (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GBytes *ssid; - const char *ssid_data = "blahblah40"; - struct stat statbuf; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP 40 ASCII", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); +static void +test_write_mobile_broadband(gconstpointer data) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4; + NMSettingGsm * s_gsm; + NMSettingCdma * s_cdma; + NMSettingPpp * s_ppp; + NMSettingSerial * s_serial; + GError * error = NULL; + gboolean gsm = GPOINTER_TO_UINT(data); + + connection = nm_simple_connection_new(); - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + gsm ? "Test Write GSM" : "Test Write CDMA", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + gsm ? NM_SETTING_GSM_SETTING_NAME : NM_SETTING_CDMA_SETTING_NAME, + NULL); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); + if (gsm) { + /* GSM setting */ + s_gsm = (NMSettingGsm *) nm_setting_gsm_new(); + nm_connection_add_setting(connection, NM_SETTING(s_gsm)); + } else { + /* CDMA setting */ + s_cdma = (NMSettingCdma *) nm_setting_cdma_new(); + nm_connection_add_setting(connection, NM_SETTING(s_cdma)); - g_bytes_unref (ssid); + g_object_set(s_cdma, NM_SETTING_CDMA_NUMBER, "#777", NULL); + } + + /* Serial setting */ + s_serial = (NMSettingSerial *) nm_setting_serial_new(); + nm_connection_add_setting(connection, NM_SETTING(s_serial)); + + g_object_set(s_serial, + NM_SETTING_SERIAL_BAUD, + 115200, + NM_SETTING_SERIAL_BITS, + 8, + NM_SETTING_SERIAL_PARITY, + NM_SETTING_SERIAL_PARITY_NONE, + NM_SETTING_SERIAL_STOPBITS, + 1, + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + /* PPP setting */ + s_ppp = (NMSettingPpp *) nm_setting_ppp_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ppp)); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connection_fail(connection, TEST_SCRATCH_DIR, NULL); + + g_object_unref(connection); + g_clear_error(&error); +} + +static void +test_read_bridge_main(void) +{ + NMConnection * connection; + NMSettingBridge *s_bridge; + NMSettingWired * s_wired; + const char * mac; + char expected_mac_address[ETH_ALEN] = {0x00, 0x16, 0x41, 0x11, 0x22, 0x33}; + + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-bridge-main", NULL, TYPE_ETHERNET, NULL); + + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "br0"); + + /* ===== Bridging SETTING ===== */ + + s_bridge = nm_connection_get_setting_bridge(connection); + g_assert(s_bridge); + g_assert_cmpuint(nm_setting_bridge_get_forward_delay(s_bridge), ==, 2); + g_assert(nm_setting_bridge_get_stp(s_bridge)); + g_assert_cmpuint(nm_setting_bridge_get_priority(s_bridge), ==, 32744); + g_assert_cmpuint(nm_setting_bridge_get_hello_time(s_bridge), ==, 7); + g_assert_cmpuint(nm_setting_bridge_get_max_age(s_bridge), ==, 39); + g_assert_cmpuint(nm_setting_bridge_get_ageing_time(s_bridge), ==, 235352); + g_assert_cmpuint(nm_setting_bridge_get_group_forward_mask(s_bridge), ==, 24); + g_assert(!nm_setting_bridge_get_multicast_snooping(s_bridge)); + g_assert_cmpint(nm_setting_bridge_get_vlan_filtering(s_bridge), ==, TRUE); + g_assert_cmpint(nm_setting_bridge_get_vlan_default_pvid(s_bridge), ==, 99); + + /* MAC address */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + mac = nm_setting_wired_get_cloned_mac_address(s_wired); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, ETH_ALEN)); + + g_object_unref(connection); +} + +static void +test_write_bridge_main(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingBridge * s_bridge; + NMSettingIPConfig * s_ip4, *s_ip6; + NMSettingWired * s_wired; + NMIPAddress * addr; + static const char * mac = "31:33:33:37:be:cd"; + GError * error = NULL; + gs_unref_ptrarray GPtrArray *vlans = NULL; + NMBridgeVlan * vlan; + + connection = nm_simple_connection_new(); + g_assert(connection); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Bridge Main", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_INTERFACE_NAME, + "br0", + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_BRIDGE_SETTING_NAME, + NULL); + + /* bridge setting */ + s_bridge = (NMSettingBridge *) nm_setting_bridge_new(); + nm_connection_add_setting(connection, NM_SETTING(s_bridge)); + + vlans = g_ptr_array_new_with_free_func((GDestroyNotify) nm_bridge_vlan_unref); + vlan = nm_bridge_vlan_new(10, 16); + nm_bridge_vlan_set_untagged(vlan, TRUE); + g_ptr_array_add(vlans, vlan); + vlan = nm_bridge_vlan_new(22, 22); + nm_bridge_vlan_set_pvid(vlan, TRUE); + nm_bridge_vlan_set_untagged(vlan, TRUE); + g_ptr_array_add(vlans, vlan); + vlan = nm_bridge_vlan_new(44, 0); + g_ptr_array_add(vlans, vlan); + + g_object_set(s_bridge, + NM_SETTING_BRIDGE_MAC_ADDRESS, + mac, + NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, + 19008, + NM_SETTING_BRIDGE_VLAN_FILTERING, + TRUE, + NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, + 4000, + NM_SETTING_BRIDGE_VLANS, + vlans, + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + nm_connection_add_setting(connection, nm_setting_proxy_new()); + + nmtst_assert_connection_verifies_without_normalization(connection); + + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_BRIDGE, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_read_bridge_component(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingBridgePort *s_port; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-bridge-component", + NULL, + TYPE_ETHERNET, + NULL); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, "br0"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_BRIDGE_SETTING_NAME); + + s_port = nm_connection_get_setting_bridge_port(connection); + g_assert(s_port); + g_assert(nm_setting_bridge_port_get_hairpin_mode(s_port)); + g_assert_cmpuint(nm_setting_bridge_port_get_priority(s_port), ==, 28); + g_assert_cmpuint(nm_setting_bridge_port_get_path_cost(s_port), ==, 100); + + g_object_unref(connection); +} + +static void +test_write_bridge_component(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSetting * s_port; + static const char * mac = "31:33:33:37:be:cd"; + guint32 mtu = 1492; + gs_unref_ptrarray GPtrArray *vlans = NULL; + NMBridgeVlan * vlan; - /* Wireless security setting */ - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + connection = nm_simple_connection_new(); + g_assert(connection); - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", - NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 2, - NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_KEY, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", - NULL); - nm_setting_wireless_security_set_wep_key (s_wsec, 0, "lorem"); - nm_setting_wireless_security_set_wep_key (s_wsec, 1, "ipsum"); - nm_setting_wireless_security_set_wep_key (s_wsec, 2, "dolor"); - nm_setting_wireless_security_set_wep_key (s_wsec, 3, "donec"); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Bridge Component", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_MASTER, + "br0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BRIDGE_SETTING_NAME, + NULL); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, mtu, NULL); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + /* Bridge port */ + vlans = g_ptr_array_new_with_free_func((GDestroyNotify) nm_bridge_vlan_unref); + vlan = nm_bridge_vlan_new(1, 0); + nm_bridge_vlan_set_untagged(vlan, TRUE); + g_ptr_array_add(vlans, vlan); + vlan = nm_bridge_vlan_new(4, 4094); + nm_bridge_vlan_set_untagged(vlan, TRUE); + g_ptr_array_add(vlans, vlan); + vlan = nm_bridge_vlan_new(2, 2); + nm_bridge_vlan_set_pvid(vlan, TRUE); + g_ptr_array_add(vlans, vlan); - nmtst_assert_connection_verifies (connection); + s_port = nm_setting_bridge_port_new(); + nm_connection_add_setting(connection, s_port); + g_object_set(s_port, + NM_SETTING_BRIDGE_PORT_PRIORITY, + 50, + NM_SETTING_BRIDGE_PORT_PATH_COST, + 33, + NM_SETTING_BRIDGE_PORT_VLANS, + vlans, + NULL); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + nmtst_assert_connection_verifies(connection); - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Bridge_Component.cexpected", + &testfile); - keyfile = utils_get_keys_path (testfile); - g_assert_cmpint (stat (keyfile, &statbuf), ==, 0); - g_assert (S_ISREG (statbuf.st_mode)); - g_assert_cmpint ((statbuf.st_mode & 0077), ==, 0); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_write_wifi_wep_104_ascii (void) +test_read_bridge_missing_stp(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GBytes *ssid; - const char *ssid_data = "blahblah104"; - struct stat statbuf; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP 104 ASCII", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + NMConnection * connection; + NMSettingBridge *s_bridge; - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-bridge-missing-stp", + NULL, + TYPE_BRIDGE, + NULL); - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "br0"); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); + /* ===== Bridging SETTING ===== */ - g_bytes_unref (ssid); + s_bridge = nm_connection_get_setting_bridge(connection); + g_assert(s_bridge); + g_assert(nm_setting_bridge_get_stp(s_bridge) == FALSE); - /* Wireless security setting */ - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + g_object_unref(connection); +} - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", - NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 0, - NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_UNKNOWN, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", - NULL); - nm_setting_wireless_security_set_wep_key (s_wsec, 0, "LoremIpsumSit"); - nm_setting_wireless_security_set_wep_key (s_wsec, 1, "AlfaBetaGamma"); - nm_setting_wireless_security_set_wep_key (s_wsec, 2, "WEP-104 ASCII"); - nm_setting_wireless_security_set_wep_key (s_wsec, 3, "thisismyascii"); +#define TEST_IFCFG_VLAN_INTERFACE TEST_IFCFG_DIR "/ifcfg-test-vlan-interface" - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); +static void +test_read_vlan_interface(void) +{ + NMConnection * connection; + NMSettingVlan *s_vlan; + guint32 from = 0, to = 0; - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + connection = _connection_from_file(TEST_IFCFG_VLAN_INTERFACE, NULL, TYPE_ETHERNET, NULL); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "vlan43"); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); - nmtst_assert_connection_verifies (connection); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth9"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 43); + g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), + ==, + NM_VLAN_FLAG_GVRP | NM_VLAN_FLAG_LOOSE_BINDING | NM_VLAN_FLAG_REORDER_HEADERS); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Wifi_WEP_104_ASCII.cexpected", - &testfile); + /* Ingress map */ + g_assert_cmpint(nm_setting_vlan_get_num_priorities(s_vlan, NM_VLAN_INGRESS_MAP), ==, 2); - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + g_assert(nm_setting_vlan_get_priority(s_vlan, NM_VLAN_INGRESS_MAP, 0, &from, &to)); + g_assert_cmpint(from, ==, 0); + g_assert_cmpint(to, ==, 1); - keyfile = utils_get_keys_path (testfile); - g_assert_cmpint (stat (keyfile, &statbuf), ==, 0); - g_assert (S_ISREG (statbuf.st_mode)); - g_assert_cmpint ((statbuf.st_mode & 0077), ==, 0); + g_assert(nm_setting_vlan_get_priority(s_vlan, NM_VLAN_INGRESS_MAP, 1, &from, &to)); + g_assert_cmpint(from, ==, 2); + g_assert_cmpint(to, ==, 5); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} + /* Egress map */ + g_assert_cmpint(nm_setting_vlan_get_num_priorities(s_vlan, NM_VLAN_EGRESS_MAP), ==, 3); -static void -test_write_wifi_leap (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GBytes *ssid; - const char *ssid_data = "blahblah"; - struct stat statbuf; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi LEAP", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + g_assert(nm_setting_vlan_get_priority(s_vlan, NM_VLAN_EGRESS_MAP, 0, &from, &to)); + g_assert_cmpint(from, ==, 3); + g_assert_cmpint(to, ==, 1); - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); - - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); - - g_bytes_unref (ssid); - - /* Wireless 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, "ieee8021x", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", - NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", - NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "foobar22", - NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_assert(nm_setting_vlan_get_priority(s_vlan, NM_VLAN_EGRESS_MAP, 1, &from, &to)); + g_assert_cmpint(from, ==, 12); + g_assert_cmpint(to, ==, 3); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + g_assert(nm_setting_vlan_get_priority(s_vlan, NM_VLAN_EGRESS_MAP, 2, &from, &to)); + g_assert_cmpint(from, ==, 14); + g_assert_cmpint(to, ==, 7); - nmtst_assert_connection_verifies (connection); + g_object_unref(connection); +} - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Wifi_LEAP.cexpected", - &testfile); +#define TEST_IFCFG_VLAN_ONLY_VLANID TEST_IFCFG_DIR "/ifcfg-test-vlan-only-vlanid" - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); +static void +test_read_vlan_only_vlan_id(void) +{ + NMConnection * connection; + NMSettingVlan *s_vlan; - keyfile = utils_get_keys_path (testfile); - g_assert_cmpint (stat (keyfile, &statbuf), ==, 0); - g_assert (S_ISREG (statbuf.st_mode)); - g_assert_cmpint ((statbuf.st_mode & 0077), ==, 0); + connection = _connection_from_file(TEST_IFCFG_VLAN_ONLY_VLANID, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_write_wifi_leap_secret_flags (gconstpointer data) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_free char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GBytes *ssid; - const char *ssid_data = "blahblah"; - NMSettingSecretFlags flags = GPOINTER_TO_UINT (data); - - connection = nm_simple_connection_new (); - g_assert (connection); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi LEAP Secret Flags", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); - - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); - g_bytes_unref (ssid); - - /* Wireless security setting */ - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + g_assert(nm_connection_get_interface_name(connection) == NULL); - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", - NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", - NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "foobar22", - NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, flags, - NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection_FIXME (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); - - /* No key should be written out since the secret is not system owned */ - keyfile = utils_get_keys_path (testfile); - g_assert (g_file_test (keyfile, G_FILE_TEST_EXISTS) == FALSE); - - /* Remove the LEAP password from the original connection since it wont' be - * in the reread connection, as the password is not system owned. - */ - g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, NULL, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_write_wifi_wpa_psk (gconstpointer test_data) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GBytes *ssid; - const char *ssid_data = "blahblah"; - struct { - const char *name, *psk; - gpointer wep_group_p, wpa_p, wpa2_p; - } args; - - nmtst_test_data_unpack (test_data, &args.name, &args.wep_group_p, &args.wpa_p, &args.wpa2_p, &args.psk); - - g_assert (args.psk); - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, args.name, - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); - - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); - - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); - - g_bytes_unref (ssid); - - /* Wireless 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, args.psk, - NM_SETTING_WIRELESS_SECURITY_PMF, (int) NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED, - NULL); - - if (GPOINTER_TO_INT (args.wep_group_p)) { - nm_setting_wireless_security_add_group (s_wsec, "wep40"); - nm_setting_wireless_security_add_group (s_wsec, "wep104"); - } - if (GPOINTER_TO_INT (args.wpa_p)) { - nm_setting_wireless_security_add_proto (s_wsec, "wpa"); - nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); - nm_setting_wireless_security_add_group (s_wsec, "tkip"); - } - if (GPOINTER_TO_INT (args.wpa2_p)) { - nm_setting_wireless_security_add_proto (s_wsec, "rsn"); - nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); - nm_setting_wireless_security_add_group (s_wsec, "ccmp"); - } - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); - keyfile = utils_get_keys_path (testfile); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth9"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 43); + g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_object_unref(connection); } static void -test_write_wifi_wpa_psk_adhoc (void) +test_read_vlan_only_device(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GError *error = NULL; - GBytes *ssid; - const char *ssid_data = "blahblah"; - NMIPAddress *addr; + NMConnection * connection; + NMSettingVlan *s_vlan; - connection = nm_simple_connection_new (); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-vlan-only-device", + NULL, + TYPE_ETHERNET, + NULL); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "eth0.9"); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA PSK", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); - - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth0"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 9); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "adhoc", - NM_SETTING_WIRELESS_CHANNEL, 11, - NM_SETTING_WIRELESS_BAND, "bg", - NULL); - - g_bytes_unref (ssid); + g_object_unref(connection); +} - /* Wireless 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, "7d308b11df1b4243b0f78e5f3fc68cdbb9a264ed0edf4c188edf329ff5b467f0", - NULL); - - nm_setting_wireless_security_add_proto (s_wsec, "rsn"); - nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); - nm_setting_wireless_security_add_group (s_wsec, "ccmp"); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NULL); +static void +test_read_vlan_physdev(void) +{ + NMConnection * connection; + NMSettingVlan *s_vlan; - /* IP Address */ - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 25, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-vlan-physdev", NULL, TYPE_ETHERNET, NULL); - nm_setting_ip_config_add_dns (s_ip4, "4.2.2.1"); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "vlan0.3"); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); - - keyfile = utils_get_keys_path (testfile); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_write_wifi_wpa_eap_tls (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSetting8021x *s_8021x; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - gboolean success; - GError *error = NULL; - GBytes *ssid; - const char *ssid_data = "blahblah"; + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth0"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 3); - connection = nm_simple_connection_new (); + g_object_unref(connection); +} - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); +static void +test_read_vlan_reorder_hdr_1(void) +{ + NMConnection * connection; + NMSettingVlan *s_vlan; - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TLS", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + NMTST_EXPECT_NM_WARN("*REORDER_HDR key is deprecated, use VLAN_FLAGS*"); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-vlan-reorder-hdr-1", + NULL, + TYPE_ETHERNET, + NULL); + g_test_assert_expected_messages(); - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "vlan0.3"); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); - g_bytes_unref (ssid); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth0"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 3); + /* Check that REORDER_HDR=0 is ignored */ + g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS); - /* Wireless 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-eap", - NM_SETTING_WIRELESS_SECURITY_FILS, (int) NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED, - NULL); - nm_setting_wireless_security_add_proto (s_wsec, "wpa"); - nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); - nm_setting_wireless_security_add_group (s_wsec, "tkip"); + g_object_unref(connection); +} - /* Wireless security setting */ - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); - g_object_set (s_8021x, - NM_SETTING_802_1X_PHASE1_AUTH_FLAGS, - (guint) (NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_0_DISABLE | - NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_1_DISABLE), - NULL); +static void +test_read_vlan_reorder_hdr_2(void) +{ + NMConnection * connection; + NMSettingVlan *s_vlan; - nm_setting_802_1x_add_eap_method (s_8021x, "tls"); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-vlan-reorder-hdr-2", + NULL, + TYPE_ETHERNET, + NULL); - success = nm_setting_802_1x_set_ca_cert (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error); - nmtst_assert_success (success, error); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "vlan0.3"); - success = nm_setting_802_1x_set_client_cert (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error); - nmtst_assert_success (success, error); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); - success = nm_setting_802_1x_set_private_key (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, - "test1", - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error); - nmtst_assert_success (success, error); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); - - keyfile = utils_get_keys_path (testfile); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_write_wifi_wpa_eap_ttls_tls (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSetting8021x *s_8021x; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - gboolean success; - GError *error = NULL; - GBytes *ssid; - const char *ssid_data = "blahblah"; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TTLS (TLS)", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); - - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); - - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); - - g_bytes_unref (ssid); - - /* Wireless 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-eap", NULL); - nm_setting_wireless_security_add_proto (s_wsec, "rsn"); - nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); - nm_setting_wireless_security_add_group (s_wsec, "ccmp"); - - /* Wireless security setting */ - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - nm_setting_802_1x_add_eap_method (s_8021x, "ttls"); - - g_object_set (s_8021x, - NM_SETTING_802_1X_IDENTITY, "Bill Smith", - NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "foobar22", - NM_SETTING_802_1X_PHASE2_AUTHEAP, "tls", - NULL); - - success = nm_setting_802_1x_set_ca_cert (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error); - nmtst_assert_success (success, error); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth0"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 3); + /* Check that VLAN_FLAGS=NO_REORDER_HDR works */ + g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), ==, NM_VLAN_FLAG_LOOSE_BINDING); - /* Phase 2 TLS stuff */ + g_object_unref(connection); +} - /* phase2 CA cert */ - success = nm_setting_802_1x_set_phase2_ca_cert (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error); - nmtst_assert_success (success, error); - - /* phase2 client cert */ - success = nm_setting_802_1x_set_phase2_client_cert (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error); - nmtst_assert_success (success, error); - - /* phase2 private key */ - success = nm_setting_802_1x_set_phase2_private_key (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, - "test1", - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error); - nmtst_assert_success (success, error); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); - - keyfile = utils_get_keys_path (testfile); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_write_wifi_wpa_eap_ttls_mschapv2 (void) +static void +test_read_vlan_flags_1(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSetting8021x *s_8021x; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - gboolean success; - GError *error = NULL; - GBytes *ssid; - const char *ssid_data = "blahblah"; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TTLS (MSCHAPv2)", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); - - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); - - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); + NMConnection * connection; + NMSettingVlan *s_vlan; - g_bytes_unref (ssid); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-vlan-flags-1", NULL, TYPE_ETHERNET, NULL); - /* Wireless 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-eap", NULL); - nm_setting_wireless_security_add_proto (s_wsec, "wpa"); - nm_setting_wireless_security_add_proto (s_wsec, "rsn"); - nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); - nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); - nm_setting_wireless_security_add_group (s_wsec, "tkip"); - nm_setting_wireless_security_add_group (s_wsec, "ccmp"); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "super-vlan"); - /* Wireless security setting */ - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); - nm_setting_802_1x_add_eap_method (s_8021x, "ttls"); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth9"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 44); + g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), + ==, + NM_VLAN_FLAG_LOOSE_BINDING | NM_VLAN_FLAG_REORDER_HEADERS); - g_object_set (s_8021x, - NM_SETTING_802_1X_IDENTITY, "Bill Smith", - NM_SETTING_802_1X_PASSWORD, ";alkdfja;dslkfjsad;lkfjsadf", - NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "foobar22", - NM_SETTING_802_1X_PHASE2_AUTHEAP, "mschapv2", - NULL); + g_object_unref(connection); +} - success = nm_setting_802_1x_set_ca_cert (s_8021x, - TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error); - nmtst_assert_success (success, error); +static void +test_read_vlan_flags_2(void) +{ + NMConnection * connection; + NMSettingVlan *s_vlan; - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-vlan-flags-2", NULL, TYPE_ETHERNET, NULL); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "super-vlan"); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth9"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 44); + g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), + ==, + NM_VLAN_FLAG_GVRP | NM_VLAN_FLAG_LOOSE_BINDING | NM_VLAN_FLAG_REORDER_HEADERS); - nmtst_assert_connection_verifies (connection); + g_object_unref(connection); +} - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); +static void +test_write_vlan(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + connection = _connection_from_file(TEST_IFCFG_VLAN_INTERFACE, NULL, TYPE_VLAN, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Vlan_test-vlan-interface.cexpected", + &testfile); +} - keyfile = utils_get_keys_path (testfile); -} - -static void -test_write_wifi_wpa_then_open (void) +static void +test_write_vlan_flags(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_free char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GBytes *ssid; - const char *ssid_data = "blahblah"; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; - /* Test that writing out a WPA config then changing that to an open - * config doesn't leave various WPA-related keys lying around in the ifcfg. - */ + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-vlan-flags-2", NULL, TYPE_VLAN, NULL); - connection = nm_simple_connection_new (); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "random wifi connection", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); +static void +test_write_vlan_only_vlanid(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); + connection = _connection_from_file(TEST_IFCFG_VLAN_ONLY_VLANID, NULL, TYPE_VLAN, NULL); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - g_bytes_unref (ssid); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - /* Wireless security setting */ - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", - NM_SETTING_WIRELESS_SECURITY_PSK, "some cool PSK", - NULL); +static void +test_write_vlan_reorder_hdr(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingVlan * s_vlan; + NMSettingWired * s_wired; - nm_setting_wireless_security_add_proto (s_wsec, "wpa"); - nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); - nm_setting_wireless_security_add_group (s_wsec, "tkip"); + connection = nm_simple_connection_new(); - nm_setting_wireless_security_add_proto (s_wsec, "rsn"); - nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); - nm_setting_wireless_security_add_group (s_wsec, "ccmp"); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write VLAN reorder_hdr", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_VLAN_SETTING_NAME, + NULL); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - nmtst_assert_connection_verifies (connection); + /* VLAN setting */ + s_vlan = (NMSettingVlan *) nm_setting_vlan_new(); + nm_connection_add_setting(connection, NM_SETTING(s_vlan)); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + g_object_set(s_vlan, + NM_SETTING_VLAN_PARENT, + "eth0", + NM_SETTING_VLAN_ID, + 444, + NM_SETTING_VLAN_FLAGS, + 1, + NULL); - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_VLAN_reorder_hdr.cexpected", + &testfile); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - g_object_unref (reread); - - nmtst_connection_normalize (connection); - - /* Now change the connection to open and recheck */ - nm_connection_remove_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); - - /* Write it back out */ - _writer_update_connection (connection, - TEST_SCRATCH_DIR, - testfile, - TEST_IFCFG_DIR"/ifcfg-random_wifi_connection.cexpected"); - keyfile = utils_get_keys_path (testfile); - g_assert (!g_file_test (keyfile, G_FILE_TEST_EXISTS)); - - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_write_wifi_wpa_then_wep_with_perms (void) +test_write_ethernet_missing_ipv6(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - gboolean success; - GBytes *ssid; - char **perms; - const char *ssid_data = "SomeSSID"; - - /* Test that writing out a WPA config then changing that to a WEP - * config works and doesn't cause infinite loop or other issues. - */ - - connection = nm_simple_connection_new (); - g_assert (connection); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - perms = g_strsplit ("user:superman:", ",", -1); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "random wifi connection 2", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_PERMISSIONS, perms, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); - g_strfreev (perms); - g_assert_cmpint (nm_setting_connection_get_num_permissions (s_con), ==, 1); - - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); - - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); - - g_bytes_unref (ssid); + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; - /* Wireless security setting */ - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + connection = nm_simple_connection_new(); + g_assert(connection); - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", - NM_SETTING_WIRELESS_SECURITY_PSK, "My cool PSK", - NULL); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - nm_setting_wireless_security_add_proto (s_wsec, "wpa"); - nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); - nm_setting_wireless_security_add_group (s_wsec, "tkip"); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Ethernet Without IPv6 Setting", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); - nm_setting_wireless_security_add_proto (s_wsec, "rsn"); - nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); - nm_setting_wireless_security_add_group (s_wsec, "ccmp"); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, + "random-client-id-00:22:33", + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, + TRUE, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, + TRUE, + NULL); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + /* IP6 setting */ + /* + * We intentionally don't add IPv6 setting here. ifcfg-rh plugin should regard + * missing IPv6 as IPv6 with NM_SETTING_IP6_CONFIG_METHOD_AUTO method. + */ - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + nmtst_assert_connection_verifies(connection); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - nmtst_assert_connection_verifies (connection); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); - - g_object_unref (reread); - - nmtst_connection_normalize (connection); - - /* Now change the connection to WEP and recheck */ - 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, "none", - NULL); - nm_setting_wireless_security_set_wep_key (s_wsec, 0, "abraka dabra"); - - /* Write it back out */ - _writer_update_connection (connection, - TEST_SCRATCH_DIR, - testfile, - TEST_IFCFG_DIR"/ifcfg-random_wifi_connection_2.cexpected"); - - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); - - nmtst_connection_normalize (connection); - success = nm_connection_compare (connection, reread, - NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | - NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS); - g_assert (success); - - keyfile = utils_get_keys_path (testfile); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_write_wifi_dynamic_wep_leap (void) +test_read_ibft_ignored(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - nmtst_auto_unlinkfile char *keyfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSetting8021x *s_8021x; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - GBytes *ssid; - const char *ssid_data = "blahblah"; - shvarFile *ifcfg; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi Dynamic WEP LEAP", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); - - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + gs_free_error GError *error = NULL; - ssid = g_bytes_new (ssid_data, strlen (ssid_data)); - - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); - - g_bytes_unref (ssid); - - /* Wireless 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, "ieee8021x", NULL); - - /* Wireless security setting */ - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - nm_setting_802_1x_add_eap_method (s_8021x, "leap"); - - g_object_set (s_8021x, - NM_SETTING_802_1X_IDENTITY, "Bill Smith", - NM_SETTING_802_1X_PASSWORD, ";alkdfja;dslkfjsad;lkfjsadf", - NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); - - keyfile = utils_get_keys_path (testfile); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); - - /* Check and make sure that an "old-school" LEAP (Network EAP) connection - * did not get written. Check first that the auth alg is not set to "LEAP" - * and next that the only IEEE 802.1x EAP method is "LEAP". - */ - ifcfg = _svOpenFile (testfile); - _svGetValue_check (ifcfg, "SECURITYMODE", NULL); - _svGetValue_check (ifcfg, "IEEE_8021X_EAP_METHODS", "LEAP"); - svCloseFile (ifcfg); + _connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-ibft", NULL, TYPE_ETHERNET, &error); + g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); } static void -test_write_wired_qeth_dhcp (void) +test_read_bond_main(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - char **subchans; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired qeth Static", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - subchans = g_strsplit ("0.0.600,0.0.601,0.0.602", ",", -1); - g_object_set (s_wired, - NM_SETTING_WIRED_S390_SUBCHANNELS, subchans, - NM_SETTING_WIRED_S390_NETTYPE, "qeth", - NULL); - g_strfreev (subchans); - - nm_setting_wired_add_s390_option (s_wired, "portname", "FOOBAR"); - nm_setting_wired_add_s390_option (s_wired, "portno", "1"); - nm_setting_wired_add_s390_option (s_wired, "layer2", "0"); - nm_setting_wired_add_s390_option (s_wired, "protocol", "blahbalh"); + NMConnection * connection; + NMSettingBond *s_bond; - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-bond-main", NULL, TYPE_ETHERNET, NULL); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "bond0"); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + /* ===== Bonding SETTING ===== */ - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + s_bond = nm_connection_get_setting_bond(connection); + g_assert(s_bond); - nmtst_assert_connection_verifies (connection); + g_assert_cmpstr(nm_setting_bond_get_option_by_name(s_bond, NM_SETTING_BOND_OPTION_MIIMON), + ==, + "100"); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_object_unref(connection); } static void -test_write_wired_ctc_dhcp (void) +test_read_bond_eth_type(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - char **subchans; - shvarFile *ifcfg; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired ctc Static", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + NMConnection * connection; + NMSettingBond *s_bond; - subchans = g_strsplit ("0.0.600,0.0.601", ",", -1); - g_object_set (s_wired, - NM_SETTING_WIRED_S390_SUBCHANNELS, subchans, - NM_SETTING_WIRED_S390_NETTYPE, "ctc", - NULL); - g_strfreev (subchans); - nm_setting_wired_add_s390_option (s_wired, "ctcprot", "0"); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-bond-eth-type", + NULL, + TYPE_ETHERNET, + NULL); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "bond0"); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + /* ===== Bonding SETTING ===== */ - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + s_bond = nm_connection_get_setting_bond(connection); + g_assert(s_bond); - nmtst_assert_connection_verifies (connection); + g_assert_cmpstr(nm_setting_bond_get_option_by_name(s_bond, NM_SETTING_BOND_OPTION_MIIMON), + ==, + "213"); + g_assert_cmpstr(nm_setting_bond_get_option_by_name(s_bond, NM_SETTING_BOND_OPTION_LACP_RATE), + ==, + "1"); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - /* Ensure the CTCPROT item gets written out as its own option */ - ifcfg = _svOpenFile (testfile); - - _svGetValue_check (ifcfg, "CTCPROT", "0"); - - /* And that it's not in the generic OPTIONS string */ - _svGetValue_check (ifcfg, "OPTIONS", NULL); - - svCloseFile (ifcfg); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_object_unref(connection); } static void -test_write_permissions (void) +test_write_bond_main(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Permissions", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - nm_setting_connection_add_permission (s_con, "user", "blahblah", NULL); - nm_setting_connection_add_permission (s_con, "user", "foobar", NULL); - nm_setting_connection_add_permission (s_con, "user", "asdfasdf", NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingBond * s_bond; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingWired * s_wired; + NMIPAddress * addr; + GError * error = NULL; - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + connection = nm_simple_connection_new(); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - nmtst_assert_connection_verifies (connection); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Bond Main", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_INTERFACE_NAME, + "bond0", + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_BOND_SETTING_NAME, + NULL); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Permissions.cexpected", - &testfile); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + /* bond setting */ + s_bond = (NMSettingBond *) nm_setting_bond_new(); + nm_connection_add_setting(connection, NM_SETTING(s_bond)); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_write_wifi_wep_agent_keys (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - const char *str_ssid = "foobarbaz"; - GBytes *ssid; - - connection = nm_simple_connection_new (); - g_assert (connection != NULL); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP Agent Owned", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + nm_setting_bond_add_option(s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY, "5"); + nm_setting_bond_add_option(s_bond, NM_SETTING_BOND_OPTION_UPDELAY, "10"); + nm_setting_bond_add_option(s_bond, NM_SETTING_BOND_OPTION_MIIMON, "100"); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); - ssid = g_bytes_new (str_ssid, strlen (str_ssid)); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); - g_bytes_unref (ssid); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - /* Wifi security setting */ - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", - NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_PASSPHRASE, - NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, NM_SETTING_SECRET_FLAG_AGENT_OWNED, - NULL); - nm_setting_wireless_security_set_wep_key (s_wsec, 0, "asdfdjaslfjasd;flasjdfl;aksdf"); + nm_connection_add_setting(connection, nm_setting_proxy_new()); - nmtst_assert_connection_verifies (connection); + nmtst_assert_connection_verifies_without_normalization(connection); - _writer_new_connection_FIXME (connection, - TEST_SCRATCH_DIR, - &testfile); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Bond_Main.cexpected", + &testfile); - reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); + reread = _connection_from_file(testfile, NULL, TYPE_BOND, NULL); - /* Remove the WEP key from the original, because it should not have been - * written out to disk as it was agent-owned. The new connection should - * not have any WEP keys set. - * Also the new connection should not have WEP key type set. - */ - nm_setting_wireless_security_set_wep_key (s_wsec, 0, NULL); - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_UNKNOWN, - NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_write_wired_pppoe (void) +test_read_bond_slave(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingPppoe *s_pppoe; - NMSettingPpp *s_ppp; - GError *error = NULL; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired PPPoE", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + NMConnection * connection; + NMSettingConnection *s_con; - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-bond-slave", NULL, TYPE_ETHERNET, NULL); + g_test_assert_expected_messages(); - /* PPPoE setting */ - s_pppoe = (NMSettingPppoe *) nm_setting_pppoe_new (); - nm_connection_add_setting (connection, NM_SETTING (s_pppoe)); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); - g_object_set (G_OBJECT (s_pppoe), - NM_SETTING_PPPOE_SERVICE, "stupid-service", - NM_SETTING_PPPOE_USERNAME, "Bill Smith", - NM_SETTING_PPPOE_PASSWORD, "test1", - NULL); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, "bond0"); - /* PPP setting */ - s_ppp = (NMSettingPpp *) nm_setting_ppp_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ppp)); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NM_SETTING_BOND_SETTING_NAME); - nmtst_assert_connection_verifies (connection); - - _writer_new_connection_fail (connection, - TEST_SCRATCH_DIR, - NULL); - - g_object_unref (connection); - g_clear_error (&error); + g_object_unref(connection); } static void -test_write_vpn (void) +test_write_bond_slave(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMSettingVpn *s_vpn; - GError *error = NULL; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + static const char * mac = "31:33:33:37:be:cd"; + guint32 mtu = 1492; - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write VPN", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_VPN_SETTING_NAME, - NULL); + connection = nm_simple_connection_new(); - /* VPN setting */ - s_vpn = (NMSettingVpn *) nm_setting_vpn_new (); - nm_connection_add_setting (connection, NM_SETTING (s_vpn)); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - g_object_set (s_vpn, - NM_SETTING_VPN_SERVICE_TYPE, "awesomevpn", - NM_SETTING_VPN_USER_NAME, "Bill Smith", - NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Bond Slave", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_MASTER, + "bond0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BOND_SETTING_NAME, + NULL); - nm_setting_vpn_add_data_item (s_vpn, "server", "vpn.somewhere.com"); - nm_setting_vpn_add_secret (s_vpn, "password", "sup3rs3cr3t"); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, mtu, NULL); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + nmtst_assert_connection_verifies(connection); - nmtst_assert_connection_verifies (connection); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - _writer_new_connection_fail (connection, - TEST_SCRATCH_DIR, - NULL); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - g_object_unref (connection); - g_clear_error (&error); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_write_mobile_broadband (gconstpointer data) +test_read_infiniband(void) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMSettingGsm *s_gsm; - NMSettingCdma *s_cdma; - NMSettingPpp *s_ppp; - NMSettingSerial *s_serial; - GError *error = NULL; - gboolean gsm = GPOINTER_TO_UINT (data); - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, gsm ? "Test Write GSM" : "Test Write CDMA", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, gsm ? NM_SETTING_GSM_SETTING_NAME : NM_SETTING_CDMA_SETTING_NAME, - NULL); + NMConnection * connection; + NMSettingInfiniband *s_infiniband; + char * unmanaged = NULL; + const char * mac; + char expected_mac_address[INFINIBAND_ALEN] = {0x80, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, + 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22}; + const char *transport_mode; - if (gsm) { - /* GSM setting */ - s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); - nm_connection_add_setting (connection, NM_SETTING (s_gsm)); - } else { - /* CDMA setting */ - s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); - nm_connection_add_setting (connection, NM_SETTING (s_cdma)); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-infiniband", + NULL, + TYPE_INFINIBAND, + &unmanaged); + g_assert(!unmanaged); - g_object_set (s_cdma, NM_SETTING_CDMA_NUMBER, "#777", NULL); - } + /* ===== INFINIBAND SETTING ===== */ - /* Serial setting */ - s_serial = (NMSettingSerial *) nm_setting_serial_new (); - nm_connection_add_setting (connection, NM_SETTING (s_serial)); + s_infiniband = nm_connection_get_setting_infiniband(connection); + g_assert(s_infiniband); - g_object_set (s_serial, - NM_SETTING_SERIAL_BAUD, 115200, - NM_SETTING_SERIAL_BITS, 8, - NM_SETTING_SERIAL_PARITY, NM_SETTING_SERIAL_PARITY_NONE, - NM_SETTING_SERIAL_STOPBITS, 1, - NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); - - /* PPP setting */ - s_ppp = (NMSettingPpp *) nm_setting_ppp_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ppp)); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection_fail (connection, - TEST_SCRATCH_DIR, - NULL); - - g_object_unref (connection); - g_clear_error (&error); -} - -static void -test_read_bridge_main (void) -{ - NMConnection *connection; - NMSettingBridge *s_bridge; - NMSettingWired *s_wired; - const char *mac; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bridge-main", - NULL, TYPE_ETHERNET, NULL); - - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "br0"); - - /* ===== Bridging SETTING ===== */ - - s_bridge = nm_connection_get_setting_bridge (connection); - g_assert (s_bridge); - g_assert_cmpuint (nm_setting_bridge_get_forward_delay (s_bridge), ==, 2); - g_assert (nm_setting_bridge_get_stp (s_bridge)); - g_assert_cmpuint (nm_setting_bridge_get_priority (s_bridge), ==, 32744); - g_assert_cmpuint (nm_setting_bridge_get_hello_time (s_bridge), ==, 7); - g_assert_cmpuint (nm_setting_bridge_get_max_age (s_bridge), ==, 39); - g_assert_cmpuint (nm_setting_bridge_get_ageing_time (s_bridge), ==, 235352); - g_assert_cmpuint (nm_setting_bridge_get_group_forward_mask (s_bridge), ==, 24); - g_assert (!nm_setting_bridge_get_multicast_snooping (s_bridge)); - g_assert_cmpint (nm_setting_bridge_get_vlan_filtering (s_bridge), ==, TRUE); - g_assert_cmpint (nm_setting_bridge_get_vlan_default_pvid (s_bridge), ==, 99); - - /* MAC address */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - mac = nm_setting_wired_get_cloned_mac_address (s_wired); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, ETH_ALEN)); - - g_object_unref (connection); -} - -static void -test_write_bridge_main (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingBridge *s_bridge; - NMSettingIPConfig *s_ip4, *s_ip6; - NMSettingWired *s_wired; - NMIPAddress *addr; - static const char *mac = "31:33:33:37:be:cd"; - GError *error = NULL; - gs_unref_ptrarray GPtrArray *vlans = NULL; - NMBridgeVlan *vlan; - - connection = nm_simple_connection_new (); - g_assert (connection); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Bridge Main", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_INTERFACE_NAME, "br0", - NM_SETTING_CONNECTION_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, - NULL); - - /* bridge setting */ - s_bridge = (NMSettingBridge *) nm_setting_bridge_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bridge)); - - vlans = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref); - vlan = nm_bridge_vlan_new (10, 16); - nm_bridge_vlan_set_untagged (vlan, TRUE); - g_ptr_array_add (vlans, vlan); - vlan = nm_bridge_vlan_new (22, 22); - nm_bridge_vlan_set_pvid (vlan, TRUE); - nm_bridge_vlan_set_untagged (vlan, TRUE); - g_ptr_array_add (vlans, vlan); - vlan = nm_bridge_vlan_new (44, 0); - g_ptr_array_add (vlans, vlan); - - g_object_set (s_bridge, - NM_SETTING_BRIDGE_MAC_ADDRESS, mac, - NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, 19008, - NM_SETTING_BRIDGE_VLAN_FILTERING, TRUE, - NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, 4000, - NM_SETTING_BRIDGE_VLANS, vlans, - NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - nm_connection_add_setting (connection, nm_setting_proxy_new ()); - - nmtst_assert_connection_verifies_without_normalization (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_BRIDGE, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_read_bridge_component (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingBridgePort *s_port; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bridge-component", - NULL, TYPE_ETHERNET, NULL); - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, "br0"); - g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BRIDGE_SETTING_NAME); + /* MAC address */ + mac = nm_setting_infiniband_get_mac_address(s_infiniband); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, sizeof(expected_mac_address))); - s_port = nm_connection_get_setting_bridge_port (connection); - g_assert (s_port); - g_assert (nm_setting_bridge_port_get_hairpin_mode (s_port)); - g_assert_cmpuint (nm_setting_bridge_port_get_priority (s_port), ==, 28); - g_assert_cmpuint (nm_setting_bridge_port_get_path_cost (s_port), ==, 100); + /* Transport mode */ + transport_mode = nm_setting_infiniband_get_transport_mode(s_infiniband); + g_assert(transport_mode); + g_assert_cmpstr(transport_mode, ==, "connected"); - g_object_unref (connection); + g_object_unref(connection); } static void -test_write_bridge_component (void) +test_write_infiniband(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSetting *s_port; - static const char *mac = "31:33:33:37:be:cd"; - guint32 mtu = 1492; - gs_unref_ptrarray GPtrArray *vlans = NULL; - NMBridgeVlan *vlan; - - connection = nm_simple_connection_new (); - g_assert (connection); + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingInfiniband * s_infiniband; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + const char * mac = "80:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22"; + guint32 mtu = 65520; + NMIPAddress *addr; + GError * error = NULL; - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + connection = nm_simple_connection_new(); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Bridge Component", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, "br0", - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, - NULL); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write InfiniBand", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_INFINIBAND_SETTING_NAME, + NULL); - g_object_set (s_wired, - NM_SETTING_WIRED_MAC_ADDRESS, mac, - NM_SETTING_WIRED_MTU, mtu, - NULL); + /* InfiniBand setting */ + s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new(); + nm_connection_add_setting(connection, NM_SETTING(s_infiniband)); - /* Bridge port */ - vlans = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref); - vlan = nm_bridge_vlan_new (1, 0); - nm_bridge_vlan_set_untagged (vlan, TRUE); - g_ptr_array_add (vlans, vlan); - vlan = nm_bridge_vlan_new (4, 4094); - nm_bridge_vlan_set_untagged (vlan, TRUE); - g_ptr_array_add (vlans, vlan); - vlan = nm_bridge_vlan_new (2, 2); - nm_bridge_vlan_set_pvid (vlan, TRUE); - g_ptr_array_add (vlans, vlan); + g_object_set(s_infiniband, + NM_SETTING_INFINIBAND_MAC_ADDRESS, + mac, + NM_SETTING_INFINIBAND_MTU, + mtu, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, + "connected", + NULL); - s_port = nm_setting_bridge_port_new (); - nm_connection_add_setting (connection, s_port); - g_object_set (s_port, - NM_SETTING_BRIDGE_PORT_PRIORITY, 50, - NM_SETTING_BRIDGE_PORT_PATH_COST, 33, - NM_SETTING_BRIDGE_PORT_VLANS, vlans, - NULL); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - nmtst_assert_connection_verifies (connection); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Bridge_Component.cexpected", - &testfile); + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_read_bridge_missing_stp (void) -{ - NMConnection *connection; - NMSettingBridge *s_bridge; + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bridge-missing-stp", - NULL, TYPE_BRIDGE, NULL); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "br0"); + nmtst_assert_connection_verifies(connection); - /* ===== Bridging SETTING ===== */ + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - s_bridge = nm_connection_get_setting_bridge (connection); - g_assert (s_bridge); - g_assert (nm_setting_bridge_get_stp (s_bridge) == FALSE); + reread = _connection_from_file(testfile, NULL, TYPE_INFINIBAND, NULL); - g_object_unref (connection); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } -#define TEST_IFCFG_VLAN_INTERFACE TEST_IFCFG_DIR"/ifcfg-test-vlan-interface" - static void -test_read_vlan_interface (void) +test_read_bond_slave_ib(void) { - NMConnection *connection; - NMSettingVlan *s_vlan; - guint32 from = 0, to = 0; - - connection = _connection_from_file (TEST_IFCFG_VLAN_INTERFACE, - NULL, TYPE_ETHERNET, NULL); - - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "vlan43"); - - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); - - g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9"); - g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 43); - g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, - NM_VLAN_FLAG_GVRP | NM_VLAN_FLAG_LOOSE_BINDING | NM_VLAN_FLAG_REORDER_HEADERS); - - /* Ingress map */ - g_assert_cmpint (nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_INGRESS_MAP), ==, 2); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; - g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_INGRESS_MAP, 0, &from, &to)); - g_assert_cmpint (from, ==, 0); - g_assert_cmpint (to, ==, 1); + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-bond-slave-ib", NULL, NULL, NULL); - g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_INGRESS_MAP, 1, &from, &to)); - g_assert_cmpint (from, ==, 2); - g_assert_cmpint (to, ==, 5); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); - /* Egress map */ - g_assert_cmpint (nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_EGRESS_MAP), ==, 3); - - g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 0, &from, &to)); - g_assert_cmpint (from, ==, 3); - g_assert_cmpint (to, ==, 1); - - g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 1, &from, &to)); - g_assert_cmpint (from, ==, 12); - g_assert_cmpint (to, ==, 3); - - g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 2, &from, &to)); - g_assert_cmpint (from, ==, 14); - g_assert_cmpint (to, ==, 7); - - g_object_unref (connection); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, "bond0"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NM_SETTING_BOND_SETTING_NAME); } -#define TEST_IFCFG_VLAN_ONLY_VLANID TEST_IFCFG_DIR"/ifcfg-test-vlan-only-vlanid" - static void -test_read_vlan_only_vlan_id (void) +test_write_bond_slave_ib(void) { - NMConnection *connection; - NMSettingVlan *s_vlan; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingInfiniband * s_infiniband; + static const char *mac = "80:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22"; - connection = _connection_from_file (TEST_IFCFG_VLAN_ONLY_VLANID, NULL, TYPE_ETHERNET, NULL); + connection = nm_simple_connection_new(); - g_assert (nm_connection_get_interface_name (connection) == NULL); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Bond Slave InfiniBand", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_CONNECTION_MASTER, + "bond0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BOND_SETTING_NAME, + NULL); - g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9"); - g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 43); - g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS); + /* InfiniBand setting */ + s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new(); + nm_connection_add_setting(connection, NM_SETTING(s_infiniband)); - g_object_unref (connection); -} + g_object_set(s_infiniband, + NM_SETTING_INFINIBAND_MAC_ADDRESS, + mac, + NM_SETTING_INFINIBAND_MTU, + 2044, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, + "datagram", + NULL); -static void -test_read_vlan_only_device (void) -{ - NMConnection *connection; - NMSettingVlan *s_vlan; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-vlan-only-device", - NULL, TYPE_ETHERNET, NULL); - - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "eth0.9"); + nmtst_assert_connection_verifies(connection); - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth0"); - g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 9); + reread = _connection_from_file(testfile, NULL, NULL, NULL); - g_object_unref (connection); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_read_vlan_physdev (void) +test_read_bond_opts_mode_numeric(void) { - NMConnection *connection; - NMSettingVlan *s_vlan; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingBond * s_bond; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-vlan-physdev", - NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-bond-mode-numeric", + NULL, + TYPE_ETHERNET, + NULL); - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "vlan0.3"); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "bond0"); - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_BOND_SETTING_NAME); - g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth0"); - g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 3); + s_bond = nm_connection_get_setting_bond(connection); + g_assert(s_bond); + g_assert_cmpstr(nm_setting_bond_get_option_by_name(s_bond, NM_SETTING_BOND_OPTION_MODE), + ==, + "802.3ad"); - g_object_unref (connection); + g_object_unref(connection); } -static void -test_read_vlan_reorder_hdr_1 (void) -{ - NMConnection *connection; - NMSettingVlan *s_vlan; - - NMTST_EXPECT_NM_WARN ("*REORDER_HDR key is deprecated, use VLAN_FLAGS*"); - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-vlan-reorder-hdr-1", - NULL, TYPE_ETHERNET, NULL); - g_test_assert_expected_messages (); - - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "vlan0.3"); - - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); - - g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth0"); - g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 3); - /* Check that REORDER_HDR=0 is ignored */ - g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS); - - g_object_unref (connection); -} +#define DCB_ALL_FLAGS \ + (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE | NM_SETTING_DCB_FLAG_WILLING) static void -test_read_vlan_reorder_hdr_2 (void) +test_read_dcb_basic(void) { - NMConnection *connection; - NMSettingVlan *s_vlan; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-vlan-reorder-hdr-2", - NULL, TYPE_ETHERNET, NULL); - - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "vlan0.3"); + NMConnection *connection; + NMSettingDcb *s_dcb; + guint i; + guint expected_group_ids[8] = {0, 0, 0, 0, 1, 1, 1, 0xF}; + guint expected_group_bandwidths[8] = {25, 0, 0, 75, 0, 0, 0, 0}; + guint expected_bandwidths[8] = {5, 10, 30, 25, 10, 50, 5, 0}; + gboolean expected_strict[8] = {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE}; + guint expected_traffic_classes[8] = {7, 6, 5, 4, 3, 2, 1, 0}; + gboolean expected_pfcs[8] = {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE}; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-dcb", NULL, TYPE_ETHERNET, NULL); + + s_dcb = nm_connection_get_setting_dcb(connection); + g_assert(s_dcb); + + g_assert_cmpint(nm_setting_dcb_get_app_fcoe_flags(s_dcb), ==, DCB_ALL_FLAGS); + g_assert_cmpint(nm_setting_dcb_get_app_fcoe_priority(s_dcb), ==, 7); + + g_assert_cmpint(nm_setting_dcb_get_app_iscsi_flags(s_dcb), ==, DCB_ALL_FLAGS); + g_assert_cmpint(nm_setting_dcb_get_app_iscsi_priority(s_dcb), ==, 6); + + g_assert_cmpint(nm_setting_dcb_get_app_fip_flags(s_dcb), ==, DCB_ALL_FLAGS); + g_assert_cmpint(nm_setting_dcb_get_app_fip_priority(s_dcb), ==, 2); + + g_assert_cmpint(nm_setting_dcb_get_priority_flow_control_flags(s_dcb), + ==, + (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE)); + for (i = 0; i < 8; i++) + g_assert_cmpint(nm_setting_dcb_get_priority_flow_control(s_dcb, i), ==, expected_pfcs[i]); + + g_assert_cmpint(nm_setting_dcb_get_priority_group_flags(s_dcb), ==, DCB_ALL_FLAGS); + + /* Group IDs */ + for (i = 0; i < 8; i++) + g_assert_cmpint(nm_setting_dcb_get_priority_group_id(s_dcb, i), ==, expected_group_ids[i]); + + /* Group bandwidth */ + for (i = 0; i < 8; i++) + g_assert_cmpint(nm_setting_dcb_get_priority_group_bandwidth(s_dcb, i), + ==, + expected_group_bandwidths[i]); + + /* User priority bandwidth */ + for (i = 0; i < 8; i++) + g_assert_cmpint(nm_setting_dcb_get_priority_bandwidth(s_dcb, i), + ==, + expected_bandwidths[i]); + + /* Strict bandwidth */ + for (i = 0; i < 8; i++) + g_assert_cmpint(nm_setting_dcb_get_priority_strict_bandwidth(s_dcb, i), + ==, + expected_strict[i]); + + /* Traffic class */ + for (i = 0; i < 8; i++) + g_assert_cmpint(nm_setting_dcb_get_priority_traffic_class(s_dcb, i), + ==, + expected_traffic_classes[i]); + + g_object_unref(connection); +} + +static void +test_write_dcb_basic(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingDcb * s_dcb; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + guint i; + const guint group_ids[8] = {4, 0xF, 6, 0xF, 1, 7, 3, 0xF}; + const guint group_bandwidths[8] = {10, 20, 15, 10, 2, 3, 35, 5}; + const guint bandwidths[8] = {10, 20, 30, 40, 50, 10, 0, 25}; + const gboolean strict[8] = {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE}; + const guint traffic_classes[8] = {3, 4, 7, 2, 1, 0, 5, 6}; + const gboolean pfcs[8] = {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE}; + + connection = nm_simple_connection_new(); + + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + g_object_set(G_OBJECT(s_con), + NM_SETTING_CONNECTION_ID, + "dcb-test", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME, + "eth0", + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* IP stuff */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(G_OBJECT(s_ip4), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + g_object_set(G_OBJECT(s_ip6), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NULL); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + /* DCB */ + s_dcb = (NMSettingDcb *) nm_setting_dcb_new(); + nm_connection_add_setting(connection, NM_SETTING(s_dcb)); - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); - - g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth0"); - g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 3); - /* Check that VLAN_FLAGS=NO_REORDER_HDR works */ - g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, NM_VLAN_FLAG_LOOSE_BINDING); - - g_object_unref (connection); -} - -static void -test_read_vlan_flags_1 (void) -{ - NMConnection *connection; - NMSettingVlan *s_vlan; + g_object_set(G_OBJECT(s_dcb), + NM_SETTING_DCB_APP_FCOE_FLAGS, + DCB_ALL_FLAGS, + NM_SETTING_DCB_APP_FCOE_PRIORITY, + 5, + NM_SETTING_DCB_APP_ISCSI_FLAGS, + DCB_ALL_FLAGS, + NM_SETTING_DCB_APP_ISCSI_PRIORITY, + 1, + NM_SETTING_DCB_APP_FIP_FLAGS, + DCB_ALL_FLAGS, + NM_SETTING_DCB_APP_FIP_PRIORITY, + 3, + NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, + DCB_ALL_FLAGS, + NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, + DCB_ALL_FLAGS, + NULL); - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-vlan-flags-1", - NULL, TYPE_ETHERNET, NULL); + for (i = 0; i < 8; i++) { + nm_setting_dcb_set_priority_flow_control(s_dcb, i, pfcs[i]); + nm_setting_dcb_set_priority_group_id(s_dcb, i, group_ids[i]); + nm_setting_dcb_set_priority_group_bandwidth(s_dcb, i, group_bandwidths[i]); + nm_setting_dcb_set_priority_bandwidth(s_dcb, i, bandwidths[i]); + nm_setting_dcb_set_priority_strict_bandwidth(s_dcb, i, strict[i]); + nm_setting_dcb_set_priority_traffic_class(s_dcb, i, traffic_classes[i]); + } - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "super-vlan"); + nmtst_assert_connection_verifies(connection); - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "//ifcfg-dcb-test.cexpected", + &testfile); - g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9"); - g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 44); - g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, - NM_VLAN_FLAG_LOOSE_BINDING | - NM_VLAN_FLAG_REORDER_HEADERS); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - g_object_unref (connection); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_read_vlan_flags_2 (void) +test_read_dcb_default_app_priorities(void) { - NMConnection *connection; - NMSettingVlan *s_vlan; + gs_unref_object NMConnection *connection = NULL; + NMSettingDcb * s_dcb; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-vlan-flags-2", - NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-dcb-default-app-priorities", + NULL, + TYPE_ETHERNET, + NULL); - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "super-vlan"); + s_dcb = nm_connection_get_setting_dcb(connection); + g_assert(s_dcb); - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); + g_assert_cmpint(nm_setting_dcb_get_app_fcoe_flags(s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE); + g_assert_cmpint(nm_setting_dcb_get_app_fcoe_priority(s_dcb), ==, -1); - g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9"); - g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 44); - g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, - NM_VLAN_FLAG_GVRP | - NM_VLAN_FLAG_LOOSE_BINDING | - NM_VLAN_FLAG_REORDER_HEADERS); + g_assert_cmpint(nm_setting_dcb_get_app_iscsi_flags(s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE); + g_assert_cmpint(nm_setting_dcb_get_app_iscsi_priority(s_dcb), ==, -1); - g_object_unref (connection); + g_assert_cmpint(nm_setting_dcb_get_app_fip_flags(s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE); + g_assert_cmpint(nm_setting_dcb_get_app_fip_priority(s_dcb), ==, -1); } static void -test_write_vlan (void) +test_read_dcb_bad_booleans(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; + gs_free_error GError *error = NULL; - connection = _connection_from_file (TEST_IFCFG_VLAN_INTERFACE, - NULL, TYPE_VLAN, NULL); + NMTST_EXPECT_NM_WARN("*invalid DCB_PG_STRICT value*not all 0s and 1s*"); + _connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-dcb-bad-booleans", + NULL, + TYPE_ETHERNET, + &error); + g_test_assert_expected_messages(); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Vlan_test-vlan-interface.cexpected", - &testfile); + g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_assert(strstr(error->message, "invalid boolean digit")); } static void -test_write_vlan_flags (void) +test_read_dcb_short_booleans(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; + gs_free_error GError *error = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-vlan-flags-2", - NULL, TYPE_VLAN, NULL); + NMTST_EXPECT_NM_WARN("*DCB_PG_STRICT value*8 characters*"); + _connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-dcb-short-booleans", + NULL, + TYPE_ETHERNET, + &error); + g_test_assert_expected_messages(); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_assert(strstr(error->message, "boolean array must be 8 characters")); } static void -test_write_vlan_only_vlanid (void) +test_read_dcb_bad_uints(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - - connection = _connection_from_file (TEST_IFCFG_VLAN_ONLY_VLANID, - NULL, TYPE_VLAN, NULL); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + gs_free_error GError *error = NULL; - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + NMTST_EXPECT_NM_WARN("*invalid DCB_PG_UP2TC value*not 0 - 7*"); + _connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-dcb-bad-uints", + NULL, + TYPE_ETHERNET, + &error); + g_test_assert_expected_messages(); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_assert(strstr(error->message, "invalid uint digit")); } static void -test_write_vlan_reorder_hdr (void) +test_read_dcb_short_uints(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingVlan *s_vlan; - NMSettingWired *s_wired; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write VLAN reorder_hdr", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_VLAN_SETTING_NAME, - NULL); + gs_free_error GError *error = NULL; - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + NMTST_EXPECT_NM_WARN("*DCB_PG_UP2TC value*8 characters*"); + _connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-dcb-short-uints", + NULL, + TYPE_ETHERNET, + &error); + g_test_assert_expected_messages(); - /* VLAN setting */ - s_vlan = (NMSettingVlan *) nm_setting_vlan_new (); - nm_connection_add_setting (connection, NM_SETTING (s_vlan)); - - g_object_set (s_vlan, - NM_SETTING_VLAN_PARENT, "eth0", - NM_SETTING_VLAN_ID, 444, - NM_SETTING_VLAN_FLAGS, 1, - NULL); - - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_VLAN_reorder_hdr.cexpected", - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_assert(strstr(error->message, "uint array must be 8 characters")); } static void -test_write_ethernet_missing_ipv6 (void) +test_read_dcb_bad_percent(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - - connection = nm_simple_connection_new (); - g_assert (connection); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + gs_free_error GError *error = NULL; - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Ethernet Without IPv6 Setting", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); + NMTST_EXPECT_NM_WARN("*invalid DCB_PG_PCT percentage value*"); + _connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-dcb-bad-percent", + NULL, + TYPE_ETHERNET, + &error); + g_test_assert_expected_messages(); - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, "random-client-id-00:22:33", - NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, TRUE, - NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE, - NULL); - - /* IP6 setting */ - /* - * We intentionally don't add IPv6 setting here. ifcfg-rh plugin should regard - * missing IPv6 as IPv6 with NM_SETTING_IP6_CONFIG_METHOD_AUTO method. - */ - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_assert(strstr(error->message, "invalid percent element")); } static void -test_read_ibft_ignored (void) +test_read_dcb_short_percent(void) { - gs_free_error GError *error = NULL; - - _connection_from_file_fail (TEST_IFCFG_DIR"/ifcfg-test-ibft", - NULL, TYPE_ETHERNET, &error); - g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); -} - -static void -test_read_bond_main (void) -{ - NMConnection *connection; - NMSettingBond *s_bond; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bond-main", - NULL, TYPE_ETHERNET,NULL); - - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "bond0"); + gs_free_error GError *error = NULL; - /* ===== Bonding SETTING ===== */ + NMTST_EXPECT_NM_WARN("*invalid DCB_PG_PCT percentage list value*"); + _connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-dcb-short-percent", + NULL, + TYPE_ETHERNET, + &error); + g_test_assert_expected_messages(); - s_bond = nm_connection_get_setting_bond (connection); - g_assert (s_bond); - - g_assert_cmpstr (nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON), ==, "100"); - - g_object_unref (connection); + g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_assert(strstr(error->message, "percent array must be 8 elements")); } static void -test_read_bond_eth_type (void) +test_read_dcb_pgpct_not_100(void) { - NMConnection *connection; - NMSettingBond *s_bond; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bond-eth-type", - NULL, TYPE_ETHERNET,NULL); - - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "bond0"); + gs_free_error GError *error = NULL; - /* ===== Bonding SETTING ===== */ + NMTST_EXPECT_NM_WARN("*DCB_PG_PCT percentages do not equal 100*"); + _connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-dcb-pgpct-not-100", + NULL, + TYPE_ETHERNET, + &error); + g_test_assert_expected_messages(); - s_bond = nm_connection_get_setting_bond (connection); - g_assert (s_bond); - - g_assert_cmpstr (nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON), ==, "213"); - g_assert_cmpstr (nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_LACP_RATE), ==, "1"); - - g_object_unref (connection); + g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_assert(strstr(error->message, "invalid percentage sum")); } static void -test_write_bond_main (void) +test_read_fcoe_mode(gconstpointer user_data) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingBond *s_bond; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMSettingWired *s_wired; - NMIPAddress *addr; - GError *error = NULL; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Bond Main", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_INTERFACE_NAME, "bond0", - NM_SETTING_CONNECTION_TYPE, NM_SETTING_BOND_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* bond setting */ - s_bond = (NMSettingBond *) nm_setting_bond_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bond)); - - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY, "5"); - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_UPDELAY, "10"); - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_MIIMON, "100"); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + gs_unref_object NMConnection *connection = NULL; + gs_free char * file = NULL; + const char * expected_mode = user_data; + NMSettingDcb * s_dcb; - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + file = g_strdup_printf(TEST_IFCFG_DIR "/ifcfg-test-fcoe-%s", expected_mode); + connection = _connection_from_file(file, NULL, TYPE_ETHERNET, NULL); - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); + s_dcb = nm_connection_get_setting_dcb(connection); + g_assert(s_dcb); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NULL); - - nm_connection_add_setting (connection, nm_setting_proxy_new ()); - - nmtst_assert_connection_verifies_without_normalization (connection); - - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Bond_Main.cexpected", - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_BOND, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_assert_cmpint(nm_setting_dcb_get_app_fcoe_flags(s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE); + g_assert_cmpstr(nm_setting_dcb_get_app_fcoe_mode(s_dcb), ==, expected_mode); } static void -test_read_bond_slave (void) +test_write_fcoe_mode(gconstpointer user_data) { - NMConnection *connection; - NMSettingConnection *s_con; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + const char * expected_mode = user_data; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingDcb * s_dcb; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + shvarFile * ifcfg; - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bond-slave", - NULL, TYPE_ETHERNET, NULL); - g_test_assert_expected_messages (); + connection = nm_simple_connection_new(); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + g_object_set(G_OBJECT(s_con), + NM_SETTING_CONNECTION_ID, + "fcoe-test", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME, + "eth0", + NULL); - g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, "bond0"); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BOND_SETTING_NAME); + /* IP stuff */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(G_OBJECT(s_ip4), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - g_object_unref (connection); -} + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + g_object_set(G_OBJECT(s_ip6), + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NULL); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); -static void -test_write_bond_slave (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - static const char *mac = "31:33:33:37:be:cd"; - guint32 mtu = 1492; - - connection = nm_simple_connection_new (); + /* DCB */ + s_dcb = (NMSettingDcb *) nm_setting_dcb_new(); + nm_connection_add_setting(connection, NM_SETTING(s_dcb)); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + g_object_set(G_OBJECT(s_dcb), + NM_SETTING_DCB_APP_FCOE_FLAGS, + NM_SETTING_DCB_FLAG_ENABLE, + NM_SETTING_DCB_APP_FCOE_MODE, + expected_mode, + NULL); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Bond Slave", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, "bond0", - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, - NULL); + nmtst_assert_connection_verifies(connection); - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - g_object_set (s_wired, - NM_SETTING_WIRED_MAC_ADDRESS, mac, - NM_SETTING_WIRED_MTU, mtu, - NULL); + ifcfg = _svOpenFile(testfile); + _svGetValue_check(ifcfg, "DCB_APP_FCOE_MODE", expected_mode); + svCloseFile(ifcfg); - nmtst_assert_connection_verifies (connection); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_read_infiniband (void) +test_read_team_master(gconstpointer user_data) { - NMConnection *connection; - NMSettingInfiniband *s_infiniband; - char *unmanaged = NULL; - const char *mac; - char expected_mac_address[INFINIBAND_ALEN] = { 0x80, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22 }; - const char *transport_mode; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-infiniband", - NULL, TYPE_INFINIBAND, &unmanaged); - g_assert (!unmanaged); + const char *const PATH_NAME = user_data; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingTeam * s_team; + const char * expected_config = + "{\"device\": \"team0\", \"link_watch\": {\"name\": \"ethtool\"}}"; - /* ===== INFINIBAND SETTING ===== */ + connection = _connection_from_file(PATH_NAME, NULL, TYPE_ETHERNET, NULL); - s_infiniband = nm_connection_get_setting_infiniband (connection); - g_assert (s_infiniband); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "team0"); - /* MAC address */ - mac = nm_setting_infiniband_get_mac_address (s_infiniband); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address))); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_TEAM_SETTING_NAME); - /* Transport mode */ - transport_mode = nm_setting_infiniband_get_transport_mode (s_infiniband); - g_assert (transport_mode); - g_assert_cmpstr (transport_mode, ==, "connected"); + s_team = nm_connection_get_setting_team(connection); + g_assert(s_team); + g_assert_cmpstr(nm_setting_team_get_config(s_team), ==, expected_config); - g_object_unref (connection); + g_object_unref(connection); } static void -test_write_infiniband (void) +test_read_team_master_invalid(gconstpointer user_data) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingInfiniband *s_infiniband; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - const char *mac = "80:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22"; - guint32 mtu = 65520; - NMIPAddress *addr; - GError *error = NULL; + const char *const PATH_NAME = user_data; + gs_free_error GError *error = NULL; + gs_unref_object NMConnection *connection = NULL; - connection = nm_simple_connection_new (); + if (nm_json_vt()) { + _connection_from_file_fail(PATH_NAME, NULL, TYPE_ETHERNET, &error); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write InfiniBand", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_INFINIBAND_SETTING_NAME, - NULL); - - /* InfiniBand setting */ - s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new (); - nm_connection_add_setting (connection, NM_SETTING (s_infiniband)); - - g_object_set (s_infiniband, - NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, - NM_SETTING_INFINIBAND_MTU, mtu, - NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", - NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NULL); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_INFINIBAND, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert(strstr(error->message, _("invalid json"))); + } else + connection = _connection_from_file(PATH_NAME, NULL, TYPE_ETHERNET, NULL); } static void -test_read_bond_slave_ib (void) +test_write_team_master(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bond-slave-ib", - NULL, NULL, NULL); + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingTeam * s_team; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + const char * expected_config = + "{\"device\": \"team0\", \"link_watch\": {\"name\": \"ethtool\"}}"; + shvarFile *f; - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); + connection = nm_simple_connection_new(); - g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, "bond0"); - g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BOND_SETTING_NAME); -} + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); -static void -test_write_bond_slave_ib (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingInfiniband *s_infiniband; - static const char *mac = "80:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22"; + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Team Master", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_INTERFACE_NAME, + "team0", + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_TEAM_SETTING_NAME, + NULL); - connection = nm_simple_connection_new (); + /* Team setting */ + s_team = (NMSettingTeam *) nm_setting_team_new(); + nm_connection_add_setting(connection, NM_SETTING(s_team)); - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + g_object_set(s_team, NM_SETTING_TEAM_CONFIG, expected_config, NULL); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Bond Slave InfiniBand", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_INFINIBAND_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, "bond0", - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, - NULL); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - /* InfiniBand setting */ - s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new (); - nm_connection_add_setting (connection, NM_SETTING (s_infiniband)); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - g_object_set (s_infiniband, - NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, - NM_SETTING_INFINIBAND_MTU, 2044, - NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", - NULL); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - nmtst_assert_connection_verifies (connection); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); - reread = _connection_from_file (testfile, NULL, NULL, NULL); + nm_connection_add_setting(connection, nm_setting_proxy_new()); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_read_bond_opts_mode_numeric (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingBond *s_bond; + nmtst_assert_connection_verifies_without_normalization(connection); - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bond-mode-numeric", - NULL, TYPE_ETHERNET, NULL); + _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "bond0"); + f = _svOpenFile(testfile); + _svGetValue_check(f, "DEVICETYPE", "Team"); + _svGetValue_check(f, "TEAM_CONFIG", expected_config); + svCloseFile(f); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_BOND_SETTING_NAME); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - s_bond = nm_connection_get_setting_bond (connection); - g_assert (s_bond); - g_assert_cmpstr (nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE), ==, "802.3ad"); - - g_object_unref (connection); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } -#define DCB_ALL_FLAGS (NM_SETTING_DCB_FLAG_ENABLE | \ - NM_SETTING_DCB_FLAG_ADVERTISE | \ - NM_SETTING_DCB_FLAG_WILLING) - static void -test_read_dcb_basic (void) +test_read_team_port(gconstpointer user_data) { - NMConnection *connection; - NMSettingDcb *s_dcb; - guint i; - guint expected_group_ids[8] = { 0, 0, 0, 0, 1, 1, 1, 0xF }; - guint expected_group_bandwidths[8] = { 25, 0, 0, 75, 0, 0, 0, 0 }; - guint expected_bandwidths[8] = { 5, 10, 30, 25, 10, 50, 5, 0 }; - gboolean expected_strict[8] = { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE }; - guint expected_traffic_classes[8] = { 7, 6, 5, 4, 3, 2, 1, 0 }; - gboolean expected_pfcs[8] = { TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE }; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-dcb", - NULL, TYPE_ETHERNET, NULL); - - s_dcb = nm_connection_get_setting_dcb (connection); - g_assert (s_dcb); - - g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, DCB_ALL_FLAGS); - g_assert_cmpint (nm_setting_dcb_get_app_fcoe_priority (s_dcb), ==, 7); - - g_assert_cmpint (nm_setting_dcb_get_app_iscsi_flags (s_dcb), ==, DCB_ALL_FLAGS); - g_assert_cmpint (nm_setting_dcb_get_app_iscsi_priority (s_dcb), ==, 6); + const char *const PATH_NAME = user_data; + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingTeamPort * s_team_port; + const char * expected_config = "{\"p4p1\": {\"prio\": -10, \"sticky\": true}}"; - g_assert_cmpint (nm_setting_dcb_get_app_fip_flags (s_dcb), ==, DCB_ALL_FLAGS); - g_assert_cmpint (nm_setting_dcb_get_app_fip_priority (s_dcb), ==, 2); + connection = _connection_from_file(PATH_NAME, NULL, TYPE_ETHERNET, NULL); - g_assert_cmpint (nm_setting_dcb_get_priority_flow_control_flags (s_dcb), ==, (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE)); - for (i = 0; i < 8; i++) - g_assert_cmpint (nm_setting_dcb_get_priority_flow_control (s_dcb, i), ==, expected_pfcs[i]); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, "team0"); - g_assert_cmpint (nm_setting_dcb_get_priority_group_flags (s_dcb), ==, DCB_ALL_FLAGS); + s_team_port = nm_connection_get_setting_team_port(connection); + g_assert(s_team_port); + g_assert_cmpstr(nm_setting_team_port_get_config(s_team_port), ==, expected_config); - /* Group IDs */ - for (i = 0; i < 8; i++) - g_assert_cmpint (nm_setting_dcb_get_priority_group_id (s_dcb, i), ==, expected_group_ids[i]); - - /* Group bandwidth */ - for (i = 0; i < 8; i++) - g_assert_cmpint (nm_setting_dcb_get_priority_group_bandwidth (s_dcb, i), ==, expected_group_bandwidths[i]); - - /* User priority bandwidth */ - for (i = 0; i < 8; i++) - g_assert_cmpint (nm_setting_dcb_get_priority_bandwidth (s_dcb, i), ==, expected_bandwidths[i]); - - /* Strict bandwidth */ - for (i = 0; i < 8; i++) - g_assert_cmpint (nm_setting_dcb_get_priority_strict_bandwidth (s_dcb, i), ==, expected_strict[i]); - - /* Traffic class */ - for (i = 0; i < 8; i++) - g_assert_cmpint (nm_setting_dcb_get_priority_traffic_class (s_dcb, i), ==, expected_traffic_classes[i]); - - g_object_unref (connection); -} - -static void -test_write_dcb_basic (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingDcb *s_dcb; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - guint i; - const guint group_ids[8] = { 4, 0xF, 6, 0xF, 1, 7, 3, 0xF }; - const guint group_bandwidths[8] = { 10, 20, 15, 10, 2, 3, 35, 5 }; - const guint bandwidths[8] = { 10, 20, 30, 40, 50, 10, 0, 25 }; - const gboolean strict[8] = { TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE }; - const guint traffic_classes[8] = { 3, 4, 7, 2, 1, 0, 5, 6 }; - const gboolean pfcs[8] = { TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE }; - - connection = nm_simple_connection_new (); - - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - g_object_set (G_OBJECT (s_con), - NM_SETTING_CONNECTION_ID, "dcb-test", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_INTERFACE_NAME, "eth0", - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP stuff */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - g_object_set (G_OBJECT (s_ip4), NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - g_object_set (G_OBJECT (s_ip6), NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - /* DCB */ - s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); - nm_connection_add_setting (connection, NM_SETTING (s_dcb)); - - g_object_set (G_OBJECT (s_dcb), - NM_SETTING_DCB_APP_FCOE_FLAGS, DCB_ALL_FLAGS, - NM_SETTING_DCB_APP_FCOE_PRIORITY, 5, - NM_SETTING_DCB_APP_ISCSI_FLAGS, DCB_ALL_FLAGS, - NM_SETTING_DCB_APP_ISCSI_PRIORITY, 1, - NM_SETTING_DCB_APP_FIP_FLAGS, DCB_ALL_FLAGS, - NM_SETTING_DCB_APP_FIP_PRIORITY, 3, - NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, DCB_ALL_FLAGS, - NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, DCB_ALL_FLAGS, - NULL); - - for (i = 0; i < 8; i++) { - nm_setting_dcb_set_priority_flow_control (s_dcb, i, pfcs[i]); - nm_setting_dcb_set_priority_group_id (s_dcb, i, group_ids[i]); - nm_setting_dcb_set_priority_group_bandwidth (s_dcb, i, group_bandwidths[i]); - nm_setting_dcb_set_priority_bandwidth (s_dcb, i, bandwidths[i]); - nm_setting_dcb_set_priority_strict_bandwidth (s_dcb, i, strict[i]); - nm_setting_dcb_set_priority_traffic_class (s_dcb, i, traffic_classes[i]); - } - - nmtst_assert_connection_verifies (connection); - - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"//ifcfg-dcb-test.cexpected", - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_read_dcb_default_app_priorities (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSettingDcb *s_dcb; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-dcb-default-app-priorities", - NULL, TYPE_ETHERNET, NULL); - - s_dcb = nm_connection_get_setting_dcb (connection); - g_assert (s_dcb); - - g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE); - g_assert_cmpint (nm_setting_dcb_get_app_fcoe_priority (s_dcb), ==, -1); - - g_assert_cmpint (nm_setting_dcb_get_app_iscsi_flags (s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE); - g_assert_cmpint (nm_setting_dcb_get_app_iscsi_priority (s_dcb), ==, -1); - - g_assert_cmpint (nm_setting_dcb_get_app_fip_flags (s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE); - g_assert_cmpint (nm_setting_dcb_get_app_fip_priority (s_dcb), ==, -1); -} - -static void -test_read_dcb_bad_booleans (void) -{ - gs_free_error GError *error = NULL; - - NMTST_EXPECT_NM_WARN ("*invalid DCB_PG_STRICT value*not all 0s and 1s*"); - _connection_from_file_fail (TEST_IFCFG_DIR"/ifcfg-test-dcb-bad-booleans", - NULL, TYPE_ETHERNET, &error); - g_test_assert_expected_messages (); - - g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); - g_assert (strstr (error->message, "invalid boolean digit")); -} - -static void -test_read_dcb_short_booleans (void) -{ - gs_free_error GError *error = NULL; - - NMTST_EXPECT_NM_WARN ("*DCB_PG_STRICT value*8 characters*"); - _connection_from_file_fail (TEST_IFCFG_DIR"/ifcfg-test-dcb-short-booleans", - NULL, TYPE_ETHERNET, &error); - g_test_assert_expected_messages (); - - g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); - g_assert (strstr (error->message, "boolean array must be 8 characters")); -} - -static void -test_read_dcb_bad_uints (void) -{ - gs_free_error GError *error = NULL; - - NMTST_EXPECT_NM_WARN ("*invalid DCB_PG_UP2TC value*not 0 - 7*"); - _connection_from_file_fail (TEST_IFCFG_DIR"/ifcfg-test-dcb-bad-uints", - NULL, TYPE_ETHERNET, &error); - g_test_assert_expected_messages (); - - g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); - g_assert (strstr (error->message, "invalid uint digit")); -} - -static void -test_read_dcb_short_uints (void) -{ - gs_free_error GError *error = NULL; - - NMTST_EXPECT_NM_WARN ("*DCB_PG_UP2TC value*8 characters*"); - _connection_from_file_fail (TEST_IFCFG_DIR"/ifcfg-test-dcb-short-uints", - NULL, TYPE_ETHERNET, &error); - g_test_assert_expected_messages (); - - g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); - g_assert (strstr (error->message, "uint array must be 8 characters")); -} - -static void -test_read_dcb_bad_percent (void) -{ - gs_free_error GError *error = NULL; - - NMTST_EXPECT_NM_WARN ("*invalid DCB_PG_PCT percentage value*"); - _connection_from_file_fail (TEST_IFCFG_DIR"/ifcfg-test-dcb-bad-percent", - NULL, TYPE_ETHERNET, &error); - g_test_assert_expected_messages (); - - g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); - g_assert (strstr (error->message, "invalid percent element")); -} - -static void -test_read_dcb_short_percent (void) -{ - gs_free_error GError *error = NULL; - - NMTST_EXPECT_NM_WARN ("*invalid DCB_PG_PCT percentage list value*"); - _connection_from_file_fail (TEST_IFCFG_DIR"/ifcfg-test-dcb-short-percent", - NULL, TYPE_ETHERNET, &error); - g_test_assert_expected_messages (); - - g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); - g_assert (strstr (error->message, "percent array must be 8 elements")); -} - -static void -test_read_dcb_pgpct_not_100 (void) -{ - gs_free_error GError *error = NULL; - - NMTST_EXPECT_NM_WARN ("*DCB_PG_PCT percentages do not equal 100*"); - _connection_from_file_fail (TEST_IFCFG_DIR"/ifcfg-test-dcb-pgpct-not-100", - NULL, TYPE_ETHERNET, &error); - g_test_assert_expected_messages (); - - g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); - g_assert (strstr (error->message, "invalid percentage sum")); -} - -static void -test_read_fcoe_mode (gconstpointer user_data) -{ - gs_unref_object NMConnection *connection = NULL; - gs_free char *file = NULL; - const char *expected_mode = user_data; - NMSettingDcb *s_dcb; - - file = g_strdup_printf (TEST_IFCFG_DIR"/ifcfg-test-fcoe-%s", expected_mode); - connection = _connection_from_file (file, NULL, TYPE_ETHERNET, NULL); - - s_dcb = nm_connection_get_setting_dcb (connection); - g_assert (s_dcb); - - g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE); - g_assert_cmpstr (nm_setting_dcb_get_app_fcoe_mode (s_dcb), ==, expected_mode); + g_object_unref(connection); } static void -test_write_fcoe_mode (gconstpointer user_data) +test_write_team_port(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - const char *expected_mode = user_data; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingDcb *s_dcb; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - shvarFile *ifcfg; - - connection = nm_simple_connection_new (); + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingTeamPort * s_team_port; + NMSettingWired * s_wired; + const char * expected_config = "{\"p4p1\": {\"prio\": -10, \"sticky\": true}}"; + shvarFile * f; - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - g_object_set (G_OBJECT (s_con), - NM_SETTING_CONNECTION_ID, "fcoe-test", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_INTERFACE_NAME, "eth0", - NULL); + connection = nm_simple_connection_new(); - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - /* IP stuff */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - g_object_set (G_OBJECT (s_ip4), NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Team Port", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_MASTER, + "team0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_TEAM_SETTING_NAME, + NULL); - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - g_object_set (G_OBJECT (s_ip6), NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + /* Team setting */ + s_team_port = (NMSettingTeamPort *) nm_setting_team_port_new(); + nm_connection_add_setting(connection, NM_SETTING(s_team_port)); + g_object_set(s_team_port, NM_SETTING_TEAM_PORT_CONFIG, expected_config, NULL); - /* DCB */ - s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); - nm_connection_add_setting (connection, NM_SETTING (s_dcb)); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - g_object_set (G_OBJECT (s_dcb), - NM_SETTING_DCB_APP_FCOE_FLAGS, NM_SETTING_DCB_FLAG_ENABLE, - NM_SETTING_DCB_APP_FCOE_MODE, expected_mode, - NULL); + nmtst_assert_connection_verifies(connection); - nmtst_assert_connection_verifies (connection); + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Team_Port.cexpected", + &testfile); - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); + f = _svOpenFile(testfile); + _svGetValue_check(f, "TYPE", NULL); + _svGetValue_check(f, "DEVICETYPE", "TeamPort"); + _svGetValue_check(f, "TEAM_PORT_CONFIG", expected_config); + _svGetValue_check(f, "TEAM_MASTER", "team0"); + svCloseFile(f); - ifcfg = _svOpenFile (testfile); - _svGetValue_check (ifcfg, "DCB_APP_FCOE_MODE", expected_mode); - svCloseFile (ifcfg); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -test_read_team_master (gconstpointer user_data) +test_write_team_infiniband_port(void) { - const char *const PATH_NAME = user_data; - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingTeam *s_team; - const char *expected_config = "{\"device\": \"team0\", \"link_watch\": {\"name\": \"ethtool\"}}"; + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingTeamPort * s_team_port; + NMSettingInfiniband * s_inf; + const char * expected_config = "{\"inf1\": {\"prio\": -10, \"sticky\": true}}"; + shvarFile * f; - connection = _connection_from_file (PATH_NAME, NULL, TYPE_ETHERNET, NULL); + connection = nm_simple_connection_new(); - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "team0"); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Team Infiniband Port", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_INFINIBAND_SETTING_NAME, + NM_SETTING_CONNECTION_MASTER, + "team0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_TEAM_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME, + "inf1", + NULL); + + /* Team setting */ + s_team_port = (NMSettingTeamPort *) nm_setting_team_port_new(); + nm_connection_add_setting(connection, NM_SETTING(s_team_port)); + g_object_set(s_team_port, NM_SETTING_TEAM_PORT_CONFIG, expected_config, NULL); + + /* Infiniband setting */ + s_inf = (NMSettingInfiniband *) nm_setting_infiniband_new(); + nm_connection_add_setting(connection, NM_SETTING(s_inf)); + g_object_set(s_inf, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Team_Infiniband_Port.cexpected", + &testfile); + + f = _svOpenFile(testfile); + _svGetValue_check(f, "TYPE", "InfiniBand"); + _svGetValue_check(f, "DEVICETYPE", "TeamPort"); + _svGetValue_check(f, "TEAM_PORT_CONFIG", expected_config); + _svGetValue_check(f, "TEAM_MASTER", "team0"); + svCloseFile(f); + + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); +} + +static void +test_read_team_port_empty_config(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-team-port-empty-config", + NULL, + TYPE_ETHERNET, + NULL); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, "team0"); + + /* Normalization adds a team-port setting */ + g_assert(nm_connection_get_setting_team_port(connection)); + + /* empty/missing config */ + g_assert(!nm_setting_team_port_get_config(nm_connection_get_setting_team_port(connection))); + + g_object_unref(connection); +} + +static void +test_team_reread_slave(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection_1 = NULL; + gs_unref_object NMConnection *connection_2 = NULL; + gs_unref_object NMConnection *reread = NULL; + gboolean reread_same = FALSE; + NMSettingConnection * s_con; + + connection_1 = + nmtst_create_connection_from_keyfile("[connection]\n" + "id=team-slave-enp31s0f1-142\n" + "uuid=74f435bb-ede4-415a-9d48-f580b60eba04\n" + "type=vlan\n" + "autoconnect=false\n" + "interface-name=enp31s0f1-142\n" + "master=team142\n" + "permissions=\n" + "slave-type=team\n" + "\n" + "[vlan]\n" + "egress-priority-map=\n" + "flags=1\n" + "id=142\n" + "ingress-priority-map=\n" + "parent=enp31s0f1\n", + "/test_team_reread_slave"); + + /* to double-check keyfile syntax, re-create the connection by hand. */ + connection_2 = nmtst_create_minimal_connection("team-slave-enp31s0f1-142", + "74f435bb-ede4-415a-9d48-f580b60eba04", + NM_SETTING_VLAN_SETTING_NAME, + &s_con); + g_object_set(s_con, + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NM_SETTING_CONNECTION_INTERFACE_NAME, + "enp31s0f1-142", + NM_SETTING_CONNECTION_MASTER, + "team142", + NM_SETTING_CONNECTION_SLAVE_TYPE, + "team", + NULL); + g_object_set(nm_connection_get_setting_vlan(connection_2), + NM_SETTING_VLAN_FLAGS, + 1, + NM_SETTING_VLAN_ID, + 142, + NM_SETTING_VLAN_PARENT, + "enp31s0f1", + NULL); + nm_connection_add_setting(connection_2, nm_setting_team_port_new()); + nmtst_connection_normalize(connection_2); + + nmtst_assert_connection_equals(connection_1, FALSE, connection_2, FALSE); + + _writer_new_connection_reread((nmtst_get_rand_uint32() % 2) ? connection_1 : connection_2, + TEST_SCRATCH_DIR, + &testfile, + TEST_IFCFG_DIR "/ifcfg-team-slave-enp31s0f1-142.cexpected", + &reread, + &reread_same); + _assert_reread_same((nmtst_get_rand_uint32() % 2) ? connection_1 : connection_2, reread); + g_assert(reread_same); + g_clear_object(&reread); + + reread = _connection_from_file(testfile, NULL, TYPE_VLAN, NULL); + nmtst_assert_connection_equals((nmtst_get_rand_uint32() % 2) ? connection_1 : connection_2, + FALSE, + reread, + FALSE); +} + +static void +test_read_proxy_basic(void) +{ + NMConnection * connection; + NMSettingProxy *s_proxy; + + /* Test basic proxy configuration */ + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-read-proxy-basic", + NULL, + TYPE_ETHERNET, + NULL); + + /* ===== Proxy setting ===== */ + s_proxy = nm_connection_get_setting_proxy(connection); + g_assert(s_proxy); + + /* Proxy method */ + g_assert_cmpint(nm_setting_proxy_get_method(s_proxy), ==, NM_SETTING_PROXY_METHOD_AUTO); + g_assert(nm_setting_proxy_get_browser_only(s_proxy)); + g_assert_cmpstr(nm_setting_proxy_get_pac_url(s_proxy), + ==, + "http://wpad.mycompany.com/wpad.dat"); + + g_object_unref(connection); +} + +static void +test_write_proxy_basic(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingProxy * s_proxy; + const char * expected_url = "https://wpad.neverland.org/wpad.dat"; + shvarFile * f; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Proxy Basic", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Proxy setting */ + s_proxy = (NMSettingProxy *) nm_setting_proxy_new(); + nm_connection_add_setting(connection, NM_SETTING(s_proxy)); + g_object_set(s_proxy, NM_SETTING_PROXY_METHOD, NM_SETTING_PROXY_METHOD_AUTO, NULL); + g_object_set(s_proxy, NM_SETTING_PROXY_PAC_URL, expected_url, NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + nmtst_assert_connection_verifies(connection); + + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-Test_Write_Proxy_Basic.cexpected", + &testfile); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_TEAM_SETTING_NAME); + f = _svOpenFile(testfile); + _svGetValue_check(f, "TYPE", "Ethernet"); + _svGetValue_check(f, "PROXY_METHOD", "auto"); + _svGetValue_check(f, "PAC_URL", expected_url); + svCloseFile(f); - s_team = nm_connection_get_setting_team (connection); - g_assert (s_team); - g_assert_cmpstr (nm_setting_team_get_config (s_team), ==, expected_config); + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - g_object_unref (connection); -} - -static void -test_read_team_master_invalid (gconstpointer user_data) -{ - const char *const PATH_NAME = user_data; - gs_free_error GError *error = NULL; - gs_unref_object NMConnection *connection = NULL; - - if (WITH_JSON_VALIDATION) { - _connection_from_file_fail (PATH_NAME, NULL, TYPE_ETHERNET, &error); - - g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); - g_assert (strstr (error->message, _("invalid json"))); - } else - connection = _connection_from_file (PATH_NAME, NULL, TYPE_ETHERNET, NULL); -} - -static void -test_write_team_master (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingTeam *s_team; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - const char *expected_config = "{\"device\": \"team0\", \"link_watch\": {\"name\": \"ethtool\"}}"; - shvarFile *f; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Team Master", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_INTERFACE_NAME, "team0", - NM_SETTING_CONNECTION_TYPE, NM_SETTING_TEAM_SETTING_NAME, - NULL); - - /* Team setting */ - s_team = (NMSettingTeam *) nm_setting_team_new (); - nm_connection_add_setting (connection, NM_SETTING (s_team)); - - g_object_set (s_team, - NM_SETTING_TEAM_CONFIG, expected_config, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NULL); - - nm_connection_add_setting (connection, nm_setting_proxy_new ()); - - nmtst_assert_connection_verifies_without_normalization (connection); - - _writer_new_connection (connection, - TEST_SCRATCH_DIR, - &testfile); - - f = _svOpenFile (testfile); - _svGetValue_check (f, "DEVICETYPE", "Team"); - _svGetValue_check (f, "TEAM_CONFIG", expected_config); - svCloseFile (f); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_read_team_port (gconstpointer user_data) -{ - const char *const PATH_NAME = user_data; - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingTeamPort *s_team_port; - const char *expected_config = "{\"p4p1\": {\"prio\": -10, \"sticky\": true}}"; - - connection = _connection_from_file (PATH_NAME, NULL, TYPE_ETHERNET, NULL); - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); - g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, "team0"); - - s_team_port = nm_connection_get_setting_team_port (connection); - g_assert (s_team_port); - g_assert_cmpstr (nm_setting_team_port_get_config (s_team_port), ==, expected_config); - - g_object_unref (connection); -} - -static void -test_write_team_port (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingTeamPort *s_team_port; - NMSettingWired *s_wired; - const char *expected_config = "{\"p4p1\": {\"prio\": -10, \"sticky\": true}}"; - shvarFile *f; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Team Port", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, "team0", - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, - NULL); - - /* Team setting */ - s_team_port = (NMSettingTeamPort *) nm_setting_team_port_new (); - nm_connection_add_setting (connection, NM_SETTING (s_team_port)); - g_object_set (s_team_port, NM_SETTING_TEAM_PORT_CONFIG, expected_config, NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Team_Port.cexpected", - &testfile); - - f = _svOpenFile (testfile); - _svGetValue_check (f, "TYPE", NULL); - _svGetValue_check (f, "DEVICETYPE", "TeamPort"); - _svGetValue_check (f, "TEAM_PORT_CONFIG", expected_config); - _svGetValue_check (f, "TEAM_MASTER", "team0"); - svCloseFile (f); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_write_team_infiniband_port (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingTeamPort *s_team_port; - NMSettingInfiniband *s_inf; - const char *expected_config = "{\"inf1\": {\"prio\": -10, \"sticky\": true}}"; - shvarFile *f; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Team Infiniband Port", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_INFINIBAND_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, "team0", - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, - NM_SETTING_CONNECTION_INTERFACE_NAME, "inf1", - NULL); - - /* Team setting */ - s_team_port = (NMSettingTeamPort *) nm_setting_team_port_new (); - nm_connection_add_setting (connection, NM_SETTING (s_team_port)); - g_object_set (s_team_port, NM_SETTING_TEAM_PORT_CONFIG, expected_config, NULL); - - /* Infiniband setting */ - s_inf = (NMSettingInfiniband *) nm_setting_infiniband_new (); - nm_connection_add_setting (connection, NM_SETTING (s_inf)); - g_object_set (s_inf, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Team_Infiniband_Port.cexpected", - &testfile); - - f = _svOpenFile (testfile); - _svGetValue_check (f, "TYPE", "InfiniBand"); - _svGetValue_check (f, "DEVICETYPE", "TeamPort"); - _svGetValue_check (f, "TEAM_PORT_CONFIG", expected_config); - _svGetValue_check (f, "TEAM_MASTER", "team0"); - svCloseFile (f); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void -test_read_team_port_empty_config (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-team-port-empty-config", - NULL, TYPE_ETHERNET, NULL); - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); - g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, "team0"); - - /* Normalization adds a team-port setting */ - g_assert (nm_connection_get_setting_team_port (connection)); - - /* empty/missing config */ - g_assert (!nm_setting_team_port_get_config (nm_connection_get_setting_team_port (connection))); - - g_object_unref (connection); -} - -static void -test_team_reread_slave (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection_1 = NULL; - gs_unref_object NMConnection *connection_2 = NULL; - gs_unref_object NMConnection *reread = NULL; - gboolean reread_same = FALSE; - NMSettingConnection *s_con; - - connection_1 = nmtst_create_connection_from_keyfile ( - "[connection]\n" - "id=team-slave-enp31s0f1-142\n" - "uuid=74f435bb-ede4-415a-9d48-f580b60eba04\n" - "type=vlan\n" - "autoconnect=false\n" - "interface-name=enp31s0f1-142\n" - "master=team142\n" - "permissions=\n" - "slave-type=team\n" - "\n" - "[vlan]\n" - "egress-priority-map=\n" - "flags=1\n" - "id=142\n" - "ingress-priority-map=\n" - "parent=enp31s0f1\n" - , "/test_team_reread_slave"); - - /* to double-check keyfile syntax, re-create the connection by hand. */ - connection_2 = nmtst_create_minimal_connection ("team-slave-enp31s0f1-142", "74f435bb-ede4-415a-9d48-f580b60eba04", NM_SETTING_VLAN_SETTING_NAME, &s_con); - g_object_set (s_con, - NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, - NM_SETTING_CONNECTION_INTERFACE_NAME, "enp31s0f1-142", - NM_SETTING_CONNECTION_MASTER, "team142", - NM_SETTING_CONNECTION_SLAVE_TYPE, "team", - NULL); - g_object_set (nm_connection_get_setting_vlan (connection_2), - NM_SETTING_VLAN_FLAGS, 1, - NM_SETTING_VLAN_ID, 142, - NM_SETTING_VLAN_PARENT, "enp31s0f1", - NULL); - nm_connection_add_setting (connection_2, nm_setting_team_port_new ()); - nmtst_connection_normalize (connection_2); - - nmtst_assert_connection_equals (connection_1, FALSE, connection_2, FALSE); - - _writer_new_connection_reread ((nmtst_get_rand_uint32 () % 2) ? connection_1 : connection_2, - TEST_SCRATCH_DIR, - &testfile, - TEST_IFCFG_DIR"/ifcfg-team-slave-enp31s0f1-142.cexpected", - &reread, - &reread_same); - _assert_reread_same ((nmtst_get_rand_uint32 () % 2) ? connection_1 : connection_2, reread); - g_assert (reread_same); - g_clear_object (&reread); - - reread = _connection_from_file (testfile, NULL, TYPE_VLAN, - NULL); - nmtst_assert_connection_equals ((nmtst_get_rand_uint32 () % 2) ? connection_1 : connection_2, FALSE, - reread, FALSE); -} - -static void -test_read_proxy_basic (void) -{ - NMConnection *connection; - NMSettingProxy *s_proxy; - - /* Test basic proxy configuration */ - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-read-proxy-basic", - NULL, TYPE_ETHERNET, NULL); - - /* ===== Proxy setting ===== */ - s_proxy = nm_connection_get_setting_proxy (connection); - g_assert (s_proxy); - - /* Proxy method */ - g_assert_cmpint (nm_setting_proxy_get_method (s_proxy), ==, NM_SETTING_PROXY_METHOD_AUTO); - g_assert (nm_setting_proxy_get_browser_only (s_proxy)); - g_assert_cmpstr (nm_setting_proxy_get_pac_url (s_proxy), ==, "http://wpad.mycompany.com/wpad.dat"); - - g_object_unref (connection); -} - -static void -test_write_proxy_basic (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingProxy *s_proxy; - const char *expected_url = "https://wpad.neverland.org/wpad.dat"; - shvarFile *f; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Proxy Basic", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Proxy setting */ - s_proxy = (NMSettingProxy *) nm_setting_proxy_new (); - nm_connection_add_setting (connection, NM_SETTING (s_proxy)); - g_object_set (s_proxy, NM_SETTING_PROXY_METHOD, NM_SETTING_PROXY_METHOD_AUTO, NULL); - g_object_set (s_proxy, NM_SETTING_PROXY_PAC_URL, expected_url, NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - nmtst_assert_connection_verifies (connection); - - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Proxy_Basic.cexpected", - &testfile); - - f = _svOpenFile (testfile); - _svGetValue_check (f, "TYPE", "Ethernet"); - _svGetValue_check (f, "PROXY_METHOD", "auto"); - _svGetValue_check (f, "PAC_URL", expected_url); - svCloseFile (f); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } /*****************************************************************************/ static const char * -_svUnescape (const char *str, char **to_free) +_svUnescape(const char *str, char **to_free) { - const char *s; - gs_free char *str_free = NULL; + const char * s; + gs_free char *str_free = NULL; - g_assert (str); - g_assert (to_free); + g_assert(str); + g_assert(to_free); - if (str[0] == '\0') { - /* avoid static string "" */ - str = (str_free = g_strdup (str)); - } + if (str[0] == '\0') { + /* avoid static string "" */ + str = (str_free = g_strdup(str)); + } - s = svUnescape (str, to_free); - if (*to_free) { - g_assert (s == *to_free); - g_assert (s[0]); - } else { - g_assert ( s == NULL - || (!s[0] && (s < str || s > strchr (str, '\0'))) - || ( s[0] && s >= str && s <= strchr (str, '\0') )); - } - return s; + s = svUnescape(str, to_free); + if (*to_free) { + g_assert(s == *to_free); + g_assert(s[0]); + } else { + g_assert(s == NULL || (!s[0] && (s < str || s > strchr(str, '\0'))) + || (s[0] && s >= str && s <= strchr(str, '\0'))); + } + return s; } typedef struct { - const char *val; - const char *exp; - bool can_concat:1; - bool needs_ascii_separator:1; + const char *val; + const char *exp; + bool can_concat : 1; + bool needs_ascii_separator : 1; } UnescapeTestData; static void -do_svUnescape_assert (const char *str, const char *expected) -{ - gs_free char *to_free = NULL; - const char *s; - - s = _svUnescape (str, &to_free); - g_assert_cmpstr (s, ==, expected); - - /* check we can make a round-trip */ - if (expected) { - gs_free char *s1_free = NULL; - gs_free char *s2_free = NULL; - const char *s1, *s2; - - s1 = svEscape (expected, &s1_free); - g_assert (s1); - - s2 = _svUnescape (s1, &s2_free); - g_assert (s2); - - g_assert_cmpstr (s2, ==, expected); - } -} - -static void -do_svUnescape_combine_ansi_append (GString *str_val, GString *str_exp, const UnescapeTestData *data, gboolean honor_needs_ascii_separator) -{ - g_string_append (str_val, data->val); - g_string_append (str_exp, data->exp); - if (honor_needs_ascii_separator && data->needs_ascii_separator) { - /* the string has an open escape sequence. We must ensure that when - * combining it with another sequence, that they don't merge into - * something diffent. for example "\xa" + "a" must not result in - * "\xaa". Instead, we add a space in between to get "\xa a". */ - g_string_append (str_val, " "); - g_string_append (str_exp, " "); - } -} - -static void -do_svUnescape_combine_ansi (GString *str_val, GString *str_exp, const UnescapeTestData *data_ansi, gsize data_len, gssize idx) -{ - gsize i, j; - - g_string_set_size (str_val, 0); - g_string_set_size (str_exp, 0); - g_string_append (str_val, "$'"); - if (idx < 0) { - for (i = -idx; i > 0; i--) { - j = nmtst_get_rand_uint32 () % data_len; - if (!data_ansi[j].can_concat) { - i++; - continue; - } - do_svUnescape_combine_ansi_append (str_val, str_exp, &data_ansi[j], i > 1); - } - } else { - g_assert_cmpint (idx, <, data_len); - do_svUnescape_combine_ansi_append (str_val, str_exp, &data_ansi[idx], FALSE); - } - g_string_append (str_val, "'"); -} - -static void -test_svUnescape (void) -{ -#define V0(v_value, v_expected) { .val = ""v_value"", .exp = v_expected, .can_concat = FALSE, } -#define V1(v_value, v_expected) { .val = ""v_value"", .exp = v_expected, .can_concat = !!v_expected, } -#define V2(v_value, v_expected) { .val = ""v_value"", .exp = v_expected, .can_concat = TRUE, .needs_ascii_separator = TRUE, } - const UnescapeTestData data_full[] = { - V1 ("", ""), - V0 ("'", NULL), - V1 ("'x'", "x"), - V1 ("' '", " "), - V1 ("'x'", "x"), - V0 ("\"", NULL), - V0 ("\\", NULL), - V0 (" ", ""), - V0 (" ", ""), - V0 ("a; #", "a"), - V0 (" ; #", ""), - V0 ("; ", ""), - V0 ("; ;", NULL), - V0 (" ; a #", NULL), - V0 (" ; a;; #", NULL), - V0 ("a; ; #", NULL), - V0 ("\t # ", ""), - V0 ("\t #a", ""), - V0 ("\t #a\r", ""), - V0 ("\r", ""), - V1 ("\\\"", "\""), - V1 ("\\`", "`"), - V1 ("\\$", "$"), - V1 ("\\\\", "\\"), - V1 ("\\a", "a"), - V1 ("\\b", "b"), - V1 ("\\'", "'"), - V1 ("\\~", "~"), - V1 ("\\\t", "\t"), - V1 ("\"\\\"\"", "\""), - V1 ("\"\\`\"", "`"), - V1 ("\"\\$\"", "$"), - V1 ("\"\\\\\"", "\\"), - V1 ("\"\\a\"", "\\a"), - V1 ("\"\\b\"", "\\b"), - V1 ("\"\\\t\"", "\\\t"), - V0 ("ab\r", "ab"), - V0 ("a'b'\r ", "ab"), - V0 ("a'b' \r", "ab"), - V0 ("a#b", "a#b"), - V0 ("#b", "#b"), - V1 ("\'some string\'", "some string"), - V0 ("Bob outside LAN", NULL), - V1 ("x", "x"), - V1 ("'{ \"device\": \"team0\", \"link_watch\": { \"name\": \"ethtool\" } }'", - "{ \"device\": \"team0\", \"link_watch\": { \"name\": \"ethtool\" } }"), - V1 ("'{\"device\": \"team0\", \"link_watch\": {\"name\": \"ethtool\"}}'", - "{\"device\": \"team0\", \"link_watch\": {\"name\": \"ethtool\"}}"), - V1 ("x\"\"b", "xb"), - V1 ("x\"c\"b", "xcb"), - V1 ("\"c\"b", "cb"), - V1 ("\"c\"\\'b", "c'b"), - V1 ("$''", ""), - V1 ("$'\\n'", "\n"), - V0 ("$'\\'", NULL), - V1 ("$'\\x'", "\\x"), - V1 ("$'\\xa'", "\xa"), - V0 ("$'\\x0'", ""), - V1 ("$'\\x12'", "\x12"), - V1 ("$'\\x12A'", "\x12""A"), - V1 ("$'\\x12t'", "\x12t"), - V1 ("\"aa\\\"\"", "aa\""), - V1 ("\"aa\\\"b\"c", "aa\"bc"), - V1 ("\"aa\\\"\"b", "aa\"b"), - - /* the following is not shell behavior, but kept for backward compatibility - * with old svEscape(). */ - V0 ("\"\\'\"", "'"), - V0 ("\"\\~\"", "~"), - V0 ("\"b\\~b\"", "b~b"), - V0 ("\"\\~\\~\"", "~~"), - V0 ("\"\\~\\'\"", "~'"), - - /* the following is shell-behavior, because it doesn't look like written - * by old svEscape(). */ - V1 ("\"\\~~\"", "\\~~"), - V1 ("\"\\a\\'\"", "\\a\\'"), - V1 ("x\"\\~\"", "x\\~"), - V1 ("\"\\'\"''", "\\'"), - V0 ("\"b\\~b\" ", "b\\~b"), - V1 ("\"b\\~b\"x", "b\\~bx"), - }; - const UnescapeTestData data_ansi[] = { - /* strings inside $''. They cannot be compared directly, but must - * be wrapped by do_svUnescape_combine_ansi(). */ - V1 ("", ""), - V1 ("a", "a"), - V1 ("b", "b"), - V1 ("x", "x"), - V1 (" ", " "), - V1 ("\\a", "\a"), - V1 ("\\b", "\b"), - V1 ("\\e", "\e"), - V1 ("\\E", "\E"), - V1 ("\\f", "\f"), - V1 ("\\n", "\n"), - V1 ("\\r", "\r"), - V1 ("\\t", "\t"), - V1 ("\\v", "\v"), - V1 ("\\\\", "\\"), - V1 ("\\'", "'"), - V1 ("\\\"", "\""), - V1 ("\\?", "\?"), - V1 ("\\?", "?"), - V2 ("\\8", "\\8"), - V2 ("\\1", "\1"), - V1 ("\\1A", "\1A"), - V1 ("\\18", "\18"), - V2 ("\\01", "\1"), - V1 ("\\001", "\1"), - V0 ("\\008", ""), - V1 ("\\018", "\0018"), - V0 ("\\08", ""), - V1 ("\\18", "\0018"), - V1 ("\\x", "\\x"), - V2 ("\\xa", "\xa"), - V1 ("\\x12", "\x12"), - V1 ("\\x12A", "\x12""A"), - V1 ("\\x12a", "\x12""a"), - V1 ("\\x12t", "\x12t"), - V1 ("\\x1a", "\x1a"), - V1 ("\\x1A", "\x1A"), - V1 ("\\ut", "\\ut"), - V2 ("\\ua", "\xa"), - V1 ("\\uat", "\xat"), - V2 ("\\uab", "\xc2\xab"), - V1 ("\\uabt", "\xc2\xabt"), - V2 ("\\uabc", "\xe0\xaa\xbc"), - V1 ("\\uabct", "\xe0\xaa\xbct"), - V2 ("\\uabcd", "\xea\xaf\x8d"), - V1 ("\\uabcdt", "\xea\xaf\x8dt"), - V2 ("\\uabcde", "\xea\xaf\x8d""e"), - V1 ("\\uabcdet", "\xea\xaf\x8d""et"), - V1 ("\\Ut", "\\Ut"), - V2 ("\\Ua", "\xa"), - V1 ("\\Uat", "\xat"), - V2 ("\\Uab", "\xc2\xab"), - V1 ("\\Uabt", "\xc2\xabt"), - V2 ("\\Uabc", "\xe0\xaa\xbc"), - V1 ("\\Uabct", "\xe0\xaa\xbct"), - V2 ("\\Uabcd", "\xea\xaf\x8d"), - V1 ("\\Uabcdt", "\xea\xaf\x8dt"), - V2 ("\\Uabcde", "\xf2\xab\xb3\x9e"), - V1 ("\\Uabcdet", "\xf2\xab\xb3\x9et"), - V2 ("\\Uabcde0", "\xf8\xaa\xbc\xb7\xa0"), - V1 ("\\Uabcde0t", "\xf8\xaa\xbc\xb7\xa0t"), - V2 ("\\Uabcde01", "\xfc\x8a\xaf\x8d\xb8\x81"), - V1 ("\\Uabcde01t", "\xfc\x8a\xaf\x8d\xb8\x81t"), - V2 ("\\U0abcde01", "\xfc\x8a\xaf\x8d\xb8\x81"), - V1 ("\\U0abcde01t", "\xfc\x8a\xaf\x8d\xb8\x81t"), - V1 ("\\U00abcde01", "\xf8\xaa\xbc\xb7\xa0""1"), - V1 ("\\U00abcde01t", "\xf8\xaa\xbc\xb7\xa0""1t"), - - /* control-x sequence is not supported */ - V1 ("\\c", "\\c"), - V1 ("\\c1", "\\c1"), - }; +do_svUnescape_assert(const char *str, const char *expected) +{ + gs_free char *to_free = NULL; + const char * s; + + s = _svUnescape(str, &to_free); + g_assert_cmpstr(s, ==, expected); + + /* check we can make a round-trip */ + if (expected) { + gs_free char *s1_free = NULL; + gs_free char *s2_free = NULL; + const char * s1, *s2; + + s1 = svEscape(expected, &s1_free); + g_assert(s1); + + s2 = _svUnescape(s1, &s2_free); + g_assert(s2); + + g_assert_cmpstr(s2, ==, expected); + } +} + +static void +do_svUnescape_combine_ansi_append(GString * str_val, + GString * str_exp, + const UnescapeTestData *data, + gboolean honor_needs_ascii_separator) +{ + g_string_append(str_val, data->val); + g_string_append(str_exp, data->exp); + if (honor_needs_ascii_separator && data->needs_ascii_separator) { + /* the string has an open escape sequence. We must ensure that when + * combining it with another sequence, that they don't merge into + * something different. for example "\xa" + "a" must not result in + * "\xaa". Instead, we add a space in between to get "\xa a". */ + g_string_append(str_val, " "); + g_string_append(str_exp, " "); + } +} + +static void +do_svUnescape_combine_ansi(GString * str_val, + GString * str_exp, + const UnescapeTestData *data_ansi, + gsize data_len, + gssize idx) +{ + gsize i, j; + + g_string_set_size(str_val, 0); + g_string_set_size(str_exp, 0); + g_string_append(str_val, "$'"); + if (idx < 0) { + for (i = -idx; i > 0; i--) { + j = nmtst_get_rand_uint32() % data_len; + if (!data_ansi[j].can_concat) { + i++; + continue; + } + do_svUnescape_combine_ansi_append(str_val, str_exp, &data_ansi[j], i > 1); + } + } else { + g_assert_cmpint(idx, <, data_len); + do_svUnescape_combine_ansi_append(str_val, str_exp, &data_ansi[idx], FALSE); + } + g_string_append(str_val, "'"); +} + +static void +test_svUnescape(void) +{ +#define V0(v_value, v_expected) \ + { \ + .val = "" v_value "", .exp = v_expected, .can_concat = FALSE, \ + } +#define V1(v_value, v_expected) \ + { \ + .val = "" v_value "", .exp = v_expected, .can_concat = !!v_expected, \ + } +#define V2(v_value, v_expected) \ + { \ + .val = "" v_value "", .exp = v_expected, .can_concat = TRUE, \ + .needs_ascii_separator = TRUE, \ + } + const UnescapeTestData data_full[] = { + V1("", ""), + V0("'", NULL), + V1("'x'", "x"), + V1("' '", " "), + V1("'x'", "x"), + V0("\"", NULL), + V0("\\", NULL), + V0(" ", ""), + V0(" ", ""), + V0("a; #", "a"), + V0(" ; #", ""), + V0("; ", ""), + V0("; ;", NULL), + V0(" ; a #", NULL), + V0(" ; a;; #", NULL), + V0("a; ; #", NULL), + V0("\t # ", ""), + V0("\t #a", ""), + V0("\t #a\r", ""), + V0("\r", ""), + V1("\\\"", "\""), + V1("\\`", "`"), + V1("\\$", "$"), + V1("\\\\", "\\"), + V1("\\a", "a"), + V1("\\b", "b"), + V1("\\'", "'"), + V1("\\~", "~"), + V1("\\\t", "\t"), + V1("\"\\\"\"", "\""), + V1("\"\\`\"", "`"), + V1("\"\\$\"", "$"), + V1("\"\\\\\"", "\\"), + V1("\"\\a\"", "\\a"), + V1("\"\\b\"", "\\b"), + V1("\"\\\t\"", "\\\t"), + V0("ab\r", "ab"), + V0("a'b'\r ", "ab"), + V0("a'b' \r", "ab"), + V0("a#b", "a#b"), + V0("#b", "#b"), + V1("\'some string\'", "some string"), + V0("Bob outside LAN", NULL), + V1("x", "x"), + V1("'{ \"device\": \"team0\", \"link_watch\": { \"name\": \"ethtool\" } }'", + "{ \"device\": \"team0\", \"link_watch\": { \"name\": \"ethtool\" } }"), + V1("'{\"device\": \"team0\", \"link_watch\": {\"name\": \"ethtool\"}}'", + "{\"device\": \"team0\", \"link_watch\": {\"name\": \"ethtool\"}}"), + V1("x\"\"b", "xb"), + V1("x\"c\"b", "xcb"), + V1("\"c\"b", "cb"), + V1("\"c\"\\'b", "c'b"), + V1("$''", ""), + V1("$'\\n'", "\n"), + V0("$'\\'", NULL), + V1("$'\\x'", "\\x"), + V1("$'\\xa'", "\xa"), + V0("$'\\x0'", ""), + V1("$'\\x12'", "\x12"), + V1("$'\\x12A'", + "\x12" + "A"), + V1("$'\\x12t'", "\x12t"), + V1("\"aa\\\"\"", "aa\""), + V1("\"aa\\\"b\"c", "aa\"bc"), + V1("\"aa\\\"\"b", "aa\"b"), + + /* the following is not shell behavior, but kept for backward compatibility + * with old svEscape(). */ + V0("\"\\'\"", "'"), + V0("\"\\~\"", "~"), + V0("\"b\\~b\"", "b~b"), + V0("\"\\~\\~\"", "~~"), + V0("\"\\~\\'\"", "~'"), + + /* the following is shell-behavior, because it doesn't look like written + * by old svEscape(). */ + V1("\"\\~~\"", "\\~~"), + V1("\"\\a\\'\"", "\\a\\'"), + V1("x\"\\~\"", "x\\~"), + V1("\"\\'\"''", "\\'"), + V0("\"b\\~b\" ", "b\\~b"), + V1("\"b\\~b\"x", "b\\~bx"), + }; + const UnescapeTestData data_ansi[] = { + /* strings inside $''. They cannot be compared directly, but must + * be wrapped by do_svUnescape_combine_ansi(). */ + V1("", ""), + V1("a", "a"), + V1("b", "b"), + V1("x", "x"), + V1(" ", " "), + V1("\\a", "\a"), + V1("\\b", "\b"), + V1("\\e", "\e"), + V1("\\E", "\E"), + V1("\\f", "\f"), + V1("\\n", "\n"), + V1("\\r", "\r"), + V1("\\t", "\t"), + V1("\\v", "\v"), + V1("\\\\", "\\"), + V1("\\'", "'"), + V1("\\\"", "\""), + V1("\\?", "\?"), + V1("\\?", "?"), + V2("\\8", "\\8"), + V2("\\1", "\1"), + V1("\\1A", "\1A"), + V1("\\18", "\18"), + V2("\\01", "\1"), + V1("\\001", "\1"), + V0("\\008", ""), + V1("\\018", "\0018"), + V0("\\08", ""), + V1("\\18", "\0018"), + V1("\\x", "\\x"), + V2("\\xa", "\xa"), + V1("\\x12", "\x12"), + V1("\\x12A", + "\x12" + "A"), + V1("\\x12a", + "\x12" + "a"), + V1("\\x12t", "\x12t"), + V1("\\x1a", "\x1a"), + V1("\\x1A", "\x1A"), + V1("\\ut", "\\ut"), + V2("\\ua", "\xa"), + V1("\\uat", "\xat"), + V2("\\uab", "\xc2\xab"), + V1("\\uabt", "\xc2\xabt"), + V2("\\uabc", "\xe0\xaa\xbc"), + V1("\\uabct", "\xe0\xaa\xbct"), + V2("\\uabcd", "\xea\xaf\x8d"), + V1("\\uabcdt", "\xea\xaf\x8dt"), + V2("\\uabcde", + "\xea\xaf\x8d" + "e"), + V1("\\uabcdet", + "\xea\xaf\x8d" + "et"), + V1("\\Ut", "\\Ut"), + V2("\\Ua", "\xa"), + V1("\\Uat", "\xat"), + V2("\\Uab", "\xc2\xab"), + V1("\\Uabt", "\xc2\xabt"), + V2("\\Uabc", "\xe0\xaa\xbc"), + V1("\\Uabct", "\xe0\xaa\xbct"), + V2("\\Uabcd", "\xea\xaf\x8d"), + V1("\\Uabcdt", "\xea\xaf\x8dt"), + V2("\\Uabcde", "\xf2\xab\xb3\x9e"), + V1("\\Uabcdet", "\xf2\xab\xb3\x9et"), + V2("\\Uabcde0", "\xf8\xaa\xbc\xb7\xa0"), + V1("\\Uabcde0t", "\xf8\xaa\xbc\xb7\xa0t"), + V2("\\Uabcde01", "\xfc\x8a\xaf\x8d\xb8\x81"), + V1("\\Uabcde01t", "\xfc\x8a\xaf\x8d\xb8\x81t"), + V2("\\U0abcde01", "\xfc\x8a\xaf\x8d\xb8\x81"), + V1("\\U0abcde01t", "\xfc\x8a\xaf\x8d\xb8\x81t"), + V1("\\U00abcde01", + "\xf8\xaa\xbc\xb7\xa0" + "1"), + V1("\\U00abcde01t", + "\xf8\xaa\xbc\xb7\xa0" + "1t"), + + /* control-x sequence is not supported */ + V1("\\c", "\\c"), + V1("\\c1", "\\c1"), + }; #undef V0 #undef V1 #undef V2 - gsize i; - nm_auto_free_gstring GString *str_val = g_string_new (NULL); - nm_auto_free_gstring GString *str_val2 = g_string_new (NULL); - nm_auto_free_gstring GString *str_exp = g_string_new (NULL); - nm_auto_free_gstring GString *str_exp2 = g_string_new (NULL); - - do_svUnescape_assert ( "' '' '", " "); - - for (i = 0; i < G_N_ELEMENTS (data_full); i++) - do_svUnescape_assert (data_full[i].val, data_full[i].exp); - - for (i = 0; i < G_N_ELEMENTS (data_ansi); i++) { - do_svUnescape_combine_ansi (str_val, str_exp, data_ansi, G_N_ELEMENTS (data_ansi), i); - do_svUnescape_assert (str_val->str, str_exp->str); - } - - /* different values can be just concatenated... */ - for (i = 0; i < 200; i++) { - gsize num_concat = (nmtst_get_rand_uint32 () % 5) + 2; - - g_string_set_size (str_val, 0); - g_string_set_size (str_exp, 0); - - while (num_concat > 0) { - gsize idx; - - if ((nmtst_get_rand_uint32 () % 3 == 0)) { - do_svUnescape_combine_ansi (str_val2, str_exp2, data_ansi, G_N_ELEMENTS (data_ansi), -((int) ((nmtst_get_rand_uint32 () % 5) + 1))); - continue; - } - - idx = nmtst_get_rand_uint32 () % G_N_ELEMENTS (data_full); - if (!data_full[idx].can_concat) - continue; - g_string_append (str_val, data_full[idx].val); - g_string_append (str_exp, data_full[idx].exp); - num_concat--; - } - - switch (nmtst_get_rand_uint32 () % 3) { - case 0: - g_string_append (str_val, " "); - break; - case 1: - g_string_append (str_val, " "); - break; - } - switch (nmtst_get_rand_uint32 () % 3) { - case 0: - g_string_append (str_val, " #"); - break; - case 1: - g_string_append (str_val, " #foo"); - break; - } - do_svUnescape_assert (str_val->str, str_exp->str); - } + gsize i; + nm_auto_free_gstring GString *str_val = g_string_new(NULL); + nm_auto_free_gstring GString *str_val2 = g_string_new(NULL); + nm_auto_free_gstring GString *str_exp = g_string_new(NULL); + nm_auto_free_gstring GString *str_exp2 = g_string_new(NULL); + + do_svUnescape_assert("' '' '", " "); + + for (i = 0; i < G_N_ELEMENTS(data_full); i++) + do_svUnescape_assert(data_full[i].val, data_full[i].exp); + + for (i = 0; i < G_N_ELEMENTS(data_ansi); i++) { + do_svUnescape_combine_ansi(str_val, str_exp, data_ansi, G_N_ELEMENTS(data_ansi), i); + do_svUnescape_assert(str_val->str, str_exp->str); + } + + /* different values can be just concatenated... */ + for (i = 0; i < 200; i++) { + gsize num_concat = (nmtst_get_rand_uint32() % 5) + 2; + + g_string_set_size(str_val, 0); + g_string_set_size(str_exp, 0); + + while (num_concat > 0) { + gsize idx; + + if ((nmtst_get_rand_uint32() % 3 == 0)) { + do_svUnescape_combine_ansi(str_val2, + str_exp2, + data_ansi, + G_N_ELEMENTS(data_ansi), + -((int) ((nmtst_get_rand_uint32() % 5) + 1))); + continue; + } + + idx = nmtst_get_rand_uint32() % G_N_ELEMENTS(data_full); + if (!data_full[idx].can_concat) + continue; + g_string_append(str_val, data_full[idx].val); + g_string_append(str_exp, data_full[idx].exp); + num_concat--; + } + + switch (nmtst_get_rand_uint32() % 3) { + case 0: + g_string_append(str_val, " "); + break; + case 1: + g_string_append(str_val, " "); + break; + } + switch (nmtst_get_rand_uint32() % 3) { + case 0: + g_string_append(str_val, " #"); + break; + case 1: + g_string_append(str_val, " #foo"); + break; + } + do_svUnescape_assert(str_val->str, str_exp->str); + } } /*****************************************************************************/ static void -test_write_unknown (gconstpointer test_data) +test_write_unknown(gconstpointer test_data) { - nmtst_auto_unlinkfile char *filename_tmp_1 = g_strdup (TEST_SCRATCH_DIR_TMP"/tmp-1"); - const char *testfile = test_data; - gs_free char *testfile_expected = g_strconcat (testfile, ".expected", NULL); - shvarFile *sv; - gs_free_error GError *error = NULL; - gboolean success; - gs_free char *file_contents_out = NULL; - gs_free char *file_contents_exp = NULL; + nmtst_auto_unlinkfile char *filename_tmp_1 = g_strdup(TEST_SCRATCH_DIR_TMP "/tmp-1"); + const char * testfile = test_data; + gs_free char * testfile_expected = g_strconcat(testfile, ".expected", NULL); + shvarFile * sv; + gs_free_error GError *error = NULL; + gboolean success; + gs_free char * file_contents_out = NULL; + gs_free char * file_contents_exp = NULL; - sv = _svOpenFile (testfile); + sv = _svOpenFile(testfile); - _nmtst_svFileSetName (sv, filename_tmp_1); - _nmtst_svFileSetModified (sv); + _nmtst_svFileSetName(sv, filename_tmp_1); + _nmtst_svFileSetModified(sv); - if (g_str_has_suffix (testfile, "ifcfg-test-write-unknown-4")) { - _svGetValue_check (sv, "IPADDR", "l4x"); - _svGetValue_check (sv, "IPADDR2", ""); - _svGetValue_check (sv, "IPADDR3", "name3-value"); + if (g_str_has_suffix(testfile, "ifcfg-test-write-unknown-4")) { + _svGetValue_check(sv, "IPADDR", "l4x"); + _svGetValue_check(sv, "IPADDR2", ""); + _svGetValue_check(sv, "IPADDR3", "name3-value"); - svSetValue (sv, "IPADDR", "set-by-test1"); - svSetValue (sv, "IPADDR2", NULL); - svSetValue (sv, "IPADDR2", "set-by-test2"); - svSetValue (sv, "IPADDR3", "set-by-test3"); + svSetValue(sv, "IPADDR", "set-by-test1"); + svSetValue(sv, "IPADDR2", NULL); + svSetValue(sv, "IPADDR2", "set-by-test2"); + svSetValue(sv, "IPADDR3", "set-by-test3"); - _svGetValue_check (sv, "METRIC", NULL); - _svGetValue_check (sv, "METRIC1", ""); - _svGetValue_check (sv, "METRIC2", ""); - _svGetValue_check (sv, "METRIC3", "x"); + _svGetValue_check(sv, "METRIC", NULL); + _svGetValue_check(sv, "METRIC1", ""); + _svGetValue_check(sv, "METRIC2", ""); + _svGetValue_check(sv, "METRIC3", "x"); - _svGetValue_check (sv, "IPADDR", "set-by-test1"); - _svGetValue_check (sv, "IPADDR2", "set-by-test2"); - _svGetValue_check (sv, "IPADDR3", "set-by-test3"); - } + _svGetValue_check(sv, "IPADDR", "set-by-test1"); + _svGetValue_check(sv, "IPADDR2", "set-by-test2"); + _svGetValue_check(sv, "IPADDR3", "set-by-test3"); + } - success = svWriteFile (sv, 0644, &error); - nmtst_assert_success (success, error); + success = svWriteFile(sv, 0644, &error); + nmtst_assert_success(success, error); - file_contents_out = nmtst_file_get_contents (filename_tmp_1); - file_contents_exp = nmtst_file_get_contents (testfile_expected); + file_contents_out = nmtst_file_get_contents(filename_tmp_1); + file_contents_exp = nmtst_file_get_contents(testfile_expected); - g_assert_cmpstr (file_contents_out, ==, file_contents_exp); + g_assert_cmpstr(file_contents_out, ==, file_contents_exp); - svCloseFile (sv); + svCloseFile(sv); } /*****************************************************************************/ static void -test_read_vlan_trailing_spaces (void) +test_read_vlan_trailing_spaces(void) { - const char *testfile = TEST_IFCFG_DIR"/ifcfg-test-vlan-trailing-spaces"; - NMConnection *connection; - gboolean success; - GError *error = NULL; - NMSettingVlan *s_vlan; - char *contents = NULL; + const char * testfile = TEST_IFCFG_DIR "/ifcfg-test-vlan-trailing-spaces"; + NMConnection * connection; + gboolean success; + GError * error = NULL; + NMSettingVlan *s_vlan; + char * contents = NULL; - /* Ensure there is whitespace at the end of the VLAN interface name, - * to prevent the whitespace getting stripped off and committed mistakenly - * by something in the future. - */ - success = g_file_get_contents (testfile, &contents, NULL, &error); - g_assert_no_error (error); - g_assert (success); - g_assert (contents && contents[0]); - g_assert (strstr (contents, "DEVICE=\"vlan201\" \n")); - g_free (contents); + /* Ensure there is whitespace at the end of the VLAN interface name, + * to prevent the whitespace getting stripped off and committed mistakenly + * by something in the future. + */ + success = g_file_get_contents(testfile, &contents, NULL, &error); + g_assert_no_error(error); + g_assert(success); + g_assert(contents && contents[0]); + g_assert(strstr(contents, "DEVICE=\"vlan201\" \n")); + g_free(contents); - connection = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + connection = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "vlan201"); - g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "enccw0.0.fb00"); - g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 201); - g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "vlan201"); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "enccw0.0.fb00"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 201); + g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS); - g_object_unref (connection); + g_object_unref(connection); } /*****************************************************************************/ static void -test_sit_read_ignore (void) +test_sit_read_ignore(void) { - gs_free_error GError *error = NULL; + gs_free_error GError *error = NULL; - _connection_from_file_fail (TEST_IFCFG_DIR"/ifcfg-test-sit-ignore", - NULL, TYPE_ETHERNET, &error); - nmtst_assert_error (error, 0, 0, "*Ignoring unsupported connection due to IPV6TUNNELIPV4*"); + _connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-sit-ignore", + NULL, + TYPE_ETHERNET, + &error); + nmtst_assert_error(error, 0, 0, "*Ignoring unsupported connection due to IPV6TUNNELIPV4*"); } /*****************************************************************************/ static void -do_test_utils_name (const char *desc, - const char *path, - gboolean only_ifcfg, - const char *expected) +do_test_utils_name(const char *desc, const char *path, gboolean only_ifcfg, const char *expected) { - const char *result; + const char *result; - result = utils_get_ifcfg_name (path, only_ifcfg); - g_assert_cmpstr (result, ==, expected); + result = utils_get_ifcfg_name(path, only_ifcfg); + g_assert_cmpstr(result, ==, expected); } static void -test_utils_name (void) +test_utils_name(void) { - do_test_utils_name ("get-ifcfg-name-bad", "/foo/bar/adfasdfadf", FALSE, NULL); - do_test_utils_name ("get-ifcfg-name-good", "/foo/bar/ifcfg-FooBar", FALSE, "FooBar"); - do_test_utils_name ("get-ifcfg-name-keys", "/foo/bar/keys-BlahLbah", FALSE, "BlahLbah"); - do_test_utils_name ("get-ifcfg-name-route", "/foo/bar/route-Lalalala", FALSE, "Lalalala"); - do_test_utils_name ("get-ifcfg-name-only-ifcfg-route", "/foo/bar/route-Lalalala", TRUE, NULL); - do_test_utils_name ("get-ifcfg-name-only-ifcfg-keys", "/foo/bar/keys-Lalalala", TRUE, NULL); - do_test_utils_name ("get-ifcfg-name-no-path-ifcfg", "ifcfg-Lalalala", FALSE, "Lalalala"); - do_test_utils_name ("get-ifcfg-name-no-path-keys", "keys-Lalalala", FALSE, "Lalalala"); - do_test_utils_name ("get-ifcfg-name-no-path-route", "route-Lalalala", FALSE, "Lalalala"); + do_test_utils_name("get-ifcfg-name-bad", "/foo/bar/adfasdfadf", FALSE, NULL); + do_test_utils_name("get-ifcfg-name-good", "/foo/bar/ifcfg-FooBar", FALSE, "FooBar"); + do_test_utils_name("get-ifcfg-name-keys", "/foo/bar/keys-BlahLbah", FALSE, "BlahLbah"); + do_test_utils_name("get-ifcfg-name-route", "/foo/bar/route-Lalalala", FALSE, "Lalalala"); + do_test_utils_name("get-ifcfg-name-only-ifcfg-route", "/foo/bar/route-Lalalala", TRUE, NULL); + do_test_utils_name("get-ifcfg-name-only-ifcfg-keys", "/foo/bar/keys-Lalalala", TRUE, NULL); + do_test_utils_name("get-ifcfg-name-no-path-ifcfg", "ifcfg-Lalalala", FALSE, "Lalalala"); + do_test_utils_name("get-ifcfg-name-no-path-keys", "keys-Lalalala", FALSE, "Lalalala"); + do_test_utils_name("get-ifcfg-name-no-path-route", "route-Lalalala", FALSE, "Lalalala"); - do_test_utils_name ("get-ifcfg-name-bad2-ifcfg", "/foo/bar/asdfasifcfg-Foobar", FALSE, NULL); - do_test_utils_name ("get-ifcfg-name-bad2-keys", "/foo/bar/asdfaskeys-Foobar", FALSE, NULL); - do_test_utils_name ("get-ifcfg-name-bad2-route", "/foo/bar/asdfasroute-Foobar", FALSE, NULL); + do_test_utils_name("get-ifcfg-name-bad2-ifcfg", "/foo/bar/asdfasifcfg-Foobar", FALSE, NULL); + do_test_utils_name("get-ifcfg-name-bad2-keys", "/foo/bar/asdfaskeys-Foobar", FALSE, NULL); + do_test_utils_name("get-ifcfg-name-bad2-route", "/foo/bar/asdfasroute-Foobar", FALSE, NULL); } /*****************************************************************************/ static void -do_test_utils_path_ifcfg (const char *desc, - const char *path, - const char *expected) +do_test_utils_path_ifcfg(const char *desc, const char *path, const char *expected) { - char *result; + char *result; - result = utils_get_ifcfg_path (path); - g_assert_cmpstr (result, ==, expected); - g_free (result); + result = utils_get_ifcfg_path(path); + g_assert_cmpstr(result, ==, expected); + g_free(result); } static void -do_test_utils_path_keys (const char *desc, - const char *path, - const char *expected) +do_test_utils_path_keys(const char *desc, const char *path, const char *expected) { - char *result; + char *result; - result = utils_get_keys_path (path); - g_assert_cmpstr (result, ==, expected); - g_free (result); + result = utils_get_keys_path(path); + g_assert_cmpstr(result, ==, expected); + g_free(result); } static void -do_test_utils_path_route (const char *desc, - const char *path, - const char *expected) +do_test_utils_path_route(const char *desc, const char *path, const char *expected) { - char *result; + char *result; - result = utils_get_route_path (path); - g_assert_cmpstr (result, ==, expected); - g_free (result); + result = utils_get_route_path(path); + g_assert_cmpstr(result, ==, expected); + g_free(result); } static void -test_utils_path (void) +test_utils_path(void) { - do_test_utils_path_ifcfg ("ifcfg-path-bad", "/foo/bar/adfasdfasdf", NULL); - do_test_utils_path_ifcfg ("ifcfg-path-from-keys-no-path", "keys-BlahBlah", "ifcfg-BlahBlah"); - do_test_utils_path_ifcfg ("ifcfg-path-from-keys", "/foo/bar/keys-BlahBlah", "/foo/bar/ifcfg-BlahBlah"); - do_test_utils_path_ifcfg ("ifcfg-path-from-route", "/foo/bar/route-BlahBlah", "/foo/bar/ifcfg-BlahBlah"); + do_test_utils_path_ifcfg("ifcfg-path-bad", "/foo/bar/adfasdfasdf", NULL); + do_test_utils_path_ifcfg("ifcfg-path-from-keys-no-path", "keys-BlahBlah", "ifcfg-BlahBlah"); + do_test_utils_path_ifcfg("ifcfg-path-from-keys", + "/foo/bar/keys-BlahBlah", + "/foo/bar/ifcfg-BlahBlah"); + do_test_utils_path_ifcfg("ifcfg-path-from-route", + "/foo/bar/route-BlahBlah", + "/foo/bar/ifcfg-BlahBlah"); - do_test_utils_path_keys ("keys-path-bad", "/foo/bar/asdfasdfasdfasdf", NULL); - do_test_utils_path_keys ("keys-path-from-ifcfg-no-path", "ifcfg-FooBar", "keys-FooBar"); - do_test_utils_path_keys ("keys-path-from-ifcfg", "/foo/bar/ifcfg-FooBar", "/foo/bar/keys-FooBar"); - do_test_utils_path_keys ("keys-path-from-route", "/foo/bar/route-FooBar", "/foo/bar/keys-FooBar"); + do_test_utils_path_keys("keys-path-bad", "/foo/bar/asdfasdfasdfasdf", NULL); + do_test_utils_path_keys("keys-path-from-ifcfg-no-path", "ifcfg-FooBar", "keys-FooBar"); + do_test_utils_path_keys("keys-path-from-ifcfg", + "/foo/bar/ifcfg-FooBar", + "/foo/bar/keys-FooBar"); + do_test_utils_path_keys("keys-path-from-route", + "/foo/bar/route-FooBar", + "/foo/bar/keys-FooBar"); - do_test_utils_path_route ("route-path-bad", "/foo/bar/asdfasdfasdfasdf", NULL); - do_test_utils_path_route ("route-path-from-ifcfg-no-path", "ifcfg-FooBar", "route-FooBar"); - do_test_utils_path_route ("route-path-from-ifcfg", "/foo/bar/ifcfg-FooBar", "/foo/bar/route-FooBar"); - do_test_utils_path_route ("route-path-from-keys", "/foo/bar/keys-FooBar", "/foo/bar/route-FooBar"); + do_test_utils_path_route("route-path-bad", "/foo/bar/asdfasdfasdfasdf", NULL); + do_test_utils_path_route("route-path-from-ifcfg-no-path", "ifcfg-FooBar", "route-FooBar"); + do_test_utils_path_route("route-path-from-ifcfg", + "/foo/bar/ifcfg-FooBar", + "/foo/bar/route-FooBar"); + do_test_utils_path_route("route-path-from-keys", + "/foo/bar/keys-FooBar", + "/foo/bar/route-FooBar"); } /*****************************************************************************/ static void -do_test_utils_ignored (const char *desc, const char *path, gboolean expected_ignored) +do_test_utils_ignored(const char *desc, const char *path, gboolean expected_ignored) { - gboolean result; + gboolean result; - result = utils_should_ignore_file (path, FALSE); - g_assert (result == expected_ignored); + result = utils_should_ignore_file(path, FALSE); + g_assert(result == expected_ignored); } static void -test_utils_ignore (void) +test_utils_ignore(void) { - do_test_utils_ignored ("ignored-ifcfg", "ifcfg-FooBar", FALSE); - do_test_utils_ignored ("ignored-keys", "keys-FooBar", FALSE); - do_test_utils_ignored ("ignored-route", "route-FooBar", FALSE); - do_test_utils_ignored ("ignored-bak", "ifcfg-FooBar" BAK_TAG, TRUE); - do_test_utils_ignored ("ignored-tilde", "ifcfg-FooBar" TILDE_TAG, TRUE); - do_test_utils_ignored ("ignored-orig", "ifcfg-FooBar" ORIG_TAG, TRUE); - do_test_utils_ignored ("ignored-rej", "ifcfg-FooBar" REJ_TAG, TRUE); - do_test_utils_ignored ("ignored-rpmnew", "ifcfg-FooBar" RPMNEW_TAG, TRUE); - do_test_utils_ignored ("ignored-augnew", "ifcfg-FooBar" AUGNEW_TAG, TRUE); - do_test_utils_ignored ("ignored-augtmp", "ifcfg-FooBar" AUGTMP_TAG, TRUE); + do_test_utils_ignored("ignored-ifcfg", "ifcfg-FooBar", FALSE); + do_test_utils_ignored("ignored-keys", "keys-FooBar", FALSE); + do_test_utils_ignored("ignored-route", "route-FooBar", FALSE); + do_test_utils_ignored("ignored-bak", "ifcfg-FooBar" BAK_TAG, TRUE); + do_test_utils_ignored("ignored-tilde", "ifcfg-FooBar" TILDE_TAG, TRUE); + do_test_utils_ignored("ignored-orig", "ifcfg-FooBar" ORIG_TAG, TRUE); + do_test_utils_ignored("ignored-rej", "ifcfg-FooBar" REJ_TAG, TRUE); + do_test_utils_ignored("ignored-rpmnew", "ifcfg-FooBar" RPMNEW_TAG, TRUE); + do_test_utils_ignored("ignored-augnew", "ifcfg-FooBar" AUGNEW_TAG, TRUE); + do_test_utils_ignored("ignored-augtmp", "ifcfg-FooBar" AUGTMP_TAG, TRUE); } /*****************************************************************************/ static void -test_sriov_read (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSettingSriov *s_sriov; - NMSriovVF *vf; - GVariant *variant; - GError *error = NULL; - char *str; - - connection = _connection_from_file (TEST_IFCFG_DIR "/ifcfg-test-sriov", - NULL, TYPE_ETHERNET,NULL); - - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "eth0"); - - s_sriov = NM_SETTING_SRIOV (nm_connection_get_setting (connection, NM_TYPE_SETTING_SRIOV)); - g_assert (s_sriov); - - g_assert_cmpint (nm_setting_sriov_get_total_vfs (s_sriov), ==, 16); - g_assert_cmpint (nm_setting_sriov_get_num_vfs (s_sriov), ==, 3); - g_assert_cmpint (nm_setting_sriov_get_autoprobe_drivers (s_sriov), ==, NM_TERNARY_FALSE); - - /* VF 3 */ - vf = nm_setting_sriov_get_vf (s_sriov, 0); - g_assert (vf); - g_assert_cmpint (nm_sriov_vf_get_index (vf), ==, 3); - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MAC); - g_assert (variant); - g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)); - g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "55:44:33:22:11:00"); - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK); - g_assert (variant); - g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN)); - g_assert_cmpint (g_variant_get_boolean (variant), ==, TRUE); - - /* VF 12 */ - vf = nm_setting_sriov_get_vf (s_sriov, 1); - str = nm_utils_sriov_vf_to_str (vf, FALSE, &error); - g_assert_no_error (error); - g_assert_cmpstr (str, ==, "12 min-tx-rate=100 trust=false vlans=1.200.ad"); - g_free (str); - - /* VF 15 */ - vf = nm_setting_sriov_get_vf (s_sriov, 2); - str = nm_utils_sriov_vf_to_str (vf, FALSE, &error); - g_assert_no_error (error); - g_assert_cmpstr (str, ==, "15 mac=01:23:45:67:89:ab max-tx-rate=200 vlans=2"); - g_free (str); -} - -static void -test_sriov_write (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMSettingWired *s_wired; - NMSettingSriov *s_sriov; - NMSriovVF *vf; - gs_unref_ptrarray GPtrArray *vfs = NULL; - NMIPAddress *addr; - GError *error = NULL; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write SR-IOV config", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_INTERFACE_NAME, "eth0", - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NULL); - - /* SRIOV setting */ - s_sriov = (NMSettingSriov *) nm_setting_sriov_new (); - nm_connection_add_setting (connection, NM_SETTING (s_sriov)); - - vfs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_sriov_vf_unref); - - vf = nm_utils_sriov_vf_from_str ("2 mac=55:55:55:55:55:55 vlans=3.10.ad;10", &error); - nmtst_assert_success (vf, error); - g_ptr_array_add (vfs, vf); - - vf = nm_utils_sriov_vf_from_str ("19 spoof-check=true", &error); - nmtst_assert_success (vf, error); - g_ptr_array_add (vfs, vf); - - g_object_set (s_sriov, - NM_SETTING_SRIOV_TOTAL_VFS, 64, - NM_SETTING_SRIOV_VFS, vfs, - NM_SETTING_SRIOV_AUTOPROBE_DRIVERS, NM_TERNARY_TRUE, - NULL); - - nm_connection_add_setting (connection, nm_setting_proxy_new ()); - - nmtst_assert_connection_verifies_without_normalization (connection); - - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR "/ifcfg-test-sriov-write.cexpected", - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); +test_sriov_read(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSettingSriov * s_sriov; + NMSriovVF * vf; + GVariant * variant; + GError * error = NULL; + char * str; + + connection = + _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-sriov", NULL, TYPE_ETHERNET, NULL); + + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "eth0"); + + s_sriov = NM_SETTING_SRIOV(nm_connection_get_setting(connection, NM_TYPE_SETTING_SRIOV)); + g_assert(s_sriov); + + g_assert_cmpint(nm_setting_sriov_get_total_vfs(s_sriov), ==, 16); + g_assert_cmpint(nm_setting_sriov_get_num_vfs(s_sriov), ==, 3); + g_assert_cmpint(nm_setting_sriov_get_autoprobe_drivers(s_sriov), ==, NM_TERNARY_FALSE); + + /* VF 3 */ + vf = nm_setting_sriov_get_vf(s_sriov, 0); + g_assert(vf); + g_assert_cmpint(nm_sriov_vf_get_index(vf), ==, 3); + + variant = nm_sriov_vf_get_attribute(vf, NM_SRIOV_VF_ATTRIBUTE_MAC); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr(g_variant_get_string(variant, NULL), ==, "55:44:33:22:11:00"); + + variant = nm_sriov_vf_get_attribute(vf, NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK); + g_assert(variant); + g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)); + g_assert_cmpint(g_variant_get_boolean(variant), ==, TRUE); + + /* VF 12 */ + vf = nm_setting_sriov_get_vf(s_sriov, 1); + str = nm_utils_sriov_vf_to_str(vf, FALSE, &error); + g_assert_no_error(error); + g_assert_cmpstr(str, ==, "12 min-tx-rate=100 trust=false vlans=1.200.ad"); + g_free(str); + + /* VF 15 */ + vf = nm_setting_sriov_get_vf(s_sriov, 2); + str = nm_utils_sriov_vf_to_str(vf, FALSE, &error); + g_assert_no_error(error); + g_assert_cmpstr(str, ==, "15 mac=01:23:45:67:89:ab max-tx-rate=200 vlans=2"); + g_free(str); +} + +static void +test_sriov_write(void) +{ + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingWired * s_wired; + NMSettingSriov * s_sriov; + NMSriovVF * vf; + gs_unref_ptrarray GPtrArray *vfs = NULL; + NMIPAddress * addr; + GError * error = NULL; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write SR-IOV config", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_INTERFACE_NAME, + "eth0", + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); + + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + + /* SRIOV setting */ + s_sriov = (NMSettingSriov *) nm_setting_sriov_new(); + nm_connection_add_setting(connection, NM_SETTING(s_sriov)); + + vfs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_sriov_vf_unref); + + vf = nm_utils_sriov_vf_from_str("2 mac=55:55:55:55:55:55 vlans=3.10.ad;10", &error); + nmtst_assert_success(vf, error); + g_ptr_array_add(vfs, vf); + + vf = nm_utils_sriov_vf_from_str("19 spoof-check=true", &error); + nmtst_assert_success(vf, error); + g_ptr_array_add(vfs, vf); + + g_object_set(s_sriov, + NM_SETTING_SRIOV_TOTAL_VFS, + 64, + NM_SETTING_SRIOV_VFS, + vfs, + NM_SETTING_SRIOV_AUTOPROBE_DRIVERS, + NM_TERNARY_TRUE, + NULL); + + nm_connection_add_setting(connection, nm_setting_proxy_new()); + + nmtst_assert_connection_verifies_without_normalization(connection); + + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-test-sriov-write.cexpected", + &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } /*****************************************************************************/ static void -test_tc_read (void) -{ - NMConnection *connection; - NMSettingTCConfig *s_tc; - NMTCQdisc *qdisc; - NMTCTfilter *filter; - char *str; - - connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-tc", - NULL, TYPE_ETHERNET,NULL); - - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "eth0"); - - s_tc = nm_connection_get_setting_tc_config (connection); - g_assert (s_tc); +test_tc_read(void) +{ + NMConnection * connection; + NMSettingTCConfig *s_tc; + NMTCQdisc * qdisc; + NMTCTfilter * filter; + char * str; + + connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-tc", NULL, TYPE_ETHERNET, NULL); + + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "eth0"); + + s_tc = nm_connection_get_setting_tc_config(connection); + g_assert(s_tc); + + g_assert_cmpint(nm_setting_tc_config_get_num_qdiscs(s_tc), ==, 1); + qdisc = nm_setting_tc_config_get_qdisc(s_tc, 0); + g_assert(qdisc); + g_assert_cmpint(nm_tc_qdisc_get_parent(qdisc), ==, TC_H_ROOT); + g_assert_cmpint(nm_tc_qdisc_get_handle(qdisc), ==, TC_H_UNSPEC); + g_assert_cmpstr(nm_tc_qdisc_get_kind(qdisc), ==, "fq_codel"); + + g_assert_cmpint(nm_setting_tc_config_get_num_tfilters(s_tc), ==, 1); + filter = nm_setting_tc_config_get_tfilter(s_tc, 0); + g_assert(filter); + str = nm_utils_tc_tfilter_to_str(filter, NULL); + g_assert_cmpstr(str, ==, "parent 1234: matchall action simple sdata Hello"); + g_free(str); - g_assert_cmpint (nm_setting_tc_config_get_num_qdiscs (s_tc), ==, 1); - qdisc = nm_setting_tc_config_get_qdisc (s_tc, 0); - g_assert (qdisc); - g_assert_cmpint (nm_tc_qdisc_get_parent (qdisc), ==, TC_H_ROOT); - g_assert_cmpint (nm_tc_qdisc_get_handle (qdisc), ==, TC_H_UNSPEC); - g_assert_cmpstr (nm_tc_qdisc_get_kind (qdisc), ==, "fq_codel"); - - g_assert_cmpint (nm_setting_tc_config_get_num_tfilters (s_tc), ==, 1); - filter = nm_setting_tc_config_get_tfilter (s_tc, 0); - g_assert (filter); - str = nm_utils_tc_tfilter_to_str (filter, NULL); - g_assert_cmpstr (str, ==, "parent 1234: matchall action simple sdata Hello"); - g_free (str); - - g_object_unref (connection); + g_object_unref(connection); } static void -test_tc_write (void) +test_tc_write(void) { - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMSettingWired *s_wired; - NMSettingTCConfig *s_tc; - NMTCQdisc *qdisc; - NMTCTfilter *tfilter; - NMIPAddress *addr; - GError *error = NULL; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write TC config", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_INTERFACE_NAME, "eth0", - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + nmtst_auto_unlinkfile char *testfile = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingWired * s_wired; + NMSettingTCConfig * s_tc; + NMTCQdisc * qdisc; + NMTCTfilter * tfilter; + NMIPAddress * addr; + GError * error = NULL; - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + connection = nm_simple_connection_new(); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write TC config", + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_INTERFACE_NAME, + "eth0", + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NULL); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - /* TC setting */ - s_tc = (NMSettingTCConfig *) nm_setting_tc_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_tc)); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NULL); - qdisc = nm_tc_qdisc_new ("pfifo_fast", TC_H_MAKE (0x2468 << 16, 0x2), &error); - g_assert_no_error (error); - nm_setting_tc_config_add_qdisc (s_tc, qdisc); - nm_tc_qdisc_unref (qdisc); + addr = nm_ip_address_new(AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip4, addr); + nm_ip_address_unref(addr); - tfilter = nm_utils_tc_tfilter_from_str ("parent 1234: matchall action simple sdata Hello", &error); - g_assert_no_error (error); - nm_setting_tc_config_add_tfilter (s_tc, tfilter); - nm_tc_tfilter_unref (tfilter); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - nm_connection_add_setting (connection, nm_setting_proxy_new ()); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); - nmtst_assert_connection_verifies_without_normalization (connection); + /* TC setting */ + s_tc = (NMSettingTCConfig *) nm_setting_tc_config_new(); + nm_connection_add_setting(connection, NM_SETTING(s_tc)); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-test-tc-write.cexpected", - &testfile); + qdisc = nm_tc_qdisc_new("pfifo_fast", TC_H_MAKE(0x2468 << 16, 0x2), &error); + g_assert_no_error(error); + nm_setting_tc_config_add_qdisc(s_tc, qdisc); + nm_tc_qdisc_unref(qdisc); + + tfilter = + nm_utils_tc_tfilter_from_str("parent 1234: matchall action simple sdata Hello", &error); + g_assert_no_error(error); + nm_setting_tc_config_add_tfilter(s_tc, tfilter); + nm_tc_tfilter_unref(tfilter); - reread = _connection_from_file (testfile, NULL, TYPE_BOND, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nm_connection_add_setting(connection, nm_setting_proxy_new()); + + nmtst_assert_connection_verifies_without_normalization(connection); + + _writer_new_connec_exp(connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR "/ifcfg-test-tc-write.cexpected", + &testfile); + + reread = _connection_from_file(testfile, NULL, TYPE_BOND, NULL); + + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } /*****************************************************************************/ static void -test_well_known_keys (void) -{ - gsize i; - - for (i = 0; i < G_N_ELEMENTS (nms_ifcfg_well_known_keys); i++) { - const NMSIfcfgKeyTypeInfo *ti = &nms_ifcfg_well_known_keys[i]; - - g_assert (ti->key_name); - g_assert (ti->key_name[0]); - g_assert (NM_FLAGS_HAS (ti->key_flags, NMS_IFCFG_KEY_TYPE_WELL_KNOWN)); - g_assert (nm_utils_is_power_of_two (ti->key_flags & ( NMS_IFCFG_KEY_TYPE_IS_PLAIN - | NMS_IFCFG_KEY_TYPE_IS_NUMBERED - | NMS_IFCFG_KEY_TYPE_IS_PREFIX))); - } - - for (i = 1; i < G_N_ELEMENTS (nms_ifcfg_well_known_keys); i++) { - const NMSIfcfgKeyTypeInfo *ti_prev = &nms_ifcfg_well_known_keys[i - 1]; - const NMSIfcfgKeyTypeInfo *ti = &nms_ifcfg_well_known_keys[i]; - - g_assert_cmpstr (ti_prev->key_name, <, ti->key_name); - } - - for (i = 0; i < G_N_ELEMENTS (nms_ifcfg_well_known_keys); i++) { - const NMSIfcfgKeyTypeInfo *ti = &nms_ifcfg_well_known_keys[i]; - gs_free char *key_name = NULL; - gssize idx; - - g_assert (ti == nms_ifcfg_well_known_key_find_info (ti->key_name, &idx)); - g_assert_cmpint (i, ==, idx); - - key_name = g_strdup (ti->key_name); - g_assert (ti == nms_ifcfg_well_known_key_find_info (key_name, &idx)); - g_assert_cmpint (i, ==, idx); - } - -#define _test_well_known(key, expected) \ - G_STMT_START { \ - const NMSIfcfgKeyTypeInfo *_ti; \ - const char *_expected = (expected); \ - \ - _ti = nms_ifcfg_rh_utils_is_well_known_key (""key""); \ - if (!_expected) { \ - g_assert (!_ti); \ - } else { \ - g_assert (_ti); \ - g_assert_cmpstr (_ti->key_name, ==, _expected); \ - } \ - } G_STMT_END - -#define _test_well_known_plain(key) \ - _test_well_known (""key"", ""key"") - - _test_well_known_plain ("ONBOOT"); - _test_well_known ("NM_USER_", NULL); - _test_well_known ("NM_USER_x", "NM_USER_"); - _test_well_known ("IPADDR", "IPADDR"); - _test_well_known ("IPADDR1", "IPADDR"); - _test_well_known ("IPADDRx", NULL); +test_well_known_keys(void) +{ + gsize i; + + for (i = 0; i < G_N_ELEMENTS(nms_ifcfg_well_known_keys); i++) { + const NMSIfcfgKeyTypeInfo *ti = &nms_ifcfg_well_known_keys[i]; + + g_assert(ti->key_name); + g_assert(ti->key_name[0]); + g_assert(NM_FLAGS_HAS(ti->key_flags, NMS_IFCFG_KEY_TYPE_WELL_KNOWN)); + g_assert( + nm_utils_is_power_of_two(ti->key_flags + & (NMS_IFCFG_KEY_TYPE_IS_PLAIN | NMS_IFCFG_KEY_TYPE_IS_NUMBERED + | NMS_IFCFG_KEY_TYPE_IS_PREFIX))); + } + + for (i = 1; i < G_N_ELEMENTS(nms_ifcfg_well_known_keys); i++) { + const NMSIfcfgKeyTypeInfo *ti_prev = &nms_ifcfg_well_known_keys[i - 1]; + const NMSIfcfgKeyTypeInfo *ti = &nms_ifcfg_well_known_keys[i]; + + g_assert_cmpstr(ti_prev->key_name, <, ti->key_name); + } + + for (i = 0; i < G_N_ELEMENTS(nms_ifcfg_well_known_keys); i++) { + const NMSIfcfgKeyTypeInfo *ti = &nms_ifcfg_well_known_keys[i]; + gs_free char * key_name = NULL; + gssize idx; + + g_assert(ti == nms_ifcfg_well_known_key_find_info(ti->key_name, &idx)); + g_assert_cmpint(i, ==, idx); + + key_name = g_strdup(ti->key_name); + g_assert(ti == nms_ifcfg_well_known_key_find_info(key_name, &idx)); + g_assert_cmpint(i, ==, idx); + } + +#define _test_well_known(key, expected) \ + G_STMT_START \ + { \ + const NMSIfcfgKeyTypeInfo *_ti; \ + const char * _expected = (expected); \ + \ + _ti = nms_ifcfg_rh_utils_is_well_known_key("" key ""); \ + if (!_expected) { \ + g_assert(!_ti); \ + } else { \ + g_assert(_ti); \ + g_assert_cmpstr(_ti->key_name, ==, _expected); \ + } \ + } \ + G_STMT_END + +#define _test_well_known_plain(key) _test_well_known("" key "", "" key "") + + _test_well_known_plain("ONBOOT"); + _test_well_known("NM_USER_", NULL); + _test_well_known("NM_USER_x", "NM_USER_"); + _test_well_known("IPADDR", "IPADDR"); + _test_well_known("IPADDR1", "IPADDR"); + _test_well_known("IPADDRx", NULL); } /*****************************************************************************/ static void -_do_utils_has_route_file_new_syntax_size (gboolean has_new_syntax, - const char *content, - gssize content_len) +_do_utils_has_route_file_new_syntax_size(gboolean has_new_syntax, + const char *content, + gssize content_len) { - nmtst_auto_unlinkfile char *testfile = g_strdup (TEST_SCRATCH_DIR"/utils-has-route-file-new-syntax-test.txt"); - gboolean val; + nmtst_auto_unlinkfile char *testfile = + g_strdup(TEST_SCRATCH_DIR "/utils-has-route-file-new-syntax-test.txt"); + gboolean val; - nmtst_file_set_contents_size (testfile, content, content_len); + nmtst_file_set_contents_size(testfile, content, content_len); - val = utils_has_route_file_new_syntax (testfile); + val = utils_has_route_file_new_syntax(testfile); - g_assert_cmpint (val, ==, has_new_syntax); + g_assert_cmpint(val, ==, has_new_syntax); } #define _do_utils_has_route_file_new_syntax(has_new_syntax, content) \ - _do_utils_has_route_file_new_syntax_size (has_new_syntax, (content), NM_STRLEN (content)) + _do_utils_has_route_file_new_syntax_size(has_new_syntax, (content), NM_STRLEN(content)) static void -test_utils_has_route_file_new_syntax (void) +test_utils_has_route_file_new_syntax(void) { - _do_utils_has_route_file_new_syntax (TRUE, ""); - _do_utils_has_route_file_new_syntax (FALSE, "\0"); - _do_utils_has_route_file_new_syntax (FALSE, "\n"); - _do_utils_has_route_file_new_syntax (FALSE, "ADDRESS=bogus"); - _do_utils_has_route_file_new_syntax (FALSE, "ADDRESS=bogus\0"); - _do_utils_has_route_file_new_syntax (TRUE, "ADDRESS1=b\0ogus\0"); - _do_utils_has_route_file_new_syntax (TRUE, "ADDRESS1=bogus\0"); - _do_utils_has_route_file_new_syntax (TRUE, "\n\n\tADDRESS1=bogus\0"); - _do_utils_has_route_file_new_syntax (FALSE, "\n\n\tADDRESS=bogus\n"); - _do_utils_has_route_file_new_syntax (TRUE, "\n\n\tADDRESS=bogus\n ADDRESS000=\n"); - _do_utils_has_route_file_new_syntax (FALSE, "\n\n\tROUTE1=bogus\n ADDRES=\n"); - _do_utils_has_route_file_new_syntax (FALSE, "\n\n\tADDRESS=bogus\n ADDRESS\000000=\n"); + _do_utils_has_route_file_new_syntax(TRUE, ""); + _do_utils_has_route_file_new_syntax(FALSE, "\0"); + _do_utils_has_route_file_new_syntax(FALSE, "\n"); + _do_utils_has_route_file_new_syntax(FALSE, "ADDRESS=bogus"); + _do_utils_has_route_file_new_syntax(FALSE, "ADDRESS=bogus\0"); + _do_utils_has_route_file_new_syntax(TRUE, "ADDRESS1=b\0ogus\0"); + _do_utils_has_route_file_new_syntax(TRUE, "ADDRESS1=bogus\0"); + _do_utils_has_route_file_new_syntax(TRUE, "\n\n\tADDRESS1=bogus\0"); + _do_utils_has_route_file_new_syntax(FALSE, "\n\n\tADDRESS=bogus\n"); + _do_utils_has_route_file_new_syntax(TRUE, "\n\n\tADDRESS=bogus\n ADDRESS000=\n"); + _do_utils_has_route_file_new_syntax(FALSE, "\n\n\tROUTE1=bogus\n ADDRES=\n"); + _do_utils_has_route_file_new_syntax(FALSE, "\n\n\tADDRESS=bogus\n ADDRESS\000000=\n"); } /*****************************************************************************/ static void -test_ethtool_names (void) -{ - static const struct { - NMEthtoolID ethtool_id; - const char *kernel_name; - } kernel_names[] = { - { NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro" }, - { NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation" }, - { NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro" }, - { NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter" }, - { NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum" }, - { NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing" }, - { NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse" }, - { NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert" }, - }; - const struct { - guint nm_ethtool_id_first; - guint nm_ethtool_id_last; - } s_idxs[] = { - { _NM_ETHTOOL_ID_FEATURE_FIRST, _NM_ETHTOOL_ID_FEATURE_LAST }, - { _NM_ETHTOOL_ID_COALESCE_FIRST, _NM_ETHTOOL_ID_COALESCE_LAST }, - { _NM_ETHTOOL_ID_RING_FIRST, _NM_ETHTOOL_ID_RING_LAST }, - }; - const NMEthtoolData *data; - NMEthtoolID id; - guint i, k; - - for (k = 0; k < sizeof(s_idxs) / sizeof(*s_idxs); ++k) { - for (id = s_idxs[k].nm_ethtool_id_first; id <= s_idxs[k].nm_ethtool_id_last; id++) { - const char *ifcfg_rh_name; - - g_assert (id >= 0); - g_assert (id < G_N_ELEMENTS (_nm_ethtool_ifcfg_names)); - ifcfg_rh_name = _nm_ethtool_ifcfg_names[id]; - g_assert (ifcfg_rh_name && ifcfg_rh_name[0]); - - for (i = s_idxs[k].nm_ethtool_id_first; i < s_idxs[k].nm_ethtool_id_last; i++) { - if (i != id) - g_assert_cmpstr (ifcfg_rh_name, !=, _nm_ethtool_ifcfg_names[i]); - } - - g_assert_cmpstr (nms_ifcfg_rh_utils_get_ethtool_name (id), ==, ifcfg_rh_name); - - data = nms_ifcfg_rh_utils_get_ethtool_by_name (ifcfg_rh_name, nm_ethtool_id_to_type (id)); - - g_assert (data); - g_assert (data->id == id); - } - } - - for (i = 0; i < G_N_ELEMENTS (kernel_names); i++) { - const char *name = kernel_names[i].kernel_name; - - id = kernel_names[i].ethtool_id; - - data = nms_ifcfg_rh_utils_get_ethtool_by_name (name, nm_ethtool_id_to_type (id)); - - g_assert (data); - g_assert (data->id == id); - g_assert_cmpstr (nms_ifcfg_rh_utils_get_ethtool_name (id), !=, name); - } +test_ethtool_names(void) +{ + static const struct { + NMEthtoolID ethtool_id; + const char *kernel_name; + } kernel_names[] = { + {NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro"}, + {NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation"}, + {NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro"}, + {NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter"}, + {NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum"}, + {NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing"}, + {NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse"}, + {NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert"}, + }; + const struct { + guint nm_ethtool_id_first; + guint nm_ethtool_id_last; + } s_idxs[] = { + {_NM_ETHTOOL_ID_FEATURE_FIRST, _NM_ETHTOOL_ID_FEATURE_LAST}, + {_NM_ETHTOOL_ID_COALESCE_FIRST, _NM_ETHTOOL_ID_COALESCE_LAST}, + {_NM_ETHTOOL_ID_RING_FIRST, _NM_ETHTOOL_ID_RING_LAST}, + }; + const NMEthtoolData *data; + NMEthtoolID id; + guint i, k; + + for (k = 0; k < sizeof(s_idxs) / sizeof(*s_idxs); ++k) { + for (id = s_idxs[k].nm_ethtool_id_first; id <= s_idxs[k].nm_ethtool_id_last; id++) { + const char *ifcfg_rh_name; + + g_assert(id >= 0); + g_assert(id < G_N_ELEMENTS(_nm_ethtool_ifcfg_names)); + ifcfg_rh_name = _nm_ethtool_ifcfg_names[id]; + g_assert(ifcfg_rh_name && ifcfg_rh_name[0]); + + for (i = s_idxs[k].nm_ethtool_id_first; i < s_idxs[k].nm_ethtool_id_last; i++) { + if (i != id) + g_assert_cmpstr(ifcfg_rh_name, !=, _nm_ethtool_ifcfg_names[i]); + } + + g_assert_cmpstr(nms_ifcfg_rh_utils_get_ethtool_name(id), ==, ifcfg_rh_name); + + data = nms_ifcfg_rh_utils_get_ethtool_by_name(ifcfg_rh_name, nm_ethtool_id_to_type(id)); + + g_assert(data); + g_assert(data->id == id); + } + } + + for (i = 0; i < G_N_ELEMENTS(kernel_names); i++) { + const char *name = kernel_names[i].kernel_name; + + id = kernel_names[i].ethtool_id; + + data = nms_ifcfg_rh_utils_get_ethtool_by_name(name, nm_ethtool_id_to_type(id)); + + g_assert(data); + g_assert(data->id == id); + g_assert_cmpstr(nms_ifcfg_rh_utils_get_ethtool_name(id), !=, name); + } } /*****************************************************************************/ #define TPATH "/settings/plugins/ifcfg-rh/" -#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_QUOTED TEST_IFCFG_DIR"/ifcfg-test-wifi-open-ssid-long-quoted" -#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_HEX TEST_IFCFG_DIR"/ifcfg-test-wifi-open-ssid-long-hex" +#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_QUOTED \ + TEST_IFCFG_DIR "/ifcfg-test-wifi-open-ssid-long-quoted" +#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_HEX TEST_IFCFG_DIR "/ifcfg-test-wifi-open-ssid-long-hex" #define DEFAULT_HEX_PSK "7d308b11df1b4243b0f78e5f3fc68cdbb9a264ed0edf4c188edf329ff5b467f0" -NMTST_DEFINE (); - -int main (int argc, char **argv) -{ - int errsv; - - nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); - - if (g_mkdir_with_parents (TEST_SCRATCH_DIR_TMP, 0755) != 0) { - errsv = errno; - g_error ("failure to create test directory \"%s\": %s", TEST_SCRATCH_DIR_TMP, nm_strerror_native (errsv)); - } - - g_test_add_func (TPATH "svUnescape", test_svUnescape); - - g_test_add_data_func (TPATH "write-unknown/1", TEST_IFCFG_DIR"/ifcfg-test-write-unknown-1", test_write_unknown); - g_test_add_data_func (TPATH "write-unknown/2", TEST_IFCFG_DIR"/ifcfg-test-write-unknown-2", test_write_unknown); - g_test_add_data_func (TPATH "write-unknown/3", TEST_IFCFG_DIR"/ifcfg-test-write-unknown-3", test_write_unknown); - g_test_add_data_func (TPATH "write-unknown/4", TEST_IFCFG_DIR"/ifcfg-test-write-unknown-4", test_write_unknown); - - g_test_add_func (TPATH "vlan-trailing-spaces", test_read_vlan_trailing_spaces); - - g_test_add_func (TPATH "unmanaged", test_read_unmanaged); - g_test_add_func (TPATH "unmanaged-unrecognized", test_read_unmanaged_unrecognized); - g_test_add_func (TPATH "unrecognized", test_read_unrecognized); - g_test_add_func (TPATH "basic", test_read_basic); - g_test_add_func (TPATH "miscellaneous-variables", test_read_miscellaneous_variables); - g_test_add_func (TPATH "variables-corner-cases", test_read_variables_corner_cases); - g_test_add_data_func (TPATH "no-prefix/8", GUINT_TO_POINTER (8), test_read_wired_static_no_prefix); - g_test_add_data_func (TPATH "no-prefix/16", GUINT_TO_POINTER (16), test_read_wired_static_no_prefix); - g_test_add_data_func (TPATH "no-prefix/24", GUINT_TO_POINTER (24), test_read_wired_static_no_prefix); - g_test_add_data_func (TPATH "static-ip6-only-gw/_NULL_", NULL, test_write_wired_static_ip6_only_gw); - g_test_add_data_func (TPATH "static-ip6-only-gw/::", "::", test_write_wired_static_ip6_only_gw); - g_test_add_data_func (TPATH "static-ip6-only-gw/2001:db8:8:4::2", "2001:db8:8:4::2", test_write_wired_static_ip6_only_gw); - g_test_add_data_func (TPATH "static-ip6-only-gw/::ffff:255.255.255.255", "::ffff:255.255.255.255", test_write_wired_static_ip6_only_gw); - g_test_add_func (TPATH "ip6/disabled", test_write_ip6_disabled); - g_test_add_func (TPATH "read-dns-options", test_read_dns_options); - g_test_add_func (TPATH "clear-master", test_clear_master); - - nmtst_add_test_func (TPATH "read-static", test_read_wired_static, TEST_IFCFG_DIR"/ifcfg-test-wired-static", "System test-wired-static", GINT_TO_POINTER (TRUE)); - nmtst_add_test_func (TPATH "read-static-bootproto", test_read_wired_static, TEST_IFCFG_DIR"/ifcfg-test-wired-static-bootproto", "System test-wired-static-bootproto", GINT_TO_POINTER (FALSE)); - - g_test_add_func (TPATH "read-netmask-1", test_read_netmask_1); - - g_test_add_func (TPATH "read-dhcp", test_read_wired_dhcp); - g_test_add_func (TPATH "read-dhcp-plus-ip", test_read_wired_dhcp_plus_ip); - g_test_add_func (TPATH "read-shared-plus-ip", test_read_wired_shared_plus_ip); - g_test_add_func (TPATH "read-dhcp-send-hostname", test_read_write_wired_dhcp_send_hostname); - g_test_add_func (TPATH "read-dhcpv6-hostname-fallback", test_read_wired_dhcpv6_hostname_fallback); - g_test_add_func (TPATH "read-global-gateway", test_read_wired_global_gateway); - g_test_add_func (TPATH "read-global-gateway-ignore", test_read_wired_global_gateway_ignore); - g_test_add_func (TPATH "read-obsolete-gateway-n", test_read_wired_obsolete_gateway_n); - g_test_add_func (TPATH "read-never-default", test_read_wired_never_default); - g_test_add_func (TPATH "read-defroute-no", test_read_wired_defroute_no); - g_test_add_func (TPATH "read-defroute-no-gatewaydev-yes", test_read_wired_defroute_no_gatewaydev_yes); - g_test_add_func (TPATH "routes/read-static", test_read_wired_static_routes); - g_test_add_func (TPATH "routes/read-static-legacy", test_read_wired_static_routes_legacy); - - nmtst_add_test_func (TPATH "wired/read/manual/1", test_read_wired_ipv4_manual, TEST_IFCFG_DIR"/ifcfg-test-wired-ipv4-manual-1", "System test-wired-ipv4-manual-1"); - nmtst_add_test_func (TPATH "wired/read/manual/2", test_read_wired_ipv4_manual, TEST_IFCFG_DIR"/ifcfg-test-wired-ipv4-manual-2", "System test-wired-ipv4-manual-2"); - nmtst_add_test_func (TPATH "wired/read/manual/3", test_read_wired_ipv4_manual, TEST_IFCFG_DIR"/ifcfg-test-wired-ipv4-manual-3", "System test-wired-ipv4-manual-3"); - nmtst_add_test_func (TPATH "wired/read/manual/4", test_read_wired_ipv4_manual, TEST_IFCFG_DIR"/ifcfg-test-wired-ipv4-manual-4", "System test-wired-ipv4-manual-4"); - - g_test_add_func (TPATH "user/1", test_user_1); - - g_test_add_func (TPATH "wired/ipv6-manual", test_read_wired_ipv6_manual); - - nmtst_add_test_func (TPATH "wired-ipv6-only/0", test_read_wired_ipv6_only, TEST_IFCFG_DIR"/ifcfg-test-wired-ipv6-only", "System test-wired-ipv6-only"); - nmtst_add_test_func (TPATH "wired-ipv6-only/1", test_read_wired_ipv6_only, TEST_IFCFG_DIR"/ifcfg-test-wired-ipv6-only-1", "System test-wired-ipv6-only-1"); - - g_test_add_func (TPATH "wired/dhcpv6-only", test_read_wired_dhcp6_only); - g_test_add_func (TPATH "wired/autoip", test_read_wired_autoip); - g_test_add_func (TPATH "wired/onboot/no", test_read_onboot_no); - g_test_add_func (TPATH "wired/no-ip", test_read_noip); - g_test_add_func (TPATH "802-1x/peap/mschapv2", test_read_wired_8021x_peap_mschapv2); - - nmtst_add_test_func (TPATH "test-wired-8021x-tls/agent", test_read_wired_8021x_tls_secret_flags, TEST_IFCFG_DIR"/ifcfg-test-wired-8021x-tls-agent", GINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); - nmtst_add_test_func (TPATH "test-wired-8021x-tls/always", test_read_wired_8021x_tls_secret_flags, TEST_IFCFG_DIR"/ifcfg-test-wired-8021x-tls-always", GINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED)); - - g_test_add_func (TPATH "802-1x/subj-matches", test_read_write_802_1X_subj_matches); - g_test_add_func (TPATH "802-1x/ttls-eapgtc", test_read_802_1x_ttls_eapgtc); - g_test_add_func (TPATH "802-1x/password_raw", test_read_write_802_1x_password_raw); - g_test_add_func (TPATH "802-1x/tls-p12-no-client-cert", test_read_802_1x_tls_p12_no_client_cert); - - g_test_add_data_func (TPATH "wired/read/aliases/good/0", GINT_TO_POINTER (0), test_read_wired_aliases_good); - g_test_add_data_func (TPATH "wired/read/aliases/good/3", GINT_TO_POINTER (3), test_read_wired_aliases_good); - g_test_add_func (TPATH "wired/read/aliases/bad1", test_read_wired_aliases_bad_1); - g_test_add_func (TPATH "wired/read/aliases/bad2", test_read_wired_aliases_bad_2); - g_test_add_func (TPATH "wifi/read/open", test_read_wifi_open); - g_test_add_func (TPATH "wifi/read/open/auto", test_read_wifi_open_auto); - g_test_add_func (TPATH "wifi/read/open/hex-ssid", test_read_wifi_open_ssid_hex); - g_test_add_func (TPATH "wifi/read/open-ssid/bad-hex", test_read_wifi_open_ssid_hex_bad); - g_test_add_data_func (TPATH "wifi/read/open-ssid/long-hex", TEST_IFCFG_WIFI_OPEN_SSID_LONG_HEX, test_read_wifi_open_ssid_bad); - g_test_add_data_func (TPATH "wifi/read/open-ssid/long-quoted", TEST_IFCFG_WIFI_OPEN_SSID_LONG_QUOTED, test_read_wifi_open_ssid_bad); - g_test_add_func (TPATH "wifi/read/open/quoted-ssid", test_read_wifi_open_ssid_quoted); - g_test_add_func (TPATH "wifi/read/wep", test_read_wifi_wep); - g_test_add_func (TPATH "wifi/read/wep/adhoc", test_read_wifi_wep_adhoc); - g_test_add_func (TPATH "wifi/read/wep/passphrase", test_read_wifi_wep_passphrase); - g_test_add_func (TPATH "wifi/read/wep/40-ascii", test_read_wifi_wep_40_ascii); - g_test_add_func (TPATH "wifi/read/wep/104-ascii", test_read_wifi_wep_104_ascii); - g_test_add_func (TPATH "wifi/read/leap", test_read_wifi_leap); - - nmtst_add_test_func (TPATH "wifi-leap-secret-flags/agent", test_read_wifi_leap_secret_flags, TEST_IFCFG_DIR"/ifcfg-test-wifi-leap-agent", GINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); - nmtst_add_test_func (TPATH "wifi-leap-secret-flags/ask", test_read_wifi_leap_secret_flags, TEST_IFCFG_DIR"/ifcfg-test-wifi-leap-always-ask", GINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED)); - - g_test_add_func (TPATH "wifi/read/wpa-psk", test_read_wifi_wpa_psk); - g_test_add_func (TPATH "wifi/read/wpa-psk/2", test_read_wifi_wpa_psk_2); - g_test_add_func (TPATH "wifi/read/wpa-psk/unquoted", test_read_wifi_wpa_psk_unquoted); - g_test_add_func (TPATH "wifi/read/wpa-psk/unquoted2", test_read_wifi_wpa_psk_unquoted2); - g_test_add_func (TPATH "wifi/read/wpa-psk/adhoc", test_read_wifi_wpa_psk_adhoc); - g_test_add_func (TPATH "wifi/read/wpa-psk/hex", test_read_wifi_wpa_psk_hex); - g_test_add_func (TPATH "wifi/read/sae", test_read_wifi_sae); - g_test_add_func (TPATH "wifi/read/owe", test_read_wifi_owe); - g_test_add_func (TPATH "wifi/read/dynamic-wep/leap", test_read_wifi_dynamic_wep_leap); - g_test_add_func (TPATH "wifi/read/wpa/eap/tls", test_read_wifi_wpa_eap_tls); - g_test_add_func (TPATH "wifi/read/wpa/eap/ttls/tls", test_read_wifi_wpa_eap_ttls_tls); - g_test_add_func (TPATH "wifi/read/dynamic-wep/eap/ttls/chap", test_read_wifi_wep_eap_ttls_chap); - g_test_add_func (TPATH "wifi/read-band-a", test_read_wifi_band_a); - g_test_add_func (TPATH "wifi/read-band-a-channel-mismatch", test_read_wifi_band_a_channel_mismatch); - g_test_add_func (TPATH "wifi/read-band-bg-channel-mismatch", test_read_wifi_band_bg_channel_mismatch); - g_test_add_func (TPATH "wifi/read-hidden", test_read_wifi_hidden); - - nmtst_add_test_func (TPATH "wifi/read-mac-random-always", test_read_wifi_mac_random, "always", GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_ALWAYS)); - nmtst_add_test_func (TPATH "wifi/read-mac-random-never", test_read_wifi_mac_random, "never", GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_NEVER)); - nmtst_add_test_func (TPATH "wifi/read-mac-random-default", test_read_wifi_mac_random, "default", GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_DEFAULT)); - nmtst_add_test_func (TPATH "wifi/read-mac-random-missing", test_read_wifi_mac_random, "missing", GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_DEFAULT)); - - nmtst_add_test_func (TPATH "wifi/write-mac-random-always", test_write_wifi_mac_random, "always", GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_ALWAYS), "always"); - nmtst_add_test_func (TPATH "wifi/write-mac-random-never", test_write_wifi_mac_random, "never", GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_NEVER), "never"); - nmtst_add_test_func (TPATH "wifi/write-mac-random-default", test_write_wifi_mac_random, "default", GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_DEFAULT), "default"); - nmtst_add_test_func (TPATH "wifi/write-mac-random-missing", test_write_wifi_mac_random, "missing", GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_NEVER), "never"); - - g_test_add_func (TPATH "wifi/read/wep-no-keys", test_read_wifi_wep_no_keys); - g_test_add_func (TPATH "wifi/read/wep-agent-keys", test_read_wifi_wep_agent_keys); - g_test_add_func (TPATH "infiniband/read", test_read_infiniband); - g_test_add_func (TPATH "vlan/read", test_read_vlan_interface); - g_test_add_func (TPATH "vlan/read-flags-1", test_read_vlan_flags_1); - g_test_add_func (TPATH "vlan/read-flags-2", test_read_vlan_flags_2); - g_test_add_func (TPATH "vlan/read/only-vlanid", test_read_vlan_only_vlan_id); - g_test_add_func (TPATH "vlan/read/only-device", test_read_vlan_only_device); - g_test_add_func (TPATH "vlan/read/physdev", test_read_vlan_physdev); - g_test_add_func (TPATH "vlan/read/reorder-hdr-1", test_read_vlan_reorder_hdr_1); - g_test_add_func (TPATH "vlan/read/reorder-hdr-2", test_read_vlan_reorder_hdr_2); - g_test_add_func (TPATH "wired/read/read-wake-on-lan", test_read_wired_wake_on_lan); - g_test_add_func (TPATH "wired/read/read-auto-negotiate-off", test_read_wired_auto_negotiate_off); - g_test_add_func (TPATH "wired/read/read-auto-negotiate-on", test_read_wired_auto_negotiate_on); - g_test_add_func (TPATH "wired/read/unkwnown-ethtool-opt", test_read_wired_unknown_ethtool_opt); - - g_test_add_func (TPATH "wired/write/static", test_write_wired_static); - g_test_add_func (TPATH "wired/write/static-with-generic", test_write_wired_static_with_generic); - g_test_add_func (TPATH "wired/write/static-ip6-only", test_write_wired_static_ip6_only); - g_test_add_func (TPATH "wired/write-static-routes", test_write_wired_static_routes); - g_test_add_func (TPATH "wired/read-write-static-routes-legacy", test_read_write_static_routes_legacy); - g_test_add_func (TPATH "wired/write/dhcp", test_write_wired_dhcp); - g_test_add_func (TPATH "wired/write-dhcp-plus-ip", test_write_wired_dhcp_plus_ip); - g_test_add_func (TPATH "wired/write/dhcp-8021x-peap-mschapv2", test_write_wired_dhcp_8021x_peap_mschapv2); - g_test_add_func (TPATH "wired/write/match", test_write_wired_match); - g_test_add_func (TPATH "wired/write/routing-rules", test_write_routing_rules); +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + int errsv; + + nmtst_init_assert_logging(&argc, &argv, "INFO", "DEFAULT"); + + if (g_mkdir_with_parents(TEST_SCRATCH_DIR_TMP, 0755) != 0) { + errsv = errno; + g_error("failure to create test directory \"%s\": %s", + TEST_SCRATCH_DIR_TMP, + nm_strerror_native(errsv)); + } + + g_test_add_func(TPATH "svUnescape", test_svUnescape); + + g_test_add_data_func(TPATH "write-unknown/1", + TEST_IFCFG_DIR "/ifcfg-test-write-unknown-1", + test_write_unknown); + g_test_add_data_func(TPATH "write-unknown/2", + TEST_IFCFG_DIR "/ifcfg-test-write-unknown-2", + test_write_unknown); + g_test_add_data_func(TPATH "write-unknown/3", + TEST_IFCFG_DIR "/ifcfg-test-write-unknown-3", + test_write_unknown); + g_test_add_data_func(TPATH "write-unknown/4", + TEST_IFCFG_DIR "/ifcfg-test-write-unknown-4", + test_write_unknown); + + g_test_add_func(TPATH "vlan-trailing-spaces", test_read_vlan_trailing_spaces); + + g_test_add_func(TPATH "unmanaged", test_read_unmanaged); + g_test_add_func(TPATH "unmanaged-unrecognized", test_read_unmanaged_unrecognized); + g_test_add_func(TPATH "unrecognized", test_read_unrecognized); + g_test_add_func(TPATH "basic", test_read_basic); + g_test_add_func(TPATH "miscellaneous-variables", test_read_miscellaneous_variables); + g_test_add_func(TPATH "variables-corner-cases", test_read_variables_corner_cases); + g_test_add_data_func(TPATH "no-prefix/8", + GUINT_TO_POINTER(8), + test_read_wired_static_no_prefix); + g_test_add_data_func(TPATH "no-prefix/16", + GUINT_TO_POINTER(16), + test_read_wired_static_no_prefix); + g_test_add_data_func(TPATH "no-prefix/24", + GUINT_TO_POINTER(24), + test_read_wired_static_no_prefix); + g_test_add_data_func(TPATH "static-ip6-only-gw/_NULL_", + NULL, + test_write_wired_static_ip6_only_gw); + g_test_add_data_func(TPATH "static-ip6-only-gw/::", "::", test_write_wired_static_ip6_only_gw); + g_test_add_data_func(TPATH "static-ip6-only-gw/2001:db8:8:4::2", + "2001:db8:8:4::2", + test_write_wired_static_ip6_only_gw); + g_test_add_data_func(TPATH "static-ip6-only-gw/::ffff:255.255.255.255", + "::ffff:255.255.255.255", + test_write_wired_static_ip6_only_gw); + g_test_add_func(TPATH "ip6/disabled", test_write_ip6_disabled); + g_test_add_func(TPATH "read-dns-options", test_read_dns_options); + g_test_add_func(TPATH "clear-master", test_clear_master); + + nmtst_add_test_func(TPATH "read-static", + test_read_wired_static, + TEST_IFCFG_DIR "/ifcfg-test-wired-static", + "System test-wired-static", + GINT_TO_POINTER(TRUE)); + nmtst_add_test_func(TPATH "read-static-bootproto", + test_read_wired_static, + TEST_IFCFG_DIR "/ifcfg-test-wired-static-bootproto", + "System test-wired-static-bootproto", + GINT_TO_POINTER(FALSE)); + + g_test_add_func(TPATH "read-netmask-1", test_read_netmask_1); + + g_test_add_func(TPATH "read-dhcp", test_read_wired_dhcp); + g_test_add_func(TPATH "read-dhcp-plus-ip", test_read_wired_dhcp_plus_ip); + g_test_add_func(TPATH "read-shared-plus-ip", test_read_wired_shared_plus_ip); + g_test_add_func(TPATH "read-dhcp-send-hostname", test_read_write_wired_dhcp_send_hostname); + g_test_add_func(TPATH "read-dhcpv6-hostname-fallback", + test_read_wired_dhcpv6_hostname_fallback); + g_test_add_func(TPATH "read-global-gateway", test_read_wired_global_gateway); + g_test_add_func(TPATH "read-global-gateway-ignore", test_read_wired_global_gateway_ignore); + g_test_add_func(TPATH "read-obsolete-gateway-n", test_read_wired_obsolete_gateway_n); + g_test_add_func(TPATH "read-never-default", test_read_wired_never_default); + g_test_add_func(TPATH "read-defroute-no", test_read_wired_defroute_no); + g_test_add_func(TPATH "read-defroute-no-gatewaydev-yes", + test_read_wired_defroute_no_gatewaydev_yes); + g_test_add_func(TPATH "routes/read-static", test_read_wired_static_routes); + g_test_add_func(TPATH "routes/read-static-legacy", test_read_wired_static_routes_legacy); + + nmtst_add_test_func(TPATH "wired/read/manual/1", + test_read_wired_ipv4_manual, + TEST_IFCFG_DIR "/ifcfg-test-wired-ipv4-manual-1", + "System test-wired-ipv4-manual-1"); + nmtst_add_test_func(TPATH "wired/read/manual/2", + test_read_wired_ipv4_manual, + TEST_IFCFG_DIR "/ifcfg-test-wired-ipv4-manual-2", + "System test-wired-ipv4-manual-2"); + nmtst_add_test_func(TPATH "wired/read/manual/3", + test_read_wired_ipv4_manual, + TEST_IFCFG_DIR "/ifcfg-test-wired-ipv4-manual-3", + "System test-wired-ipv4-manual-3"); + nmtst_add_test_func(TPATH "wired/read/manual/4", + test_read_wired_ipv4_manual, + TEST_IFCFG_DIR "/ifcfg-test-wired-ipv4-manual-4", + "System test-wired-ipv4-manual-4"); + + g_test_add_func(TPATH "user/1", test_user_1); + + g_test_add_func(TPATH "wired/ipv6-manual", test_read_wired_ipv6_manual); + + nmtst_add_test_func(TPATH "wired-ipv6-only/0", + test_read_wired_ipv6_only, + TEST_IFCFG_DIR "/ifcfg-test-wired-ipv6-only", + "System test-wired-ipv6-only"); + nmtst_add_test_func(TPATH "wired-ipv6-only/1", + test_read_wired_ipv6_only, + TEST_IFCFG_DIR "/ifcfg-test-wired-ipv6-only-1", + "System test-wired-ipv6-only-1"); + + g_test_add_func(TPATH "wired/dhcpv6-only", test_read_wired_dhcp6_only); + g_test_add_func(TPATH "wired/autoip", test_read_wired_autoip); + g_test_add_func(TPATH "wired/onboot/no", test_read_onboot_no); + g_test_add_func(TPATH "wired/no-ip", test_read_noip); + g_test_add_func(TPATH "802-1x/peap/mschapv2", test_read_wired_8021x_peap_mschapv2); + + nmtst_add_test_func(TPATH "test-wired-8021x-tls/agent", + test_read_wired_8021x_tls_secret_flags, + TEST_IFCFG_DIR "/ifcfg-test-wired-8021x-tls-agent", + GINT_TO_POINTER(NM_SETTING_SECRET_FLAG_AGENT_OWNED)); + nmtst_add_test_func( + TPATH "test-wired-8021x-tls/always", + test_read_wired_8021x_tls_secret_flags, + TEST_IFCFG_DIR "/ifcfg-test-wired-8021x-tls-always", + GINT_TO_POINTER(NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED)); + + g_test_add_func(TPATH "802-1x/subj-matches", test_read_write_802_1X_subj_matches); + g_test_add_func(TPATH "802-1x/ttls-eapgtc", test_read_802_1x_ttls_eapgtc); + g_test_add_func(TPATH "802-1x/password_raw", test_read_write_802_1x_password_raw); + g_test_add_func(TPATH "802-1x/tls-p12-no-client-cert", test_read_802_1x_tls_p12_no_client_cert); + + g_test_add_data_func(TPATH "wired/read/aliases/good/0", + GINT_TO_POINTER(0), + test_read_wired_aliases_good); + g_test_add_data_func(TPATH "wired/read/aliases/good/3", + GINT_TO_POINTER(3), + test_read_wired_aliases_good); + g_test_add_func(TPATH "wired/read/aliases/bad1", test_read_wired_aliases_bad_1); + g_test_add_func(TPATH "wired/read/aliases/bad2", test_read_wired_aliases_bad_2); + g_test_add_func(TPATH "wifi/read/open", test_read_wifi_open); + g_test_add_func(TPATH "wifi/read/open/auto", test_read_wifi_open_auto); + g_test_add_func(TPATH "wifi/read/open/hex-ssid", test_read_wifi_open_ssid_hex); + g_test_add_func(TPATH "wifi/read/open-ssid/bad-hex", test_read_wifi_open_ssid_hex_bad); + g_test_add_data_func(TPATH "wifi/read/open-ssid/long-hex", + TEST_IFCFG_WIFI_OPEN_SSID_LONG_HEX, + test_read_wifi_open_ssid_bad); + g_test_add_data_func(TPATH "wifi/read/open-ssid/long-quoted", + TEST_IFCFG_WIFI_OPEN_SSID_LONG_QUOTED, + test_read_wifi_open_ssid_bad); + g_test_add_func(TPATH "wifi/read/open/quoted-ssid", test_read_wifi_open_ssid_quoted); + g_test_add_func(TPATH "wifi/read/wep", test_read_wifi_wep); + g_test_add_func(TPATH "wifi/read/wep/adhoc", test_read_wifi_wep_adhoc); + g_test_add_func(TPATH "wifi/read/wep/passphrase", test_read_wifi_wep_passphrase); + g_test_add_func(TPATH "wifi/read/wep/40-ascii", test_read_wifi_wep_40_ascii); + g_test_add_func(TPATH "wifi/read/wep/104-ascii", test_read_wifi_wep_104_ascii); + g_test_add_func(TPATH "wifi/read/leap", test_read_wifi_leap); + + nmtst_add_test_func(TPATH "wifi-leap-secret-flags/agent", + test_read_wifi_leap_secret_flags, + TEST_IFCFG_DIR "/ifcfg-test-wifi-leap-agent", + GINT_TO_POINTER(NM_SETTING_SECRET_FLAG_AGENT_OWNED)); + nmtst_add_test_func( + TPATH "wifi-leap-secret-flags/ask", + test_read_wifi_leap_secret_flags, + TEST_IFCFG_DIR "/ifcfg-test-wifi-leap-always-ask", + GINT_TO_POINTER(NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED)); + + g_test_add_func(TPATH "wifi/read/wpa-psk", test_read_wifi_wpa_psk); + g_test_add_func(TPATH "wifi/read/wpa-psk/2", test_read_wifi_wpa_psk_2); + g_test_add_func(TPATH "wifi/read/wpa-psk/unquoted", test_read_wifi_wpa_psk_unquoted); + g_test_add_func(TPATH "wifi/read/wpa-psk/unquoted2", test_read_wifi_wpa_psk_unquoted2); + g_test_add_func(TPATH "wifi/read/wpa-psk/adhoc", test_read_wifi_wpa_psk_adhoc); + g_test_add_func(TPATH "wifi/read/wpa-psk/hex", test_read_wifi_wpa_psk_hex); + g_test_add_func(TPATH "wifi/read/sae", test_read_wifi_sae); + g_test_add_func(TPATH "wifi/read/owe", test_read_wifi_owe); + g_test_add_func(TPATH "wifi/read/dynamic-wep/leap", test_read_wifi_dynamic_wep_leap); + g_test_add_func(TPATH "wifi/read/wpa/eap/tls", test_read_wifi_wpa_eap_tls); + g_test_add_func(TPATH "wifi/read/wpa/eap/ttls/tls", test_read_wifi_wpa_eap_ttls_tls); + g_test_add_func(TPATH "wifi/read/dynamic-wep/eap/ttls/chap", test_read_wifi_wep_eap_ttls_chap); + g_test_add_func(TPATH "wifi/read-band-a", test_read_wifi_band_a); + g_test_add_func(TPATH "wifi/read-band-a-channel-mismatch", + test_read_wifi_band_a_channel_mismatch); + g_test_add_func(TPATH "wifi/read-band-bg-channel-mismatch", + test_read_wifi_band_bg_channel_mismatch); + g_test_add_func(TPATH "wifi/read-hidden", test_read_wifi_hidden); + + nmtst_add_test_func(TPATH "wifi/read-mac-random-always", + test_read_wifi_mac_random, + "always", + GINT_TO_POINTER(NM_SETTING_MAC_RANDOMIZATION_ALWAYS)); + nmtst_add_test_func(TPATH "wifi/read-mac-random-never", + test_read_wifi_mac_random, + "never", + GINT_TO_POINTER(NM_SETTING_MAC_RANDOMIZATION_NEVER)); + nmtst_add_test_func(TPATH "wifi/read-mac-random-default", + test_read_wifi_mac_random, + "default", + GINT_TO_POINTER(NM_SETTING_MAC_RANDOMIZATION_DEFAULT)); + nmtst_add_test_func(TPATH "wifi/read-mac-random-missing", + test_read_wifi_mac_random, + "missing", + GINT_TO_POINTER(NM_SETTING_MAC_RANDOMIZATION_DEFAULT)); + + nmtst_add_test_func(TPATH "wifi/write-mac-random-always", + test_write_wifi_mac_random, + "always", + GINT_TO_POINTER(NM_SETTING_MAC_RANDOMIZATION_ALWAYS), + "always"); + nmtst_add_test_func(TPATH "wifi/write-mac-random-never", + test_write_wifi_mac_random, + "never", + GINT_TO_POINTER(NM_SETTING_MAC_RANDOMIZATION_NEVER), + "never"); + nmtst_add_test_func(TPATH "wifi/write-mac-random-default", + test_write_wifi_mac_random, + "default", + GINT_TO_POINTER(NM_SETTING_MAC_RANDOMIZATION_DEFAULT), + "default"); + nmtst_add_test_func(TPATH "wifi/write-mac-random-missing", + test_write_wifi_mac_random, + "missing", + GINT_TO_POINTER(NM_SETTING_MAC_RANDOMIZATION_NEVER), + "never"); + + g_test_add_func(TPATH "wifi/read/wep-no-keys", test_read_wifi_wep_no_keys); + g_test_add_func(TPATH "wifi/read/wep-agent-keys", test_read_wifi_wep_agent_keys); + g_test_add_func(TPATH "infiniband/read", test_read_infiniband); + g_test_add_func(TPATH "vlan/read", test_read_vlan_interface); + g_test_add_func(TPATH "vlan/read-flags-1", test_read_vlan_flags_1); + g_test_add_func(TPATH "vlan/read-flags-2", test_read_vlan_flags_2); + g_test_add_func(TPATH "vlan/read/only-vlanid", test_read_vlan_only_vlan_id); + g_test_add_func(TPATH "vlan/read/only-device", test_read_vlan_only_device); + g_test_add_func(TPATH "vlan/read/physdev", test_read_vlan_physdev); + g_test_add_func(TPATH "vlan/read/reorder-hdr-1", test_read_vlan_reorder_hdr_1); + g_test_add_func(TPATH "vlan/read/reorder-hdr-2", test_read_vlan_reorder_hdr_2); + g_test_add_func(TPATH "wired/read/read-wake-on-lan", test_read_wired_wake_on_lan); + g_test_add_func(TPATH "wired/read/read-auto-negotiate-off", test_read_wired_auto_negotiate_off); + g_test_add_func(TPATH "wired/read/read-auto-negotiate-on", test_read_wired_auto_negotiate_on); + g_test_add_func(TPATH "wired/read/unkwnown-ethtool-opt", test_read_wired_unknown_ethtool_opt); + + g_test_add_func(TPATH "wired/write/static", test_write_wired_static); + g_test_add_func(TPATH "wired/write/static-with-generic", test_write_wired_static_with_generic); + g_test_add_func(TPATH "wired/write/static-ip6-only", test_write_wired_static_ip6_only); + g_test_add_func(TPATH "wired/write-static-routes", test_write_wired_static_routes); + g_test_add_func(TPATH "wired/read-write-static-routes-legacy", + test_read_write_static_routes_legacy); + g_test_add_func(TPATH "wired/write/dhcp", test_write_wired_dhcp); + g_test_add_func(TPATH "wired/write-dhcp-plus-ip", test_write_wired_dhcp_plus_ip); + g_test_add_func(TPATH "wired/write/dhcp-8021x-peap-mschapv2", + test_write_wired_dhcp_8021x_peap_mschapv2); + g_test_add_func(TPATH "wired/write/match", test_write_wired_match); + g_test_add_func(TPATH "wired/write/routing-rules", test_write_routing_rules); #define _add_test_write_wired_8021x_tls(testpath, scheme, flags) \ - nmtst_add_test_func (testpath, test_write_wired_8021x_tls, GINT_TO_POINTER (scheme), GINT_TO_POINTER (flags)) - _add_test_write_wired_8021x_tls (TPATH "wired-8021x-tls/1", NM_SETTING_802_1X_CK_SCHEME_PATH, NM_SETTING_SECRET_FLAG_AGENT_OWNED); - _add_test_write_wired_8021x_tls (TPATH "wired-8021x-tls/2", NM_SETTING_802_1X_CK_SCHEME_PATH, NM_SETTING_SECRET_FLAG_NOT_SAVED); - _add_test_write_wired_8021x_tls (TPATH "wired-8021x-tls/3", NM_SETTING_802_1X_CK_SCHEME_PATH, NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED); - _add_test_write_wired_8021x_tls (TPATH "wired-8021x-tls/4", NM_SETTING_802_1X_CK_SCHEME_BLOB, NM_SETTING_SECRET_FLAG_NONE); - - g_test_add_func (TPATH "wired/write-aliases", test_write_wired_aliases); - g_test_add_func (TPATH "ipv4/write-static-addresses-GATEWAY", test_write_gateway); - g_test_add_func (TPATH "wired/write-wake-on-lan", test_write_wired_wake_on_lan); - g_test_add_func (TPATH "wired/write-auto-negotiate-off", test_write_wired_auto_negotiate_off); - g_test_add_func (TPATH "wired/write-auto-negotiate-on", test_write_wired_auto_negotiate_on); - g_test_add_func (TPATH "wifi/write/open", test_write_wifi_open); - g_test_add_func (TPATH "wifi/write/open/hex-ssid", test_write_wifi_open_hex_ssid); - g_test_add_func (TPATH "wifi/write/wep", test_write_wifi_wep); - g_test_add_func (TPATH "wifi/write/wep/adhoc", test_write_wifi_wep_adhoc); - g_test_add_func (TPATH "wifi/write/wep/passphrase", test_write_wifi_wep_passphrase); - g_test_add_func (TPATH "wifi/write/wep/40-ascii", test_write_wifi_wep_40_ascii); - g_test_add_func (TPATH "wifi/write/wep/104-ascii", test_write_wifi_wep_104_ascii); - g_test_add_func (TPATH "wifi/write/leap", test_write_wifi_leap); - g_test_add_data_func (TPATH "wifi/write/leap/flags/agent", - GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED), - test_write_wifi_leap_secret_flags); - g_test_add_data_func (TPATH "wifi/write/leap/flags/not-saved", - GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_NOT_SAVED), - test_write_wifi_leap_secret_flags); - g_test_add_data_func (TPATH "wifi/write/leap/flags/agent-and-not-saved", - GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED), - test_write_wifi_leap_secret_flags); + nmtst_add_test_func(testpath, \ + test_write_wired_8021x_tls, \ + GINT_TO_POINTER(scheme), \ + GINT_TO_POINTER(flags)) + _add_test_write_wired_8021x_tls(TPATH "wired-8021x-tls/1", + NM_SETTING_802_1X_CK_SCHEME_PATH, + NM_SETTING_SECRET_FLAG_AGENT_OWNED); + _add_test_write_wired_8021x_tls(TPATH "wired-8021x-tls/2", + NM_SETTING_802_1X_CK_SCHEME_PATH, + NM_SETTING_SECRET_FLAG_NOT_SAVED); + _add_test_write_wired_8021x_tls(TPATH "wired-8021x-tls/3", + NM_SETTING_802_1X_CK_SCHEME_PATH, + NM_SETTING_SECRET_FLAG_AGENT_OWNED + | NM_SETTING_SECRET_FLAG_NOT_SAVED); + _add_test_write_wired_8021x_tls(TPATH "wired-8021x-tls/4", + NM_SETTING_802_1X_CK_SCHEME_BLOB, + NM_SETTING_SECRET_FLAG_NONE); + + g_test_add_func(TPATH "wired/write-aliases", test_write_wired_aliases); + g_test_add_func(TPATH "ipv4/write-static-addresses-GATEWAY", test_write_gateway); + g_test_add_func(TPATH "wired/write-wake-on-lan", test_write_wired_wake_on_lan); + g_test_add_func(TPATH "wired/write-auto-negotiate-off", test_write_wired_auto_negotiate_off); + g_test_add_func(TPATH "wired/write-auto-negotiate-on", test_write_wired_auto_negotiate_on); + g_test_add_func(TPATH "wifi/write/open", test_write_wifi_open); + g_test_add_func(TPATH "wifi/write/open/hex-ssid", test_write_wifi_open_hex_ssid); + g_test_add_func(TPATH "wifi/write/wep", test_write_wifi_wep); + g_test_add_func(TPATH "wifi/write/wep/adhoc", test_write_wifi_wep_adhoc); + g_test_add_func(TPATH "wifi/write/wep/passphrase", test_write_wifi_wep_passphrase); + g_test_add_func(TPATH "wifi/write/wep/40-ascii", test_write_wifi_wep_40_ascii); + g_test_add_func(TPATH "wifi/write/wep/104-ascii", test_write_wifi_wep_104_ascii); + g_test_add_func(TPATH "wifi/write/leap", test_write_wifi_leap); + g_test_add_data_func(TPATH "wifi/write/leap/flags/agent", + GUINT_TO_POINTER(NM_SETTING_SECRET_FLAG_AGENT_OWNED), + test_write_wifi_leap_secret_flags); + g_test_add_data_func(TPATH "wifi/write/leap/flags/not-saved", + GUINT_TO_POINTER(NM_SETTING_SECRET_FLAG_NOT_SAVED), + test_write_wifi_leap_secret_flags); + g_test_add_data_func( + TPATH "wifi/write/leap/flags/agent-and-not-saved", + GUINT_TO_POINTER(NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED), + test_write_wifi_leap_secret_flags); #define _add_test_write_wifi_wpa_psk(testpath, name, wep_group, wpa, wpa2, psk) \ - nmtst_add_test_func (testpath, test_write_wifi_wpa_psk, name, GPOINTER_TO_INT (wep_group), GPOINTER_TO_INT (wpa), GPOINTER_TO_INT (wpa2), psk) - _add_test_write_wifi_wpa_psk (TPATH "wifi-wpa-psk/wpa-psk-write", "Test Write Wifi WPA PSK", FALSE, TRUE, FALSE, DEFAULT_HEX_PSK); - _add_test_write_wifi_wpa_psk (TPATH "wifi-wpa-psk/wpa2-psk-write", "Test Write Wifi WPA2 PSK", FALSE, FALSE, TRUE, DEFAULT_HEX_PSK); - _add_test_write_wifi_wpa_psk (TPATH "wifi-wpa-psk/wpa-wpa2-psk-write", "Test Write Wifi WPA WPA2 PSK", FALSE, TRUE, TRUE, DEFAULT_HEX_PSK); - _add_test_write_wifi_wpa_psk (TPATH "wifi-wpa-psk/wep-wpa-wpa2-psk-write", "Test Write Wifi WEP WPA WPA2 PSK", TRUE, TRUE, TRUE, DEFAULT_HEX_PSK); - _add_test_write_wifi_wpa_psk (TPATH "wifi-wpa-psk/wpa-wpa2-psk-passphrase-write", "Test Write Wifi WPA WPA2 PSK Passphrase", FALSE, TRUE, TRUE, "really insecure passphrase04!"); - _add_test_write_wifi_wpa_psk (TPATH "wifi-wpa-psk/wpa-wpa2-psk-passphrase-write-spec-chars", "Test Write Wifi WPA WPA2 PSK Passphrase Special Chars", FALSE, TRUE, TRUE, "blah`oops\"grr'$*@~!%\\"); - - g_test_add_func (TPATH "wifi/write/wpa/psk/adhoc", test_write_wifi_wpa_psk_adhoc); - g_test_add_func (TPATH "wifi/write/wpa/eap/tls", test_write_wifi_wpa_eap_tls); - g_test_add_func (TPATH "wifi/write/wpa/eap/ttls/tls", test_write_wifi_wpa_eap_ttls_tls); - g_test_add_func (TPATH "wifi/write/wpa/eap/ttls/mschapv2", test_write_wifi_wpa_eap_ttls_mschapv2); - g_test_add_func (TPATH "wifi/write/dynamic-wep/leap", test_write_wifi_dynamic_wep_leap); - g_test_add_func (TPATH "wifi/write-wpa-then-open", test_write_wifi_wpa_then_open); - g_test_add_func (TPATH "wifi/write-wpa-then-wep-with-perms", test_write_wifi_wpa_then_wep_with_perms); - g_test_add_func (TPATH "wifi/write-hidden", test_write_wifi_hidden); - g_test_add_func (TPATH "wifi/write-band-a", test_write_wifi_band_a); - - g_test_add_func (TPATH "s390/read-qeth-static", test_read_wired_qeth_static); - g_test_add_func (TPATH "s390/write-qeth-dhcp", test_write_wired_qeth_dhcp); - g_test_add_func (TPATH "s390/read-ctc-static", test_read_wired_ctc_static); - g_test_add_func (TPATH "s390/write-ctc-dhcp", test_write_wired_ctc_dhcp); - - g_test_add_func (TPATH "permissions/read", test_read_permissions); - g_test_add_func (TPATH "permissions/write", test_write_permissions); - g_test_add_func (TPATH "wifi/write-wep-agent-keys", test_write_wifi_wep_agent_keys); - g_test_add_func (TPATH "infiniband/write", test_write_infiniband); - g_test_add_func (TPATH "vlan/write", test_write_vlan); - g_test_add_func (TPATH "vlan/write-flags", test_write_vlan_flags); - g_test_add_func (TPATH "vlan/write-only-vlanid", test_write_vlan_only_vlanid); - g_test_add_func (TPATH "vlan/write-vlan-reorder-hdr", test_write_vlan_reorder_hdr); - g_test_add_func (TPATH "wired/write-missing-ipv6", test_write_ethernet_missing_ipv6); - g_test_add_func (TPATH "write-dns-options", test_write_dns_options); - - g_test_add_func (TPATH "ibft/ignored", test_read_ibft_ignored); - - g_test_add_func (TPATH "dcb/read-basic", test_read_dcb_basic); - g_test_add_func (TPATH "dcb/write-basic", test_write_dcb_basic); - g_test_add_func (TPATH "dcb/default-app-priorities", test_read_dcb_default_app_priorities); - g_test_add_func (TPATH "dcb/bad-booleans", test_read_dcb_bad_booleans); - g_test_add_func (TPATH "dcb/short-booleans", test_read_dcb_short_booleans); - g_test_add_func (TPATH "dcb/bad-uints", test_read_dcb_bad_uints); - g_test_add_func (TPATH "dcb/short-uints", test_read_dcb_short_uints); - g_test_add_func (TPATH "dcb/bad-percent", test_read_dcb_bad_percent); - g_test_add_func (TPATH "dcb/short-percent", test_read_dcb_short_percent); - g_test_add_func (TPATH "dcb/pgpct-not-100", test_read_dcb_pgpct_not_100); - g_test_add_data_func (TPATH "fcoe/fabric", (gpointer) NM_SETTING_DCB_FCOE_MODE_FABRIC, test_read_fcoe_mode); - g_test_add_data_func (TPATH "fcoe/vn2vn", (gpointer) NM_SETTING_DCB_FCOE_MODE_VN2VN, test_read_fcoe_mode); - g_test_add_data_func (TPATH "fcoe/write-fabric", (gpointer) NM_SETTING_DCB_FCOE_MODE_FABRIC, test_write_fcoe_mode); - g_test_add_data_func (TPATH "fcoe/write-vn2vn", (gpointer) NM_SETTING_DCB_FCOE_MODE_VN2VN, test_write_fcoe_mode); - - g_test_add_func (TPATH "bond/read-master", test_read_bond_main); - g_test_add_func (TPATH "bond/read-master-eth-type", test_read_bond_eth_type); - g_test_add_func (TPATH "bond/read-slave", test_read_bond_slave); - g_test_add_func (TPATH "bond/read-slave-ib", test_read_bond_slave_ib); - g_test_add_func (TPATH "bond/write-master", test_write_bond_main); - g_test_add_func (TPATH "bond/write-slave", test_write_bond_slave); - g_test_add_func (TPATH "bond/write-slave-ib", test_write_bond_slave_ib); - g_test_add_func (TPATH "bond/bonding-opts-numeric-mode", test_read_bond_opts_mode_numeric); - - g_test_add_func (TPATH "bridge/read-master", test_read_bridge_main); - g_test_add_func (TPATH "bridge/write-master", test_write_bridge_main); - g_test_add_func (TPATH "bridge/read-component", test_read_bridge_component); - g_test_add_func (TPATH "bridge/write-component", test_write_bridge_component); - g_test_add_func (TPATH "bridge/read-missing-stp", test_read_bridge_missing_stp); - - g_test_add_data_func (TPATH "team/read-master-1", TEST_IFCFG_DIR"/ifcfg-test-team-master-1", test_read_team_master); - g_test_add_data_func (TPATH "team/read-master-2", TEST_IFCFG_DIR"/ifcfg-test-team-master-2", test_read_team_master); - g_test_add_data_func (TPATH "team/read-master-invalid", TEST_IFCFG_DIR"/ifcfg-test-team-master-invalid", test_read_team_master_invalid); - g_test_add_func (TPATH "team/write-master", test_write_team_master); - g_test_add_data_func (TPATH "team/read-port-1", TEST_IFCFG_DIR"/ifcfg-test-team-port-1", test_read_team_port); - g_test_add_data_func (TPATH "team/read-port-2", TEST_IFCFG_DIR"/ifcfg-test-team-port-2", test_read_team_port); - g_test_add_func (TPATH "team/write-port", test_write_team_port); - g_test_add_func (TPATH "team/write-infiniband-port", test_write_team_infiniband_port); - g_test_add_func (TPATH "team/read-port-empty-config", test_read_team_port_empty_config); - g_test_add_func (TPATH "team/reread-slave", test_team_reread_slave); - - g_test_add_func (TPATH "proxy/read-proxy-basic", test_read_proxy_basic); - g_test_add_func (TPATH "proxy/write-proxy-basic", test_write_proxy_basic); - - g_test_add_func (TPATH "sit/read/ignore", test_sit_read_ignore); - - /* Stuff we expect to fail for now */ - g_test_add_func (TPATH "pppoe/write-wired", test_write_wired_pppoe); - g_test_add_func (TPATH "vpn/write", test_write_vpn); - g_test_add_data_func (TPATH "wwan/write-gsm", GUINT_TO_POINTER (TRUE), test_write_mobile_broadband); - g_test_add_data_func (TPATH "wwan/write-cdma", GUINT_TO_POINTER (FALSE), test_write_mobile_broadband); - - g_test_add_func (TPATH "no-trailing-newline", test_ifcfg_no_trailing_newline); - - g_test_add_func (TPATH "utils/name", test_utils_name); - g_test_add_func (TPATH "utils/path", test_utils_path); - g_test_add_func (TPATH "utils/ignore", test_utils_ignore); - - g_test_add_func (TPATH "sriov/read", test_sriov_read); - g_test_add_func (TPATH "sriov/write", test_sriov_write); - - g_test_add_func (TPATH "tc/read", test_tc_read); - g_test_add_func (TPATH "tc/write", test_tc_write); - g_test_add_func (TPATH "utils/test_well_known_keys", test_well_known_keys); - g_test_add_func (TPATH "utils/test_utils_has_route_file_new_syntax", test_utils_has_route_file_new_syntax); - - g_test_add_func (TPATH "utils/test_ethtool_names", test_ethtool_names); - - return g_test_run (); + nmtst_add_test_func(testpath, \ + test_write_wifi_wpa_psk, \ + name, \ + GPOINTER_TO_INT(wep_group), \ + GPOINTER_TO_INT(wpa), \ + GPOINTER_TO_INT(wpa2), \ + psk) + _add_test_write_wifi_wpa_psk(TPATH "wifi-wpa-psk/wpa-psk-write", + "Test Write Wifi WPA PSK", + FALSE, + TRUE, + FALSE, + DEFAULT_HEX_PSK); + _add_test_write_wifi_wpa_psk(TPATH "wifi-wpa-psk/wpa2-psk-write", + "Test Write Wifi WPA2 PSK", + FALSE, + FALSE, + TRUE, + DEFAULT_HEX_PSK); + _add_test_write_wifi_wpa_psk(TPATH "wifi-wpa-psk/wpa-wpa2-psk-write", + "Test Write Wifi WPA WPA2 PSK", + FALSE, + TRUE, + TRUE, + DEFAULT_HEX_PSK); + _add_test_write_wifi_wpa_psk(TPATH "wifi-wpa-psk/wep-wpa-wpa2-psk-write", + "Test Write Wifi WEP WPA WPA2 PSK", + TRUE, + TRUE, + TRUE, + DEFAULT_HEX_PSK); + _add_test_write_wifi_wpa_psk(TPATH "wifi-wpa-psk/wpa-wpa2-psk-passphrase-write", + "Test Write Wifi WPA WPA2 PSK Passphrase", + FALSE, + TRUE, + TRUE, + "really insecure passphrase04!"); + _add_test_write_wifi_wpa_psk(TPATH "wifi-wpa-psk/wpa-wpa2-psk-passphrase-write-spec-chars", + "Test Write Wifi WPA WPA2 PSK Passphrase Special Chars", + FALSE, + TRUE, + TRUE, + "blah`oops\"grr'$*@~!%\\"); + + g_test_add_func(TPATH "wifi/write/wpa/psk/adhoc", test_write_wifi_wpa_psk_adhoc); + g_test_add_func(TPATH "wifi/write/wpa/eap/tls", test_write_wifi_wpa_eap_tls); + g_test_add_func(TPATH "wifi/write/wpa/eap/ttls/tls", test_write_wifi_wpa_eap_ttls_tls); + g_test_add_func(TPATH "wifi/write/wpa/eap/ttls/mschapv2", + test_write_wifi_wpa_eap_ttls_mschapv2); + g_test_add_func(TPATH "wifi/write/dynamic-wep/leap", test_write_wifi_dynamic_wep_leap); + g_test_add_func(TPATH "wifi/write-wpa-then-open", test_write_wifi_wpa_then_open); + g_test_add_func(TPATH "wifi/write-wpa-then-wep-with-perms", + test_write_wifi_wpa_then_wep_with_perms); + g_test_add_func(TPATH "wifi/write-hidden", test_write_wifi_hidden); + g_test_add_func(TPATH "wifi/write-band-a", test_write_wifi_band_a); + g_test_add_func(TPATH "wifi/write-ap-mode", test_write_wifi_ap_mode); + + g_test_add_func(TPATH "s390/read-qeth-static", test_read_wired_qeth_static); + g_test_add_func(TPATH "s390/write-qeth-dhcp", test_write_wired_qeth_dhcp); + g_test_add_func(TPATH "s390/read-ctc-static", test_read_wired_ctc_static); + g_test_add_func(TPATH "s390/write-ctc-dhcp", test_write_wired_ctc_dhcp); + + g_test_add_func(TPATH "permissions/read", test_read_permissions); + g_test_add_func(TPATH "permissions/write", test_write_permissions); + g_test_add_func(TPATH "wifi/write-wep-agent-keys", test_write_wifi_wep_agent_keys); + g_test_add_func(TPATH "infiniband/write", test_write_infiniband); + g_test_add_func(TPATH "vlan/write", test_write_vlan); + g_test_add_func(TPATH "vlan/write-flags", test_write_vlan_flags); + g_test_add_func(TPATH "vlan/write-only-vlanid", test_write_vlan_only_vlanid); + g_test_add_func(TPATH "vlan/write-vlan-reorder-hdr", test_write_vlan_reorder_hdr); + g_test_add_func(TPATH "wired/write-missing-ipv6", test_write_ethernet_missing_ipv6); + g_test_add_func(TPATH "write-dns-options", test_write_dns_options); + + g_test_add_func(TPATH "ibft/ignored", test_read_ibft_ignored); + + g_test_add_func(TPATH "dcb/read-basic", test_read_dcb_basic); + g_test_add_func(TPATH "dcb/write-basic", test_write_dcb_basic); + g_test_add_func(TPATH "dcb/default-app-priorities", test_read_dcb_default_app_priorities); + g_test_add_func(TPATH "dcb/bad-booleans", test_read_dcb_bad_booleans); + g_test_add_func(TPATH "dcb/short-booleans", test_read_dcb_short_booleans); + g_test_add_func(TPATH "dcb/bad-uints", test_read_dcb_bad_uints); + g_test_add_func(TPATH "dcb/short-uints", test_read_dcb_short_uints); + g_test_add_func(TPATH "dcb/bad-percent", test_read_dcb_bad_percent); + g_test_add_func(TPATH "dcb/short-percent", test_read_dcb_short_percent); + g_test_add_func(TPATH "dcb/pgpct-not-100", test_read_dcb_pgpct_not_100); + g_test_add_data_func(TPATH "fcoe/fabric", + (gpointer) NM_SETTING_DCB_FCOE_MODE_FABRIC, + test_read_fcoe_mode); + g_test_add_data_func(TPATH "fcoe/vn2vn", + (gpointer) NM_SETTING_DCB_FCOE_MODE_VN2VN, + test_read_fcoe_mode); + g_test_add_data_func(TPATH "fcoe/write-fabric", + (gpointer) NM_SETTING_DCB_FCOE_MODE_FABRIC, + test_write_fcoe_mode); + g_test_add_data_func(TPATH "fcoe/write-vn2vn", + (gpointer) NM_SETTING_DCB_FCOE_MODE_VN2VN, + test_write_fcoe_mode); + + g_test_add_func(TPATH "bond/read-master", test_read_bond_main); + g_test_add_func(TPATH "bond/read-master-eth-type", test_read_bond_eth_type); + g_test_add_func(TPATH "bond/read-slave", test_read_bond_slave); + g_test_add_func(TPATH "bond/read-slave-ib", test_read_bond_slave_ib); + g_test_add_func(TPATH "bond/write-master", test_write_bond_main); + g_test_add_func(TPATH "bond/write-slave", test_write_bond_slave); + g_test_add_func(TPATH "bond/write-slave-ib", test_write_bond_slave_ib); + g_test_add_func(TPATH "bond/bonding-opts-numeric-mode", test_read_bond_opts_mode_numeric); + + g_test_add_func(TPATH "bridge/read-master", test_read_bridge_main); + g_test_add_func(TPATH "bridge/write-master", test_write_bridge_main); + g_test_add_func(TPATH "bridge/read-component", test_read_bridge_component); + g_test_add_func(TPATH "bridge/write-component", test_write_bridge_component); + g_test_add_func(TPATH "bridge/read-missing-stp", test_read_bridge_missing_stp); + + g_test_add_data_func(TPATH "team/read-master-1", + TEST_IFCFG_DIR "/ifcfg-test-team-master-1", + test_read_team_master); + g_test_add_data_func(TPATH "team/read-master-2", + TEST_IFCFG_DIR "/ifcfg-test-team-master-2", + test_read_team_master); + g_test_add_data_func(TPATH "team/read-master-invalid", + TEST_IFCFG_DIR "/ifcfg-test-team-master-invalid", + test_read_team_master_invalid); + g_test_add_func(TPATH "team/write-master", test_write_team_master); + g_test_add_data_func(TPATH "team/read-port-1", + TEST_IFCFG_DIR "/ifcfg-test-team-port-1", + test_read_team_port); + g_test_add_data_func(TPATH "team/read-port-2", + TEST_IFCFG_DIR "/ifcfg-test-team-port-2", + test_read_team_port); + g_test_add_func(TPATH "team/write-port", test_write_team_port); + g_test_add_func(TPATH "team/write-infiniband-port", test_write_team_infiniband_port); + g_test_add_func(TPATH "team/read-port-empty-config", test_read_team_port_empty_config); + g_test_add_func(TPATH "team/reread-slave", test_team_reread_slave); + + g_test_add_func(TPATH "proxy/read-proxy-basic", test_read_proxy_basic); + g_test_add_func(TPATH "proxy/write-proxy-basic", test_write_proxy_basic); + + g_test_add_func(TPATH "sit/read/ignore", test_sit_read_ignore); + + /* Stuff we expect to fail for now */ + g_test_add_func(TPATH "pppoe/write-wired", test_write_wired_pppoe); + g_test_add_func(TPATH "vpn/write", test_write_vpn); + g_test_add_data_func(TPATH "wwan/write-gsm", + GUINT_TO_POINTER(TRUE), + test_write_mobile_broadband); + g_test_add_data_func(TPATH "wwan/write-cdma", + GUINT_TO_POINTER(FALSE), + test_write_mobile_broadband); + + g_test_add_func(TPATH "no-trailing-newline", test_ifcfg_no_trailing_newline); + + g_test_add_func(TPATH "utils/name", test_utils_name); + g_test_add_func(TPATH "utils/path", test_utils_path); + g_test_add_func(TPATH "utils/ignore", test_utils_ignore); + + g_test_add_func(TPATH "sriov/read", test_sriov_read); + g_test_add_func(TPATH "sriov/write", test_sriov_write); + + g_test_add_func(TPATH "tc/read", test_tc_read); + g_test_add_func(TPATH "tc/write", test_tc_write); + g_test_add_func(TPATH "utils/test_well_known_keys", test_well_known_keys); + g_test_add_func(TPATH "utils/test_utils_has_route_file_new_syntax", + test_utils_has_route_file_new_syntax); + + g_test_add_func(TPATH "utils/test_ethtool_names", test_ethtool_names); + + return g_test_run(); } diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c index a146ae60..219490b8 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Tom Parker * Copyright (C) 2004 Tom Parker @@ -17,377 +17,372 @@ /*****************************************************************************/ -static void _ifparser_source (if_parser *parser, const char *path, const char *en_dir, int quiet, int dir); +static void +_ifparser_source(if_parser *parser, const char *path, const char *en_dir, int quiet, int dir); /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "ifupdown" -#define _NMLOG_DOMAIN LOGD_SETTINGS -#define _NMLOG(level, ...) \ - nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME": " \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)) +#define _NMLOG_PREFIX_NAME "ifupdown" +#define _NMLOG_DOMAIN LOGD_SETTINGS +#define _NMLOG(level, ...) \ + nm_log((level), \ + _NMLOG_DOMAIN, \ + NULL, \ + NULL, \ + "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME ": " _NM_UTILS_MACRO_REST(__VA_ARGS__)) /*****************************************************************************/ static void -add_block (if_parser *parser, const char *type, const char* name) +add_block(if_parser *parser, const char *type, const char *name) { - if_block *ifb; - gsize l_type, l_name; - - l_type = strlen (type) + 1; - l_name = strlen (name) + 1; - - ifb = g_malloc (sizeof (if_block) + l_type + l_name); - memcpy ((char *) ifb->name, name, l_name); - ifb->type = &ifb->name[l_name]; - memcpy ((char *) ifb->type, type, l_type); - c_list_init (&ifb->data_lst_head); - c_list_link_tail (&parser->block_lst_head, &ifb->block_lst); + if_block *ifb; + gsize l_type, l_name; + + l_type = strlen(type) + 1; + l_name = strlen(name) + 1; + + ifb = g_malloc(sizeof(if_block) + l_type + l_name); + memcpy((char *) ifb->name, name, l_name); + ifb->type = &ifb->name[l_name]; + memcpy((char *) ifb->type, type, l_type); + c_list_init(&ifb->data_lst_head); + c_list_link_tail(&parser->block_lst_head, &ifb->block_lst); } static void -add_data (if_parser *parser, const char *key, const char *data) +add_data(if_parser *parser, const char *key, const char *data) { - if_block *last_block; - if_data *ifd; - char *idx; - gsize l_key, l_data; + if_block *last_block; + if_data * ifd; + char * idx; + gsize l_key, l_data; - last_block = c_list_last_entry (&parser->block_lst_head, if_block, block_lst); + last_block = c_list_last_entry(&parser->block_lst_head, if_block, block_lst); - /* Check if there is a block where we can attach our data */ - if (!last_block) - return; + /* Check if there is a block where we can attach our data */ + if (!last_block) + return; - l_key = strlen (key) + 1; - l_data = strlen (data) + 1; + l_key = strlen(key) + 1; + l_data = strlen(data) + 1; - ifd = g_malloc (sizeof (if_data) + l_key + l_data); - memcpy ((char *) ifd->key, key, l_key); - ifd->data = &ifd->key[l_key]; - memcpy ((char *) ifd->data, data, l_data); + ifd = g_malloc(sizeof(if_data) + l_key + l_data); + memcpy((char *) ifd->key, key, l_key); + ifd->data = &ifd->key[l_key]; + memcpy((char *) ifd->data, data, l_data); - /* Normalize keys. Convert '_' to '-', as ifupdown accepts both variants. - * When querying keys via ifparser_getkey(), use '-'. */ - idx = (char *) ifd->key; - while ((idx = strchr (idx, '_'))) - *(idx++) = '-'; + /* Normalize keys. Convert '_' to '-', as ifupdown accepts both variants. + * When querying keys via ifparser_getkey(), use '-'. */ + idx = (char *) ifd->key; + while ((idx = strchr(idx, '_'))) + *(idx++) = '-'; - c_list_link_tail (&last_block->data_lst_head, &ifd->data_lst); + c_list_link_tail(&last_block->data_lst_head, &ifd->data_lst); } /* join values in src with spaces into dst; dst needs to be large enough */ static char * -join_values_with_spaces (char *dst, char **src) +join_values_with_spaces(char *dst, char **src) { - if (dst != NULL) { - *dst = '\0'; - if (src != NULL && *src != NULL) { - strcat (dst, *src); - - for (src++; *src != NULL; src++) { - strcat (dst, " "); - strcat (dst, *src); - } - } - } - return (dst); + if (dst != NULL) { + *dst = '\0'; + if (src != NULL && *src != NULL) { + strcat(dst, *src); + + for (src++; *src != NULL; src++) { + strcat(dst, " "); + strcat(dst, *src); + } + } + } + return (dst); } static void -_recursive_ifparser (if_parser *parser, const char *eni_file, int quiet) +_recursive_ifparser(if_parser *parser, const char *eni_file, int quiet) { - FILE *inp; - char line[255]; - int skip_to_block = 1; - int skip_long_line = 0; - int offs = 0; - - /* Check if interfaces file exists and open it */ - if (!g_file_test (eni_file, G_FILE_TEST_EXISTS)) { - if (!quiet) - _LOGW ("interfaces file %s doesn't exist", eni_file); - return; - } - inp = fopen (eni_file, "re"); - if (inp == NULL) { - if (!quiet) - _LOGW ("Can't open %s", eni_file); - return; - } - if (!quiet) - _LOGI (" interface-parser: parsing file %s", eni_file); - - while (!feof (inp)) { - char *token[128]; /* 255 chars can only be split into 127 tokens */ - char value[255]; /* large enough to join previously split tokens */ - char *safeptr; - int toknum; - int len = 0; - - char *ptr = fgets (line+offs, 255-offs, inp); - if (ptr == NULL) - break; - - len = strlen (line); - /* skip over-long lines */ - if (!feof (inp) && len > 0 && line[len-1] != '\n') { - if (!skip_long_line) { - if (!quiet) - _LOGW ("Skipping over-long-line '%s...'", line); - } - skip_long_line = 1; - continue; - } - - /* trailing '\n' found: remove it & reset offset to 0 */ - if (len > 0 && line[len-1] == '\n') { - line[--len] = '\0'; - offs = 0; - } - - /* if we're in long_line_skip mode, terminate it for real next line */ - if (skip_long_line) { - if (len == 0 || line[len-1] != '\\') - skip_long_line = 0; - continue; - } - - /* unwrap wrapped lines */ - if (len > 0 && line[len-1] == '\\') { - offs = len - 1; - continue; - } + FILE *inp; + char line[255]; + int skip_to_block = 1; + int skip_long_line = 0; + int offs = 0; + + /* Check if interfaces file exists and open it */ + if (!g_file_test(eni_file, G_FILE_TEST_EXISTS)) { + if (!quiet) + _LOGW("interfaces file %s doesn't exist", eni_file); + return; + } + inp = fopen(eni_file, "re"); + if (inp == NULL) { + if (!quiet) + _LOGW("Can't open %s", eni_file); + return; + } + if (!quiet) + _LOGI(" interface-parser: parsing file %s", eni_file); + + while (!feof(inp)) { + char *token[128]; /* 255 chars can only be split into 127 tokens */ + char value[255]; /* large enough to join previously split tokens */ + char *safeptr; + int toknum; + int len = 0; + + char *ptr = fgets(line + offs, 255 - offs, inp); + if (ptr == NULL) + break; + + len = strlen(line); + /* skip over-long lines */ + if (!feof(inp) && len > 0 && line[len - 1] != '\n') { + if (!skip_long_line) { + if (!quiet) + _LOGW("Skipping over-long-line '%s...'", line); + } + skip_long_line = 1; + continue; + } + + /* trailing '\n' found: remove it & reset offset to 0 */ + if (len > 0 && line[len - 1] == '\n') { + line[--len] = '\0'; + offs = 0; + } + + /* if we're in long_line_skip mode, terminate it for real next line */ + if (skip_long_line) { + if (len == 0 || line[len - 1] != '\\') + skip_long_line = 0; + continue; + } + + /* unwrap wrapped lines */ + if (len > 0 && line[len - 1] == '\\') { + offs = len - 1; + continue; + } #define SPACES " \t" - /* tokenize input; */ - for (toknum = 0, token[toknum] = strtok_r (line, SPACES, &safeptr); - token[toknum] != NULL; - toknum++, token[toknum] = strtok_r (NULL, SPACES, &safeptr)) - ; - - /* ignore comments and empty lines */ - if (toknum == 0 || *token[0]=='#') - continue; - - if (toknum < 2) { - if (!quiet) { - _LOGW ("Can't parse interface line '%s'", - join_values_with_spaces (value, token)); - } - skip_to_block = 1; - continue; - } - - /* There are six different stanzas: - * iface, mapping, auto, allow-*, source, and source-directory. - * Create a block for each of them except source and source-directory. */ - - /* iface stanza takes at least 3 parameters */ - if (nm_streq (token[0], "iface")) { - if (toknum < 4) { - if (!quiet) { - _LOGW ("Can't parse iface line '%s'", - join_values_with_spaces (value, token)); - } - continue; - } - add_block (parser, token[0], token[1]); - skip_to_block = 0; - add_data (parser, token[2], join_values_with_spaces (value, token + 3)); - } - /* auto and allow-auto stanzas are equivalent, - * both can take multiple interfaces as parameters: add one block for each */ - else if (NM_IN_STRSET (token[0], "auto", "allow-auto")) { - int i; - - for (i = 1; i < toknum; i++) - add_block (parser, "auto", token[i]); - skip_to_block = 0; - } - else if (nm_streq (token[0], "mapping")) { - add_block (parser, token[0], join_values_with_spaces (value, token + 1)); - skip_to_block = 0; - } - /* allow-* can take multiple interfaces as parameters: add one block for each */ - else if (g_str_has_prefix (token[0], "allow-")) { - int i; - for (i = 1; i < toknum; i++) - add_block (parser, token[0], token[i]); - skip_to_block = 0; - } - /* source and source-directory stanzas take one or more paths as parameters */ - else if (NM_IN_STRSET (token[0], "source", "source-directory")) { - int i; - char *en_dir; - - skip_to_block = 0; - en_dir = g_path_get_dirname (eni_file); - for (i = 1; i < toknum; ++i) { - if (nm_streq (token[0], "source-directory")) - _ifparser_source (parser, token[i], en_dir, quiet, TRUE); - else - _ifparser_source (parser, token[i], en_dir, quiet, FALSE); - } - g_free (en_dir); - } - else { - if (skip_to_block) { - if (!quiet) { - _LOGW ("ignoring out-of-block data '%s'", - join_values_with_spaces (value, token)); - } - } else - add_data (parser, token[0], join_values_with_spaces (value, token + 1)); - } - } - fclose (inp); - - if (!quiet) - _LOGI (" interface-parser: finished parsing file %s", eni_file); + /* tokenize input; */ + for (toknum = 0, token[toknum] = strtok_r(line, SPACES, &safeptr); token[toknum] != NULL; + toknum++, token[toknum] = strtok_r(NULL, SPACES, &safeptr)) + ; + + /* ignore comments and empty lines */ + if (toknum == 0 || *token[0] == '#') + continue; + + if (toknum < 2) { + if (!quiet) { + _LOGW("Can't parse interface line '%s'", join_values_with_spaces(value, token)); + } + skip_to_block = 1; + continue; + } + + /* There are six different stanzas: + * iface, mapping, auto, allow-*, source, and source-directory. + * Create a block for each of them except source and source-directory. */ + + /* iface stanza takes at least 3 parameters */ + if (nm_streq(token[0], "iface")) { + if (toknum < 4) { + if (!quiet) { + _LOGW("Can't parse iface line '%s'", join_values_with_spaces(value, token)); + } + continue; + } + add_block(parser, token[0], token[1]); + skip_to_block = 0; + add_data(parser, token[2], join_values_with_spaces(value, token + 3)); + } + /* auto and allow-auto stanzas are equivalent, + * both can take multiple interfaces as parameters: add one block for each */ + else if (NM_IN_STRSET(token[0], "auto", "allow-auto")) { + int i; + + for (i = 1; i < toknum; i++) + add_block(parser, "auto", token[i]); + skip_to_block = 0; + } else if (nm_streq(token[0], "mapping")) { + add_block(parser, token[0], join_values_with_spaces(value, token + 1)); + skip_to_block = 0; + } + /* allow-* can take multiple interfaces as parameters: add one block for each */ + else if (g_str_has_prefix(token[0], "allow-")) { + int i; + for (i = 1; i < toknum; i++) + add_block(parser, token[0], token[i]); + skip_to_block = 0; + } + /* source and source-directory stanzas take one or more paths as parameters */ + else if (NM_IN_STRSET(token[0], "source", "source-directory")) { + int i; + char *en_dir; + + skip_to_block = 0; + en_dir = g_path_get_dirname(eni_file); + for (i = 1; i < toknum; ++i) { + if (nm_streq(token[0], "source-directory")) + _ifparser_source(parser, token[i], en_dir, quiet, TRUE); + else + _ifparser_source(parser, token[i], en_dir, quiet, FALSE); + } + g_free(en_dir); + } else { + if (skip_to_block) { + if (!quiet) { + _LOGW("ignoring out-of-block data '%s'", join_values_with_spaces(value, token)); + } + } else + add_data(parser, token[0], join_values_with_spaces(value, token + 1)); + } + } + fclose(inp); + + if (!quiet) + _LOGI(" interface-parser: finished parsing file %s", eni_file); } static void -_ifparser_source (if_parser *parser, const char *path, const char *en_dir, int quiet, int dir) +_ifparser_source(if_parser *parser, const char *path, const char *en_dir, int quiet, int dir) { - char *abs_path; - const char *item; - wordexp_t we; - GDir *source_dir; - GError *error = NULL; - uint i; - - if (g_path_is_absolute (path)) - abs_path = g_strdup (path); - else - abs_path = g_build_filename (en_dir, path, NULL); - - if (!quiet) - _LOGI (" interface-parser: source line includes interfaces file(s) %s", abs_path); - - /* ifupdown uses WRDE_NOCMD for wordexp. */ - if (wordexp (abs_path, &we, WRDE_NOCMD)) { - if (!quiet) - _LOGW ("word expansion for %s failed", abs_path); - } else { - for (i = 0; i < we.we_wordc; i++) { - if (dir) { - source_dir = g_dir_open (we.we_wordv[i], 0, &error); - if (!source_dir) { - if (!quiet) { - _LOGW ("Failed to open directory %s: %s", - we.we_wordv[i], error->message); - } - g_clear_error (&error); - } else { - while ((item = g_dir_read_name (source_dir))) - _ifparser_source (parser, item, we.we_wordv[i], quiet, FALSE); - g_dir_close (source_dir); - } - } else - _recursive_ifparser (parser, we.we_wordv[i], quiet); - } - wordfree (&we); - } - g_free (abs_path); + char * abs_path; + const char *item; + wordexp_t we; + GDir * source_dir; + GError * error = NULL; + uint i; + + if (g_path_is_absolute(path)) + abs_path = g_strdup(path); + else + abs_path = g_build_filename(en_dir, path, NULL); + + if (!quiet) + _LOGI(" interface-parser: source line includes interfaces file(s) %s", abs_path); + + /* ifupdown uses WRDE_NOCMD for wordexp. */ + if (wordexp(abs_path, &we, WRDE_NOCMD)) { + if (!quiet) + _LOGW("word expansion for %s failed", abs_path); + } else { + for (i = 0; i < we.we_wordc; i++) { + if (dir) { + source_dir = g_dir_open(we.we_wordv[i], 0, &error); + if (!source_dir) { + if (!quiet) { + _LOGW("Failed to open directory %s: %s", we.we_wordv[i], error->message); + } + g_clear_error(&error); + } else { + while ((item = g_dir_read_name(source_dir))) + _ifparser_source(parser, item, we.we_wordv[i], quiet, FALSE); + g_dir_close(source_dir); + } + } else + _recursive_ifparser(parser, we.we_wordv[i], quiet); + } + wordfree(&we); + } + g_free(abs_path); } if_parser * -ifparser_parse (const char *eni_file, int quiet) +ifparser_parse(const char *eni_file, int quiet) { - if_parser *parser; + if_parser *parser; - parser = g_slice_new (if_parser); - c_list_init (&parser->block_lst_head); - _recursive_ifparser (parser, eni_file, quiet); - return parser; + parser = g_slice_new(if_parser); + c_list_init(&parser->block_lst_head); + _recursive_ifparser(parser, eni_file, quiet); + return parser; } static void -_destroy_data (if_data *ifd) +_destroy_data(if_data *ifd) { - c_list_unlink_stale (&ifd->data_lst); - g_free (ifd); + c_list_unlink_stale(&ifd->data_lst); + g_free(ifd); } static void -_destroy_block (if_block* ifb) +_destroy_block(if_block *ifb) { - if_data *ifd; + if_data *ifd; - while ((ifd = c_list_first_entry (&ifb->data_lst_head, if_data, data_lst))) - _destroy_data (ifd); - c_list_unlink_stale (&ifb->block_lst); - g_free (ifb); + while ((ifd = c_list_first_entry(&ifb->data_lst_head, if_data, data_lst))) + _destroy_data(ifd); + c_list_unlink_stale(&ifb->block_lst); + g_free(ifb); } void -ifparser_destroy (if_parser *parser) +ifparser_destroy(if_parser *parser) { - if_block *ifb; + if_block *ifb; - while ((ifb = c_list_first_entry (&parser->block_lst_head, if_block, block_lst))) - _destroy_block (ifb); - g_slice_free (if_parser, parser); + while ((ifb = c_list_first_entry(&parser->block_lst_head, if_block, block_lst))) + _destroy_block(ifb); + g_slice_free(if_parser, parser); } if_block * -ifparser_getfirst (if_parser *parser) +ifparser_getfirst(if_parser *parser) { - return c_list_first_entry (&parser->block_lst_head, if_block, block_lst); + return c_list_first_entry(&parser->block_lst_head, if_block, block_lst); } guint -ifparser_get_num_blocks (if_parser *parser) +ifparser_get_num_blocks(if_parser *parser) { - return c_list_length (&parser->block_lst_head); + return c_list_length(&parser->block_lst_head); } if_block * -ifparser_getif (if_parser *parser, const char* iface) +ifparser_getif(if_parser *parser, const char *iface) { - if_block *ifb; - - c_list_for_each_entry (ifb, &parser->block_lst_head, block_lst) { - if ( nm_streq (ifb->type, "iface") - && nm_streq (ifb->name, iface)) - return ifb; - } - return NULL; + if_block *ifb; + + c_list_for_each_entry (ifb, &parser->block_lst_head, block_lst) { + if (nm_streq(ifb->type, "iface") && nm_streq(ifb->name, iface)) + return ifb; + } + return NULL; } static if_data * -ifparser_findkey (if_block* iface, const char *key) +ifparser_findkey(if_block *iface, const char *key) { - if_data *ifd; + if_data *ifd; - c_list_for_each_entry (ifd, &iface->data_lst_head, data_lst) { - if (nm_streq (ifd->key, key)) - return ifd; - } - return NULL; + c_list_for_each_entry (ifd, &iface->data_lst_head, data_lst) { + if (nm_streq(ifd->key, key)) + return ifd; + } + return NULL; } const char * -ifparser_getkey (if_block* iface, const char *key) +ifparser_getkey(if_block *iface, const char *key) { - if_data *ifd; + if_data *ifd; - ifd = ifparser_findkey (iface, key); - return ifd ? ifd->data : NULL; + ifd = ifparser_findkey(iface, key); + return ifd ? ifd->data : NULL; } gboolean -ifparser_haskey (if_block* iface, const char *key) +ifparser_haskey(if_block *iface, const char *key) { - return !!ifparser_findkey (iface, key); + return !!ifparser_findkey(iface, key); } guint -ifparser_get_num_info (if_block* iface) +ifparser_get_num_info(if_block *iface) { - return c_list_length (&iface->data_lst_head); + return c_list_length(&iface->data_lst_head); } diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h index af02c7f6..d8256a5b 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h +++ b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Tom Parker * Copyright (C) 2004 Tom Parker @@ -10,34 +10,34 @@ #include "c-list/src/c-list.h" typedef struct { - CList data_lst; - const char *data; - const char key[]; + CList data_lst; + const char *data; + const char key[]; } if_data; typedef struct { - CList block_lst; - CList data_lst_head; - const char *type; - const char name[]; + CList block_lst; + CList data_lst_head; + const char *type; + const char name[]; } if_block; typedef struct { - CList block_lst_head; + CList block_lst_head; } if_parser; -if_parser *ifparser_parse (const char *eni_file, int quiet); +if_parser *ifparser_parse(const char *eni_file, int quiet); -void ifparser_destroy (if_parser *parser); -NM_AUTO_DEFINE_FCN0 (if_parser *, _nm_auto_ifparser, ifparser_destroy); +void ifparser_destroy(if_parser *parser); +NM_AUTO_DEFINE_FCN0(if_parser *, _nm_auto_ifparser, ifparser_destroy); #define nm_auto_ifparser nm_auto(_nm_auto_ifparser) -if_block *ifparser_getif (if_parser *parser, const char* iface); -if_block *ifparser_getfirst (if_parser *parser); -const char *ifparser_getkey (if_block* iface, const char *key); -gboolean ifparser_haskey (if_block* iface, const char *key); +if_block * ifparser_getif(if_parser *parser, const char *iface); +if_block * ifparser_getfirst(if_parser *parser); +const char *ifparser_getkey(if_block *iface, const char *key); +gboolean ifparser_haskey(if_block *iface, const char *key); -guint ifparser_get_num_blocks (if_parser *parser); -guint ifparser_get_num_info (if_block* iface); +guint ifparser_get_num_blocks(if_parser *parser); +guint ifparser_get_num_info(if_block *iface); #endif diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-parser.c b/src/settings/plugins/ifupdown/nms-ifupdown-parser.c index ac3ed1ce..0e01d6c5 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-parser.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-parser.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Alexander Sack * Copyright (C) 2008 Canonical Ltd. @@ -20,667 +20,667 @@ /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "ifupdown" -#define _NMLOG_DOMAIN LOGD_SETTINGS -#define _NMLOG(level, ...) \ - nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME": " \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)) +#define _NMLOG_PREFIX_NAME "ifupdown" +#define _NMLOG_DOMAIN LOGD_SETTINGS +#define _NMLOG(level, ...) \ + nm_log((level), \ + _NMLOG_DOMAIN, \ + NULL, \ + NULL, \ + "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME ": " _NM_UTILS_MACRO_REST(__VA_ARGS__)) /*****************************************************************************/ -#define _str_has_prefix(val, prefix, require_suffix) \ - ({ \ - const char *_val = (val); \ - \ - (strncmp (_val, ""prefix"", NM_STRLEN (prefix)) == 0) \ - && ( !(require_suffix) \ - || _val[NM_STRLEN (prefix)] != '\0'); \ - }) - -static const char* -_ifupdownplugin_guess_connection_type (if_block *block) +#define _str_has_prefix(val, prefix, require_suffix) \ + ({ \ + const char *_val = (val); \ + \ + (strncmp(_val, "" prefix "", NM_STRLEN(prefix)) == 0) \ + && (!(require_suffix) || _val[NM_STRLEN(prefix)] != '\0'); \ + }) + +static const char * +_ifupdownplugin_guess_connection_type(if_block *block) { - const char *ret_type = NULL; - - if (nm_streq0 (ifparser_getkey (block, "inet"), "ppp")) - ret_type = NM_SETTING_PPP_SETTING_NAME; - else { - if_data *ifb; - - c_list_for_each_entry (ifb, &block->data_lst_head, data_lst) { - if ( _str_has_prefix (ifb->key, "wireless-", FALSE) - || _str_has_prefix (ifb->key, "wpa-", FALSE)) { - ret_type = NM_SETTING_WIRELESS_SETTING_NAME; - break; - } - } - if (!ret_type) - ret_type = NM_SETTING_WIRED_SETTING_NAME; - } - - _LOGI ("guessed connection type (%s) = %s", block->name, ret_type); - return ret_type; + const char *ret_type = NULL; + + if (nm_streq0(ifparser_getkey(block, "inet"), "ppp")) + ret_type = NM_SETTING_PPP_SETTING_NAME; + else { + if_data *ifb; + + c_list_for_each_entry (ifb, &block->data_lst_head, data_lst) { + if (_str_has_prefix(ifb->key, "wireless-", FALSE) + || _str_has_prefix(ifb->key, "wpa-", FALSE)) { + ret_type = NM_SETTING_WIRELESS_SETTING_NAME; + break; + } + } + if (!ret_type) + ret_type = NM_SETTING_WIRED_SETTING_NAME; + } + + _LOGI("guessed connection type (%s) = %s", block->name, ret_type); + return ret_type; } struct _Mapping { - const char *domain; - const gpointer target; + const char * domain; + const gpointer target; }; static gpointer -map_by_mapping (struct _Mapping *mapping, const char *key) +map_by_mapping(struct _Mapping *mapping, const char *key) { - struct _Mapping *curr = mapping; - - while (curr->domain) { - if (nm_streq (curr->domain, key)) - return curr->target; - curr++; - } - return NULL; + struct _Mapping *curr = mapping; + + while (curr->domain) { + if (nm_streq(curr->domain, key)) + return curr->target; + curr++; + } + return NULL; } static void -update_wireless_setting_from_if_block (NMConnection *connection, - if_block *block) +update_wireless_setting_from_if_block(NMConnection *connection, if_block *block) { - if_data *curr; - const char *value = ifparser_getkey (block, "inet"); - struct _Mapping mapping[] = { - {"ssid", "ssid"}, - {"essid", "ssid"}, - {"mode", "mode"}, - { NULL, NULL} - }; - - NMSettingWireless *wireless_setting = NULL; - - if (nm_streq0 (value, "ppp")) - return; - - _LOGI ("update wireless settings (%s).", block->name); - wireless_setting = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - - c_list_for_each_entry (curr, &block->data_lst_head, data_lst) { - if (_str_has_prefix (curr->key, "wireless-", TRUE)) { - const char* newkey = map_by_mapping (mapping, curr->key + NM_STRLEN ("wireless-")); - - _LOGI ("wireless setting key: %s='%s'", newkey, curr->data); - if (nm_streq0 (newkey, "ssid")) { - GBytes *ssid; - int len = strlen (curr->data); - - ssid = g_bytes_new (curr->data, len); - g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, ssid, NULL); - g_bytes_unref (ssid); - _LOGI ("setting wireless ssid = %d", len); - } else if (nm_streq0 (newkey, "mode")) { - if (!g_ascii_strcasecmp (curr->data, "Managed") || !g_ascii_strcasecmp (curr->data, "Auto")) - g_object_set (wireless_setting, NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA, NULL); - else if (!g_ascii_strcasecmp (curr->data, "Ad-Hoc")) - g_object_set (wireless_setting, NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_ADHOC, NULL); - else if (!g_ascii_strcasecmp (curr->data, "Master")) - g_object_set (wireless_setting, NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_AP, NULL); - else - _LOGW ("Invalid mode '%s' (not 'Ad-Hoc', 'Ap', 'Managed', or 'Auto')", curr->data); - } else { - g_object_set (wireless_setting, - newkey, curr->data, - NULL); - } - } else if (_str_has_prefix (curr->key, "wpa-", TRUE)) { - const char* newkey = map_by_mapping (mapping, curr->key + NM_STRLEN ("wpa-")); - - if (nm_streq0 (newkey, "ssid")) { - GBytes *ssid; - int len = strlen (curr->data); - - ssid = g_bytes_new (curr->data, len); - g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, ssid, NULL); - g_bytes_unref (ssid); - _LOGI ("setting wpa ssid = %d", len); - } else if (newkey) { - - g_object_set (wireless_setting, - newkey, curr->data, - NULL); - _LOGI ("setting wpa newkey(%s)=data(%s)", newkey, curr->data); - } - } - } - nm_connection_add_setting (connection, (NMSetting*) wireless_setting); + if_data * curr; + const char * value = ifparser_getkey(block, "inet"); + struct _Mapping mapping[] = {{"ssid", "ssid"}, + {"essid", "ssid"}, + {"mode", "mode"}, + {NULL, NULL}}; + + NMSettingWireless *wireless_setting = NULL; + + if (nm_streq0(value, "ppp")) + return; + + _LOGI("update wireless settings (%s).", block->name); + wireless_setting = NM_SETTING_WIRELESS(nm_setting_wireless_new()); + + c_list_for_each_entry (curr, &block->data_lst_head, data_lst) { + if (_str_has_prefix(curr->key, "wireless-", TRUE)) { + const char *newkey = map_by_mapping(mapping, curr->key + NM_STRLEN("wireless-")); + + _LOGI("wireless setting key: %s='%s'", newkey, curr->data); + if (nm_streq0(newkey, "ssid")) { + GBytes *ssid; + int len = strlen(curr->data); + + ssid = g_bytes_new(curr->data, len); + g_object_set(wireless_setting, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_bytes_unref(ssid); + _LOGI("setting wireless ssid = %d", len); + } else if (nm_streq0(newkey, "mode")) { + if (!g_ascii_strcasecmp(curr->data, "Managed") + || !g_ascii_strcasecmp(curr->data, "Auto")) + g_object_set(wireless_setting, + NM_SETTING_WIRELESS_MODE, + NM_SETTING_WIRELESS_MODE_INFRA, + NULL); + else if (!g_ascii_strcasecmp(curr->data, "Ad-Hoc")) + g_object_set(wireless_setting, + NM_SETTING_WIRELESS_MODE, + NM_SETTING_WIRELESS_MODE_ADHOC, + NULL); + else if (!g_ascii_strcasecmp(curr->data, "Master")) + g_object_set(wireless_setting, + NM_SETTING_WIRELESS_MODE, + NM_SETTING_WIRELESS_MODE_AP, + NULL); + else + _LOGW("Invalid mode '%s' (not 'Ad-Hoc', 'Ap', 'Managed', or 'Auto')", + curr->data); + } else { + g_object_set(wireless_setting, newkey, curr->data, NULL); + } + } else if (_str_has_prefix(curr->key, "wpa-", TRUE)) { + const char *newkey = map_by_mapping(mapping, curr->key + NM_STRLEN("wpa-")); + + if (nm_streq0(newkey, "ssid")) { + GBytes *ssid; + int len = strlen(curr->data); + + ssid = g_bytes_new(curr->data, len); + g_object_set(wireless_setting, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_bytes_unref(ssid); + _LOGI("setting wpa ssid = %d", len); + } else if (newkey) { + g_object_set(wireless_setting, newkey, curr->data, NULL); + _LOGI("setting wpa newkey(%s)=data(%s)", newkey, curr->data); + } + } + } + nm_connection_add_setting(connection, (NMSetting *) wireless_setting); } -typedef char* (*IfupdownStrDupeFunc) (gconstpointer value, gpointer data); -typedef gpointer (*IfupdownStrToTypeFunc) (const char* value); - -static char* -normalize_dupe_wireless_key (gpointer value, gpointer data) { - char* valuec = value; - char* endc = valuec + strlen (valuec); - char* delim = valuec; - char* next = delim; - char* result = malloc (strlen (valuec) + 1); - char* result_cur = result; - - while (*delim && (next = strchr (delim, '-')) != NULL) { - if (next == delim) { - delim++; - continue; - } - strncpy (result_cur, delim, next - delim); - result_cur += next - delim; - delim = next + 1; - } - if (*delim && strlen (valuec) > GPOINTER_TO_UINT (delim - valuec)) { - strncpy (result_cur, delim, endc - delim); - result_cur += endc - delim; - } - *result_cur = '\0'; - return result; +typedef char *(*IfupdownStrDupeFunc)(gconstpointer value, gpointer data); +typedef gpointer (*IfupdownStrToTypeFunc)(const char *value); + +static char * +normalize_dupe_wireless_key(gpointer value, gpointer data) +{ + char *valuec = value; + char *endc = valuec + strlen(valuec); + char *delim = valuec; + char *next = delim; + char *result = malloc(strlen(valuec) + 1); + char *result_cur = result; + + while (*delim && (next = strchr(delim, '-')) != NULL) { + if (next == delim) { + delim++; + continue; + } + strncpy(result_cur, delim, next - delim); + result_cur += next - delim; + delim = next + 1; + } + if (*delim && strlen(valuec) > GPOINTER_TO_UINT(delim - valuec)) { + strncpy(result_cur, delim, endc - delim); + result_cur += endc - delim; + } + *result_cur = '\0'; + return result; } -static char* -normalize_dupe (gpointer value, gpointer data) { - return g_strdup (value); +static char * +normalize_dupe(gpointer value, gpointer data) +{ + return g_strdup(value); } -static char* -normalize_tolower (gpointer value, gpointer data) { - return g_ascii_strdown (value, -1); +static char * +normalize_tolower(gpointer value, gpointer data) +{ + return g_ascii_strdown(value, -1); } -static char *normalize_psk (gpointer value, gpointer data) +static char * +normalize_psk(gpointer value, gpointer data) { - if (strlen (value) >= 8 && strlen (value) <= 64) - return g_strdup (value); - return NULL; + if (strlen(value) >= 8 && strlen(value) <= 64) + return g_strdup(value); + return NULL; } static gpointer -string_to_gpointerint (const char* data) +string_to_gpointerint(const char *data) { - int result = (int) strtol (data, NULL, 10); - return GINT_TO_POINTER (result); + int result = (int) strtol(data, NULL, 10); + return GINT_TO_POINTER(result); } static gpointer -string_to_glist_of_strings (const char* data) +string_to_glist_of_strings(const char *data) { - GSList *ret = NULL; - char *string = (char*) data; - while (string) { - char* next = NULL; - if ( (next = strchr (string, ' ')) || - (next = strchr (string, '\t')) || - (next = strchr (string, '\0')) ) { - - char *part = g_strndup (string, (next - string)); - ret = g_slist_append (ret, part); - if (*next) - string = next+1; - else - string = NULL; - } else { - string = NULL; - } - } - return ret; + GSList *ret = NULL; + char * string = (char *) data; + while (string) { + char *next = NULL; + if ((next = strchr(string, ' ')) || (next = strchr(string, '\t')) + || (next = strchr(string, '\0'))) { + char *part = g_strndup(string, (next - string)); + ret = g_slist_append(ret, part); + if (*next) + string = next + 1; + else + string = NULL; + } else { + string = NULL; + } + } + return ret; } static void -slist_free_all (gpointer slist) +slist_free_all(gpointer slist) { - g_slist_free_full ((GSList *) slist, g_free); + g_slist_free_full((GSList *) slist, g_free); } static void -update_wireless_security_setting_from_if_block (NMConnection *connection, - if_block *block) +update_wireless_security_setting_from_if_block(NMConnection *connection, if_block *block) { - if_data *curr; - const char* value = ifparser_getkey (block, "inet"); - struct _Mapping mapping[] = { - {"psk", "psk"}, - {"identity", "leap-username"}, - {"password", "leap-password"}, - {"key", "wep-key0"}, - {"key-mgmt", "key-mgmt"}, - {"group", "group"}, - {"pairwise", "pairwise"}, - {"proto", "proto"}, - {"pin", "pin"}, - {"wep-key0", "wep-key0"}, - {"wep-key1", "wep-key1"}, - {"wep-key2", "wep-key2"}, - {"wep-key3", "wep-key3"}, - {"wep-tx-keyidx", "wep-tx-keyidx"}, - { NULL, NULL} - }; - - struct _Mapping dupe_mapping[] = { - {"psk", normalize_psk}, - {"identity", normalize_dupe}, - {"password", normalize_dupe}, - {"key", normalize_dupe_wireless_key}, - {"key-mgmt", normalize_tolower}, - {"group", normalize_tolower}, - {"pairwise", normalize_tolower}, - {"proto", normalize_tolower}, - {"pin", normalize_dupe}, - {"wep-key0", normalize_dupe_wireless_key}, - {"wep-key1", normalize_dupe_wireless_key}, - {"wep-key2", normalize_dupe_wireless_key}, - {"wep-key3", normalize_dupe_wireless_key}, - {"wep-tx-keyidx", normalize_dupe}, - { NULL, NULL} - }; - - struct _Mapping type_mapping[] = { - {"group", string_to_glist_of_strings}, - {"pairwise", string_to_glist_of_strings}, - {"proto", string_to_glist_of_strings}, - {"wep-tx-keyidx", string_to_gpointerint}, - { NULL, NULL} - }; - - struct _Mapping free_type_mapping[] = { - {"group", slist_free_all}, - {"pairwise", slist_free_all}, - {"proto", slist_free_all}, - { NULL, NULL} - }; - - NMSettingWirelessSecurity *wireless_security_setting; - NMSettingWireless *s_wireless; - gboolean security = FALSE; - - if (nm_streq0 (value, "ppp")) - return; - - s_wireless = nm_connection_get_setting_wireless (connection); - g_return_if_fail (s_wireless); - - _LOGI ("update wireless security settings (%s).", block->name); - wireless_security_setting = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); - - c_list_for_each_entry (curr, &block->data_lst_head, data_lst) { - if (_str_has_prefix (curr->key, "wireless-", TRUE)) { - const char *key = curr->key + NM_STRLEN ("wireless-"); - char *property_value = NULL; - gpointer typed_property_value = NULL; - const char* newkey = map_by_mapping (mapping, key); - IfupdownStrDupeFunc dupe_func = map_by_mapping (dupe_mapping, key); - IfupdownStrToTypeFunc type_map_func = map_by_mapping (type_mapping, key); - GFreeFunc free_func = map_by_mapping (free_type_mapping, key); - if (!newkey || !dupe_func) - goto next; - - property_value = (*dupe_func) (curr->data, connection); - _LOGI ("setting wireless security key: %s=%s", - newkey, property_value); - - if (type_map_func) { - errno = 0; - typed_property_value = (*type_map_func) (property_value); - if (errno) - goto wireless_next; - } - - g_object_set (wireless_security_setting, - newkey, typed_property_value ?: property_value, - NULL); - security = TRUE; + if_data * curr; + const char * value = ifparser_getkey(block, "inet"); + struct _Mapping mapping[] = {{"psk", "psk"}, + {"identity", "leap-username"}, + {"password", "leap-password"}, + {"key", "wep-key0"}, + {"key-mgmt", "key-mgmt"}, + {"group", "group"}, + {"pairwise", "pairwise"}, + {"proto", "proto"}, + {"pin", "pin"}, + {"wep-key0", "wep-key0"}, + {"wep-key1", "wep-key1"}, + {"wep-key2", "wep-key2"}, + {"wep-key3", "wep-key3"}, + {"wep-tx-keyidx", "wep-tx-keyidx"}, + {NULL, NULL}}; + + struct _Mapping dupe_mapping[] = {{"psk", normalize_psk}, + {"identity", normalize_dupe}, + {"password", normalize_dupe}, + {"key", normalize_dupe_wireless_key}, + {"key-mgmt", normalize_tolower}, + {"group", normalize_tolower}, + {"pairwise", normalize_tolower}, + {"proto", normalize_tolower}, + {"pin", normalize_dupe}, + {"wep-key0", normalize_dupe_wireless_key}, + {"wep-key1", normalize_dupe_wireless_key}, + {"wep-key2", normalize_dupe_wireless_key}, + {"wep-key3", normalize_dupe_wireless_key}, + {"wep-tx-keyidx", normalize_dupe}, + {NULL, NULL}}; + + struct _Mapping type_mapping[] = {{"group", string_to_glist_of_strings}, + {"pairwise", string_to_glist_of_strings}, + {"proto", string_to_glist_of_strings}, + {"wep-tx-keyidx", string_to_gpointerint}, + {NULL, NULL}}; + + struct _Mapping free_type_mapping[] = {{"group", slist_free_all}, + {"pairwise", slist_free_all}, + {"proto", slist_free_all}, + {NULL, NULL}}; + + NMSettingWirelessSecurity *wireless_security_setting; + NMSettingWireless * s_wireless; + gboolean security = FALSE; + + if (nm_streq0(value, "ppp")) + return; + + s_wireless = nm_connection_get_setting_wireless(connection); + g_return_if_fail(s_wireless); + + _LOGI("update wireless security settings (%s).", block->name); + wireless_security_setting = NM_SETTING_WIRELESS_SECURITY(nm_setting_wireless_security_new()); + + c_list_for_each_entry (curr, &block->data_lst_head, data_lst) { + if (_str_has_prefix(curr->key, "wireless-", TRUE)) { + const char * key = curr->key + NM_STRLEN("wireless-"); + char * property_value = NULL; + gpointer typed_property_value = NULL; + const char * newkey = map_by_mapping(mapping, key); + IfupdownStrDupeFunc dupe_func = map_by_mapping(dupe_mapping, key); + IfupdownStrToTypeFunc type_map_func = map_by_mapping(type_mapping, key); + GFreeFunc free_func = map_by_mapping(free_type_mapping, key); + if (!newkey || !dupe_func) + goto next; + + property_value = (*dupe_func)(curr->data, connection); + _LOGI("setting wireless security key: %s=%s", newkey, property_value); + + if (type_map_func) { + errno = 0; + typed_property_value = (*type_map_func)(property_value); + if (errno) + goto wireless_next; + } + + g_object_set(wireless_security_setting, + newkey, + typed_property_value ?: property_value, + NULL); + security = TRUE; wireless_next: - g_free (property_value); - if (typed_property_value && free_func) - (*free_func) (typed_property_value); - - } else if (_str_has_prefix (curr->key, "wpa-", TRUE)) { - const char *key = curr->key + NM_STRLEN ("wpa-"); - char *property_value = NULL; - gpointer typed_property_value = NULL; - const char* newkey = map_by_mapping (mapping, key); - IfupdownStrDupeFunc dupe_func = map_by_mapping (dupe_mapping, key); - IfupdownStrToTypeFunc type_map_func = map_by_mapping (type_mapping, key); - GFreeFunc free_func = map_by_mapping (free_type_mapping, key); - if (!newkey || !dupe_func) - goto next; - - property_value = (*dupe_func) (curr->data, connection); - _LOGI ("setting wpa security key: %s=%s", - newkey, - NM_IN_STRSET (newkey, "key", - "leap-password", - "pin", - "psk", - "wep-key0", - "wep-key1", - "wep-key2", - "wep-key3") - ? "" - : property_value - ); - - if (type_map_func) { - errno = 0; - typed_property_value = (*type_map_func) (property_value); - if (errno) - goto wpa_next; - } - - g_object_set (wireless_security_setting, - newkey, typed_property_value ?: property_value, - NULL); - security = TRUE; + g_free(property_value); + if (typed_property_value && free_func) + (*free_func)(typed_property_value); + + } else if (_str_has_prefix(curr->key, "wpa-", TRUE)) { + const char * key = curr->key + NM_STRLEN("wpa-"); + char * property_value = NULL; + gpointer typed_property_value = NULL; + const char * newkey = map_by_mapping(mapping, key); + IfupdownStrDupeFunc dupe_func = map_by_mapping(dupe_mapping, key); + IfupdownStrToTypeFunc type_map_func = map_by_mapping(type_mapping, key); + GFreeFunc free_func = map_by_mapping(free_type_mapping, key); + if (!newkey || !dupe_func) + goto next; + + property_value = (*dupe_func)(curr->data, connection); + _LOGI("setting wpa security key: %s=%s", + newkey, + NM_IN_STRSET(newkey, + "key", + "leap-password", + "pin", + "psk", + "wep-key0", + "wep-key1", + "wep-key2", + "wep-key3") + ? "" + : property_value); + + if (type_map_func) { + errno = 0; + typed_property_value = (*type_map_func)(property_value); + if (errno) + goto wpa_next; + } + + g_object_set(wireless_security_setting, + newkey, + typed_property_value ?: property_value, + NULL); + security = TRUE; wpa_next: - g_free (property_value); - if (free_func && typed_property_value) - (*free_func) (typed_property_value); - } -next: - ; - } - - if (security) - nm_connection_add_setting (connection, NM_SETTING (wireless_security_setting)); + g_free(property_value); + if (free_func && typed_property_value) + (*free_func)(typed_property_value); + } +next:; + } + + if (security) + nm_connection_add_setting(connection, NM_SETTING(wireless_security_setting)); } static void -update_wired_setting_from_if_block (NMConnection *connection, - if_block *block) +update_wired_setting_from_if_block(NMConnection *connection, if_block *block) { - NMSettingWired *s_wired = NULL; - s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + NMSettingWired *s_wired = NULL; + s_wired = NM_SETTING_WIRED(nm_setting_wired_new()); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); } static void -ifupdown_ip4_add_dns (NMSettingIPConfig *s_ip4, const char *dns) +ifupdown_ip4_add_dns(NMSettingIPConfig *s_ip4, const char *dns) { - gs_free const char **list = NULL; - const char **iter; - guint32 addr; - - if (dns == NULL) - return; - - list = nm_utils_strsplit_set (dns, " \t"); - for (iter = list; iter && *iter; iter++) { - if (!inet_pton (AF_INET, *iter, &addr)) { - _LOGW (" ignoring invalid nameserver '%s'", *iter); - continue; - } - - if (!nm_setting_ip_config_add_dns (s_ip4, *iter)) - _LOGW (" duplicate DNS domain '%s'", *iter); - } + gs_free const char **list = NULL; + const char ** iter; + guint32 addr; + + if (dns == NULL) + return; + + list = nm_utils_strsplit_set(dns, " \t"); + for (iter = list; iter && *iter; iter++) { + if (!inet_pton(AF_INET, *iter, &addr)) { + _LOGW(" ignoring invalid nameserver '%s'", *iter); + continue; + } + + if (!nm_setting_ip_config_add_dns(s_ip4, *iter)) + _LOGW(" duplicate DNS domain '%s'", *iter); + } } static gboolean -update_ip4_setting_from_if_block (NMConnection *connection, - if_block *block, - GError **error) +update_ip4_setting_from_if_block(NMConnection *connection, if_block *block, GError **error) { - - gs_unref_object NMSettingIPConfig *s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); - const char *type = ifparser_getkey (block, "inet"); - - if (!nm_streq0 (type, "static")) { - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, - NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); - } else { - guint32 tmp_mask; - NMIPAddress *addr; - const char *address_v; - const char *netmask_v; - const char *gateway_v; - const char *nameserver_v; - const char *nameservers_v; - const char *search_v; - guint32 netmask_int = 32; - - /* Address */ - address_v = ifparser_getkey (block, "address"); - if (!address_v) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing IPv4 address"); - return FALSE; - } - - /* mask/prefix */ - netmask_v = ifparser_getkey (block, "netmask"); - if (netmask_v) { - if (strlen (netmask_v) < 7) { - netmask_int = atoi (netmask_v); - } else if (!inet_pton (AF_INET, netmask_v, &tmp_mask)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid IPv4 netmask '%s'", netmask_v); - return FALSE; - } else { - netmask_int = nm_utils_ip4_netmask_to_prefix (tmp_mask); - } - } - - /* Add the new address to the setting */ - addr = nm_ip_address_new (AF_INET, address_v, netmask_int, error); - if (!addr) - return FALSE; - - if (nm_setting_ip_config_add_address (s_ip4, addr)) { - _LOGI ("addresses count: %d", - nm_setting_ip_config_get_num_addresses (s_ip4)); - } else { - _LOGI ("ignoring duplicate IP4 address"); - } - nm_ip_address_unref (addr); - - /* gateway */ - gateway_v = ifparser_getkey (block, "gateway"); - if (gateway_v) { - if (!nm_utils_ipaddr_is_valid (AF_INET, gateway_v)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid IPv4 gateway '%s'", gateway_v); - return FALSE; - } - if (!nm_setting_ip_config_get_gateway (s_ip4)) - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL); - } - - nameserver_v = ifparser_getkey (block, "dns-nameserver"); - ifupdown_ip4_add_dns (s_ip4, nameserver_v); - - nameservers_v = ifparser_getkey (block, "dns-nameservers"); - ifupdown_ip4_add_dns (s_ip4, nameservers_v); - - if (!nm_setting_ip_config_get_num_dns (s_ip4)) - _LOGI ("No dns-nameserver configured in /etc/network/interfaces"); - - /* DNS searches */ - search_v = ifparser_getkey (block, "dns-search"); - if (search_v) { - gs_free const char **list = NULL; - const char **iter; - - list = nm_utils_strsplit_set (search_v, " \t"); - for (iter = list; iter && *iter; iter++) { - if (!nm_setting_ip_config_add_dns_search (s_ip4, *iter)) - _LOGW (" duplicate DNS domain '%s'", *iter); - } - } - - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); - } - - nm_connection_add_setting (connection, NM_SETTING (g_steal_pointer (&s_ip4))); - return TRUE; + gs_unref_object NMSettingIPConfig *s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new()); + const char * type = ifparser_getkey(block, "inet"); + + if (!nm_streq0(type, "static")) { + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + } else { + guint32 tmp_mask; + NMIPAddress *addr; + const char * address_v; + const char * netmask_v; + const char * gateway_v; + const char * nameserver_v; + const char * nameservers_v; + const char * search_v; + guint32 netmask_int = 32; + + /* Address */ + address_v = ifparser_getkey(block, "address"); + if (!address_v) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IPv4 address"); + return FALSE; + } + + /* mask/prefix */ + netmask_v = ifparser_getkey(block, "netmask"); + if (netmask_v) { + if (strlen(netmask_v) < 7) { + netmask_int = atoi(netmask_v); + } else if (!inet_pton(AF_INET, netmask_v, &tmp_mask)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IPv4 netmask '%s'", + netmask_v); + return FALSE; + } else { + netmask_int = nm_utils_ip4_netmask_to_prefix(tmp_mask); + } + } + + /* Add the new address to the setting */ + addr = nm_ip_address_new(AF_INET, address_v, netmask_int, error); + if (!addr) + return FALSE; + + if (nm_setting_ip_config_add_address(s_ip4, addr)) { + _LOGI("addresses count: %d", nm_setting_ip_config_get_num_addresses(s_ip4)); + } else { + _LOGI("ignoring duplicate IP4 address"); + } + nm_ip_address_unref(addr); + + /* gateway */ + gateway_v = ifparser_getkey(block, "gateway"); + if (gateway_v) { + if (!nm_utils_ipaddr_is_valid(AF_INET, gateway_v)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IPv4 gateway '%s'", + gateway_v); + return FALSE; + } + if (!nm_setting_ip_config_get_gateway(s_ip4)) + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL); + } + + nameserver_v = ifparser_getkey(block, "dns-nameserver"); + ifupdown_ip4_add_dns(s_ip4, nameserver_v); + + nameservers_v = ifparser_getkey(block, "dns-nameservers"); + ifupdown_ip4_add_dns(s_ip4, nameservers_v); + + if (!nm_setting_ip_config_get_num_dns(s_ip4)) + _LOGI("No dns-nameserver configured in /etc/network/interfaces"); + + /* DNS searches */ + search_v = ifparser_getkey(block, "dns-search"); + if (search_v) { + gs_free const char **list = NULL; + const char ** iter; + + list = nm_utils_strsplit_set(search_v, " \t"); + for (iter = list; iter && *iter; iter++) { + if (!nm_setting_ip_config_add_dns_search(s_ip4, *iter)) + _LOGW(" duplicate DNS domain '%s'", *iter); + } + } + + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + } + + nm_connection_add_setting(connection, NM_SETTING(g_steal_pointer(&s_ip4))); + return TRUE; } static void -ifupdown_ip6_add_dns (NMSettingIPConfig *s_ip6, const char *dns) +ifupdown_ip6_add_dns(NMSettingIPConfig *s_ip6, const char *dns) { - gs_free const char **list = NULL; - const char **iter; - struct in6_addr addr; - - if (dns == NULL) - return; - - list = nm_utils_strsplit_set (dns, " \t"); - for (iter = list; iter && *iter; iter++) { - if (!inet_pton (AF_INET6, *iter, &addr)) { - _LOGW (" ignoring invalid nameserver '%s'", *iter); - continue; - } - - if (!nm_setting_ip_config_add_dns (s_ip6, *iter)) - _LOGW (" duplicate DNS domain '%s'", *iter); - } + gs_free const char **list = NULL; + const char ** iter; + struct in6_addr addr; + + if (dns == NULL) + return; + + list = nm_utils_strsplit_set(dns, " \t"); + for (iter = list; iter && *iter; iter++) { + if (!inet_pton(AF_INET6, *iter, &addr)) { + _LOGW(" ignoring invalid nameserver '%s'", *iter); + continue; + } + + if (!nm_setting_ip_config_add_dns(s_ip6, *iter)) + _LOGW(" duplicate DNS domain '%s'", *iter); + } } static gboolean -update_ip6_setting_from_if_block (NMConnection *connection, - if_block *block, - GError **error) +update_ip6_setting_from_if_block(NMConnection *connection, if_block *block, GError **error) { - gs_unref_object NMSettingIPConfig *s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); - const char *type = ifparser_getkey (block, "inet6"); - - if (!NM_IN_STRSET (type, "static", "v4tunnel")) { - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, - NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NULL); - } else { - NMIPAddress *addr; - const char *address_v; - const char *prefix_v; - const char *gateway_v; - const char *nameserver_v; - const char *nameservers_v; - const char *search_v; - guint prefix_int; - - address_v = ifparser_getkey (block, "address"); - if (!address_v) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing IPv6 address"); - return FALSE; - } - - prefix_v = ifparser_getkey (block, "netmask"); - if (prefix_v) - prefix_int = _nm_utils_ascii_str_to_int64 (prefix_v, 10, 0, 128, G_MAXINT); - else - prefix_int = 128; - - addr = nm_ip_address_new (AF_INET6, address_v, prefix_int, error); - if (!addr) - return FALSE; - - if (nm_setting_ip_config_add_address (s_ip6, addr)) { - _LOGI ("addresses count: %d", - nm_setting_ip_config_get_num_addresses (s_ip6)); - } else { - _LOGI ("ignoring duplicate IP6 address"); - } - nm_ip_address_unref (addr); - - gateway_v = ifparser_getkey (block, "gateway"); - if (gateway_v) { - if (!nm_utils_ipaddr_is_valid (AF_INET6, gateway_v)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid IPv6 gateway '%s'", gateway_v); - return FALSE; - } - if (!nm_setting_ip_config_get_gateway (s_ip6)) - g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL); - } - - nameserver_v = ifparser_getkey (block, "dns-nameserver"); - ifupdown_ip6_add_dns (s_ip6, nameserver_v); - - nameservers_v = ifparser_getkey (block, "dns-nameservers"); - ifupdown_ip6_add_dns (s_ip6, nameservers_v); - - if (!nm_setting_ip_config_get_num_dns (s_ip6)) - _LOGI ("No dns-nameserver configured in /etc/network/interfaces"); - - search_v = ifparser_getkey (block, "dns-search"); - if (search_v) { - gs_free const char **list = NULL; - const char **iter; - - list = nm_utils_strsplit_set (search_v, " \t"); - for (iter = list; iter && *iter; iter++) { - if (!nm_setting_ip_config_add_dns_search (s_ip6, *iter)) - _LOGW (" duplicate DNS domain '%s'", *iter); - } - } - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NULL); - } - - nm_connection_add_setting (connection, NM_SETTING (g_steal_pointer (&s_ip6))); - return TRUE; + gs_unref_object NMSettingIPConfig *s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new()); + const char * type = ifparser_getkey(block, "inet6"); + + if (!NM_IN_STRSET(type, "static", "v4tunnel")) { + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + } else { + NMIPAddress *addr; + const char * address_v; + const char * prefix_v; + const char * gateway_v; + const char * nameserver_v; + const char * nameservers_v; + const char * search_v; + guint prefix_int; + + address_v = ifparser_getkey(block, "address"); + if (!address_v) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IPv6 address"); + return FALSE; + } + + prefix_v = ifparser_getkey(block, "netmask"); + if (prefix_v) + prefix_int = _nm_utils_ascii_str_to_int64(prefix_v, 10, 0, 128, G_MAXINT); + else + prefix_int = 128; + + addr = nm_ip_address_new(AF_INET6, address_v, prefix_int, error); + if (!addr) + return FALSE; + + if (nm_setting_ip_config_add_address(s_ip6, addr)) { + _LOGI("addresses count: %d", nm_setting_ip_config_get_num_addresses(s_ip6)); + } else { + _LOGI("ignoring duplicate IP6 address"); + } + nm_ip_address_unref(addr); + + gateway_v = ifparser_getkey(block, "gateway"); + if (gateway_v) { + if (!nm_utils_ipaddr_is_valid(AF_INET6, gateway_v)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IPv6 gateway '%s'", + gateway_v); + return FALSE; + } + if (!nm_setting_ip_config_get_gateway(s_ip6)) + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL); + } + + nameserver_v = ifparser_getkey(block, "dns-nameserver"); + ifupdown_ip6_add_dns(s_ip6, nameserver_v); + + nameservers_v = ifparser_getkey(block, "dns-nameservers"); + ifupdown_ip6_add_dns(s_ip6, nameservers_v); + + if (!nm_setting_ip_config_get_num_dns(s_ip6)) + _LOGI("No dns-nameserver configured in /etc/network/interfaces"); + + search_v = ifparser_getkey(block, "dns-search"); + if (search_v) { + gs_free const char **list = NULL; + const char ** iter; + + list = nm_utils_strsplit_set(search_v, " \t"); + for (iter = list; iter && *iter; iter++) { + if (!nm_setting_ip_config_add_dns_search(s_ip6, *iter)) + _LOGW(" duplicate DNS domain '%s'", *iter); + } + } + + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NULL); + } + + nm_connection_add_setting(connection, NM_SETTING(g_steal_pointer(&s_ip6))); + return TRUE; } NMConnection * -ifupdown_new_connection_from_if_block (if_block *block, - gboolean autoconnect, - GError **error) +ifupdown_new_connection_from_if_block(if_block *block, gboolean autoconnect, GError **error) { - gs_unref_object NMConnection *connection = NULL; - const char *type; - gs_free char *idstr = NULL; - gs_free char *uuid = NULL; - NMSettingConnection *s_con; - - connection = nm_simple_connection_new (); - - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - type = _ifupdownplugin_guess_connection_type (block); - idstr = g_strconcat ("Ifupdown (", block->name, ")", NULL); - - uuid = nm_utils_uuid_generate_from_string (idstr, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); - g_object_set (s_con, - NM_SETTING_CONNECTION_TYPE, type, - NM_SETTING_CONNECTION_INTERFACE_NAME, block->name, - NM_SETTING_CONNECTION_ID, idstr, - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_AUTOCONNECT, (gboolean) (!!autoconnect), - NULL); - - _LOGD ("update_connection_setting_from_if_block: name:%s, type:%s, id:%s, uuid: %s", - block->name, type, idstr, nm_setting_connection_get_uuid (s_con)); - - if (nm_streq (type, NM_SETTING_WIRED_SETTING_NAME)) - update_wired_setting_from_if_block (connection, block); - else if (nm_streq (type, NM_SETTING_WIRELESS_SETTING_NAME)) { - update_wireless_setting_from_if_block (connection, block); - update_wireless_security_setting_from_if_block (connection, block); - } - - if (ifparser_haskey (block, "inet6")) { - if (!update_ip6_setting_from_if_block (connection, block, error)) - return FALSE; - } else { - if (!update_ip4_setting_from_if_block (connection, block, error)) - return FALSE; - } - - if (!nm_connection_normalize (connection, NULL, NULL, error)) - return NULL; - - return g_steal_pointer (&connection); + gs_unref_object NMConnection *connection = NULL; + const char * type; + gs_free char * idstr = NULL; + gs_free char * uuid = NULL; + NMSettingConnection * s_con; + + connection = nm_simple_connection_new(); + + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + type = _ifupdownplugin_guess_connection_type(block); + idstr = g_strconcat("Ifupdown (", block->name, ")", NULL); + + uuid = nm_utils_uuid_generate_from_string(idstr, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_TYPE, + type, + NM_SETTING_CONNECTION_INTERFACE_NAME, + block->name, + NM_SETTING_CONNECTION_ID, + idstr, + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, + (gboolean)(!!autoconnect), + NULL); + + _LOGD("update_connection_setting_from_if_block: name:%s, type:%s, id:%s, uuid: %s", + block->name, + type, + idstr, + nm_setting_connection_get_uuid(s_con)); + + if (nm_streq(type, NM_SETTING_WIRED_SETTING_NAME)) + update_wired_setting_from_if_block(connection, block); + else if (nm_streq(type, NM_SETTING_WIRELESS_SETTING_NAME)) { + update_wireless_setting_from_if_block(connection, block); + update_wireless_security_setting_from_if_block(connection, block); + } + + if (ifparser_haskey(block, "inet6")) { + if (!update_ip6_setting_from_if_block(connection, block, error)) + return FALSE; + } else { + if (!update_ip4_setting_from_if_block(connection, block, error)) + return FALSE; + } + + if (!nm_connection_normalize(connection, NULL, NULL, error)) + return NULL; + + return g_steal_pointer(&connection); } diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-parser.h b/src/settings/plugins/ifupdown/nms-ifupdown-parser.h index b8761fc3..c5fc2874 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-parser.h +++ b/src/settings/plugins/ifupdown/nms-ifupdown-parser.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Alexander Sack * Copyright (C) 2008 Canonical Ltd. @@ -10,8 +10,7 @@ #include "nm-connection.h" #include "nms-ifupdown-interface-parser.h" -NMConnection *ifupdown_new_connection_from_if_block (if_block *block, - gboolean autoconnect, - GError **error); +NMConnection * +ifupdown_new_connection_from_if_block(if_block *block, gboolean autoconnect, GError **error); #endif /* __NMS_IFUPDOWN_PARSER_H__ */ diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c index 808df49f..b6ba423c 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Alexander Sack * Copyright (C) 2007, 2008 Canonical Ltd. @@ -25,379 +25,375 @@ /*****************************************************************************/ typedef struct { - NMConnection *connection; - NMSettingsStorage *storage; + NMConnection * connection; + NMSettingsStorage *storage; } StorageData; typedef struct { - /* Stores an entry for blocks/interfaces read from /e/n/i and (if exists) - * the StorageData associated with the block. - */ - GHashTable *eni_ifaces; + /* Stores an entry for blocks/interfaces read from /e/n/i and (if exists) + * the StorageData associated with the block. + */ + GHashTable *eni_ifaces; - bool ifupdown_managed:1; + bool ifupdown_managed : 1; - bool initialized:1; + bool initialized : 1; - bool already_reloaded:1; + bool already_reloaded : 1; } NMSIfupdownPluginPrivate; struct _NMSIfupdownPlugin { - NMSettingsPlugin parent; - NMSIfupdownPluginPrivate _priv; + NMSettingsPlugin parent; + NMSIfupdownPluginPrivate _priv; }; struct _NMSIfupdownPluginClass { - NMSettingsPluginClass parent; + NMSettingsPluginClass parent; }; -G_DEFINE_TYPE (NMSIfupdownPlugin, nms_ifupdown_plugin, NM_TYPE_SETTINGS_PLUGIN) +G_DEFINE_TYPE(NMSIfupdownPlugin, nms_ifupdown_plugin, NM_TYPE_SETTINGS_PLUGIN) -#define NMS_IFUPDOWN_PLUGIN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSIfupdownPlugin, NMS_IS_IFUPDOWN_PLUGIN) +#define NMS_IFUPDOWN_PLUGIN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSIfupdownPlugin, NMS_IS_IFUPDOWN_PLUGIN) /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "ifupdown" -#define _NMLOG_DOMAIN LOGD_SETTINGS -#define _NMLOG(level, ...) \ - nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME": " \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)) +#define _NMLOG_PREFIX_NAME "ifupdown" +#define _NMLOG_DOMAIN LOGD_SETTINGS +#define _NMLOG(level, ...) \ + nm_log((level), \ + _NMLOG_DOMAIN, \ + NULL, \ + NULL, \ + "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME ": " _NM_UTILS_MACRO_REST(__VA_ARGS__)) /*****************************************************************************/ -static GHashTable *load_eni_ifaces (NMSIfupdownPlugin *self); +static GHashTable *load_eni_ifaces(NMSIfupdownPlugin *self); /*****************************************************************************/ static void -_storage_data_destroy (StorageData *sd) +_storage_data_destroy(StorageData *sd) { - if (!sd) - return; - nm_g_object_unref (sd->connection); - nm_g_object_unref (sd->storage); - g_slice_free (StorageData, sd); + if (!sd) + return; + nm_g_object_unref(sd->connection); + nm_g_object_unref(sd->storage); + g_slice_free(StorageData, sd); } /*****************************************************************************/ static void -initialize (NMSIfupdownPlugin *self) +initialize(NMSIfupdownPlugin *self) { - NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE (self); - gboolean ifupdown_managed; + NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE(self); + gboolean ifupdown_managed; - nm_assert (!priv->initialized); + nm_assert(!priv->initialized); - priv->initialized = TRUE; + priv->initialized = TRUE; - ifupdown_managed = nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG, - NM_CONFIG_KEYFILE_GROUP_IFUPDOWN, - NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED, - !IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT); - _LOGI ("management mode: %s", ifupdown_managed ? "managed" : "unmanaged"); - priv->ifupdown_managed = ifupdown_managed; + ifupdown_managed = nm_config_data_get_value_boolean(NM_CONFIG_GET_DATA_ORIG, + NM_CONFIG_KEYFILE_GROUP_IFUPDOWN, + NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED, + !IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT); + _LOGI("management mode: %s", ifupdown_managed ? "managed" : "unmanaged"); + priv->ifupdown_managed = ifupdown_managed; - priv->eni_ifaces = load_eni_ifaces (self); + priv->eni_ifaces = load_eni_ifaces(self); } static void -reload_connections (NMSettingsPlugin *plugin, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data) +reload_connections(NMSettingsPlugin * plugin, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data) { - NMSIfupdownPlugin *self = NMS_IFUPDOWN_PLUGIN (plugin); - NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE (self); - gs_unref_hashtable GHashTable *eni_ifaces_old = NULL; - GHashTableIter iter; - StorageData *sd; - StorageData *sd2; - const char *block_name; - - if (!priv->initialized) - initialize (self); - else if (!priv->already_reloaded) { - /* This is the first call to reload, but we are already initialized. - * - * This happens because during start NMSettings first queries unmanaged-specs, - * and then issues a reload call right away. - * - * On future reloads, we really want to load /e/n/i again. */ - priv->already_reloaded = TRUE; - } else { - eni_ifaces_old = priv->eni_ifaces; - priv->eni_ifaces = load_eni_ifaces (self); - - g_hash_table_iter_init (&iter, eni_ifaces_old); - while (g_hash_table_iter_next (&iter, (gpointer *) &block_name, (gpointer *) &sd)) { - if (!sd) - continue; - - sd2 = g_hash_table_lookup (priv->eni_ifaces, block_name); - if (!sd2) - continue; - - nm_assert (nm_streq (nm_settings_storage_get_uuid (sd->storage), nm_settings_storage_get_uuid (sd2->storage))); - nm_g_object_ref_set (&sd2->storage, sd->storage); - g_hash_table_iter_remove (&iter); - } - } - - if (!priv->ifupdown_managed) - _LOGD ("load: no connections due to managed=false"); - - g_hash_table_iter_init (&iter, priv->eni_ifaces); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &sd)) { - gs_unref_object NMConnection *connection = NULL; - - if (!sd) - continue; - - connection = g_steal_pointer (&sd->connection); - - if (!priv->ifupdown_managed) - continue; - - _LOGD ("load: %s (%s)", - nm_settings_storage_get_uuid (sd->storage), - nm_connection_get_id (connection)); - callback (plugin, - sd->storage, - connection, - user_data); - } - if ( eni_ifaces_old - && priv->ifupdown_managed) { - g_hash_table_iter_init (&iter, eni_ifaces_old); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &sd)) { - if (!sd) - continue; - _LOGD ("unload: %s", - nm_settings_storage_get_uuid (sd->storage)); - callback (plugin, - sd->storage, - NULL, - user_data); - } - } + NMSIfupdownPlugin * self = NMS_IFUPDOWN_PLUGIN(plugin); + NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE(self); + gs_unref_hashtable GHashTable *eni_ifaces_old = NULL; + GHashTableIter iter; + StorageData * sd; + StorageData * sd2; + const char * block_name; + + if (!priv->initialized) + initialize(self); + else if (!priv->already_reloaded) { + /* This is the first call to reload, but we are already initialized. + * + * This happens because during start NMSettings first queries unmanaged-specs, + * and then issues a reload call right away. + * + * On future reloads, we really want to load /e/n/i again. */ + priv->already_reloaded = TRUE; + } else { + eni_ifaces_old = priv->eni_ifaces; + priv->eni_ifaces = load_eni_ifaces(self); + + g_hash_table_iter_init(&iter, eni_ifaces_old); + while (g_hash_table_iter_next(&iter, (gpointer *) &block_name, (gpointer *) &sd)) { + if (!sd) + continue; + + sd2 = g_hash_table_lookup(priv->eni_ifaces, block_name); + if (!sd2) + continue; + + nm_assert(nm_streq(nm_settings_storage_get_uuid(sd->storage), + nm_settings_storage_get_uuid(sd2->storage))); + nm_g_object_ref_set(&sd2->storage, sd->storage); + g_hash_table_iter_remove(&iter); + } + } + + if (!priv->ifupdown_managed) + _LOGD("load: no connections due to managed=false"); + + g_hash_table_iter_init(&iter, priv->eni_ifaces); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &sd)) { + gs_unref_object NMConnection *connection = NULL; + + if (!sd) + continue; + + connection = g_steal_pointer(&sd->connection); + + if (!priv->ifupdown_managed) + continue; + + _LOGD("load: %s (%s)", + nm_settings_storage_get_uuid(sd->storage), + nm_connection_get_id(connection)); + callback(plugin, sd->storage, connection, user_data); + } + if (eni_ifaces_old && priv->ifupdown_managed) { + g_hash_table_iter_init(&iter, eni_ifaces_old); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &sd)) { + if (!sd) + continue; + _LOGD("unload: %s", nm_settings_storage_get_uuid(sd->storage)); + callback(plugin, sd->storage, NULL, user_data); + } + } } /*****************************************************************************/ static GSList * -_unmanaged_specs (GHashTable *eni_ifaces) +_unmanaged_specs(GHashTable *eni_ifaces) { - gs_free const char **keys = NULL; - GSList *specs = NULL; - guint i, len; - - keys = nm_utils_strdict_get_keys (eni_ifaces, TRUE, &len); - for (i = len; i > 0; ) { - i--; - specs = g_slist_prepend (specs, g_strdup_printf (NM_MATCH_SPEC_INTERFACE_NAME_TAG"=%s", keys[i])); - } - return specs; + gs_free const char **keys = NULL; + GSList * specs = NULL; + guint i, len; + + keys = nm_utils_strdict_get_keys(eni_ifaces, TRUE, &len); + for (i = len; i > 0;) { + i--; + specs = g_slist_prepend(specs, + g_strdup_printf(NM_MATCH_SPEC_INTERFACE_NAME_TAG "=%s", keys[i])); + } + return specs; } -static GSList* -get_unmanaged_specs (NMSettingsPlugin *plugin) +static GSList * +get_unmanaged_specs(NMSettingsPlugin *plugin) { - NMSIfupdownPlugin *self = NMS_IFUPDOWN_PLUGIN (plugin); - NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE (self); + NMSIfupdownPlugin * self = NMS_IFUPDOWN_PLUGIN(plugin); + NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE(self); - if (G_UNLIKELY (!priv->initialized)) - initialize (self); + if (G_UNLIKELY(!priv->initialized)) + initialize(self); - if (priv->ifupdown_managed) - return NULL; + if (priv->ifupdown_managed) + return NULL; - _LOGD ("unmanaged-specs: unmanaged devices count %u", - g_hash_table_size (priv->eni_ifaces)); + _LOGD("unmanaged-specs: unmanaged devices count %u", g_hash_table_size(priv->eni_ifaces)); - return _unmanaged_specs (priv->eni_ifaces); + return _unmanaged_specs(priv->eni_ifaces); } /*****************************************************************************/ static GHashTable * -load_eni_ifaces (NMSIfupdownPlugin *self) +load_eni_ifaces(NMSIfupdownPlugin *self) { - gs_unref_hashtable GHashTable *eni_ifaces = NULL; - gs_unref_hashtable GHashTable *auto_ifaces = NULL; - nm_auto_ifparser if_parser *parser = NULL; - if_block *block; - StorageData *sd; - - eni_ifaces = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) _storage_data_destroy); - - parser = ifparser_parse (ENI_INTERFACES_FILE, 0); - - c_list_for_each_entry (block, &parser->block_lst_head, block_lst) { - if (NM_IN_STRSET (block->type, "auto", - "allow-hotplug")) { - if (!auto_ifaces) - auto_ifaces = g_hash_table_new (nm_str_hash, g_str_equal); - g_hash_table_add (auto_ifaces, (char *) block->name); - } - } - - c_list_for_each_entry (block, &parser->block_lst_head, block_lst) { - - if (NM_IN_STRSET (block->type, "auto", - "allow-hotplug")) - continue; - - if (nm_streq (block->type, "iface")) { - gs_free_error GError *local = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMSettingsStorage *storage = NULL; - const char *uuid = NULL; - StorageData *sd_repl; - - /* Bridge configuration */ - if (g_str_has_prefix (block->name, "br")) { - /* Try to find bridge ports */ - const char *ports = ifparser_getkey (block, "bridge-ports"); - - if (ports) { - int state = 0; - gs_free const char **port_ifaces = NULL; - gsize i; - - _LOGD ("parse: found bridge ports %s for %s", ports, block->name); - - port_ifaces = nm_utils_strsplit_set (ports, " \t"); - for (i = 0; port_ifaces && port_ifaces[i]; i++) { - const char *token = port_ifaces[i]; - - /* Skip crazy stuff like regex or all */ - if (nm_streq (token, "all")) - continue; - - /* Small SM to skip everything inside regex */ - if (nm_streq (token, "regex")) { - state++; - continue; - } - if (nm_streq (token, "noregex")) { - state--; - continue; - } - if (nm_streq (token, "none")) - continue; - if (state == 0) { - sd = g_hash_table_lookup (eni_ifaces, block->name); - if (!sd) { - _LOGD ("parse: adding bridge port \"%s\"", token); - g_hash_table_insert (eni_ifaces, g_strdup (token), NULL); - } else { - _LOGD ("parse: adding bridge port \"%s\" (have connection %s)", token, - nm_settings_storage_get_uuid (sd->storage)); - } - } - } - } - continue; - } - - /* Skip loopback configuration */ - if (nm_streq (block->name, "lo")) - continue; - - sd_repl = g_hash_table_lookup (eni_ifaces, block->name); - if (sd_repl) { - _LOGD ("parse: replace connection \"%s\" (%s)", - block->name, - nm_settings_storage_get_uuid (sd_repl->storage)); - storage = g_steal_pointer (&sd_repl->storage); - g_hash_table_remove (eni_ifaces, block->name); - } - - connection = ifupdown_new_connection_from_if_block (block, - auto_ifaces - && g_hash_table_contains (auto_ifaces, block->name), - &local); - - if (!connection) { - _LOGD ("parse: adding place holder for \"%s\"%s%s%s", - block->name, - NM_PRINT_FMT_QUOTED (local, " (", local->message, ")", "")); - sd = NULL; - } else { - - nmtst_connection_assert_unchanging (connection); - uuid = nm_connection_get_uuid (connection); - - if (!storage) - storage = nm_settings_storage_new (NM_SETTINGS_PLUGIN (self), uuid, NULL); - - sd = g_slice_new (StorageData); - *sd = (StorageData) { - .connection = g_steal_pointer (&connection), - .storage = g_steal_pointer (&storage), - }; - _LOGD ("parse: adding connection \"%s\" (%s)", block->name, uuid); - } - - g_hash_table_replace (eni_ifaces, g_strdup (block->name), sd); - continue; - } - - if (nm_streq (block->type, "mapping")) { - sd = g_hash_table_lookup (eni_ifaces, block->name); - if (!sd) { - _LOGD ("parse: adding mapping \"%s\"", block->name); - g_hash_table_insert (eni_ifaces, g_strdup (block->name), NULL); - } else { - _LOGD ("parse: adding mapping \"%s\" (have connection %s)", block->name, - nm_settings_storage_get_uuid (sd->storage)); - } - continue; - } - } - - nm_clear_pointer (&auto_ifaces, g_hash_table_destroy); - - return g_steal_pointer (&eni_ifaces); + gs_unref_hashtable GHashTable *eni_ifaces = NULL; + gs_unref_hashtable GHashTable *auto_ifaces = NULL; + nm_auto_ifparser if_parser *parser = NULL; + if_block * block; + StorageData * sd; + + eni_ifaces = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) _storage_data_destroy); + + parser = ifparser_parse(ENI_INTERFACES_FILE, 0); + + c_list_for_each_entry (block, &parser->block_lst_head, block_lst) { + if (NM_IN_STRSET(block->type, "auto", "allow-hotplug")) { + if (!auto_ifaces) + auto_ifaces = g_hash_table_new(nm_str_hash, g_str_equal); + g_hash_table_add(auto_ifaces, (char *) block->name); + } + } + + c_list_for_each_entry (block, &parser->block_lst_head, block_lst) { + if (NM_IN_STRSET(block->type, "auto", "allow-hotplug")) + continue; + + if (nm_streq(block->type, "iface")) { + gs_free_error GError *local = NULL; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMSettingsStorage *storage = NULL; + const char * uuid = NULL; + StorageData * sd_repl; + + /* Bridge configuration */ + if (g_str_has_prefix(block->name, "br")) { + /* Try to find bridge ports */ + const char *ports = ifparser_getkey(block, "bridge-ports"); + + if (ports) { + int state = 0; + gs_free const char **port_ifaces = NULL; + gsize i; + + _LOGD("parse: found bridge ports %s for %s", ports, block->name); + + port_ifaces = nm_utils_strsplit_set(ports, " \t"); + for (i = 0; port_ifaces && port_ifaces[i]; i++) { + const char *token = port_ifaces[i]; + + /* Skip crazy stuff like regex or all */ + if (nm_streq(token, "all")) + continue; + + /* Small SM to skip everything inside regex */ + if (nm_streq(token, "regex")) { + state++; + continue; + } + if (nm_streq(token, "noregex")) { + state--; + continue; + } + if (nm_streq(token, "none")) + continue; + if (state == 0) { + sd = g_hash_table_lookup(eni_ifaces, block->name); + if (!sd) { + _LOGD("parse: adding bridge port \"%s\"", token); + g_hash_table_insert(eni_ifaces, g_strdup(token), NULL); + } else { + _LOGD("parse: adding bridge port \"%s\" (have connection %s)", + token, + nm_settings_storage_get_uuid(sd->storage)); + } + } + } + } + continue; + } + + /* Skip loopback configuration */ + if (nm_streq(block->name, "lo")) + continue; + + sd_repl = g_hash_table_lookup(eni_ifaces, block->name); + if (sd_repl) { + _LOGD("parse: replace connection \"%s\" (%s)", + block->name, + nm_settings_storage_get_uuid(sd_repl->storage)); + storage = g_steal_pointer(&sd_repl->storage); + g_hash_table_remove(eni_ifaces, block->name); + } + + connection = ifupdown_new_connection_from_if_block( + block, + auto_ifaces && g_hash_table_contains(auto_ifaces, block->name), + &local); + + if (!connection) { + _LOGD("parse: adding place holder for \"%s\"%s%s%s", + block->name, + NM_PRINT_FMT_QUOTED(local, " (", local->message, ")", "")); + sd = NULL; + } else { + nmtst_connection_assert_unchanging(connection); + uuid = nm_connection_get_uuid(connection); + + if (!storage) + storage = nm_settings_storage_new(NM_SETTINGS_PLUGIN(self), uuid, NULL); + + sd = g_slice_new(StorageData); + *sd = (StorageData){ + .connection = g_steal_pointer(&connection), + .storage = g_steal_pointer(&storage), + }; + _LOGD("parse: adding connection \"%s\" (%s)", block->name, uuid); + } + + g_hash_table_replace(eni_ifaces, g_strdup(block->name), sd); + continue; + } + + if (nm_streq(block->type, "mapping")) { + sd = g_hash_table_lookup(eni_ifaces, block->name); + if (!sd) { + _LOGD("parse: adding mapping \"%s\"", block->name); + g_hash_table_insert(eni_ifaces, g_strdup(block->name), NULL); + } else { + _LOGD("parse: adding mapping \"%s\" (have connection %s)", + block->name, + nm_settings_storage_get_uuid(sd->storage)); + } + continue; + } + } + + nm_clear_pointer(&auto_ifaces, g_hash_table_destroy); + + return g_steal_pointer(&eni_ifaces); } /*****************************************************************************/ static void -nms_ifupdown_plugin_init (NMSIfupdownPlugin *self) -{ -} +nms_ifupdown_plugin_init(NMSIfupdownPlugin *self) +{} static void -dispose (GObject *object) +dispose(GObject *object) { - NMSIfupdownPlugin *plugin = NMS_IFUPDOWN_PLUGIN (object); - NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE (plugin); + NMSIfupdownPlugin * plugin = NMS_IFUPDOWN_PLUGIN(object); + NMSIfupdownPluginPrivate *priv = NMS_IFUPDOWN_PLUGIN_GET_PRIVATE(plugin); - nm_clear_pointer (&priv->eni_ifaces, g_hash_table_destroy); + nm_clear_pointer(&priv->eni_ifaces, g_hash_table_destroy); - G_OBJECT_CLASS (nms_ifupdown_plugin_parent_class)->dispose (object); + G_OBJECT_CLASS(nms_ifupdown_plugin_parent_class)->dispose(object); } static void -nms_ifupdown_plugin_class_init (NMSIfupdownPluginClass *klass) +nms_ifupdown_plugin_class_init(NMSIfupdownPluginClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMSettingsPluginClass *plugin_class = NM_SETTINGS_PLUGIN_CLASS (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingsPluginClass *plugin_class = NM_SETTINGS_PLUGIN_CLASS(klass); - object_class->dispose = dispose; + object_class->dispose = dispose; - plugin_class->plugin_name = "ifupdown"; - plugin_class->reload_connections = reload_connections; - plugin_class->get_unmanaged_specs = get_unmanaged_specs; + plugin_class->plugin_name = "ifupdown"; + plugin_class->reload_connections = reload_connections; + plugin_class->get_unmanaged_specs = get_unmanaged_specs; } /*****************************************************************************/ G_MODULE_EXPORT NMSettingsPlugin * -nm_settings_plugin_factory (void) + nm_settings_plugin_factory(void) { - return g_object_new (NMS_TYPE_IFUPDOWN_PLUGIN, NULL); + return g_object_new(NMS_TYPE_IFUPDOWN_PLUGIN, NULL); } diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.h b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.h index 91e3e43a..a3b73ea1 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.h +++ b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Alexander Sack * Copyright (C) 2008 Canonical Ltd. @@ -9,16 +9,20 @@ #define PLUGIN_NAME "ifupdown" -#define NMS_TYPE_IFUPDOWN_PLUGIN (nms_ifupdown_plugin_get_type ()) -#define NMS_IFUPDOWN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMS_TYPE_IFUPDOWN_PLUGIN, NMSIfupdownPlugin)) -#define NMS_IFUPDOWN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMS_TYPE_IFUPDOWN_PLUGIN, NMSIfupdownPluginClass)) -#define NMS_IS_IFUPDOWN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMS_TYPE_IFUPDOWN_PLUGIN)) -#define NMS_IS_IFUPDOWN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMS_TYPE_IFUPDOWN_PLUGIN)) -#define NMS_IFUPDOWN_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMS_TYPE_IFUPDOWN_PLUGIN, NMSIfupdownPluginClass)) +#define NMS_TYPE_IFUPDOWN_PLUGIN (nms_ifupdown_plugin_get_type()) +#define NMS_IFUPDOWN_PLUGIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NMS_TYPE_IFUPDOWN_PLUGIN, NMSIfupdownPlugin)) +#define NMS_IFUPDOWN_PLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NMS_TYPE_IFUPDOWN_PLUGIN, NMSIfupdownPluginClass)) +#define NMS_IS_IFUPDOWN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMS_TYPE_IFUPDOWN_PLUGIN)) +#define NMS_IS_IFUPDOWN_PLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NMS_TYPE_IFUPDOWN_PLUGIN)) +#define NMS_IFUPDOWN_PLUGIN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NMS_TYPE_IFUPDOWN_PLUGIN, NMSIfupdownPluginClass)) -typedef struct _NMSIfupdownPlugin NMSIfupdownPlugin; +typedef struct _NMSIfupdownPlugin NMSIfupdownPlugin; typedef struct _NMSIfupdownPluginClass NMSIfupdownPluginClass; -GType nms_ifupdown_plugin_get_type (void); +GType nms_ifupdown_plugin_get_type(void); #endif /* __NMS_IFUPDOWN_PLUGIN_H__ */ diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c index 6a7b5ecc..d2d8558e 100644 --- a/src/settings/plugins/ifupdown/tests/test-ifupdown.c +++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 Red Hat, Inc. */ @@ -12,631 +12,637 @@ #include "nm-test-utils-core.h" -#define TEST_DIR NM_BUILD_SRCDIR"/src/settings/plugins/ifupdown/tests" +#define TEST_DIR NM_BUILD_SRCDIR "/src/settings/plugins/ifupdown/tests" /*****************************************************************************/ -#define _connection_from_if_block(block) \ - ({ \ - NMConnection *_con; \ - if_block *_block = (block); \ - GError *_local = NULL; \ - \ - g_assert (_block); \ - _con = ifupdown_new_connection_from_if_block (_block, FALSE, &_local); \ - nmtst_assert_success (NM_IS_CONNECTION (_con), _local); \ - nmtst_assert_connection_verifies_without_normalization (_con); \ - _con; \ - }) - -#define _connection_first_from_parser(parser) \ - ({ \ - if_parser *_parser = (parser); \ - \ - g_assert (_parser); \ - _connection_from_if_block (ifparser_getfirst (_parser)); \ - }) +#define _connection_from_if_block(block) \ + ({ \ + NMConnection *_con; \ + if_block * _block = (block); \ + GError * _local = NULL; \ + \ + g_assert(_block); \ + _con = ifupdown_new_connection_from_if_block(_block, FALSE, &_local); \ + nmtst_assert_success(NM_IS_CONNECTION(_con), _local); \ + nmtst_assert_connection_verifies_without_normalization(_con); \ + _con; \ + }) + +#define _connection_first_from_parser(parser) \ + ({ \ + if_parser *_parser = (parser); \ + \ + g_assert(_parser); \ + _connection_from_if_block(ifparser_getfirst(_parser)); \ + }) /*****************************************************************************/ typedef struct { - char *key; - char *data; + char *key; + char *data; } ExpectedKey; typedef struct { - char *type; - char *name; - GSList *keys; + char * type; + char * name; + GSList *keys; } ExpectedBlock; typedef struct { - GSList *blocks; + GSList *blocks; } Expected; static ExpectedKey * -expected_key_new (const char *key, const char *data) +expected_key_new(const char *key, const char *data) { - ExpectedKey *k; + ExpectedKey *k; - k = g_malloc0 (sizeof (ExpectedKey)); - k->key = g_strdup (key); - k->data = g_strdup (data); - return k; + k = g_malloc0(sizeof(ExpectedKey)); + k->key = g_strdup(key); + k->data = g_strdup(data); + return k; } static void -expected_key_free (gpointer ptr) +expected_key_free(gpointer ptr) { - ExpectedKey *k = ptr; + ExpectedKey *k = ptr; - g_assert (k); - g_free (k->key); - g_free (k->data); - memset (k, 0, sizeof (ExpectedKey)); - g_free (k); + g_assert(k); + g_free(k->key); + g_free(k->data); + memset(k, 0, sizeof(ExpectedKey)); + g_free(k); } static ExpectedBlock * -expected_block_new (const char *type, const char *name) +expected_block_new(const char *type, const char *name) { - ExpectedBlock *b; + ExpectedBlock *b; - g_assert (type); - g_assert (name); - b = g_malloc0 (sizeof (ExpectedBlock)); - g_assert (b); - b->type = g_strdup (type); - b->name = g_strdup (name); - return b; + g_assert(type); + g_assert(name); + b = g_malloc0(sizeof(ExpectedBlock)); + g_assert(b); + b->type = g_strdup(type); + b->name = g_strdup(name); + return b; } static void -expected_block_free (gpointer ptr) +expected_block_free(gpointer ptr) { - ExpectedBlock *b = ptr; + ExpectedBlock *b = ptr; - g_assert (b); - g_slist_free_full (b->keys, expected_key_free); - g_free (b->type); - g_free (b->name); - memset (b, 0, sizeof (ExpectedBlock)); - g_free (b); + g_assert(b); + g_slist_free_full(b->keys, expected_key_free); + g_free(b->type); + g_free(b->name); + memset(b, 0, sizeof(ExpectedBlock)); + g_free(b); } static void -expected_block_add_key (ExpectedBlock *b, ExpectedKey *k) +expected_block_add_key(ExpectedBlock *b, ExpectedKey *k) { - g_assert (b); - g_assert (k); - b->keys = g_slist_append (b->keys, k); + g_assert(b); + g_assert(k); + b->keys = g_slist_append(b->keys, k); } static Expected * -expected_new (void) +expected_new(void) { - return g_malloc0 (sizeof (Expected)); + return g_malloc0(sizeof(Expected)); } static void -expected_add_block (Expected *e, ExpectedBlock *b) +expected_add_block(Expected *e, ExpectedBlock *b) { - g_assert (e); - g_assert (b); - e->blocks = g_slist_append (e->blocks, b); + g_assert(e); + g_assert(b); + e->blocks = g_slist_append(e->blocks, b); } static void -expected_free (Expected *e) +expected_free(Expected *e) { - g_assert (e); - g_slist_free_full (e->blocks, expected_block_free); - memset (e, 0, sizeof (Expected)); - g_free (e); + g_assert(e); + g_slist_free_full(e->blocks, expected_block_free); + memset(e, 0, sizeof(Expected)); + g_free(e); } -NM_AUTO_DEFINE_FCN_VOID0 (Expected *, _nm_auto_free_expected, expected_free) +NM_AUTO_DEFINE_FCN_VOID0(Expected *, _nm_auto_free_expected, expected_free); #define nm_auto_free_expected nm_auto(_nm_auto_free_expected) static void -compare_expected_to_ifparser (if_parser *parser, Expected *e) +compare_expected_to_ifparser(if_parser *parser, Expected *e) { - if_block *n; - GSList *biter, *kiter; + if_block *n; + GSList * biter, *kiter; - g_assert_cmpint (g_slist_length (e->blocks), ==, ifparser_get_num_blocks (parser)); + g_assert_cmpint(g_slist_length(e->blocks), ==, ifparser_get_num_blocks(parser)); - biter = e->blocks; - c_list_for_each_entry (n, &parser->block_lst_head, block_lst) { - if_data *m; - ExpectedBlock *b = biter->data; + biter = e->blocks; + c_list_for_each_entry (n, &parser->block_lst_head, block_lst) { + if_data * m; + ExpectedBlock *b = biter->data; - g_assert (b->type && n->type); - g_assert_cmpstr (b->type, ==, n->type); - g_assert (b->name); - g_assert_cmpstr (b->name, ==, n->name); + g_assert(b->type && n->type); + g_assert_cmpstr(b->type, ==, n->type); + g_assert(b->name); + g_assert_cmpstr(b->name, ==, n->name); - g_assert_cmpint (g_slist_length (b->keys), ==, ifparser_get_num_info (n)); + g_assert_cmpint(g_slist_length(b->keys), ==, ifparser_get_num_info(n)); - kiter = b->keys; - c_list_for_each_entry (m, &n->data_lst_head, data_lst) { - ExpectedKey *k = kiter->data; + kiter = b->keys; + c_list_for_each_entry (m, &n->data_lst_head, data_lst) { + ExpectedKey *k = kiter->data; - g_assert (k->key); - g_assert_cmpstr (k->key, ==, m->key); - g_assert (k->data && m->data); - g_assert_cmpstr (k->data, ==, m->data); + g_assert(k->key); + g_assert_cmpstr(k->key, ==, m->key); + g_assert(k->data && m->data); + g_assert_cmpstr(k->data, ==, m->data); - kiter = g_slist_next (kiter); - } - g_assert (!kiter); + kiter = g_slist_next(kiter); + } + g_assert(!kiter); - biter = g_slist_next (biter); - } - g_assert (!biter); + biter = g_slist_next(biter); + } + g_assert(!biter); } static void -dump_blocks (if_parser *parser) +dump_blocks(if_parser *parser) { - if_block *n; + if_block *n; - g_message ("\n***************************************************"); - c_list_for_each_entry (n, &parser->block_lst_head, block_lst) { - if_data *m; + g_message("\n***************************************************"); + c_list_for_each_entry (n, &parser->block_lst_head, block_lst) { + if_data *m; - // each block start with its type & name - // (single quotes used to show typ & name baoundaries) - g_print("'%s' '%s'\n", n->type, n->name); + // each block start with its type & name + // (single quotes used to show typ & name baoundaries) + g_print("'%s' '%s'\n", n->type, n->name); - // each key-value pair within a block is indented & separated by a tab - // (single quotes used to show typ & name baoundaries) - c_list_for_each_entry (m, &n->data_lst_head, data_lst) - g_print("\t'%s'\t'%s'\n", m->key, m->data); + // each key-value pair within a block is indented & separated by a tab + // (single quotes used to show type & name boundaries) + c_list_for_each_entry (m, &n->data_lst_head, data_lst) + g_print("\t'%s'\t'%s'\n", m->key, m->data); - // blocks are separated by an empty line - g_print("\n"); - } - g_message ("##################################################\n"); + // blocks are separated by an empty line + g_print("\n"); + } + g_message("##################################################\n"); } static if_parser * -init_ifparser_with_file (const char *file) +init_ifparser_with_file(const char *file) { - if_parser *parser; - gs_free char *tmp = NULL; + if_parser * parser; + gs_free char *tmp = NULL; - tmp = g_strdup_printf ("%s/%s", TEST_DIR, file); - parser = ifparser_parse (tmp, 1); - g_assert (parser); - return parser; + tmp = g_strdup_printf("%s/%s", TEST_DIR, file); + parser = ifparser_parse(tmp, 1); + g_assert(parser); + return parser; } static void -test1_ignore_line_before_first_block (void) +test1_ignore_line_before_first_block(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test1"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test1"); - e = expected_new (); - b = expected_block_new ("auto", "eth0"); - expected_add_block (e, b); - b = expected_block_new ("iface", "eth0"); - expected_add_block (e, b); - expected_block_add_key (b, expected_key_new ("inet", "dhcp")); + e = expected_new(); + b = expected_block_new("auto", "eth0"); + expected_add_block(e, b); + b = expected_block_new("iface", "eth0"); + expected_add_block(e, b); + expected_block_add_key(b, expected_key_new("inet", "dhcp")); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test2_wrapped_line (void) +test2_wrapped_line(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test2"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test2"); - e = expected_new (); - b = expected_block_new ("auto", "lo"); - expected_add_block (e, b); + e = expected_new(); + b = expected_block_new("auto", "lo"); + expected_add_block(e, b); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test3_wrapped_multiline_multiarg (void) +test3_wrapped_multiline_multiarg(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test3"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test3"); - e = expected_new (); - b = expected_block_new ("allow-hotplug", "eth0"); - expected_add_block (e, b); - b = expected_block_new ("allow-hotplug", "wlan0"); - expected_add_block (e, b); - b = expected_block_new ("allow-hotplug", "bnep0"); - expected_add_block (e, b); + e = expected_new(); + b = expected_block_new("allow-hotplug", "eth0"); + expected_add_block(e, b); + b = expected_block_new("allow-hotplug", "wlan0"); + expected_add_block(e, b); + b = expected_block_new("allow-hotplug", "bnep0"); + expected_add_block(e, b); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test4_allow_auto_is_auto (void) +test4_allow_auto_is_auto(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test4"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test4"); - e = expected_new (); - b = expected_block_new ("auto", "eth0"); - expected_add_block (e, b); + e = expected_new(); + b = expected_block_new("auto", "eth0"); + expected_add_block(e, b); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test5_allow_auto_multiarg (void) +test5_allow_auto_multiarg(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test5"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test5"); - e = expected_new (); - b = expected_block_new ("allow-hotplug", "eth0"); - expected_add_block (e, b); - b = expected_block_new ("allow-hotplug", "wlan0"); - expected_add_block (e, b); + e = expected_new(); + b = expected_block_new("allow-hotplug", "eth0"); + expected_add_block(e, b); + b = expected_block_new("allow-hotplug", "wlan0"); + expected_add_block(e, b); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test6_mixed_whitespace (void) +test6_mixed_whitespace(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test6"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test6"); - e = expected_new (); - b = expected_block_new ("iface", "lo"); - expected_block_add_key (b, expected_key_new ("inet", "loopback")); - expected_add_block (e, b); + e = expected_new(); + b = expected_block_new("iface", "lo"); + expected_block_add_key(b, expected_key_new("inet", "loopback")); + expected_add_block(e, b); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test7_long_line (void) +test7_long_line(void) { - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test7"); + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test7"); - g_assert_cmpint (ifparser_get_num_blocks (parser), ==, 0); + g_assert_cmpint(ifparser_get_num_blocks(parser), ==, 0); } static void -test8_long_line_wrapped (void) +test8_long_line_wrapped(void) { - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test8"); + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test8"); - g_assert_cmpint (ifparser_get_num_blocks (parser), ==, 0); + g_assert_cmpint(ifparser_get_num_blocks(parser), ==, 0); } static void -test9_wrapped_lines_in_block (void) +test9_wrapped_lines_in_block(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test9"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test9"); - e = expected_new (); - b = expected_block_new ("iface", "eth0"); - expected_add_block (e, b); - expected_block_add_key (b, expected_key_new ("inet", "static")); - expected_block_add_key (b, expected_key_new ("address", "10.250.2.3")); - expected_block_add_key (b, expected_key_new ("netmask", "255.255.255.192")); - expected_block_add_key (b, expected_key_new ("broadcast", "10.250.2.63")); - expected_block_add_key (b, expected_key_new ("gateway", "10.250.2.50")); + e = expected_new(); + b = expected_block_new("iface", "eth0"); + expected_add_block(e, b); + expected_block_add_key(b, expected_key_new("inet", "static")); + expected_block_add_key(b, expected_key_new("address", "10.250.2.3")); + expected_block_add_key(b, expected_key_new("netmask", "255.255.255.192")); + expected_block_add_key(b, expected_key_new("broadcast", "10.250.2.63")); + expected_block_add_key(b, expected_key_new("gateway", "10.250.2.50")); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test11_complex_wrap (void) +test11_complex_wrap(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test11"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test11"); - e = expected_new (); - b = expected_block_new ("iface", "pppoe"); - expected_add_block (e, b); - expected_block_add_key (b, expected_key_new ("inet", "manual")); - expected_block_add_key (b, expected_key_new ("pre-up", "/sbin/ifconfig eth0 up")); + e = expected_new(); + b = expected_block_new("iface", "pppoe"); + expected_add_block(e, b); + expected_block_add_key(b, expected_key_new("inet", "manual")); + expected_block_add_key(b, expected_key_new("pre-up", "/sbin/ifconfig eth0 up")); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test12_complex_wrap_split_word (void) +test12_complex_wrap_split_word(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test12"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test12"); - e = expected_new (); - b = expected_block_new ("iface", "pppoe"); - expected_add_block (e, b); - expected_block_add_key (b, expected_key_new ("inet", "manual")); - expected_block_add_key (b, expected_key_new ("up", "ifup ppp0=dsl")); + e = expected_new(); + b = expected_block_new("iface", "pppoe"); + expected_add_block(e, b); + expected_block_add_key(b, expected_key_new("inet", "manual")); + expected_block_add_key(b, expected_key_new("up", "ifup ppp0=dsl")); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test13_more_mixed_whitespace (void) +test13_more_mixed_whitespace(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test13"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test13"); - e = expected_new (); - b = expected_block_new ("iface", "dsl"); - expected_block_add_key (b, expected_key_new ("inet", "ppp")); - expected_add_block (e, b); + e = expected_new(); + b = expected_block_new("iface", "dsl"); + expected_block_add_key(b, expected_key_new("inet", "ppp")); + expected_add_block(e, b); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test14_mixed_whitespace_block_start (void) +test14_mixed_whitespace_block_start(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test14"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test14"); - e = expected_new (); - b = expected_block_new ("iface", "wlan0"); - expected_block_add_key (b, expected_key_new ("inet", "manual")); - expected_add_block (e, b); - b = expected_block_new ("iface", "wlan-adpm"); - expected_block_add_key (b, expected_key_new ("inet", "dhcp")); - expected_add_block (e, b); - b = expected_block_new ("iface", "wlan-default"); - expected_block_add_key (b, expected_key_new ("inet", "dhcp")); - expected_add_block (e, b); + e = expected_new(); + b = expected_block_new("iface", "wlan0"); + expected_block_add_key(b, expected_key_new("inet", "manual")); + expected_add_block(e, b); + b = expected_block_new("iface", "wlan-adpm"); + expected_block_add_key(b, expected_key_new("inet", "dhcp")); + expected_add_block(e, b); + b = expected_block_new("iface", "wlan-default"); + expected_block_add_key(b, expected_key_new("inet", "dhcp")); + expected_add_block(e, b); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test15_trailing_space (void) +test15_trailing_space(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test15"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test15"); - e = expected_new (); - b = expected_block_new ("iface", "bnep0"); - expected_block_add_key (b, expected_key_new ("inet", "static")); - expected_add_block (e, b); + e = expected_new(); + b = expected_block_new("iface", "bnep0"); + expected_block_add_key(b, expected_key_new("inet", "static")); + expected_add_block(e, b); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test16_missing_newline (void) +test16_missing_newline(void) { - nm_auto_free_expected Expected *e = NULL; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test16"); + nm_auto_free_expected Expected *e = NULL; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test16"); - e = expected_new (); - expected_add_block (e, expected_block_new ("mapping", "eth0")); + e = expected_new(); + expected_add_block(e, expected_block_new("mapping", "eth0")); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test17_read_static_ipv4 (void) +test17_read_static_ipv4(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMSettingWired *s_wired; - NMIPAddress *ip4_addr; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test17-wired-static-verify-ip4"); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingWired * s_wired; + NMIPAddress * ip4_addr; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test17-wired-static-verify-ip4"); - connection = _connection_first_from_parser (parser); + connection = _connection_first_from_parser(parser); - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "Ifupdown (eth0)"); + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "Ifupdown (eth0)"); - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); - g_assert (ip4_addr != NULL); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "10.0.0.3"); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 8); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr != NULL); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "10.0.0.3"); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 8); - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "10.0.0.1"); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 1), ==, "10.0.0.2"); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 0), ==, "10.0.0.1"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 1), ==, "10.0.0.2"); - g_assert_cmpint (nm_setting_ip_config_get_num_dns_searches (s_ip4), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 0), ==, "example.com"); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 1), ==, "foo.example.com"); + g_assert_cmpint(nm_setting_ip_config_get_num_dns_searches(s_ip4), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip4, 0), ==, "example.com"); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip4, 1), ==, "foo.example.com"); } static void -test18_read_static_ipv6 (void) +test18_read_static_ipv6(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip6; - NMSettingWired *s_wired; - NMIPAddress *ip6_addr; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test18-wired-static-verify-ip6"); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip6; + NMSettingWired * s_wired; + NMIPAddress * ip6_addr; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test18-wired-static-verify-ip6"); - connection = _connection_first_from_parser (parser); + connection = _connection_first_from_parser(parser); - /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "Ifupdown (myip6tunnel)"); + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "Ifupdown (myip6tunnel)"); - /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - /* ===== IPv6 SETTING ===== */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_MANUAL); + /* ===== IPv6 SETTING ===== */ + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL); - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip6), ==, 1); - ip6_addr = nm_setting_ip_config_get_address (s_ip6, 0); - g_assert (ip6_addr != NULL); - g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "fc00::1"); - g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 64); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 1); + ip6_addr = nm_setting_ip_config_get_address(s_ip6, 0); + g_assert(ip6_addr != NULL); + g_assert_cmpstr(nm_ip_address_get_address(ip6_addr), ==, "fc00::1"); + g_assert_cmpint(nm_ip_address_get_prefix(ip6_addr), ==, 64); - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip6), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 0), ==, "fc00::2"); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 1), ==, "fc00::3"); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 0), ==, "fc00::2"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 1), ==, "fc00::3"); - g_assert_cmpint (nm_setting_ip_config_get_num_dns_searches (s_ip6), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 0), ==, "example.com"); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 1), ==, "foo.example.com"); + g_assert_cmpint(nm_setting_ip_config_get_num_dns_searches(s_ip6), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 0), ==, "example.com"); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 1), ==, "foo.example.com"); } static void -test19_read_static_ipv4_plen (void) +test19_read_static_ipv4_plen(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingIPConfig *s_ip4; - NMIPAddress *ip4_addr; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test19-wired-static-verify-ip4-plen"); + gs_unref_object NMConnection *connection = NULL; + NMSettingIPConfig * s_ip4; + NMIPAddress * ip4_addr; + nm_auto_ifparser if_parser *parser = + init_ifparser_with_file("test19-wired-static-verify-ip4-plen"); - connection = _connection_first_from_parser (parser); + connection = _connection_first_from_parser(parser); - /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); - ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); - g_assert (ip4_addr != NULL); - g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "10.0.0.3"); - g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 8); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr != NULL); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "10.0.0.3"); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 8); } static void -test20_source_stanza (void) +test20_source_stanza(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test20-source-stanza"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test20-source-stanza"); - e = expected_new (); + e = expected_new(); - b = expected_block_new ("auto", "eth0"); - expected_add_block (e, b); - b = expected_block_new ("iface", "eth0"); - expected_add_block (e, b); - expected_block_add_key (b, expected_key_new ("inet", "dhcp")); + b = expected_block_new("auto", "eth0"); + expected_add_block(e, b); + b = expected_block_new("iface", "eth0"); + expected_add_block(e, b); + expected_block_add_key(b, expected_key_new("inet", "dhcp")); - b = expected_block_new ("auto", "eth1"); - expected_add_block (e, b); - b = expected_block_new ("iface", "eth1"); - expected_add_block (e, b); - expected_block_add_key (b, expected_key_new ("inet", "dhcp")); + b = expected_block_new("auto", "eth1"); + expected_add_block(e, b); + b = expected_block_new("iface", "eth1"); + expected_add_block(e, b); + expected_block_add_key(b, expected_key_new("inet", "dhcp")); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test21_source_dir_stanza (void) +test21_source_dir_stanza(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test21-source-dir-stanza"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test21-source-dir-stanza"); - e = expected_new (); + e = expected_new(); - b = expected_block_new ("auto", "eth0"); - expected_add_block (e, b); - b = expected_block_new ("iface", "eth0"); - expected_add_block (e, b); - expected_block_add_key (b, expected_key_new ("inet", "dhcp")); + b = expected_block_new("auto", "eth0"); + expected_add_block(e, b); + b = expected_block_new("iface", "eth0"); + expected_add_block(e, b); + expected_block_add_key(b, expected_key_new("inet", "dhcp")); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } static void -test22_duplicate_stanzas (void) +test22_duplicate_stanzas(void) { - nm_auto_free_expected Expected *e = NULL; - ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test22-duplicate-stanzas"); + nm_auto_free_expected Expected *e = NULL; + ExpectedBlock * b; + nm_auto_ifparser if_parser *parser = init_ifparser_with_file("test22-duplicate-stanzas"); - e = expected_new (); + e = expected_new(); - b = expected_block_new ("iface", "br10"); - expected_add_block (e, b); - expected_block_add_key (b, expected_key_new ("inet", "manual")); - expected_block_add_key (b, expected_key_new ("bridge-ports", "enp6s0.15")); - expected_block_add_key (b, expected_key_new ("bridge-stp", "off")); - expected_block_add_key (b, expected_key_new ("bridge-maxwait", "0")); - expected_block_add_key (b, expected_key_new ("bridge-fd", "0")); - b = expected_block_new ("iface", "br10"); - expected_add_block (e, b); - expected_block_add_key (b, expected_key_new ("inet", "auto")); - expected_block_add_key (b, expected_key_new ("bridge-ports", "enp6s0.15")); + b = expected_block_new("iface", "br10"); + expected_add_block(e, b); + expected_block_add_key(b, expected_key_new("inet", "manual")); + expected_block_add_key(b, expected_key_new("bridge-ports", "enp6s0.15")); + expected_block_add_key(b, expected_key_new("bridge-stp", "off")); + expected_block_add_key(b, expected_key_new("bridge-maxwait", "0")); + expected_block_add_key(b, expected_key_new("bridge-fd", "0")); + b = expected_block_new("iface", "br10"); + expected_add_block(e, b); + expected_block_add_key(b, expected_key_new("inet", "auto")); + expected_block_add_key(b, expected_key_new("bridge-ports", "enp6s0.15")); - compare_expected_to_ifparser (parser, e); + compare_expected_to_ifparser(parser, e); } /*****************************************************************************/ -NMTST_DEFINE (); +NMTST_DEFINE(); int -main (int argc, char **argv) -{ - nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT"); - - (void) dump_blocks; - - g_test_add_func ("/ifupdate/ignore_line_before_first_block", test1_ignore_line_before_first_block); - g_test_add_func ("/ifupdate/wrapped_line", test2_wrapped_line); - g_test_add_func ("/ifupdate/wrapped_multiline_multiarg", test3_wrapped_multiline_multiarg); - g_test_add_func ("/ifupdate/allow_auto_is_auto", test4_allow_auto_is_auto); - g_test_add_func ("/ifupdate/allow_auto_multiarg", test5_allow_auto_multiarg); - g_test_add_func ("/ifupdate/mixed_whitespace", test6_mixed_whitespace); - g_test_add_func ("/ifupdate/long_line", test7_long_line); - g_test_add_func ("/ifupdate/long_line_wrapped", test8_long_line_wrapped); - g_test_add_func ("/ifupdate/wrapped_lines_in_block", test9_wrapped_lines_in_block); - g_test_add_func ("/ifupdate/complex_wrap", test11_complex_wrap); - g_test_add_func ("/ifupdate/complex_wrap_split_word", test12_complex_wrap_split_word); - g_test_add_func ("/ifupdate/more_mixed_whitespace", test13_more_mixed_whitespace); - g_test_add_func ("/ifupdate/mixed_whitespace_block_start", test14_mixed_whitespace_block_start); - g_test_add_func ("/ifupdate/trailing_space", test15_trailing_space); - g_test_add_func ("/ifupdate/missing_newline", test16_missing_newline); - g_test_add_func ("/ifupdate/read_static_ipv4", test17_read_static_ipv4); - g_test_add_func ("/ifupdate/read_static_ipv6", test18_read_static_ipv6); - g_test_add_func ("/ifupdate/read_static_ipv4_plen", test19_read_static_ipv4_plen); - g_test_add_func ("/ifupdate/source_stanza", test20_source_stanza); - g_test_add_func ("/ifupdate/source_dir_stanza", test21_source_dir_stanza); - g_test_add_func ("/ifupdate/test22-duplicate-stanzas", test22_duplicate_stanzas); - - return g_test_run (); +main(int argc, char **argv) +{ + nmtst_init_assert_logging(&argc, &argv, "WARN", "DEFAULT"); + + (void) dump_blocks; + + g_test_add_func("/ifupdate/ignore_line_before_first_block", + test1_ignore_line_before_first_block); + g_test_add_func("/ifupdate/wrapped_line", test2_wrapped_line); + g_test_add_func("/ifupdate/wrapped_multiline_multiarg", test3_wrapped_multiline_multiarg); + g_test_add_func("/ifupdate/allow_auto_is_auto", test4_allow_auto_is_auto); + g_test_add_func("/ifupdate/allow_auto_multiarg", test5_allow_auto_multiarg); + g_test_add_func("/ifupdate/mixed_whitespace", test6_mixed_whitespace); + g_test_add_func("/ifupdate/long_line", test7_long_line); + g_test_add_func("/ifupdate/long_line_wrapped", test8_long_line_wrapped); + g_test_add_func("/ifupdate/wrapped_lines_in_block", test9_wrapped_lines_in_block); + g_test_add_func("/ifupdate/complex_wrap", test11_complex_wrap); + g_test_add_func("/ifupdate/complex_wrap_split_word", test12_complex_wrap_split_word); + g_test_add_func("/ifupdate/more_mixed_whitespace", test13_more_mixed_whitespace); + g_test_add_func("/ifupdate/mixed_whitespace_block_start", test14_mixed_whitespace_block_start); + g_test_add_func("/ifupdate/trailing_space", test15_trailing_space); + g_test_add_func("/ifupdate/missing_newline", test16_missing_newline); + g_test_add_func("/ifupdate/read_static_ipv4", test17_read_static_ipv4); + g_test_add_func("/ifupdate/read_static_ipv6", test18_read_static_ipv6); + g_test_add_func("/ifupdate/read_static_ipv4_plen", test19_read_static_ipv4_plen); + g_test_add_func("/ifupdate/source_stanza", test20_source_stanza); + g_test_add_func("/ifupdate/source_dir_stanza", test21_source_dir_stanza); + g_test_add_func("/ifupdate/test22-duplicate-stanzas", test22_duplicate_stanzas); + + return g_test_run(); } diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.c b/src/settings/plugins/keyfile/nms-keyfile-plugin.c index c84bd78d..48cb8caa 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-plugin.c +++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 Novell, Inc. * Copyright (C) 2008 - 2018 Red Hat, Inc. @@ -39,1017 +39,1014 @@ /*****************************************************************************/ typedef struct { - - NMConfig *config; - - /* there can/could be multiple read-only directories. For example, one - * could set dirname_libs to - * - /usr/lib/NetworkManager/profiles/ - * - /etc/NetworkManager/system-connections - * and leave dirname_etc unset. In this case, there would be multiple - * read-only directories. - * - * Directories that come later have higher priority and shadow profiles - * from earlier directories. - * - * Currently, this is only an array with zero or one elements. It could be - * easily extended to support multiple read-only directories. - */ - char *dirname_libs[2]; - char *dirname_etc; - char *dirname_run; - - NMSettUtilStorages storages; + NMConfig *config; + + /* there can/could be multiple read-only directories. For example, one + * could set dirname_libs to + * - /usr/lib/NetworkManager/profiles/ + * - /etc/NetworkManager/system-connections + * and leave dirname_etc unset. In this case, there would be multiple + * read-only directories. + * + * Directories that come later have higher priority and shadow profiles + * from earlier directories. + * + * Currently, this is only an array with zero or one elements. It could be + * easily extended to support multiple read-only directories. + */ + char *dirname_libs[2]; + char *dirname_etc; + char *dirname_run; + + NMSettUtilStorages storages; } NMSKeyfilePluginPrivate; struct _NMSKeyfilePlugin { - NMSettingsPlugin parent; - NMSKeyfilePluginPrivate _priv; + NMSettingsPlugin parent; + NMSKeyfilePluginPrivate _priv; }; struct _NMSKeyfilePluginClass { - NMSettingsPluginClass parent; + NMSettingsPluginClass parent; }; -G_DEFINE_TYPE (NMSKeyfilePlugin, nms_keyfile_plugin, NM_TYPE_SETTINGS_PLUGIN) +G_DEFINE_TYPE(NMSKeyfilePlugin, nms_keyfile_plugin, NM_TYPE_SETTINGS_PLUGIN) -#define NMS_KEYFILE_PLUGIN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSKeyfilePlugin, NMS_IS_KEYFILE_PLUGIN, NMSettingsPlugin) +#define NMS_KEYFILE_PLUGIN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSKeyfilePlugin, NMS_IS_KEYFILE_PLUGIN, NMSettingsPlugin) /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "keyfile" -#define _NMLOG_DOMAIN LOGD_SETTINGS -#define _NMLOG(level, ...) \ - nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME": " \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)) +#define _NMLOG_PREFIX_NAME "keyfile" +#define _NMLOG_DOMAIN LOGD_SETTINGS +#define _NMLOG(level, ...) \ + nm_log((level), \ + _NMLOG_DOMAIN, \ + NULL, \ + NULL, \ + "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME ": " _NM_UTILS_MACRO_REST(__VA_ARGS__)) /*****************************************************************************/ static const char * -_extra_flags_to_string (char *str, gsize str_len, gboolean is_nm_generated, gboolean is_volatile, gboolean is_external) +_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_external) - nm_utils_strbuf_append_str (&str, &str_len, ""); - else { - 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"); - ch = ','; - } - 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, ')'); - } - - return str0; + const char *str0 = str; + + if (!is_nm_generated && !is_volatile && !is_external) + nm_utils_strbuf_append_str(&str, &str_len, ""); + else { + 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"); + ch = ','; + } + 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, ')'); + } + + return str0; } static gboolean -_ignore_filename (NMSKeyfileStorageType storage_type, - const char *filename) +_ignore_filename(NMSKeyfileStorageType storage_type, const char *filename) { - /* for backward-compatibility, we don't require an extension for - * files under "/etc/...". */ - return nm_keyfile_utils_ignore_filename (filename, - (storage_type != NMS_KEYFILE_STORAGE_TYPE_ETC)); + /* for backward-compatibility, we don't require an extension for + * files under "/etc/...". */ + return nm_keyfile_utils_ignore_filename(filename, + (storage_type != NMS_KEYFILE_STORAGE_TYPE_ETC)); } static const char * -_get_plugin_dir (NMSKeyfilePluginPrivate *priv) +_get_plugin_dir(NMSKeyfilePluginPrivate *priv) { - /* the plugin dir is only needed to generate connection.uuid value via - * nm_keyfile_read_ensure_uuid(). This is either the configured /etc - * directory, of the compile-time default (in case the /etc directory - * is disabled). */ - return priv->dirname_etc ?: NM_KEYFILE_PATH_NAME_ETC_DEFAULT; + /* the plugin dir is only needed to generate connection.uuid value via + * nm_keyfile_read_ensure_uuid(). This is either the configured /etc + * directory, of the compile-time default (in case the /etc directory + * is disabled). */ + return priv->dirname_etc ?: NM_KEYFILE_PATH_NAME_ETC_DEFAULT; } static gboolean -_path_detect_storage_type (const char *full_filename, - const char *const*dirname_libs, - const char *dirname_etc, - const char *dirname_run, - NMSKeyfileStorageType *out_storage_type, - const char **out_dirname, - const char **out_filename, - gboolean *out_is_nmmeta_file, - gboolean *out_failed_due_to_invalid_filename) +_path_detect_storage_type(const char * full_filename, + const char *const * dirname_libs, + const char * dirname_etc, + const char * dirname_run, + NMSKeyfileStorageType *out_storage_type, + const char ** out_dirname, + const char ** out_filename, + gboolean * out_is_nmmeta_file, + gboolean * out_failed_due_to_invalid_filename) { - NMSKeyfileStorageType storage_type; - const char *filename = NULL; - const char *dirname = NULL; - guint i; - gboolean is_nmmeta_file = FALSE; - - NM_SET_OUT (out_failed_due_to_invalid_filename, FALSE); - - if (full_filename[0] != '/') - return FALSE; - - if ( dirname_run - && (filename = nm_utils_file_is_in_path (full_filename, dirname_run))) { - storage_type = NMS_KEYFILE_STORAGE_TYPE_RUN; - dirname = dirname_run; - } else if ( dirname_etc - && (filename = nm_utils_file_is_in_path (full_filename, dirname_etc))) { - storage_type = NMS_KEYFILE_STORAGE_TYPE_ETC; - dirname = dirname_etc; - } else { - for (i = 0; dirname_libs && dirname_libs[i]; i++) { - if ((filename = nm_utils_file_is_in_path (full_filename, dirname_libs[i]))) { - storage_type = NMS_KEYFILE_STORAGE_TYPE_LIB (i); - dirname = dirname_libs[i]; - break; - } - } - if (!dirname) - return FALSE; - } - - if (_ignore_filename (storage_type, filename)) { - - /* we accept nmmeta files, but only in /etc and /run directories. */ - - if ( !NM_IN_SET (storage_type, NMS_KEYFILE_STORAGE_TYPE_RUN, - NMS_KEYFILE_STORAGE_TYPE_ETC) - || !nms_keyfile_nmmeta_check_filename (filename, NULL)) { - NM_SET_OUT (out_failed_due_to_invalid_filename, TRUE); - return FALSE; - } - - is_nmmeta_file = TRUE; - } - - NM_SET_OUT (out_storage_type, storage_type); - NM_SET_OUT (out_dirname, dirname); - NM_SET_OUT (out_filename, filename); - NM_SET_OUT (out_is_nmmeta_file, is_nmmeta_file); - return TRUE; + NMSKeyfileStorageType storage_type; + const char * filename = NULL; + const char * dirname = NULL; + guint i; + gboolean is_nmmeta_file = FALSE; + + NM_SET_OUT(out_failed_due_to_invalid_filename, FALSE); + + if (full_filename[0] != '/') + return FALSE; + + if (dirname_run && (filename = nm_utils_file_is_in_path(full_filename, dirname_run))) { + storage_type = NMS_KEYFILE_STORAGE_TYPE_RUN; + dirname = dirname_run; + } else if (dirname_etc && (filename = nm_utils_file_is_in_path(full_filename, dirname_etc))) { + storage_type = NMS_KEYFILE_STORAGE_TYPE_ETC; + dirname = dirname_etc; + } else { + for (i = 0; dirname_libs && dirname_libs[i]; i++) { + if ((filename = nm_utils_file_is_in_path(full_filename, dirname_libs[i]))) { + storage_type = NMS_KEYFILE_STORAGE_TYPE_LIB(i); + dirname = dirname_libs[i]; + break; + } + } + if (!dirname) + return FALSE; + } + + if (_ignore_filename(storage_type, filename)) { + /* we accept nmmeta files, but only in /etc and /run directories. */ + + if (!NM_IN_SET(storage_type, NMS_KEYFILE_STORAGE_TYPE_RUN, NMS_KEYFILE_STORAGE_TYPE_ETC) + || !nms_keyfile_nmmeta_check_filename(filename, NULL)) { + NM_SET_OUT(out_failed_due_to_invalid_filename, TRUE); + return FALSE; + } + + is_nmmeta_file = TRUE; + } + + NM_SET_OUT(out_storage_type, storage_type); + NM_SET_OUT(out_dirname, dirname); + NM_SET_OUT(out_filename, filename); + NM_SET_OUT(out_is_nmmeta_file, is_nmmeta_file); + return TRUE; } /*****************************************************************************/ static NMConnection * -_read_from_file (const char *full_filename, - const char *plugin_dir, - 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) +_read_from_file(const char * full_filename, + const char * plugin_dir, + 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) { - NMConnection *connection; + NMConnection *connection; - nm_assert (full_filename && full_filename[0] == '/'); + nm_assert(full_filename && full_filename[0] == '/'); - connection = nms_keyfile_reader_from_file (full_filename, - plugin_dir, - out_stat, - out_is_nm_generated, - out_is_volatile, - out_is_external, - out_shadowed_storage, - out_shadowed_owned, - error); + connection = nms_keyfile_reader_from_file(full_filename, + plugin_dir, + out_stat, + out_is_nm_generated, + out_is_volatile, + out_is_external, + out_shadowed_storage, + out_shadowed_owned, + error); - nm_assert (!connection || (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS)); - nm_assert (!connection || nm_utils_is_uuid (nm_connection_get_uuid (connection))); + nm_assert(!connection + || (_nm_connection_verify(connection, NULL) == NM_SETTING_VERIFY_SUCCESS)); + nm_assert(!connection || nm_utils_is_uuid(nm_connection_get_uuid(connection))); - return connection; + return connection; } /*****************************************************************************/ static void -_nm_assert_storage (gpointer plugin /* NMSKeyfilePlugin */, - gpointer storage /* NMSKeyfileStorage */, - gboolean tracked) +_nm_assert_storage(gpointer plugin /* NMSKeyfilePlugin */, + gpointer storage /* NMSKeyfileStorage */, + gboolean tracked) { #if NM_MORE_ASSERTS - NMSettUtilStorageByUuidHead *sbuh; - const char *uuid; - - nm_assert (!plugin || NMS_IS_KEYFILE_PLUGIN (plugin)); - nm_assert (NMS_IS_KEYFILE_STORAGE (storage)); - nm_assert (!plugin || plugin == nm_settings_storage_get_plugin (storage)); - - nm_assert (({ - const char *f = nms_keyfile_storage_get_filename (storage); - f && f[0] == '/'; - })); - - uuid = nms_keyfile_storage_get_uuid (storage); - - nm_assert (nm_utils_is_uuid (uuid)); - - nm_assert ( ((NMSKeyfileStorage *) storage)->is_meta_data - || !(((NMSKeyfileStorage *) storage)->u.conn_data.connection) - || ( NM_IS_CONNECTION ((((NMSKeyfileStorage *) storage)->u.conn_data.connection)) - && nm_streq0 (uuid, nm_connection_get_uuid ((((NMSKeyfileStorage *) storage)->u.conn_data.connection))))); - - nm_assert ( !tracked - || !plugin - || c_list_contains (&NMS_KEYFILE_PLUGIN_GET_PRIVATE (plugin)->storages._storage_lst_head, - &NMS_KEYFILE_STORAGE (storage)->parent._storage_lst)); - - nm_assert ( !tracked - || !plugin - || storage == g_hash_table_lookup (NMS_KEYFILE_PLUGIN_GET_PRIVATE (plugin)->storages.idx_by_filename, - nms_keyfile_storage_get_filename (storage))); - - if ( tracked - && plugin) { - sbuh = g_hash_table_lookup (NMS_KEYFILE_PLUGIN_GET_PRIVATE (plugin)->storages.idx_by_uuid, &uuid); - nm_assert (sbuh); - nm_assert (c_list_contains (&sbuh->_storage_by_uuid_lst_head, &((NMSKeyfileStorage *) storage)->parent._storage_by_uuid_lst)); - } + NMSettUtilStorageByUuidHead *sbuh; + const char * uuid; + + nm_assert(!plugin || NMS_IS_KEYFILE_PLUGIN(plugin)); + nm_assert(NMS_IS_KEYFILE_STORAGE(storage)); + nm_assert(!plugin || plugin == nm_settings_storage_get_plugin(storage)); + + nm_assert(({ + const char *f = nms_keyfile_storage_get_filename(storage); + f && f[0] == '/'; + })); + + uuid = nms_keyfile_storage_get_uuid(storage); + + nm_assert(nm_utils_is_uuid(uuid)); + + nm_assert(((NMSKeyfileStorage *) storage)->is_meta_data + || !(((NMSKeyfileStorage *) storage)->u.conn_data.connection) + || (NM_IS_CONNECTION((((NMSKeyfileStorage *) storage)->u.conn_data.connection)) + && nm_streq0(uuid, + nm_connection_get_uuid( + (((NMSKeyfileStorage *) storage)->u.conn_data.connection))))); + + nm_assert( + !tracked || !plugin + || c_list_contains(&NMS_KEYFILE_PLUGIN_GET_PRIVATE(plugin)->storages._storage_lst_head, + &NMS_KEYFILE_STORAGE(storage)->parent._storage_lst)); + + nm_assert(!tracked || !plugin + || storage + == g_hash_table_lookup( + NMS_KEYFILE_PLUGIN_GET_PRIVATE(plugin)->storages.idx_by_filename, + nms_keyfile_storage_get_filename(storage))); + + if (tracked && plugin) { + sbuh = g_hash_table_lookup(NMS_KEYFILE_PLUGIN_GET_PRIVATE(plugin)->storages.idx_by_uuid, + &uuid); + nm_assert(sbuh); + nm_assert(c_list_contains(&sbuh->_storage_by_uuid_lst_head, + &((NMSKeyfileStorage *) storage)->parent._storage_by_uuid_lst)); + } #endif } /*****************************************************************************/ static NMSKeyfileStorage * -_load_file (NMSKeyfilePlugin *self, - const char *dirname, - const char *filename, - NMSKeyfileStorageType storage_type, - GError **error) +_load_file(NMSKeyfilePlugin * self, + const char * dirname, + const char * filename, + NMSKeyfileStorageType storage_type, + GError ** error) { - NMSKeyfilePluginPrivate *priv; - gs_unref_object NMConnection *connection = NULL; - 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; - gs_free char *full_filename = NULL; - struct stat st; - - if (_ignore_filename (storage_type, filename)) { - gs_free char *nmmeta = NULL; - gs_free char *loaded_path = NULL; - gs_free char *shadowed_storage_filename = NULL; - - if (!nms_keyfile_nmmeta_check_filename (filename, NULL)) { - if (error) - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, "skip due to invalid filename"); - else - _LOGT ("load: \"%s/%s\": skip file due to invalid filename", dirname, filename); - return NULL; - } - if (!nms_keyfile_nmmeta_read (dirname, - filename, - &full_filename, - &nmmeta, - &loaded_path, - &shadowed_storage_filename, - NULL)) { - if (error) - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, "skip unreadable nmmeta file"); - else - _LOGT ("load: \"%s/%s\": skip unreadable nmmeta file", dirname, filename); - return NULL; - } - nm_assert (loaded_path); - if (!NM_IN_SET (storage_type, NMS_KEYFILE_STORAGE_TYPE_RUN, - NMS_KEYFILE_STORAGE_TYPE_ETC)) { - if (error) - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, "skip nmmeta file from read-only directory"); - else - _LOGT ("load: \"%s/%s\": skip nmmeta file from read-only directory", dirname, filename); - return NULL; - } - if (!nm_streq (loaded_path, NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL)) { - if (error) - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, "skip nmmeta file not symlinking %s", NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL); - else - _LOGT ("load: \"%s/%s\": skip nmmeta file not symlinking to %s", dirname, filename, NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL); - return NULL; - } - - return nms_keyfile_storage_new_tombstone (self, - nmmeta, - full_filename, - storage_type, - shadowed_storage_filename); - } - - full_filename = g_build_filename (dirname, filename, NULL); - - priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (self); - - connection = _read_from_file (full_filename, - _get_plugin_dir (priv), - &st, - &is_nm_generated_opt, - &is_volatile_opt, - &is_external_opt, - &shadowed_storage, - &shadowed_owned_opt, - &local); - if (!connection) { - if (error) - g_propagate_error (error, g_steal_pointer (&local)); - else - _LOGW ("load: \"%s\": failed to load connection: %s", full_filename, local->message); - return NULL; - } - - return nms_keyfile_storage_new_connection (self, - g_steal_pointer (&connection), - full_filename, - storage_type, - is_nm_generated_opt, - is_volatile_opt, - is_external_opt, - shadowed_storage, - shadowed_owned_opt, - &st.st_mtim); + NMSKeyfilePluginPrivate *priv; + gs_unref_object NMConnection *connection = NULL; + 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; + gs_free char * full_filename = NULL; + struct stat st; + + if (_ignore_filename(storage_type, filename)) { + gs_free char *nmmeta = NULL; + gs_free char *loaded_path = NULL; + gs_free char *shadowed_storage_filename = NULL; + + if (!nms_keyfile_nmmeta_check_filename(filename, NULL)) { + if (error) + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "skip due to invalid filename"); + else + _LOGT("load: \"%s/%s\": skip file due to invalid filename", dirname, filename); + return NULL; + } + if (!nms_keyfile_nmmeta_read(dirname, + filename, + &full_filename, + &nmmeta, + &loaded_path, + &shadowed_storage_filename, + NULL)) { + if (error) + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "skip unreadable nmmeta file"); + else + _LOGT("load: \"%s/%s\": skip unreadable nmmeta file", dirname, filename); + return NULL; + } + nm_assert(loaded_path); + if (!NM_IN_SET(storage_type, NMS_KEYFILE_STORAGE_TYPE_RUN, NMS_KEYFILE_STORAGE_TYPE_ETC)) { + if (error) + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + "skip nmmeta file from read-only directory"); + else + _LOGT("load: \"%s/%s\": skip nmmeta file from read-only directory", + dirname, + filename); + return NULL; + } + if (!nm_streq(loaded_path, NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL)) { + if (error) + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + "skip nmmeta file not symlinking %s", + NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL); + else + _LOGT("load: \"%s/%s\": skip nmmeta file not symlinking to %s", + dirname, + filename, + NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL); + return NULL; + } + + return nms_keyfile_storage_new_tombstone(self, + nmmeta, + full_filename, + storage_type, + shadowed_storage_filename); + } + + full_filename = g_build_filename(dirname, filename, NULL); + + priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(self); + + connection = _read_from_file(full_filename, + _get_plugin_dir(priv), + &st, + &is_nm_generated_opt, + &is_volatile_opt, + &is_external_opt, + &shadowed_storage, + &shadowed_owned_opt, + &local); + if (!connection) { + if (error) + g_propagate_error(error, g_steal_pointer(&local)); + else + _LOGW("load: \"%s\": failed to load connection: %s", full_filename, local->message); + return NULL; + } + + return nms_keyfile_storage_new_connection(self, + g_steal_pointer(&connection), + full_filename, + storage_type, + is_nm_generated_opt, + is_volatile_opt, + is_external_opt, + shadowed_storage, + shadowed_owned_opt, + &st.st_mtim); } static NMSKeyfileStorage * -_load_file_from_path (NMSKeyfilePlugin *self, - const char *full_filename, - NMSKeyfileStorageType storage_type, - GError **error) +_load_file_from_path(NMSKeyfilePlugin * self, + const char * full_filename, + NMSKeyfileStorageType storage_type, + GError ** error) { - gs_free char *f_dirname_free = NULL; - const char *f_filename; - const char *f_dirname; - - nm_assert (full_filename && full_filename[0] == '/'); - - f_filename = strrchr (full_filename, '/'); - f_dirname = nm_strndup_a (300, full_filename, f_filename - full_filename, &f_dirname_free); - f_filename++; - return _load_file (self, - f_dirname, - f_filename, - storage_type, - error); + gs_free char *f_dirname_free = NULL; + const char * f_filename; + const char * f_dirname; + + nm_assert(full_filename && full_filename[0] == '/'); + + f_filename = strrchr(full_filename, '/'); + f_dirname = nm_strndup_a(300, full_filename, f_filename - full_filename, &f_dirname_free); + f_filename++; + return _load_file(self, f_dirname, f_filename, storage_type, error); } static void -_load_dir (NMSKeyfilePlugin *self, - NMSKeyfileStorageType storage_type, - const char *dirname, - NMSettUtilStorages *storages) +_load_dir(NMSKeyfilePlugin * self, + NMSKeyfileStorageType storage_type, + const char * dirname, + NMSettUtilStorages * storages) { - const char *filename; - GDir *dir; - gs_unref_hashtable GHashTable *dupl_filenames = NULL; + const char * filename; + GDir * dir; + gs_unref_hashtable GHashTable *dupl_filenames = NULL; - dir = g_dir_open (dirname, 0, NULL); - if (!dir) - return; + dir = g_dir_open(dirname, 0, NULL); + if (!dir) + return; - dupl_filenames = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_free); + dupl_filenames = g_hash_table_new_full(nm_str_hash, g_str_equal, NULL, g_free); - while ((filename = g_dir_read_name (dir))) { - gs_unref_object NMSKeyfileStorage *storage = NULL; + while ((filename = g_dir_read_name(dir))) { + gs_unref_object NMSKeyfileStorage *storage = NULL; - filename = g_strdup (filename); - if (!g_hash_table_add (dupl_filenames, (char *) filename)) - continue; + filename = g_strdup(filename); + if (!g_hash_table_add(dupl_filenames, (char *) filename)) + continue; - storage = _load_file (self, - dirname, - filename, - storage_type, - NULL); - if (!storage) - continue; + storage = _load_file(self, dirname, filename, storage_type, NULL); + if (!storage) + continue; - nm_sett_util_storages_add_take (storages, g_steal_pointer (&storage)); - } + nm_sett_util_storages_add_take(storages, g_steal_pointer(&storage)); + } - g_dir_close (dir); + g_dir_close(dir); #if NM_MORE_ASSERTS - { - NMSKeyfileStorage *storage; + { + NMSKeyfileStorage *storage; - c_list_for_each_entry (storage, &storages->_storage_lst_head, parent._storage_lst) - nm_assert (NMS_IS_KEYFILE_STORAGE (storage)); - } + c_list_for_each_entry (storage, &storages->_storage_lst_head, parent._storage_lst) + nm_assert(NMS_IS_KEYFILE_STORAGE(storage)); + } #endif } /*****************************************************************************/ static void -_storages_consolidate (NMSKeyfilePlugin *self, - NMSettUtilStorages *storages_new, - gboolean replace_all, - GHashTable *storages_replaced, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data) +_storages_consolidate(NMSKeyfilePlugin * self, + NMSettUtilStorages * storages_new, + gboolean replace_all, + GHashTable * storages_replaced, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data) { - NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (self); - CList lst_conn_info_deleted = C_LIST_INIT (lst_conn_info_deleted); - gs_unref_ptrarray GPtrArray *storages_modified = NULL; - CList storages_deleted; - NMSKeyfileStorage *storage_safe; - NMSKeyfileStorage *storage_new; - NMSKeyfileStorage *storage_old; - NMSKeyfileStorage *storage; - guint i; - - storages_modified = g_ptr_array_new_with_free_func (g_object_unref); - c_list_init (&storages_deleted); - - c_list_for_each_entry (storage_old, &priv->storages._storage_lst_head, parent._storage_lst) - storage_old->is_dirty = TRUE; - - c_list_for_each_entry_safe (storage_new, storage_safe, &storages_new->_storage_lst_head, parent._storage_lst) { - storage_old = nm_sett_util_storages_lookup_by_filename (&priv->storages, nms_keyfile_storage_get_filename (storage_new)); - - nm_sett_util_storages_steal (storages_new, storage_new); - - if ( !storage_old - || !nm_streq (nms_keyfile_storage_get_uuid (storage_new), nms_keyfile_storage_get_uuid (storage_old))) { - if (storage_old) { - nm_sett_util_storages_steal (&priv->storages, storage_old); - c_list_link_tail (&storages_deleted, &storage_old->parent._storage_by_uuid_lst); - } - storage_new->is_dirty = FALSE; - nm_sett_util_storages_add_take (&priv->storages, storage_new); - g_ptr_array_add (storages_modified, g_object_ref (storage_new)); - continue; - } - - storage_old->is_dirty = FALSE; - nms_keyfile_storage_copy_content (storage_old, storage_new); - nms_keyfile_storage_destroy (storage_new); - g_ptr_array_add (storages_modified, g_object_ref (storage_old)); - } - - c_list_for_each_entry_safe (storage_old, storage_safe, &priv->storages._storage_lst_head, parent._storage_lst) { - if (!storage_old->is_dirty) - continue; - if ( replace_all - || ( storages_replaced - && g_hash_table_contains (storages_replaced, storage_old))) { - nm_sett_util_storages_steal (&priv->storages, storage_old); - c_list_link_tail (&storages_deleted, &storage_old->parent._storage_by_uuid_lst); - } - } - - /* raise events. */ - - for (i = 0; i < storages_modified->len; i++) { - storage = storages_modified->pdata[i]; - storage->is_dirty = TRUE; - } - - for (i = 0; i < storages_modified->len; i++) { - gs_unref_object NMConnection *connection = NULL; - - storage = storages_modified->pdata[i]; - - if (!storage->is_dirty) { - /* the entry is no longer is_dirty. In the meantime we already emited - * another signal for it. */ - continue; - } - storage->is_dirty = FALSE; - - if (c_list_is_empty (&storage->parent._storage_lst)) { - /* hm? The profile was deleted in the meantime? That is only possible - * if the signal handler called again into the plugin. In any case, the event - * was already emitted. Skip. */ - continue; - } - - nm_assert (storage == nm_sett_util_storages_lookup_by_filename (&priv->storages, nms_keyfile_storage_get_filename (storage))); - - connection = nms_keyfile_storage_steal_connection (storage); - - callback (NM_SETTINGS_PLUGIN (self), - NM_SETTINGS_STORAGE (storage), - connection, - user_data); - } - - while ((storage = c_list_first_entry (&storages_deleted, NMSKeyfileStorage, parent._storage_by_uuid_lst))) { - c_list_unlink (&storage->parent._storage_by_uuid_lst); - callback (NM_SETTINGS_PLUGIN (self), - NM_SETTINGS_STORAGE (storage), - NULL, - user_data); - nms_keyfile_storage_destroy (storage); - } + NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(self); + CList lst_conn_info_deleted = C_LIST_INIT(lst_conn_info_deleted); + gs_unref_ptrarray GPtrArray *storages_modified = NULL; + CList storages_deleted; + NMSKeyfileStorage * storage_safe; + NMSKeyfileStorage * storage_new; + NMSKeyfileStorage * storage_old; + NMSKeyfileStorage * storage; + guint i; + + storages_modified = g_ptr_array_new_with_free_func(g_object_unref); + c_list_init(&storages_deleted); + + c_list_for_each_entry (storage_old, &priv->storages._storage_lst_head, parent._storage_lst) + storage_old->is_dirty = TRUE; + + c_list_for_each_entry_safe (storage_new, + storage_safe, + &storages_new->_storage_lst_head, + parent._storage_lst) { + storage_old = + nm_sett_util_storages_lookup_by_filename(&priv->storages, + nms_keyfile_storage_get_filename(storage_new)); + + nm_sett_util_storages_steal(storages_new, storage_new); + + if (!storage_old + || !nm_streq(nms_keyfile_storage_get_uuid(storage_new), + nms_keyfile_storage_get_uuid(storage_old))) { + if (storage_old) { + nm_sett_util_storages_steal(&priv->storages, storage_old); + c_list_link_tail(&storages_deleted, &storage_old->parent._storage_by_uuid_lst); + } + storage_new->is_dirty = FALSE; + nm_sett_util_storages_add_take(&priv->storages, storage_new); + g_ptr_array_add(storages_modified, g_object_ref(storage_new)); + continue; + } + + storage_old->is_dirty = FALSE; + nms_keyfile_storage_copy_content(storage_old, storage_new); + nms_keyfile_storage_destroy(storage_new); + g_ptr_array_add(storages_modified, g_object_ref(storage_old)); + } + + c_list_for_each_entry_safe (storage_old, + storage_safe, + &priv->storages._storage_lst_head, + parent._storage_lst) { + if (!storage_old->is_dirty) + continue; + if (replace_all + || (storages_replaced && g_hash_table_contains(storages_replaced, storage_old))) { + nm_sett_util_storages_steal(&priv->storages, storage_old); + c_list_link_tail(&storages_deleted, &storage_old->parent._storage_by_uuid_lst); + } + } + + /* raise events. */ + + for (i = 0; i < storages_modified->len; i++) { + storage = storages_modified->pdata[i]; + storage->is_dirty = TRUE; + } + + for (i = 0; i < storages_modified->len; i++) { + gs_unref_object NMConnection *connection = NULL; + + storage = storages_modified->pdata[i]; + + if (!storage->is_dirty) { + /* the entry is no longer is_dirty. In the meantime we already emitted + * another signal for it. */ + continue; + } + storage->is_dirty = FALSE; + + if (c_list_is_empty(&storage->parent._storage_lst)) { + /* hm? The profile was deleted in the meantime? That is only possible + * if the signal handler called again into the plugin. In any case, the event + * was already emitted. Skip. */ + continue; + } + + nm_assert( + storage + == nm_sett_util_storages_lookup_by_filename(&priv->storages, + nms_keyfile_storage_get_filename(storage))); + + connection = nms_keyfile_storage_steal_connection(storage); + + callback(NM_SETTINGS_PLUGIN(self), NM_SETTINGS_STORAGE(storage), connection, user_data); + } + + while ((storage = c_list_first_entry(&storages_deleted, + NMSKeyfileStorage, + parent._storage_by_uuid_lst))) { + c_list_unlink(&storage->parent._storage_by_uuid_lst); + callback(NM_SETTINGS_PLUGIN(self), NM_SETTINGS_STORAGE(storage), NULL, user_data); + nms_keyfile_storage_destroy(storage); + } } static void -reload_connections (NMSettingsPlugin *plugin, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data) +reload_connections(NMSettingsPlugin * plugin, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data) { - NMSKeyfilePlugin *self = NMS_KEYFILE_PLUGIN (plugin); - NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (self); - nm_auto_clear_sett_util_storages NMSettUtilStorages storages_new = NM_SETT_UTIL_STORAGES_INIT (storages_new, nms_keyfile_storage_destroy); - int i; - - _load_dir (self, NMS_KEYFILE_STORAGE_TYPE_RUN, priv->dirname_run, &storages_new); - if (priv->dirname_etc) - _load_dir (self, NMS_KEYFILE_STORAGE_TYPE_ETC, priv->dirname_etc, &storages_new); - for (i = 0; priv->dirname_libs[i]; i++) - _load_dir (self, NMS_KEYFILE_STORAGE_TYPE_LIB (i), priv->dirname_libs[i], &storages_new); - - _storages_consolidate (self, - &storages_new, - TRUE, - NULL, - callback, - user_data); + NMSKeyfilePlugin * self = NMS_KEYFILE_PLUGIN(plugin); + NMSKeyfilePluginPrivate * priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(self); + nm_auto_clear_sett_util_storages NMSettUtilStorages storages_new = + NM_SETT_UTIL_STORAGES_INIT(storages_new, nms_keyfile_storage_destroy); + int i; + + _load_dir(self, NMS_KEYFILE_STORAGE_TYPE_RUN, priv->dirname_run, &storages_new); + if (priv->dirname_etc) + _load_dir(self, NMS_KEYFILE_STORAGE_TYPE_ETC, priv->dirname_etc, &storages_new); + for (i = 0; priv->dirname_libs[i]; i++) + _load_dir(self, NMS_KEYFILE_STORAGE_TYPE_LIB(i), priv->dirname_libs[i], &storages_new); + + _storages_consolidate(self, &storages_new, TRUE, NULL, callback, user_data); } static void -load_connections (NMSettingsPlugin *plugin, - NMSettingsPluginConnectionLoadEntry *entries, - gsize n_entries, - NMSettingsPluginConnectionLoadCallback callback, - gpointer user_data) +load_connections(NMSettingsPlugin * plugin, + NMSettingsPluginConnectionLoadEntry * entries, + gsize n_entries, + NMSettingsPluginConnectionLoadCallback callback, + gpointer user_data) { - NMSKeyfilePlugin *self = NMS_KEYFILE_PLUGIN (plugin); - NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (self); - nm_auto_clear_sett_util_storages NMSettUtilStorages storages_new = NM_SETT_UTIL_STORAGES_INIT (storages_new, nms_keyfile_storage_destroy); - gs_unref_hashtable GHashTable *dupl_filenames = NULL; - gs_unref_hashtable GHashTable *storages_replaced = NULL; - gs_unref_hashtable GHashTable *loaded_uuids = NULL; - const char *loaded_uuid; - GHashTableIter h_iter; - gsize i; - - if (n_entries == 0) - return; - - dupl_filenames = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); - - loaded_uuids = g_hash_table_new (nm_str_hash, g_str_equal); - - storages_replaced = g_hash_table_new_full (nm_direct_hash, NULL, g_object_unref, NULL); - - for (i = 0; i < n_entries; i++) { - NMSettingsPluginConnectionLoadEntry *const entry = &entries[i]; - NMSKeyfileStorageType storage_type; - gs_free_error GError *local = NULL; - const char *f_filename; - const char *f_dirname; - const char *full_filename; - gs_free char *full_filename_keep = NULL; - gboolean is_nmmeta_file; - NMSettingsPluginConnectionLoadEntry *dupl_content_entry; - gboolean failed_due_to_invalid_filename; - gs_unref_object NMSKeyfileStorage *storage = NULL; - - if (entry->handled) - continue; - - if (!_path_detect_storage_type (entry->filename, - (const char *const*) priv->dirname_libs, - priv->dirname_etc, - priv->dirname_run, - &storage_type, - &f_dirname, - &f_filename, - &is_nmmeta_file, - &failed_due_to_invalid_filename)) { - if (failed_due_to_invalid_filename) { - entry->handled = TRUE; - nm_utils_error_set (&entry->error, NM_UTILS_ERROR_UNKNOWN, "filename is not valid for a keyfile"); - } - continue; - } - - full_filename_keep = g_build_filename (f_dirname, f_filename, NULL); - - if ((dupl_content_entry = g_hash_table_lookup (dupl_filenames, full_filename_keep))) { - /* we already visited this file. */ - entry->handled = dupl_content_entry->handled; - if (dupl_content_entry->error) { - g_set_error_literal (&entry->error, - dupl_content_entry->error->domain, - dupl_content_entry->error->code, - dupl_content_entry->error->message); - } - continue; - } - - entry->handled = TRUE; - - full_filename = full_filename_keep; - if (!g_hash_table_insert (dupl_filenames, g_steal_pointer (&full_filename_keep), entry)) - nm_assert_not_reached (); - - storage = _load_file (self, - f_dirname, - f_filename, - storage_type, - &local); - if (!storage) { - if (nm_utils_file_stat (full_filename, NULL) == -ENOENT) { - NMSKeyfileStorage *storage2; - - /* the file does not exist. We take that as indication to unload the file - * that was previously loaded... */ - storage2 = nm_sett_util_storages_lookup_by_filename (&priv->storages, full_filename); - if (storage2) - g_hash_table_add (storages_replaced, g_object_ref (storage2)); - continue; - } - g_propagate_error (&entry->error, g_steal_pointer (&local)); - continue; - } - - g_hash_table_add (loaded_uuids, (char *) nms_keyfile_storage_get_uuid (storage)); - - nm_sett_util_storages_add_take (&storages_new, g_steal_pointer (&storage)); - } - - /* now we visit all UUIDs that are about to change... */ - g_hash_table_iter_init (&h_iter, loaded_uuids); - while (g_hash_table_iter_next (&h_iter, (gpointer *) &loaded_uuid, NULL)) { - NMSKeyfileStorage *storage; - NMSettUtilStorageByUuidHead *sbuh; - - sbuh = nm_sett_util_storages_lookup_by_uuid (&priv->storages, loaded_uuid); - if (!sbuh) - continue; - - c_list_for_each_entry (storage, &sbuh->_storage_by_uuid_lst_head, parent._storage_by_uuid_lst) { - const char *full_filename = nms_keyfile_storage_get_filename (storage); - gs_unref_object NMSKeyfileStorage *storage_new = NULL; - gs_free_error GError *local = NULL; - - if (g_hash_table_contains (dupl_filenames, full_filename)) { - /* already re-loaded. */ - continue; - } - - /* @storage has a UUID that was just loaded from disk, but we have an entry in cache. - * Reload that file too despite not being told to do so. The reason is to get - * the latest file timestamp so that we get the priorities right. */ - - storage_new = _load_file_from_path (self, - full_filename, - storage->storage_type, - &local); - if ( storage_new - && !nm_streq (loaded_uuid, nms_keyfile_storage_get_uuid (storage_new))) { - /* the file now references a different UUID. We are not told to reload - * that file, so this means the existing storage (with the previous - * filename and UUID tuple) is no longer valid. */ - g_clear_object (&storage_new); - } - - g_hash_table_add (storages_replaced, g_object_ref (storage)); - if (storage_new) - nm_sett_util_storages_add_take (&storages_new, g_steal_pointer (&storage_new)); - } - } - - nm_clear_pointer (&loaded_uuids, g_hash_table_destroy); - nm_clear_pointer (&dupl_filenames, g_hash_table_destroy); - - _storages_consolidate (self, - &storages_new, - FALSE, - storages_replaced, - callback, - user_data); + NMSKeyfilePlugin * self = NMS_KEYFILE_PLUGIN(plugin); + NMSKeyfilePluginPrivate * priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(self); + nm_auto_clear_sett_util_storages NMSettUtilStorages storages_new = + NM_SETT_UTIL_STORAGES_INIT(storages_new, nms_keyfile_storage_destroy); + gs_unref_hashtable GHashTable *dupl_filenames = NULL; + gs_unref_hashtable GHashTable *storages_replaced = NULL; + gs_unref_hashtable GHashTable *loaded_uuids = NULL; + const char * loaded_uuid; + GHashTableIter h_iter; + gsize i; + + if (n_entries == 0) + return; + + dupl_filenames = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL); + + loaded_uuids = g_hash_table_new(nm_str_hash, g_str_equal); + + storages_replaced = g_hash_table_new_full(nm_direct_hash, NULL, g_object_unref, NULL); + + for (i = 0; i < n_entries; i++) { + NMSettingsPluginConnectionLoadEntry *const entry = &entries[i]; + NMSKeyfileStorageType storage_type; + gs_free_error GError * local = NULL; + const char * f_filename; + const char * f_dirname; + const char * full_filename; + gs_free char * full_filename_keep = NULL; + gboolean is_nmmeta_file; + NMSettingsPluginConnectionLoadEntry *dupl_content_entry; + gboolean failed_due_to_invalid_filename; + gs_unref_object NMSKeyfileStorage *storage = NULL; + + if (entry->handled) + continue; + + if (!_path_detect_storage_type(entry->filename, + (const char *const *) priv->dirname_libs, + priv->dirname_etc, + priv->dirname_run, + &storage_type, + &f_dirname, + &f_filename, + &is_nmmeta_file, + &failed_due_to_invalid_filename)) { + if (failed_due_to_invalid_filename) { + entry->handled = TRUE; + nm_utils_error_set(&entry->error, + NM_UTILS_ERROR_UNKNOWN, + "filename is not valid for a keyfile"); + } + continue; + } + + full_filename_keep = g_build_filename(f_dirname, f_filename, NULL); + + if ((dupl_content_entry = g_hash_table_lookup(dupl_filenames, full_filename_keep))) { + /* we already visited this file. */ + entry->handled = dupl_content_entry->handled; + if (dupl_content_entry->error) { + g_set_error_literal(&entry->error, + dupl_content_entry->error->domain, + dupl_content_entry->error->code, + dupl_content_entry->error->message); + } + continue; + } + + entry->handled = TRUE; + + full_filename = full_filename_keep; + if (!g_hash_table_insert(dupl_filenames, g_steal_pointer(&full_filename_keep), entry)) + nm_assert_not_reached(); + + storage = _load_file(self, f_dirname, f_filename, storage_type, &local); + if (!storage) { + if (nm_utils_file_stat(full_filename, NULL) == -ENOENT) { + NMSKeyfileStorage *storage2; + + /* the file does not exist. We take that as indication to unload the file + * that was previously loaded... */ + storage2 = nm_sett_util_storages_lookup_by_filename(&priv->storages, full_filename); + if (storage2) + g_hash_table_add(storages_replaced, g_object_ref(storage2)); + continue; + } + g_propagate_error(&entry->error, g_steal_pointer(&local)); + continue; + } + + g_hash_table_add(loaded_uuids, (char *) nms_keyfile_storage_get_uuid(storage)); + + nm_sett_util_storages_add_take(&storages_new, g_steal_pointer(&storage)); + } + + /* now we visit all UUIDs that are about to change... */ + g_hash_table_iter_init(&h_iter, loaded_uuids); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &loaded_uuid, NULL)) { + NMSKeyfileStorage * storage; + NMSettUtilStorageByUuidHead *sbuh; + + sbuh = nm_sett_util_storages_lookup_by_uuid(&priv->storages, loaded_uuid); + if (!sbuh) + continue; + + c_list_for_each_entry (storage, + &sbuh->_storage_by_uuid_lst_head, + parent._storage_by_uuid_lst) { + const char * full_filename = nms_keyfile_storage_get_filename(storage); + gs_unref_object NMSKeyfileStorage *storage_new = NULL; + gs_free_error GError *local = NULL; + + if (g_hash_table_contains(dupl_filenames, full_filename)) { + /* already re-loaded. */ + continue; + } + + /* @storage has a UUID that was just loaded from disk, but we have an entry in cache. + * Reload that file too despite not being told to do so. The reason is to get + * the latest file timestamp so that we get the priorities right. */ + + storage_new = _load_file_from_path(self, full_filename, storage->storage_type, &local); + if (storage_new && !nm_streq(loaded_uuid, nms_keyfile_storage_get_uuid(storage_new))) { + /* the file now references a different UUID. We are not told to reload + * that file, so this means the existing storage (with the previous + * filename and UUID tuple) is no longer valid. */ + g_clear_object(&storage_new); + } + + g_hash_table_add(storages_replaced, g_object_ref(storage)); + if (storage_new) + nm_sett_util_storages_add_take(&storages_new, g_steal_pointer(&storage_new)); + } + } + + nm_clear_pointer(&loaded_uuids, g_hash_table_destroy); + nm_clear_pointer(&dupl_filenames, g_hash_table_destroy); + + _storages_consolidate(self, &storages_new, FALSE, storages_replaced, callback, user_data); } gboolean -nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self, - NMConnection *connection, - gboolean in_memory, - gboolean is_nm_generated, - gboolean is_volatile, - gboolean is_external, - const char *shadowed_storage, - gboolean shadowed_owned, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error) +nms_keyfile_plugin_add_connection(NMSKeyfilePlugin * self, + NMConnection * connection, + gboolean in_memory, + gboolean is_nm_generated, + gboolean is_volatile, + gboolean is_external, + const char * shadowed_storage, + gboolean shadowed_owned, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error) { - NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (self); - gs_unref_object NMConnection *reread = NULL; - gs_free char *full_filename = NULL; - NMSKeyfileStorageType storage_type; - gs_unref_object NMSKeyfileStorage *storage = NULL; - GError *local = NULL; - const char *uuid; - gboolean reread_same; - struct timespec mtime; - char strbuf[100]; - - nm_assert (NM_IS_CONNECTION (connection)); - nm_assert (out_storage && !*out_storage); - nm_assert (out_connection && !*out_connection); - - nm_assert ( in_memory - || ( !is_nm_generated - && !is_volatile - && !is_external - && !shadowed_storage - && !shadowed_owned)); - - uuid = nm_connection_get_uuid (connection); - - /* Note that even if the caller requests persistent storage, we may switch to in-memory, if - * no /etc directory is configured. */ - storage_type = !in_memory && priv->dirname_etc - ? NMS_KEYFILE_STORAGE_TYPE_ETC - : NMS_KEYFILE_STORAGE_TYPE_RUN; - - if (!nms_keyfile_writer_connection (connection, - is_nm_generated, - is_volatile, - is_external, - shadowed_storage, - shadowed_owned, - storage_type == NMS_KEYFILE_STORAGE_TYPE_ETC - ? priv->dirname_etc - : priv->dirname_run, - _get_plugin_dir (priv), - NULL, - FALSE, - FALSE, - nm_sett_util_allow_filename_cb, - NM_SETT_UTIL_ALLOW_FILENAME_DATA (&priv->storages, NULL), - &full_filename, - &reread, - &reread_same, - &local)) { - _LOGT ("commit: %s (%s) failed to add: %s", - nm_connection_get_uuid (connection), - nm_connection_get_id (connection), - local->message); - g_propagate_error (error, local); - return FALSE; - } - - if ( !reread - || reread_same) - nm_g_object_ref_set (&reread, connection); - - nm_assert (_nm_connection_verify (reread, NULL) == NM_SETTING_VERIFY_SUCCESS); - nm_assert (nm_streq0 (nm_connection_get_uuid (connection), nm_connection_get_uuid (reread))); - - nm_assert (full_filename && full_filename[0] == '/'); - nm_assert (!nm_sett_util_storages_lookup_by_filename (&priv->storages, full_filename)); - - _LOGT ("commit: %s (%s) added as \"%s\"%s%s%s%s", - uuid, - nm_connection_get_id (connection), - full_filename, - _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, - g_steal_pointer (&reread), - full_filename, - 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)); - - nm_sett_util_storages_add_take (&priv->storages, g_object_ref (storage)); - - *out_connection = nms_keyfile_storage_steal_connection (storage); - *out_storage = NM_SETTINGS_STORAGE (g_steal_pointer (&storage)); - - return TRUE; + NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(self); + gs_unref_object NMConnection *reread = NULL; + gs_free char * full_filename = NULL; + NMSKeyfileStorageType storage_type; + gs_unref_object NMSKeyfileStorage *storage = NULL; + GError * local = NULL; + const char * uuid; + gboolean reread_same; + struct timespec mtime; + char strbuf[100]; + + nm_assert(NM_IS_CONNECTION(connection)); + nm_assert(out_storage && !*out_storage); + nm_assert(out_connection && !*out_connection); + + nm_assert(in_memory + || (!is_nm_generated && !is_volatile && !is_external && !shadowed_storage + && !shadowed_owned)); + + uuid = nm_connection_get_uuid(connection); + + /* Note that even if the caller requests persistent storage, we may switch to in-memory, if + * no /etc directory is configured. */ + storage_type = !in_memory && priv->dirname_etc ? NMS_KEYFILE_STORAGE_TYPE_ETC + : NMS_KEYFILE_STORAGE_TYPE_RUN; + + if (!nms_keyfile_writer_connection( + connection, + is_nm_generated, + is_volatile, + is_external, + shadowed_storage, + shadowed_owned, + storage_type == NMS_KEYFILE_STORAGE_TYPE_ETC ? priv->dirname_etc : priv->dirname_run, + _get_plugin_dir(priv), + NULL, + FALSE, + FALSE, + nm_sett_util_allow_filename_cb, + NM_SETT_UTIL_ALLOW_FILENAME_DATA(&priv->storages, NULL), + &full_filename, + &reread, + &reread_same, + &local)) { + _LOGT("commit: %s (%s) failed to add: %s", + nm_connection_get_uuid(connection), + nm_connection_get_id(connection), + local->message); + g_propagate_error(error, local); + return FALSE; + } + + if (!reread || reread_same) + nm_g_object_ref_set(&reread, connection); + + nm_assert(_nm_connection_verify(reread, NULL) == NM_SETTING_VERIFY_SUCCESS); + nm_assert(nm_streq0(nm_connection_get_uuid(connection), nm_connection_get_uuid(reread))); + + nm_assert(full_filename && full_filename[0] == '/'); + nm_assert(!nm_sett_util_storages_lookup_by_filename(&priv->storages, full_filename)); + + _LOGT("commit: %s (%s) added as \"%s\"%s%s%s%s", + uuid, + nm_connection_get_id(connection), + full_filename, + _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, + g_steal_pointer(&reread), + full_filename, + 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)); + + nm_sett_util_storages_add_take(&priv->storages, g_object_ref(storage)); + + *out_connection = nms_keyfile_storage_steal_connection(storage); + *out_storage = NM_SETTINGS_STORAGE(g_steal_pointer(&storage)); + + return TRUE; } static gboolean -add_connection (NMSettingsPlugin *plugin, - NMConnection *connection, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error) +add_connection(NMSettingsPlugin * plugin, + NMConnection * connection, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error) { - return nms_keyfile_plugin_add_connection (NMS_KEYFILE_PLUGIN (plugin), - connection, - FALSE, - FALSE, - FALSE, - FALSE, - NULL, - FALSE, - out_storage, - out_connection, - error); + return nms_keyfile_plugin_add_connection(NMS_KEYFILE_PLUGIN(plugin), + connection, + FALSE, + FALSE, + FALSE, + FALSE, + NULL, + FALSE, + out_storage, + out_connection, + error); } gboolean -nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self, - NMSettingsStorage *storage_x, - NMConnection *connection, - gboolean is_nm_generated, - gboolean is_volatile, - gboolean is_external, - const char *shadowed_storage, - gboolean shadowed_owned, - gboolean force_rename, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error) +nms_keyfile_plugin_update_connection(NMSKeyfilePlugin * self, + NMSettingsStorage * storage_x, + NMConnection * connection, + gboolean is_nm_generated, + gboolean is_volatile, + gboolean is_external, + const char * shadowed_storage, + gboolean shadowed_owned, + gboolean force_rename, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error) { - NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (self); - NMSKeyfileStorage *storage = NMS_KEYFILE_STORAGE (storage_x); - gs_unref_object NMConnection *connection_clone = NULL; - gs_unref_object NMConnection *reread = NULL; - gs_free char *full_filename = NULL; - gs_free_error GError *local = NULL; - struct timespec mtime; - const char *previous_filename; - gboolean reread_same; - const char *uuid; - char strbuf[100]; - - _nm_assert_storage (self, storage, TRUE); - nm_assert (NM_IS_CONNECTION (connection)); - nm_assert (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS); - nm_assert (nm_streq (nms_keyfile_storage_get_uuid (storage), nm_connection_get_uuid (connection))); - nm_assert (!error || !*error); - nm_assert (NM_IN_SET (storage->storage_type, NMS_KEYFILE_STORAGE_TYPE_ETC, - NMS_KEYFILE_STORAGE_TYPE_RUN)); - nm_assert (!storage->is_meta_data); - 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); - nm_assert ( priv->dirname_etc - || storage->storage_type != NMS_KEYFILE_STORAGE_TYPE_ETC); - - previous_filename = nms_keyfile_storage_get_filename (storage); - uuid = nms_keyfile_storage_get_uuid (storage); - - 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 - ? priv->dirname_etc - : priv->dirname_run, - _get_plugin_dir (priv), - previous_filename, - FALSE, - FALSE, - nm_sett_util_allow_filename_cb, - NM_SETT_UTIL_ALLOW_FILENAME_DATA (&priv->storages, previous_filename), - &full_filename, - &reread, - &reread_same, - &local)) { - _LOGW ("commit: failure to write %s (%s) to \"%s\": %s", - uuid, - nm_connection_get_id (connection_clone), - previous_filename, - local->message); - g_propagate_error (error, g_steal_pointer (&local)); - return FALSE; - } - - nm_assert ( full_filename - && nm_streq (full_filename, previous_filename)); - - if ( !reread - || reread_same) - nm_g_object_ref_set (&reread, connection); - - nm_assert (_nm_connection_verify (reread, NULL) == NM_SETTING_VERIFY_SUCCESS); - nm_assert (nm_streq (nm_connection_get_uuid (reread), uuid)); - - _LOGT ("commit: \"%s\": profile %s (%s) written%s%s%s%s", - full_filename, - uuid, - nm_connection_get_id (connection), - _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; - - *out_storage = g_object_ref (NM_SETTINGS_STORAGE (storage)); - *out_connection = g_steal_pointer (&reread); - return TRUE; + NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(self); + NMSKeyfileStorage * storage = NMS_KEYFILE_STORAGE(storage_x); + gs_unref_object NMConnection *connection_clone = NULL; + gs_unref_object NMConnection *reread = NULL; + gs_free char * full_filename = NULL; + gs_free_error GError *local = NULL; + struct timespec mtime; + const char * previous_filename; + gboolean reread_same; + const char * uuid; + char strbuf[100]; + + _nm_assert_storage(self, storage, TRUE); + nm_assert(NM_IS_CONNECTION(connection)); + nm_assert(_nm_connection_verify(connection, NULL) == NM_SETTING_VERIFY_SUCCESS); + nm_assert(nm_streq(nms_keyfile_storage_get_uuid(storage), nm_connection_get_uuid(connection))); + nm_assert(!error || !*error); + nm_assert(NM_IN_SET(storage->storage_type, + NMS_KEYFILE_STORAGE_TYPE_ETC, + NMS_KEYFILE_STORAGE_TYPE_RUN)); + nm_assert(!storage->is_meta_data); + 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); + nm_assert(priv->dirname_etc || storage->storage_type != NMS_KEYFILE_STORAGE_TYPE_ETC); + + previous_filename = nms_keyfile_storage_get_filename(storage); + uuid = nms_keyfile_storage_get_uuid(storage); + + 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 ? priv->dirname_etc + : priv->dirname_run, + _get_plugin_dir(priv), + previous_filename, + FALSE, + FALSE, + nm_sett_util_allow_filename_cb, + NM_SETT_UTIL_ALLOW_FILENAME_DATA(&priv->storages, previous_filename), + &full_filename, + &reread, + &reread_same, + &local)) { + _LOGW("commit: failure to write %s (%s) to \"%s\": %s", + uuid, + nm_connection_get_id(connection_clone), + previous_filename, + local->message); + g_propagate_error(error, g_steal_pointer(&local)); + return FALSE; + } + + nm_assert(full_filename && nm_streq(full_filename, previous_filename)); + + if (!reread || reread_same) + nm_g_object_ref_set(&reread, connection); + + nm_assert(_nm_connection_verify(reread, NULL) == NM_SETTING_VERIFY_SUCCESS); + nm_assert(nm_streq(nm_connection_get_uuid(reread), uuid)); + + _LOGT("commit: \"%s\": profile %s (%s) written%s%s%s%s", + full_filename, + uuid, + nm_connection_get_id(connection), + _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; + + *out_storage = g_object_ref(NM_SETTINGS_STORAGE(storage)); + *out_connection = g_steal_pointer(&reread); + return TRUE; } static gboolean -update_connection (NMSettingsPlugin *plugin, - NMSettingsStorage *storage, - NMConnection *connection, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error) +update_connection(NMSettingsPlugin * plugin, + NMSettingsStorage * storage, + NMConnection * connection, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error) { - return nms_keyfile_plugin_update_connection (NMS_KEYFILE_PLUGIN (plugin), - storage, - connection, - FALSE, - FALSE, - FALSE, - NULL, - FALSE, - FALSE, - out_storage, - out_connection, - error); + return nms_keyfile_plugin_update_connection(NMS_KEYFILE_PLUGIN(plugin), + storage, + connection, + FALSE, + FALSE, + FALSE, + NULL, + FALSE, + FALSE, + out_storage, + out_connection, + error); } static gboolean -delete_connection (NMSettingsPlugin *plugin, - NMSettingsStorage *storage_x, - GError **error) +delete_connection(NMSettingsPlugin *plugin, NMSettingsStorage *storage_x, GError **error) { - NMSKeyfilePlugin *self = NMS_KEYFILE_PLUGIN (plugin); - NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (self); - gs_unref_object NMSKeyfileStorage *storage = g_object_ref (NMS_KEYFILE_STORAGE (storage_x)); - const char *remove_from_disk_errmsg = NULL; - const char *operation_message; - const char *previous_filename; - const char *uuid; - gboolean success = TRUE; - - _nm_assert_storage (self, storage, TRUE); - nm_assert (!error || !*error); - - previous_filename = nms_keyfile_storage_get_filename (storage); - uuid = nms_keyfile_storage_get_uuid (storage); - - if (!NM_IN_SET (storage->storage_type, NMS_KEYFILE_STORAGE_TYPE_ETC, - NMS_KEYFILE_STORAGE_TYPE_RUN)) { - nm_utils_error_set (error, - NM_UTILS_ERROR_UNKNOWN, - "profile in read-only storage cannot be deleted"); - success = FALSE; - operation_message = "dropped readonly file from memory"; - } else if (unlink (previous_filename) != 0) { - int errsv; - - errsv = errno; - if (errsv != ENOENT) { - remove_from_disk_errmsg = nm_strerror_native (errsv); - operation_message = "failed to delete from disk"; - success = FALSE; - nm_utils_error_set_errno (error, - errsv, - "failure to delete \"%s\": %s", - previous_filename); - } else - operation_message = "does not exist on disk"; - } else - operation_message = "deleted from disk"; - - _LOGT ("commit: deleted \"%s\", %s %s (%s%s%s%s)", - previous_filename, - storage->is_meta_data ? "meta-data" : "profile", - uuid, - operation_message, - NM_PRINT_FMT_QUOTED (remove_from_disk_errmsg, ": ", remove_from_disk_errmsg, "", "")); - - if (success) { - nm_sett_util_storages_steal (&priv->storages, storage); - nms_keyfile_storage_destroy (storage); - } - - return success; + NMSKeyfilePlugin * self = NMS_KEYFILE_PLUGIN(plugin); + NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(self); + gs_unref_object NMSKeyfileStorage *storage = g_object_ref(NMS_KEYFILE_STORAGE(storage_x)); + const char * remove_from_disk_errmsg = NULL; + const char * operation_message; + const char * previous_filename; + const char * uuid; + gboolean success = TRUE; + + _nm_assert_storage(self, storage, TRUE); + nm_assert(!error || !*error); + + previous_filename = nms_keyfile_storage_get_filename(storage); + uuid = nms_keyfile_storage_get_uuid(storage); + + if (!NM_IN_SET(storage->storage_type, + NMS_KEYFILE_STORAGE_TYPE_ETC, + NMS_KEYFILE_STORAGE_TYPE_RUN)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + "profile in read-only storage cannot be deleted"); + success = FALSE; + operation_message = "dropped readonly file from memory"; + } else if (unlink(previous_filename) != 0) { + int errsv; + + errsv = errno; + if (errsv != ENOENT) { + remove_from_disk_errmsg = nm_strerror_native(errsv); + operation_message = "failed to delete from disk"; + success = FALSE; + nm_utils_error_set_errno(error, + errsv, + "failure to delete \"%s\": %s", + previous_filename); + } else + operation_message = "does not exist on disk"; + } else + operation_message = "deleted from disk"; + + _LOGT("commit: deleted \"%s\", %s %s (%s%s%s%s)", + previous_filename, + storage->is_meta_data ? "meta-data" : "profile", + uuid, + operation_message, + NM_PRINT_FMT_QUOTED(remove_from_disk_errmsg, ": ", remove_from_disk_errmsg, "", "")); + + if (success) { + nm_sett_util_storages_steal(&priv->storages, storage); + nms_keyfile_storage_destroy(storage); + } + + return success; } /** @@ -1089,260 +1086,263 @@ delete_connection (NMSettingsPlugin *plugin, * Returns: %TRUE on success. */ gboolean -nms_keyfile_plugin_set_nmmeta_tombstone (NMSKeyfilePlugin *self, - gboolean simulate, - const char *uuid, - gboolean in_memory, - gboolean set, - const char *shadowed_storage, - NMSettingsStorage **out_storage, - gboolean *out_hard_failure) +nms_keyfile_plugin_set_nmmeta_tombstone(NMSKeyfilePlugin * self, + gboolean simulate, + const char * uuid, + gboolean in_memory, + gboolean set, + const char * shadowed_storage, + NMSettingsStorage **out_storage, + gboolean * out_hard_failure) { - NMSKeyfilePluginPrivate *priv; - gboolean hard_failure = FALSE; - NMSKeyfileStorage *storage; - gs_unref_object NMSKeyfileStorage *storage_result = NULL; - gboolean nmmeta_errno; - gs_free char *nmmeta_filename = NULL; - NMSKeyfileStorageType storage_type; - const char *loaded_path; - const char *dirname; - - nm_assert (NMS_IS_KEYFILE_PLUGIN (self)); - nm_assert (nm_utils_is_uuid (uuid)); - nm_assert (!out_storage || !*out_storage); - nm_assert (!shadowed_storage || (set && in_memory)); - - priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (self); - - loaded_path = set - ? NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL - : NULL; - - if (in_memory) { - storage_type = NMS_KEYFILE_STORAGE_TYPE_RUN; - dirname = priv->dirname_run; - } else { - if (!priv->dirname_etc) { - _LOGT ("commit: cannot %s%s nmmeta file for %s as there is no /etc directory", - simulate ? "simulate " : "", - loaded_path ? "write" : "delete", - uuid); - nmmeta_errno = 0; - hard_failure = TRUE; - goto out; - } - storage_type = NMS_KEYFILE_STORAGE_TYPE_ETC; - dirname = priv->dirname_etc; - } - - if (simulate) { - nmmeta_errno = 0; - nmmeta_filename = nms_keyfile_nmmeta_filename (dirname, uuid, FALSE); - } else { - nmmeta_errno = nms_keyfile_nmmeta_write (dirname, - uuid, - loaded_path, - FALSE, - shadowed_storage, - &nmmeta_filename); - } - - _LOGT ("commit: %s nmmeta file \"%s\"%s%s%s%s%s%s %s%s%s%s", - loaded_path ? "writing" : "deleting", - nmmeta_filename, - NM_PRINT_FMT_QUOTED (loaded_path, " (pointing to \"", loaded_path, "\")", ""), - NM_PRINT_FMT_QUOTED (shadowed_storage, " (shadows \"", shadowed_storage, "\")", ""), - simulate - ? "simulated" - : ( nmmeta_errno < 0 - ? "failed" - : "succeeded"), - NM_PRINT_FMT_QUOTED (nmmeta_errno < 0, " (", nm_strerror_native (nm_errno_native (nmmeta_errno)), ")", "")); - - if (nmmeta_errno < 0) - goto out; - - storage = nm_sett_util_storages_lookup_by_filename (&priv->storages, nmmeta_filename); - - nm_assert ( !storage - || ( storage->is_meta_data - && storage->storage_type == storage_type - && nm_streq (nms_keyfile_storage_get_uuid (storage), uuid))); - - if (loaded_path) { - - if (!storage) { - storage = nms_keyfile_storage_new_tombstone (self, - uuid, - nmmeta_filename, - storage_type, - shadowed_storage); - nm_sett_util_storages_add_take (&priv->storages, storage); - } else { - g_free (storage->u.meta_data.shadowed_storage); - storage->u.meta_data.shadowed_storage = g_strdup (shadowed_storage); - } - - storage_result = g_object_ref (storage); - } else { - if (storage) - storage_result = nm_sett_util_storages_steal (&priv->storages, storage); - } + NMSKeyfilePluginPrivate *priv; + gboolean hard_failure = FALSE; + NMSKeyfileStorage * storage; + gs_unref_object NMSKeyfileStorage *storage_result = NULL; + gboolean nmmeta_errno; + gs_free char * nmmeta_filename = NULL; + NMSKeyfileStorageType storage_type; + const char * loaded_path; + const char * dirname; + + nm_assert(NMS_IS_KEYFILE_PLUGIN(self)); + nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(!out_storage || !*out_storage); + nm_assert(!shadowed_storage || (set && in_memory)); + + priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(self); + + loaded_path = set ? NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL : NULL; + + if (in_memory) { + storage_type = NMS_KEYFILE_STORAGE_TYPE_RUN; + dirname = priv->dirname_run; + } else { + if (!priv->dirname_etc) { + _LOGT("commit: cannot %s%s nmmeta file for %s as there is no /etc directory", + simulate ? "simulate " : "", + loaded_path ? "write" : "delete", + uuid); + nmmeta_errno = 0; + hard_failure = TRUE; + goto out; + } + storage_type = NMS_KEYFILE_STORAGE_TYPE_ETC; + dirname = priv->dirname_etc; + } + + if (simulate) { + nmmeta_errno = 0; + nmmeta_filename = nms_keyfile_nmmeta_filename(dirname, uuid, FALSE); + } else { + nmmeta_errno = nms_keyfile_nmmeta_write(dirname, + uuid, + loaded_path, + FALSE, + shadowed_storage, + &nmmeta_filename); + } + + _LOGT("commit: %s nmmeta file \"%s\"%s%s%s%s%s%s %s%s%s%s", + loaded_path ? "writing" : "deleting", + nmmeta_filename, + NM_PRINT_FMT_QUOTED(loaded_path, " (pointing to \"", loaded_path, "\")", ""), + NM_PRINT_FMT_QUOTED(shadowed_storage, " (shadows \"", shadowed_storage, "\")", ""), + simulate ? "simulated" : (nmmeta_errno < 0 ? "failed" : "succeeded"), + NM_PRINT_FMT_QUOTED(nmmeta_errno < 0, + " (", + nm_strerror_native(nm_errno_native(nmmeta_errno)), + ")", + "")); + + if (nmmeta_errno < 0) + goto out; + + storage = nm_sett_util_storages_lookup_by_filename(&priv->storages, nmmeta_filename); + + nm_assert(!storage + || (storage->is_meta_data && storage->storage_type == storage_type + && nm_streq(nms_keyfile_storage_get_uuid(storage), uuid))); + + if (loaded_path) { + if (!storage) { + storage = nms_keyfile_storage_new_tombstone(self, + uuid, + nmmeta_filename, + storage_type, + shadowed_storage); + nm_sett_util_storages_add_take(&priv->storages, storage); + } else { + g_free(storage->u.meta_data.shadowed_storage); + storage->u.meta_data.shadowed_storage = g_strdup(shadowed_storage); + } + + storage_result = g_object_ref(storage); + } else { + if (storage) + storage_result = nm_sett_util_storages_steal(&priv->storages, storage); + } out: - nm_assert (nmmeta_errno <= 0); - nm_assert (nmmeta_errno < 0 || !hard_failure); - nm_assert (nmmeta_errno == 0 || !storage_result); + nm_assert(nmmeta_errno <= 0); + nm_assert(nmmeta_errno < 0 || !hard_failure); + nm_assert(nmmeta_errno == 0 || !storage_result); - NM_SET_OUT (out_hard_failure, hard_failure); - NM_SET_OUT (out_storage, (NMSettingsStorage *) g_steal_pointer (&storage_result)); - return nmmeta_errno >= 0; + NM_SET_OUT(out_hard_failure, hard_failure); + NM_SET_OUT(out_storage, (NMSettingsStorage *) g_steal_pointer(&storage_result)); + return nmmeta_errno >= 0; } /*****************************************************************************/ static void -config_changed_cb (NMConfig *config, - NMConfigData *config_data, - NMConfigChangeFlags changes, - NMConfigData *old_data, - NMSKeyfilePlugin *self) +config_changed_cb(NMConfig * config, + NMConfigData * config_data, + NMConfigChangeFlags changes, + NMConfigData * old_data, + NMSKeyfilePlugin * self) { - gs_free char *old_value = NULL; - gs_free char *new_value = NULL; - - old_value = nm_config_data_get_value (old_data, NM_CONFIG_KEYFILE_GROUP_KEYFILE, NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES, NM_CONFIG_GET_VALUE_TYPE_SPEC); - new_value = nm_config_data_get_value (config_data, NM_CONFIG_KEYFILE_GROUP_KEYFILE, NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES, NM_CONFIG_GET_VALUE_TYPE_SPEC); - - if (!nm_streq0 (old_value, new_value)) - _nm_settings_plugin_emit_signal_unmanaged_specs_changed (NM_SETTINGS_PLUGIN (self)); + gs_free char *old_value = NULL; + gs_free char *new_value = NULL; + + old_value = nm_config_data_get_value(old_data, + NM_CONFIG_KEYFILE_GROUP_KEYFILE, + NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES, + NM_CONFIG_GET_VALUE_TYPE_SPEC); + new_value = nm_config_data_get_value(config_data, + NM_CONFIG_KEYFILE_GROUP_KEYFILE, + NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES, + NM_CONFIG_GET_VALUE_TYPE_SPEC); + + if (!nm_streq0(old_value, new_value)) + _nm_settings_plugin_emit_signal_unmanaged_specs_changed(NM_SETTINGS_PLUGIN(self)); } static GSList * -get_unmanaged_specs (NMSettingsPlugin *config) +get_unmanaged_specs(NMSettingsPlugin *config) { - NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (config); - gs_free char *value = NULL; - - value = nm_config_data_get_value (nm_config_get_data (priv->config), - NM_CONFIG_KEYFILE_GROUP_KEYFILE, - NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES, - NM_CONFIG_GET_VALUE_TYPE_SPEC); - return nm_match_spec_split (value); + NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(config); + gs_free char * value = NULL; + + value = nm_config_data_get_value(nm_config_get_data(priv->config), + NM_CONFIG_KEYFILE_GROUP_KEYFILE, + NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES, + NM_CONFIG_GET_VALUE_TYPE_SPEC); + return nm_match_spec_split(value); } /*****************************************************************************/ static void -nms_keyfile_plugin_init (NMSKeyfilePlugin *plugin) +nms_keyfile_plugin_init(NMSKeyfilePlugin *plugin) { - NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (plugin); - - priv->config = g_object_ref (nm_config_get ()); - - priv->storages = (NMSettUtilStorages) NM_SETT_UTIL_STORAGES_INIT (priv->storages, nms_keyfile_storage_destroy); - - /* dirname_libs are a set of read-only directories with lower priority than /etc or /run. - * There is nothing complicated about having multiple of such directories, so dirname_libs - * is a list (which currently only has at most one directory). */ - priv->dirname_libs[0] = nm_sd_utils_path_simplify (g_strdup (NM_KEYFILE_PATH_NAME_LIB), FALSE); - priv->dirname_libs[1] = NULL; - priv->dirname_run = nm_sd_utils_path_simplify (g_strdup (NM_KEYFILE_PATH_NAME_RUN), FALSE); - priv->dirname_etc = nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG, - NM_CONFIG_KEYFILE_GROUP_KEYFILE, - NM_CONFIG_KEYFILE_KEY_KEYFILE_PATH, - NM_CONFIG_GET_VALUE_STRIP); - if (priv->dirname_etc && priv->dirname_etc[0] == '\0') { - /* special case: configure an empty keyfile path so that NM has no writable keyfile - * directory. In this case, NM will only honor dirname_libs and dirname_run, meaning - * it cannot persist profile to non-volatile memory. */ - nm_clear_g_free (&priv->dirname_etc); - } else if (!priv->dirname_etc || priv->dirname_etc[0] != '/') { - /* either invalid path or unspecified. Use the default. */ - g_free (priv->dirname_etc); - priv->dirname_etc = nm_sd_utils_path_simplify (g_strdup (NM_KEYFILE_PATH_NAME_ETC_DEFAULT), FALSE); - } else - nm_sd_utils_path_simplify (priv->dirname_etc, FALSE); - - /* no duplicates */ - if (NM_IN_STRSET (priv->dirname_libs[0], priv->dirname_etc, - priv->dirname_run)) - nm_clear_g_free (&priv->dirname_libs[0]); - if (NM_IN_STRSET (priv->dirname_etc, priv->dirname_run)) - nm_clear_g_free (&priv->dirname_etc); - - nm_assert (!priv->dirname_libs[0] || priv->dirname_libs[0][0] == '/'); - nm_assert (!priv->dirname_etc || priv->dirname_etc[0] == '/'); - nm_assert ( priv->dirname_run && priv->dirname_run[0] == '/'); + NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(plugin); + + priv->config = g_object_ref(nm_config_get()); + + priv->storages = (NMSettUtilStorages) NM_SETT_UTIL_STORAGES_INIT(priv->storages, + nms_keyfile_storage_destroy); + + /* dirname_libs are a set of read-only directories with lower priority than /etc or /run. + * There is nothing complicated about having multiple of such directories, so dirname_libs + * is a list (which currently only has at most one directory). */ + priv->dirname_libs[0] = nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_LIB), FALSE); + priv->dirname_libs[1] = NULL; + priv->dirname_run = nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_RUN), FALSE); + priv->dirname_etc = nm_config_data_get_value(NM_CONFIG_GET_DATA_ORIG, + NM_CONFIG_KEYFILE_GROUP_KEYFILE, + NM_CONFIG_KEYFILE_KEY_KEYFILE_PATH, + NM_CONFIG_GET_VALUE_STRIP); + if (priv->dirname_etc && priv->dirname_etc[0] == '\0') { + /* special case: configure an empty keyfile path so that NM has no writable keyfile + * directory. In this case, NM will only honor dirname_libs and dirname_run, meaning + * it cannot persist profile to non-volatile memory. */ + nm_clear_g_free(&priv->dirname_etc); + } else if (!priv->dirname_etc || priv->dirname_etc[0] != '/') { + /* either invalid path or unspecified. Use the default. */ + g_free(priv->dirname_etc); + priv->dirname_etc = + nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_ETC_DEFAULT), FALSE); + } else + nm_sd_utils_path_simplify(priv->dirname_etc, FALSE); + + /* no duplicates */ + if (NM_IN_STRSET(priv->dirname_libs[0], priv->dirname_etc, priv->dirname_run)) + nm_clear_g_free(&priv->dirname_libs[0]); + if (NM_IN_STRSET(priv->dirname_etc, priv->dirname_run)) + nm_clear_g_free(&priv->dirname_etc); + + nm_assert(!priv->dirname_libs[0] || priv->dirname_libs[0][0] == '/'); + nm_assert(!priv->dirname_etc || priv->dirname_etc[0] == '/'); + nm_assert(priv->dirname_run && priv->dirname_run[0] == '/'); } static void -constructed (GObject *object) +constructed(GObject *object) { - NMSKeyfilePlugin *self = NMS_KEYFILE_PLUGIN (object); - NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (self); - - G_OBJECT_CLASS (nms_keyfile_plugin_parent_class)->constructed (object); - - if (nm_config_data_has_value (nm_config_get_data_orig (priv->config), - NM_CONFIG_KEYFILE_GROUP_KEYFILE, - NM_CONFIG_KEYFILE_KEY_KEYFILE_HOSTNAME, - NM_CONFIG_GET_VALUE_RAW)) - _LOGW ("'hostname' option is deprecated and has no effect"); - - if (nm_config_data_has_value (nm_config_get_data_orig (priv->config), - NM_CONFIG_KEYFILE_GROUP_MAIN, - NM_CONFIG_KEYFILE_KEY_MAIN_MONITOR_CONNECTION_FILES, - NM_CONFIG_GET_VALUE_RAW)) - _LOGW ("'monitor-connection-files' option is deprecated and has no effect"); - - g_signal_connect (G_OBJECT (priv->config), - NM_CONFIG_SIGNAL_CONFIG_CHANGED, - G_CALLBACK (config_changed_cb), - self); + NMSKeyfilePlugin * self = NMS_KEYFILE_PLUGIN(object); + NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(self); + + G_OBJECT_CLASS(nms_keyfile_plugin_parent_class)->constructed(object); + + if (nm_config_data_has_value(nm_config_get_data_orig(priv->config), + NM_CONFIG_KEYFILE_GROUP_KEYFILE, + NM_CONFIG_KEYFILE_KEY_KEYFILE_HOSTNAME, + NM_CONFIG_GET_VALUE_RAW)) + _LOGW("'hostname' option is deprecated and has no effect"); + + if (nm_config_data_has_value(nm_config_get_data_orig(priv->config), + NM_CONFIG_KEYFILE_GROUP_MAIN, + NM_CONFIG_KEYFILE_KEY_MAIN_MONITOR_CONNECTION_FILES, + NM_CONFIG_GET_VALUE_RAW)) + _LOGW("'monitor-connection-files' option is deprecated and has no effect"); + + g_signal_connect(G_OBJECT(priv->config), + NM_CONFIG_SIGNAL_CONFIG_CHANGED, + G_CALLBACK(config_changed_cb), + self); } NMSKeyfilePlugin * -nms_keyfile_plugin_new (void) +nms_keyfile_plugin_new(void) { - return g_object_new (NMS_TYPE_KEYFILE_PLUGIN, NULL); + return g_object_new(NMS_TYPE_KEYFILE_PLUGIN, NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMSKeyfilePlugin *self = NMS_KEYFILE_PLUGIN (object); - NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE (self); + NMSKeyfilePlugin * self = NMS_KEYFILE_PLUGIN(object); + NMSKeyfilePluginPrivate *priv = NMS_KEYFILE_PLUGIN_GET_PRIVATE(self); - if (priv->config) - g_signal_handlers_disconnect_by_func (priv->config, config_changed_cb, object); + if (priv->config) + g_signal_handlers_disconnect_by_func(priv->config, config_changed_cb, object); - nm_sett_util_storages_clear (&priv->storages); + nm_sett_util_storages_clear(&priv->storages); - nm_clear_g_free (&priv->dirname_libs[0]); - nm_clear_g_free (&priv->dirname_etc); - nm_clear_g_free (&priv->dirname_run); + nm_clear_g_free(&priv->dirname_libs[0]); + nm_clear_g_free(&priv->dirname_etc); + nm_clear_g_free(&priv->dirname_run); - g_clear_object (&priv->config); + g_clear_object(&priv->config); - G_OBJECT_CLASS (nms_keyfile_plugin_parent_class)->dispose (object); + G_OBJECT_CLASS(nms_keyfile_plugin_parent_class)->dispose(object); } static void -nms_keyfile_plugin_class_init (NMSKeyfilePluginClass *klass) +nms_keyfile_plugin_class_init(NMSKeyfilePluginClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMSettingsPluginClass *plugin_class = NM_SETTINGS_PLUGIN_CLASS (klass); - - object_class->constructed = constructed; - object_class->dispose = dispose; - - plugin_class->plugin_name = "keyfile"; - plugin_class->get_unmanaged_specs = get_unmanaged_specs; - plugin_class->reload_connections = reload_connections; - plugin_class->load_connections = load_connections; - plugin_class->add_connection = add_connection; - plugin_class->update_connection = update_connection; - plugin_class->delete_connection = delete_connection; + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingsPluginClass *plugin_class = NM_SETTINGS_PLUGIN_CLASS(klass); + + object_class->constructed = constructed; + object_class->dispose = dispose; + + plugin_class->plugin_name = "keyfile"; + plugin_class->get_unmanaged_specs = get_unmanaged_specs; + plugin_class->reload_connections = reload_connections; + plugin_class->load_connections = load_connections; + plugin_class->add_connection = add_connection; + plugin_class->update_connection = update_connection; + plugin_class->delete_connection = delete_connection; } diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.h b/src/settings/plugins/keyfile/nms-keyfile-plugin.h index 603f0c26..b52fe9db 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-plugin.h +++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 Novell, Inc. * Copyright (C) 2008 - 2011 Red Hat, Inc. @@ -12,52 +12,56 @@ #include "nms-keyfile-utils.h" -#define NMS_TYPE_KEYFILE_PLUGIN (nms_keyfile_plugin_get_type ()) -#define NMS_KEYFILE_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMS_TYPE_KEYFILE_PLUGIN, NMSKeyfilePlugin)) -#define NMS_KEYFILE_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMS_TYPE_KEYFILE_PLUGIN, NMSKeyfilePluginClass)) -#define NMS_IS_KEYFILE_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMS_TYPE_KEYFILE_PLUGIN)) -#define NMS_IS_KEYFILE_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMS_TYPE_KEYFILE_PLUGIN)) -#define NMS_KEYFILE_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMS_TYPE_KEYFILE_PLUGIN, NMSKeyfilePluginClass)) +#define NMS_TYPE_KEYFILE_PLUGIN (nms_keyfile_plugin_get_type()) +#define NMS_KEYFILE_PLUGIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NMS_TYPE_KEYFILE_PLUGIN, NMSKeyfilePlugin)) +#define NMS_KEYFILE_PLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NMS_TYPE_KEYFILE_PLUGIN, NMSKeyfilePluginClass)) +#define NMS_IS_KEYFILE_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMS_TYPE_KEYFILE_PLUGIN)) +#define NMS_IS_KEYFILE_PLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NMS_TYPE_KEYFILE_PLUGIN)) +#define NMS_KEYFILE_PLUGIN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NMS_TYPE_KEYFILE_PLUGIN, NMSKeyfilePluginClass)) -typedef struct _NMSKeyfilePlugin NMSKeyfilePlugin; +typedef struct _NMSKeyfilePlugin NMSKeyfilePlugin; typedef struct _NMSKeyfilePluginClass NMSKeyfilePluginClass; -GType nms_keyfile_plugin_get_type (void); - -NMSKeyfilePlugin *nms_keyfile_plugin_new (void); - -gboolean nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self, - NMConnection *connection, - gboolean in_memory, - gboolean is_nm_generated, - gboolean is_volatile, - gboolean is_external, - const char *shadowed_storage, - gboolean shadowed_owned, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error); - -gboolean nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self, - NMSettingsStorage *storage, - NMConnection *connection, - gboolean is_nm_generated, - gboolean is_volatile, - gboolean is_external, - const char *shadowed_storage, - gboolean shadowed_owned, - gboolean force_rename, - NMSettingsStorage **out_storage, - NMConnection **out_connection, - GError **error); - -gboolean nms_keyfile_plugin_set_nmmeta_tombstone (NMSKeyfilePlugin *self, - gboolean simulate, - const char *uuid, - gboolean in_memory, - gboolean set, - const char *shadowed_storage, - NMSettingsStorage **out_storage, - gboolean *out_hard_failure); +GType nms_keyfile_plugin_get_type(void); + +NMSKeyfilePlugin *nms_keyfile_plugin_new(void); + +gboolean nms_keyfile_plugin_add_connection(NMSKeyfilePlugin * self, + NMConnection * connection, + gboolean in_memory, + gboolean is_nm_generated, + gboolean is_volatile, + gboolean is_external, + const char * shadowed_storage, + gboolean shadowed_owned, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error); + +gboolean nms_keyfile_plugin_update_connection(NMSKeyfilePlugin * self, + NMSettingsStorage * storage, + NMConnection * connection, + gboolean is_nm_generated, + gboolean is_volatile, + gboolean is_external, + const char * shadowed_storage, + gboolean shadowed_owned, + gboolean force_rename, + NMSettingsStorage **out_storage, + NMConnection ** out_connection, + GError ** error); + +gboolean nms_keyfile_plugin_set_nmmeta_tombstone(NMSKeyfilePlugin * self, + gboolean simulate, + const char * uuid, + gboolean in_memory, + gboolean set, + const char * shadowed_storage, + NMSettingsStorage **out_storage, + gboolean * out_hard_failure); #endif /* __NMS_KEYFILE_PLUGIN_H__ */ diff --git a/src/settings/plugins/keyfile/nms-keyfile-reader.c b/src/settings/plugins/keyfile/nms-keyfile-reader.c index 0e9ad5fa..669f22fd 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-reader.c +++ b/src/settings/plugins/keyfile/nms-keyfile-reader.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 Red Hat, Inc. */ @@ -17,211 +17,221 @@ /*****************************************************************************/ static const char * -_fmt_warn (const NMKeyfileHandlerData *handler_data, char **out_message) +_fmt_warn(const NMKeyfileHandlerData *handler_data, char **out_message) { - 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) { - if (property_name && !strcmp (group, setting_name)) - res = g_strdup_printf ("%s.%s: %s", group, property_name, message); - else if (property_name) - res = g_strdup_printf ("%s/%s.%s: %s", group, setting_name, property_name, message); - else if (!strcmp (group, setting_name)) - res = g_strdup_printf ("%s: %s", group, message); - else - res = g_strdup_printf ("%s/%s: %s", group, setting_name, message); - } else - res = g_strdup_printf ("%s: %s", group, message); - *out_message = res; - return res; - } - - return message; + 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) { + if (property_name && !strcmp(group, setting_name)) + res = g_strdup_printf("%s.%s: %s", group, property_name, message); + else if (property_name) + res = g_strdup_printf("%s/%s.%s: %s", group, setting_name, property_name, message); + else if (!strcmp(group, setting_name)) + res = g_strdup_printf("%s: %s", group, message); + else + res = g_strdup_printf("%s/%s: %s", group, setting_name, message); + } else + res = g_strdup_printf("%s: %s", group, message); + *out_message = res; + return res; + } + + return message; } typedef struct { - bool verbose; + bool verbose; } ReadInfo; static gboolean -_handler_read (GKeyFile *keyfile, - NMConnection *connection, - NMKeyfileHandlerType handler_type, - NMKeyfileHandlerData *handler_data, - void *user_data) +_handler_read(GKeyFile * keyfile, + NMConnection * connection, + NMKeyfileHandlerType handler_type, + NMKeyfileHandlerData *handler_data, + void * user_data) { - const ReadInfo *read_info = user_data; - - if (handler_type == NM_KEYFILE_HANDLER_TYPE_WARN) { - const NMKeyfileHandlerDataWarn *warn_data = &handler_data->warn; - NMLogLevel level; - char *message_free = NULL; - - if (!read_info->verbose) - return TRUE; - - if (warn_data->severity > NM_KEYFILE_WARN_SEVERITY_WARN) - level = LOGL_ERR; - else if (warn_data->severity >= NM_KEYFILE_WARN_SEVERITY_WARN) - level = LOGL_WARN; - else if (warn_data->severity == NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE) - level = LOGL_WARN; - else - level = LOGL_INFO; - - nm_log (level, - LOGD_SETTINGS, - NULL, - nm_connection_get_uuid (connection), - "keyfile: %s", - _fmt_warn (handler_data, - &message_free)); - g_free (message_free); - return TRUE; - } - - return FALSE; + const ReadInfo *read_info = user_data; + + if (handler_type == NM_KEYFILE_HANDLER_TYPE_WARN) { + const NMKeyfileHandlerDataWarn *warn_data = &handler_data->warn; + NMLogLevel level; + char * message_free = NULL; + + if (!read_info->verbose) + return TRUE; + + if (warn_data->severity > NM_KEYFILE_WARN_SEVERITY_WARN) + level = LOGL_ERR; + else if (warn_data->severity >= NM_KEYFILE_WARN_SEVERITY_WARN) + level = LOGL_WARN; + else if (warn_data->severity == NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE) + level = LOGL_WARN; + else + level = LOGL_INFO; + + nm_log(level, + LOGD_SETTINGS, + NULL, + nm_connection_get_uuid(connection), + "keyfile: %s", + _fmt_warn(handler_data, &message_free)); + g_free(message_free); + return TRUE; + } + + return FALSE; } NMConnection * -nms_keyfile_reader_from_keyfile (GKeyFile *key_file, - const char *filename, - const char *base_dir, - const char *profile_dir, - gboolean verbose, - GError **error) +nms_keyfile_reader_from_keyfile(GKeyFile * key_file, + const char *filename, + const char *base_dir, + const char *profile_dir, + gboolean verbose, + GError ** error) { - NMConnection *connection; - ReadInfo read_info = { - .verbose = verbose, - }; - gs_free char *base_dir_free = NULL; - gs_free char *profile_filename_free = NULL; - gs_free char *filename_id = NULL; - const char *profile_filename = NULL; - - nm_assert (filename && filename[0]); - nm_assert (!base_dir || base_dir[0] == '/'); - nm_assert (!profile_dir || profile_dir[0] == '/'); - - if (base_dir) - nm_assert (!strchr (filename, '/')); - else { - const char *s; - - nm_assert (filename[0] == '/'); - - /* @base_dir may be NULL, in which case @filename must be an absolute path, - * and the directory is taken as the @base_dir. */ - s = strrchr (filename, '/'); - base_dir = nm_strndup_a (255, filename, s - filename, &base_dir_free); - if ( !profile_dir - || nm_streq (base_dir, profile_dir)) - profile_filename = filename; - filename = &s[1]; - } - - connection = nm_keyfile_read (key_file, base_dir, NM_KEYFILE_HANDLER_FLAGS_NONE, _handler_read, &read_info, error); - if (!connection) - return NULL; - - if (g_str_has_suffix (filename, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)) { - gsize l = strlen (filename); - - if (l > NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)) - filename_id = g_strndup (filename, l - NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)); - } - - nm_keyfile_read_ensure_id (connection, filename_id ?: filename); - - if (!profile_filename) { - profile_filename_free = g_build_filename (profile_dir ?: base_dir, filename, NULL); - profile_filename = profile_filename_free; - } - nm_keyfile_read_ensure_uuid (connection, profile_filename); - - return connection; + NMConnection *connection; + ReadInfo read_info = { + .verbose = verbose, + }; + gs_free char *base_dir_free = NULL; + gs_free char *profile_filename_free = NULL; + gs_free char *filename_id = NULL; + const char * profile_filename = NULL; + + nm_assert(filename && filename[0]); + nm_assert(!base_dir || base_dir[0] == '/'); + nm_assert(!profile_dir || profile_dir[0] == '/'); + + if (base_dir) + nm_assert(!strchr(filename, '/')); + else { + const char *s; + + nm_assert(filename[0] == '/'); + + /* @base_dir may be NULL, in which case @filename must be an absolute path, + * and the directory is taken as the @base_dir. */ + s = strrchr(filename, '/'); + base_dir = nm_strndup_a(255, filename, s - filename, &base_dir_free); + if (!profile_dir || nm_streq(base_dir, profile_dir)) + profile_filename = filename; + filename = &s[1]; + } + + connection = nm_keyfile_read(key_file, + base_dir, + NM_KEYFILE_HANDLER_FLAGS_NONE, + _handler_read, + &read_info, + error); + if (!connection) + return NULL; + + if (g_str_has_suffix(filename, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)) { + gsize l = strlen(filename); + + if (l > NM_STRLEN(NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)) + filename_id = g_strndup(filename, l - NM_STRLEN(NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)); + } + + nm_keyfile_read_ensure_id(connection, filename_id ?: filename); + + if (!profile_filename) { + profile_filename_free = g_build_filename(profile_dir ?: base_dir, filename, NULL); + profile_filename = profile_filename_free; + } + nm_keyfile_read_ensure_uuid(connection, profile_filename); + + return connection; } NMConnection * -nms_keyfile_reader_from_file (const char *full_filename, - const char *profile_dir, - 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) +nms_keyfile_reader_from_file(const char * full_filename, + const char * profile_dir, + 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) { - gs_unref_keyfile GKeyFile *key_file = NULL; - NMConnection *connection = NULL; - GError *verify_error = NULL; - - nm_assert (full_filename && full_filename[0] == '/'); - nm_assert (!profile_dir || profile_dir[0] == '/'); - - 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); - NM_SET_OUT (out_shadowed_owned, NM_TERNARY_DEFAULT); - - if (!nms_keyfile_utils_check_file_permissions (NMS_KEYFILE_FILETYPE_KEYFILE, - full_filename, - out_stat, - error)) - return NULL; - - key_file = g_key_file_new (); - if (!g_key_file_load_from_file (key_file, full_filename, G_KEY_FILE_NONE, error)) - return NULL; - - connection = nms_keyfile_reader_from_keyfile (key_file, full_filename, NULL, profile_dir, TRUE, error); - if (!connection) - return NULL; - - /* Normalize and verify the connection */ - if (!nm_connection_normalize (connection, NULL, NULL, &verify_error)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "invalid connection: %s", - verify_error->message); - g_clear_error (&verify_error); - g_object_unref (connection); - connection = NULL; - } - - NM_SET_OUT (out_is_nm_generated, nm_key_file_get_boolean (key_file, - NM_KEYFILE_GROUP_NMMETA, - NM_KEYFILE_KEY_NMMETA_NM_GENERATED, - NM_TERNARY_DEFAULT)); - - NM_SET_OUT (out_is_volatile, nm_key_file_get_boolean (key_file, - NM_KEYFILE_GROUP_NMMETA, - 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, - NULL)); - - NM_SET_OUT (out_shadowed_owned, nm_key_file_get_boolean (key_file, - NM_KEYFILE_GROUP_NMMETA, - NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED, - NM_TERNARY_DEFAULT)); - - return connection; + nm_auto_unref_keyfile GKeyFile *key_file = NULL; + NMConnection * connection = NULL; + GError * verify_error = NULL; + + nm_assert(full_filename && full_filename[0] == '/'); + nm_assert(!profile_dir || profile_dir[0] == '/'); + + 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); + NM_SET_OUT(out_shadowed_owned, NM_TERNARY_DEFAULT); + + if (!nms_keyfile_utils_check_file_permissions(NMS_KEYFILE_FILETYPE_KEYFILE, + full_filename, + out_stat, + error)) + return NULL; + + key_file = g_key_file_new(); + if (!g_key_file_load_from_file(key_file, full_filename, G_KEY_FILE_NONE, error)) + return NULL; + + connection = + nms_keyfile_reader_from_keyfile(key_file, full_filename, NULL, profile_dir, TRUE, error); + if (!connection) + return NULL; + + /* Normalize and verify the connection */ + if (!nm_connection_normalize(connection, NULL, NULL, &verify_error)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid connection: %s", + verify_error->message); + g_clear_error(&verify_error); + g_object_unref(connection); + connection = NULL; + } + + NM_SET_OUT(out_is_nm_generated, + nm_key_file_get_boolean(key_file, + NM_KEYFILE_GROUP_NMMETA, + NM_KEYFILE_KEY_NMMETA_NM_GENERATED, + NM_TERNARY_DEFAULT)); + + NM_SET_OUT(out_is_volatile, + nm_key_file_get_boolean(key_file, + NM_KEYFILE_GROUP_NMMETA, + 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, + NULL)); + + NM_SET_OUT(out_shadowed_owned, + nm_key_file_get_boolean(key_file, + NM_KEYFILE_GROUP_NMMETA, + NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED, + NM_TERNARY_DEFAULT)); + + return connection; } - diff --git a/src/settings/plugins/keyfile/nms-keyfile-reader.h b/src/settings/plugins/keyfile/nms-keyfile-reader.h index 828715fa..e7853cc6 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-reader.h +++ b/src/settings/plugins/keyfile/nms-keyfile-reader.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 Novell, Inc. * Copyright (C) 2008 Red Hat, Inc. @@ -9,23 +9,23 @@ #include "nm-connection.h" -NMConnection *nms_keyfile_reader_from_keyfile (GKeyFile *key_file, - const char *filename, - const char *base_dir, - const char *profile_dir, - gboolean verbose, - GError **error); +NMConnection *nms_keyfile_reader_from_keyfile(GKeyFile * key_file, + const char *filename, + const char *base_dir, + const char *profile_dir, + gboolean verbose, + GError ** error); struct stat; -NMConnection *nms_keyfile_reader_from_file (const char *full_filename, - const char *profile_dir, - 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); +NMConnection *nms_keyfile_reader_from_file(const char * full_filename, + const char * profile_dir, + 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); #endif /* __NMS_KEYFILE_READER_H__ */ diff --git a/src/settings/plugins/keyfile/nms-keyfile-storage.c b/src/settings/plugins/keyfile/nms-keyfile-storage.c index 15f20295..9cd62780 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-storage.c +++ b/src/settings/plugins/keyfile/nms-keyfile-storage.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -14,222 +14,225 @@ /*****************************************************************************/ struct _NMSKeyfileStorageClass { - NMSettingsStorageClass parent; + NMSettingsStorageClass parent; }; -G_DEFINE_TYPE (NMSKeyfileStorage, nms_keyfile_storage, NM_TYPE_SETTINGS_STORAGE) +G_DEFINE_TYPE(NMSKeyfileStorage, nms_keyfile_storage, NM_TYPE_SETTINGS_STORAGE) /*****************************************************************************/ void -nms_keyfile_storage_copy_content (NMSKeyfileStorage *dst, - const NMSKeyfileStorage *src) +nms_keyfile_storage_copy_content(NMSKeyfileStorage *dst, const NMSKeyfileStorage *src) { - nm_assert (src != dst); - nm_assert (nm_streq (nms_keyfile_storage_get_uuid (dst), nms_keyfile_storage_get_uuid (src))); - nm_assert ( nms_keyfile_storage_get_filename (dst) - && nm_streq (nms_keyfile_storage_get_filename (dst), nms_keyfile_storage_get_filename (src))); - nm_assert (dst->storage_type == src->storage_type); - nm_assert (dst->is_meta_data == src->is_meta_data); - - if (dst->is_meta_data) { - gs_free char *shadowed_storage_to_free = NULL; - - shadowed_storage_to_free = g_steal_pointer (&dst->u.meta_data.shadowed_storage); - dst->u.meta_data = src->u.meta_data; - dst->u.meta_data.shadowed_storage = g_strdup (dst->u.meta_data.shadowed_storage); - } else { - gs_unref_object NMConnection *connection_to_free = NULL; - gs_free char *shadowed_storage_to_free = NULL; - - connection_to_free = g_steal_pointer (&dst->u.conn_data.connection); - shadowed_storage_to_free = g_steal_pointer (&dst->u.conn_data.shadowed_storage); - dst->u.conn_data = src->u.conn_data; - nm_g_object_ref (dst->u.conn_data.connection); - dst->u.conn_data.shadowed_storage = g_strdup (dst->u.conn_data.shadowed_storage); - } + nm_assert(src != dst); + nm_assert(nm_streq(nms_keyfile_storage_get_uuid(dst), nms_keyfile_storage_get_uuid(src))); + nm_assert( + nms_keyfile_storage_get_filename(dst) + && nm_streq(nms_keyfile_storage_get_filename(dst), nms_keyfile_storage_get_filename(src))); + nm_assert(dst->storage_type == src->storage_type); + nm_assert(dst->is_meta_data == src->is_meta_data); + + if (dst->is_meta_data) { + gs_free char *shadowed_storage_to_free = NULL; + + shadowed_storage_to_free = g_steal_pointer(&dst->u.meta_data.shadowed_storage); + dst->u.meta_data = src->u.meta_data; + dst->u.meta_data.shadowed_storage = g_strdup(dst->u.meta_data.shadowed_storage); + } else { + gs_unref_object NMConnection *connection_to_free = NULL; + gs_free char * shadowed_storage_to_free = NULL; + + connection_to_free = g_steal_pointer(&dst->u.conn_data.connection); + shadowed_storage_to_free = g_steal_pointer(&dst->u.conn_data.shadowed_storage); + dst->u.conn_data = src->u.conn_data; + nm_g_object_ref(dst->u.conn_data.connection); + dst->u.conn_data.shadowed_storage = g_strdup(dst->u.conn_data.shadowed_storage); + } } NMConnection * -nms_keyfile_storage_steal_connection (NMSKeyfileStorage *self) +nms_keyfile_storage_steal_connection(NMSKeyfileStorage *self) { - nm_assert (NMS_IS_KEYFILE_STORAGE (self)); - nm_assert ( self->is_meta_data - || NM_IS_CONNECTION (self->u.conn_data.connection)); + nm_assert(NMS_IS_KEYFILE_STORAGE(self)); + nm_assert(self->is_meta_data || NM_IS_CONNECTION(self->u.conn_data.connection)); - return self->is_meta_data - ? NULL - : g_steal_pointer (&self->u.conn_data.connection); + return self->is_meta_data ? NULL : g_steal_pointer(&self->u.conn_data.connection); } /*****************************************************************************/ static int -cmp_fcn (const NMSKeyfileStorage *a, - const NMSKeyfileStorage *b) +cmp_fcn(const NMSKeyfileStorage *a, const NMSKeyfileStorage *b) { - nm_assert (NMS_IS_KEYFILE_STORAGE (a)); - nm_assert (NMS_IS_KEYFILE_STORAGE (b)); - nm_assert (a != b); - - /* sort by storage-type, which also has a numeric value according to their - * (inverse) priority. */ - NM_CMP_FIELD_UNSAFE (b, a, storage_type); - - /* meta-data is more important. */ - NM_CMP_FIELD_UNSAFE (a, b, is_meta_data); - - if (a->is_meta_data) { - nm_assert (nm_streq (nms_keyfile_storage_get_filename (a), nms_keyfile_storage_get_filename (b))); - NM_CMP_FIELD_UNSAFE (a, b, u.meta_data.is_tombstone); - } else { - /* newer files are more important. */ - NM_CMP_FIELD (a, b, u.conn_data.stat_mtime.tv_sec); - NM_CMP_FIELD (a, b, u.conn_data.stat_mtime.tv_nsec); - - NM_CMP_DIRECT_STRCMP (nms_keyfile_storage_get_filename (a), nms_keyfile_storage_get_filename (b)); - } - - return 0; + nm_assert(NMS_IS_KEYFILE_STORAGE(a)); + nm_assert(NMS_IS_KEYFILE_STORAGE(b)); + nm_assert(a != b); + + /* sort by storage-type, which also has a numeric value according to their + * (inverse) priority. */ + NM_CMP_FIELD_UNSAFE(b, a, storage_type); + + /* meta-data is more important. */ + NM_CMP_FIELD_UNSAFE(a, b, is_meta_data); + + if (a->is_meta_data) { + nm_assert( + nm_streq(nms_keyfile_storage_get_filename(a), nms_keyfile_storage_get_filename(b))); + NM_CMP_FIELD_UNSAFE(a, b, u.meta_data.is_tombstone); + } else { + /* newer files are more important. */ + NM_CMP_FIELD(a, b, u.conn_data.stat_mtime.tv_sec); + NM_CMP_FIELD(a, b, u.conn_data.stat_mtime.tv_nsec); + + NM_CMP_DIRECT_STRCMP(nms_keyfile_storage_get_filename(a), + nms_keyfile_storage_get_filename(b)); + } + + return 0; } /*****************************************************************************/ static void -nms_keyfile_storage_init (NMSKeyfileStorage *self) -{ -} +nms_keyfile_storage_init(NMSKeyfileStorage *self) +{} static NMSKeyfileStorage * -_storage_new (NMSKeyfilePlugin *plugin, - const char *uuid, - const char *filename, - gboolean is_meta_data, - NMSKeyfileStorageType storage_type) +_storage_new(NMSKeyfilePlugin * plugin, + const char * uuid, + const char * filename, + gboolean is_meta_data, + NMSKeyfileStorageType storage_type) { - NMSKeyfileStorage *self; + NMSKeyfileStorage *self; - nm_assert (NMS_IS_KEYFILE_PLUGIN (plugin)); - nm_assert (nm_utils_is_uuid (uuid)); - nm_assert (filename && filename[0] == '/'); + nm_assert(NMS_IS_KEYFILE_PLUGIN(plugin)); + nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(filename && filename[0] == '/'); - self = g_object_new (NMS_TYPE_KEYFILE_STORAGE, - NM_SETTINGS_STORAGE_PLUGIN, plugin, - NM_SETTINGS_STORAGE_UUID, uuid, - NM_SETTINGS_STORAGE_FILENAME, filename, - NULL); + self = g_object_new(NMS_TYPE_KEYFILE_STORAGE, + NM_SETTINGS_STORAGE_PLUGIN, + plugin, + NM_SETTINGS_STORAGE_UUID, + uuid, + NM_SETTINGS_STORAGE_FILENAME, + filename, + NULL); - *((bool *) &self->is_meta_data) = is_meta_data; - *((NMSKeyfileStorageType *) &self->storage_type) = storage_type; + *((bool *) &self->is_meta_data) = is_meta_data; + *((NMSKeyfileStorageType *) &self->storage_type) = storage_type; - return self; + return self; } NMSKeyfileStorage * -nms_keyfile_storage_new_tombstone (NMSKeyfilePlugin *plugin, - const char *uuid, - const char *filename, - NMSKeyfileStorageType storage_type, - const char *shadowed_storage) +nms_keyfile_storage_new_tombstone(NMSKeyfilePlugin * plugin, + const char * uuid, + const char * filename, + NMSKeyfileStorageType storage_type, + const char * shadowed_storage) { - NMSKeyfileStorage *self; - - nm_assert (nm_utils_is_uuid (uuid)); - nm_assert (filename && filename[0] == '/'); - nm_assert (nms_keyfile_nmmeta_check_filename (filename, NULL)); - nm_assert (NM_IN_SET (storage_type, NMS_KEYFILE_STORAGE_TYPE_ETC, - NMS_KEYFILE_STORAGE_TYPE_RUN)); - - self = _storage_new (plugin, uuid, filename, TRUE, storage_type); - self->u.meta_data.is_tombstone = TRUE; - if (storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN) - self->u.meta_data.shadowed_storage = g_strdup (shadowed_storage); - return self; + NMSKeyfileStorage *self; + + nm_assert(nm_utils_is_uuid(uuid)); + nm_assert(filename && filename[0] == '/'); + nm_assert(nms_keyfile_nmmeta_check_filename(filename, NULL)); + nm_assert(NM_IN_SET(storage_type, NMS_KEYFILE_STORAGE_TYPE_ETC, NMS_KEYFILE_STORAGE_TYPE_RUN)); + + self = _storage_new(plugin, uuid, filename, TRUE, storage_type); + self->u.meta_data.is_tombstone = TRUE; + if (storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN) + self->u.meta_data.shadowed_storage = g_strdup(shadowed_storage); + return self; } NMSKeyfileStorage * -nms_keyfile_storage_new_connection (NMSKeyfilePlugin *plugin, - NMConnection *connection_take /* pass reference */, - const char *filename, - 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) +nms_keyfile_storage_new_connection(NMSKeyfilePlugin * plugin, + NMConnection * connection_take /* pass reference */, + const char * filename, + 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) { - NMSKeyfileStorage *self; - - nm_assert (NMS_IS_KEYFILE_PLUGIN (plugin)); - nm_assert (NM_IS_CONNECTION (connection_take)); - nm_assert (_nm_connection_verify (connection_take, NULL) == NM_SETTING_VERIFY_SUCCESS); - nm_assert (filename && filename[0] == '/'); - nm_assert ( storage_type >= NMS_KEYFILE_STORAGE_TYPE_RUN - && storage_type <= _NMS_KEYFILE_STORAGE_TYPE_LIB_LAST); - nmtst_connection_assert_unchanging (connection_take); - - self = _storage_new (plugin, nm_connection_get_uuid (connection_take), filename, FALSE, storage_type); - - self->u.conn_data.connection = connection_take; /* take reference. */ - - self->u.conn_data.shadowed_storage = g_strdup (shadowed_storage); - - if (stat_mtime) - self->u.conn_data.stat_mtime = *stat_mtime; - - 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); - } - - return self; + NMSKeyfileStorage *self; + + nm_assert(NMS_IS_KEYFILE_PLUGIN(plugin)); + nm_assert(NM_IS_CONNECTION(connection_take)); + nm_assert(_nm_connection_verify(connection_take, NULL) == NM_SETTING_VERIFY_SUCCESS); + nm_assert(filename && filename[0] == '/'); + nm_assert(storage_type >= NMS_KEYFILE_STORAGE_TYPE_RUN + && storage_type <= _NMS_KEYFILE_STORAGE_TYPE_LIB_LAST); + nmtst_connection_assert_unchanging(connection_take); + + self = _storage_new(plugin, + nm_connection_get_uuid(connection_take), + filename, + FALSE, + storage_type); + + self->u.conn_data.connection = connection_take; /* take reference. */ + + self->u.conn_data.shadowed_storage = g_strdup(shadowed_storage); + + if (stat_mtime) + self->u.conn_data.stat_mtime = *stat_mtime; + + 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); + } + + return self; } static void -_storage_clear (NMSKeyfileStorage *self) +_storage_clear(NMSKeyfileStorage *self) { - c_list_unlink (&self->parent._storage_lst); - c_list_unlink (&self->parent._storage_by_uuid_lst); - if (self->is_meta_data) - nm_clear_g_free (&self->u.meta_data.shadowed_storage); - else { - g_clear_object (&self->u.conn_data.connection); - nm_clear_g_free (&self->u.conn_data.shadowed_storage); - self->u.conn_data.shadowed_owned = FALSE; - } + c_list_unlink(&self->parent._storage_lst); + c_list_unlink(&self->parent._storage_by_uuid_lst); + if (self->is_meta_data) + nm_clear_g_free(&self->u.meta_data.shadowed_storage); + else { + g_clear_object(&self->u.conn_data.connection); + nm_clear_g_free(&self->u.conn_data.shadowed_storage); + self->u.conn_data.shadowed_owned = FALSE; + } } static void -dispose (GObject *object) +dispose(GObject *object) { - NMSKeyfileStorage *self = NMS_KEYFILE_STORAGE (object); + NMSKeyfileStorage *self = NMS_KEYFILE_STORAGE(object); - _storage_clear (self); + _storage_clear(self); - G_OBJECT_CLASS (nms_keyfile_storage_parent_class)->dispose (object); + G_OBJECT_CLASS(nms_keyfile_storage_parent_class)->dispose(object); } void -nms_keyfile_storage_destroy (NMSKeyfileStorage *self) +nms_keyfile_storage_destroy(NMSKeyfileStorage *self) { - _storage_clear (self); - g_object_unref (self); + _storage_clear(self); + g_object_unref(self); } static void -nms_keyfile_storage_class_init (NMSKeyfileStorageClass *klass) +nms_keyfile_storage_class_init(NMSKeyfileStorageClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMSettingsStorageClass *storage_class = NM_SETTINGS_STORAGE_CLASS (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingsStorageClass *storage_class = NM_SETTINGS_STORAGE_CLASS(klass); - object_class->dispose = dispose; + object_class->dispose = dispose; - storage_class->cmp_fcn = (int (*) (NMSettingsStorage *, NMSettingsStorage *)) cmp_fcn; + storage_class->cmp_fcn = (int (*)(NMSettingsStorage *, NMSettingsStorage *)) cmp_fcn; } /*****************************************************************************/ @@ -237,33 +240,33 @@ nms_keyfile_storage_class_init (NMSKeyfileStorageClass *klass) #include "settings/nm-settings-connection.h" void -nm_settings_storage_load_sett_flags (NMSettingsStorage *self, - NMSettingsConnectionIntFlags *sett_flags, - NMSettingsConnectionIntFlags *sett_mask) +nm_settings_storage_load_sett_flags(NMSettingsStorage * self, + NMSettingsConnectionIntFlags *sett_flags, + NMSettingsConnectionIntFlags *sett_mask) { - NMSKeyfileStorage *s; + NMSKeyfileStorage *s; - *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_EXTERNAL; + *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_EXTERNAL; - if (!NMS_IS_KEYFILE_STORAGE (self)) - return; + if (!NMS_IS_KEYFILE_STORAGE(self)) + return; - s = NMS_KEYFILE_STORAGE (self); + s = NMS_KEYFILE_STORAGE(self); - if (s->is_meta_data) - return; - if (s->storage_type != NMS_KEYFILE_STORAGE_TYPE_RUN) - return; + if (s->is_meta_data) + return; + if (s->storage_type != NMS_KEYFILE_STORAGE_TYPE_RUN) + return; - if (s->u.conn_data.is_nm_generated) - *sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED; + if (s->u.conn_data.is_nm_generated) + *sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED; - if (s->u.conn_data.is_volatile) - *sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE; + 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; + 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 bd8a4367..90ff6f35 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-storage.h +++ b/src/settings/plugins/keyfile/nms-keyfile-storage.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -12,241 +12,244 @@ /*****************************************************************************/ -#define NMS_TYPE_KEYFILE_STORAGE (nms_keyfile_storage_get_type ()) -#define NMS_KEYFILE_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMS_TYPE_KEYFILE_STORAGE, NMSKeyfileStorage)) -#define NMS_KEYFILE_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMS_TYPE_KEYFILE_STORAGE, NMSKeyfileStorageClass)) -#define NMS_IS_KEYFILE_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMS_TYPE_KEYFILE_STORAGE)) -#define NMS_IS_KEYFILE_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMS_TYPE_KEYFILE_STORAGE)) -#define NMS_KEYFILE_STORAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMS_TYPE_KEYFILE_STORAGE, NMSKeyfileStorageClass)) +#define NMS_TYPE_KEYFILE_STORAGE (nms_keyfile_storage_get_type()) +#define NMS_KEYFILE_STORAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NMS_TYPE_KEYFILE_STORAGE, NMSKeyfileStorage)) +#define NMS_KEYFILE_STORAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NMS_TYPE_KEYFILE_STORAGE, NMSKeyfileStorageClass)) +#define NMS_IS_KEYFILE_STORAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMS_TYPE_KEYFILE_STORAGE)) +#define NMS_IS_KEYFILE_STORAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NMS_TYPE_KEYFILE_STORAGE)) +#define NMS_KEYFILE_STORAGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NMS_TYPE_KEYFILE_STORAGE, NMSKeyfileStorageClass)) typedef struct { - /* whether this is a tombstone to hide a UUID (via symlink to /dev/null). */ - char *shadowed_storage; - bool is_tombstone:1; + /* whether this is a tombstone to hide a UUID (via symlink to /dev/null). */ + char *shadowed_storage; + bool is_tombstone : 1; } NMSettingsMetaData; typedef struct { - NMSettingsStorage parent; - - /* The connection. Note that there are tombstones (loaded-uuid files to /dev/null) - * that don't have a connection. - * - * Also, we don't actually remember the loaded connection after returning it - * to NMSettings. So, also for regular storages (non-tombstones) this field - * is often cleared. */ - union { - struct { - NMConnection *connection; - - /* when we move a profile from permanent storage to unsaved (/run), then - * we may leave the profile on disk (depending on options for Update2()). - * - * Later, when we save the profile again to disk, we want to re-use that filename. - * Likewise, we delete the (now in-memory) profile, we may want to also delete - * the original filename. - * - * This is the original filename, and we store it inside [.nmmeta] in the - * keyfile in /run. Note that we don't store this in the .nmmeta file, because - * the information is tied to the particular keyfile in /run, not to all UUIDs - * in general. */ - char *shadowed_storage; - - /* the timestamp (stat's mtime) of the keyfile. For meta-data this - * is irrelevant. The purpose is that if the same storage type (directory) has - * multiple files with the same UUID, then the newer file gets preferred. */ - struct timespec stat_mtime; - - /* these flags are only relevant for storages with %NMS_KEYFILE_STORAGE_TYPE_RUN - * (and non-metadata). This is to persist and reload these settings flags to - * /run. - * - * Note that these flags are not stored in as meta-data. The reason is that meta-data - * is per UUID. But these flags are only relevant for a particular keyfile on disk. - * 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, - * shadowing profile: a owned profile will also be deleted. */ - bool shadowed_owned:1; - - } conn_data; - - /* the content from the .nmmeta file. Note that the nmmeta file has the UUID - * in the filename, that means there can be only two variants of this file: - * in /etc and in /run. As such, this is really meta-data about the entire profile - * (the UUID), and not about the individual keyfile. */ - NMSettingsMetaData meta_data; - - } u; - - /* The storage type. This is directly related to the filename. Since - * the filename cannot change, this value is unchanging. */ - const NMSKeyfileStorageType storage_type; - - /* whether union "u" has meta_data or conn_data. Since the type of the storage - * depends on the (immutable) filename, this is also const. */ - const bool is_meta_data; - - /* this flag is only used during reload to mark and prune old entries. */ - bool is_dirty:1; + NMSettingsStorage parent; + + /* The connection. Note that there are tombstones (loaded-uuid files to /dev/null) + * that don't have a connection. + * + * Also, we don't actually remember the loaded connection after returning it + * to NMSettings. So, also for regular storages (non-tombstones) this field + * is often cleared. */ + union { + struct { + NMConnection *connection; + + /* when we move a profile from permanent storage to unsaved (/run), then + * we may leave the profile on disk (depending on options for Update2()). + * + * Later, when we save the profile again to disk, we want to re-use that filename. + * Likewise, we delete the (now in-memory) profile, we may want to also delete + * the original filename. + * + * This is the original filename, and we store it inside [.nmmeta] in the + * keyfile in /run. Note that we don't store this in the .nmmeta file, because + * the information is tied to the particular keyfile in /run, not to all UUIDs + * in general. */ + char *shadowed_storage; + + /* the timestamp (stat's mtime) of the keyfile. For meta-data this + * is irrelevant. The purpose is that if the same storage type (directory) has + * multiple files with the same UUID, then the newer file gets preferred. */ + struct timespec stat_mtime; + + /* these flags are only relevant for storages with %NMS_KEYFILE_STORAGE_TYPE_RUN + * (and non-metadata). This is to persist and reload these settings flags to + * /run. + * + * Note that these flags are not stored in as meta-data. The reason is that meta-data + * is per UUID. But these flags are only relevant for a particular keyfile on disk. + * 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, + * shadowing profile: a owned profile will also be deleted. */ + bool shadowed_owned : 1; + + } conn_data; + + /* the content from the .nmmeta file. Note that the nmmeta file has the UUID + * in the filename, that means there can be only two variants of this file: + * in /etc and in /run. As such, this is really meta-data about the entire profile + * (the UUID), and not about the individual keyfile. */ + NMSettingsMetaData meta_data; + + } u; + + /* The storage type. This is directly related to the filename. Since + * the filename cannot change, this value is unchanging. */ + const NMSKeyfileStorageType storage_type; + + /* whether union "u" has meta_data or conn_data. Since the type of the storage + * depends on the (immutable) filename, this is also const. */ + const bool is_meta_data; + + /* this flag is only used during reload to mark and prune old entries. */ + bool is_dirty : 1; } NMSKeyfileStorage; typedef struct _NMSKeyfileStorageClass NMSKeyfileStorageClass; -GType nms_keyfile_storage_get_type (void); +GType nms_keyfile_storage_get_type(void); struct _NMSKeyfilePlugin; -NMSKeyfileStorage *nms_keyfile_storage_new_tombstone (struct _NMSKeyfilePlugin *self, - const char *uuid, - const char *filename, - NMSKeyfileStorageType storage_type, - const char *shadowed_storage); - -NMSKeyfileStorage *nms_keyfile_storage_new_connection (struct _NMSKeyfilePlugin *self, - NMConnection *connection_take /* pass reference */, - const char *filename, - 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); - -void nms_keyfile_storage_destroy (NMSKeyfileStorage *storage); +NMSKeyfileStorage *nms_keyfile_storage_new_tombstone(struct _NMSKeyfilePlugin *self, + const char * uuid, + const char * filename, + NMSKeyfileStorageType storage_type, + const char * shadowed_storage); + +NMSKeyfileStorage * +nms_keyfile_storage_new_connection(struct _NMSKeyfilePlugin *self, + NMConnection * connection_take /* pass reference */, + const char * filename, + 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); + +void nms_keyfile_storage_destroy(NMSKeyfileStorage *storage); /*****************************************************************************/ -void nms_keyfile_storage_copy_content (NMSKeyfileStorage *dst, - const NMSKeyfileStorage *src); +void nms_keyfile_storage_copy_content(NMSKeyfileStorage *dst, const NMSKeyfileStorage *src); -NMConnection *nms_keyfile_storage_steal_connection (NMSKeyfileStorage *storage); +NMConnection *nms_keyfile_storage_steal_connection(NMSKeyfileStorage *storage); /*****************************************************************************/ static inline const char * -nms_keyfile_storage_get_uuid (const NMSKeyfileStorage *self) +nms_keyfile_storage_get_uuid(const NMSKeyfileStorage *self) { - return nm_settings_storage_get_uuid ((const NMSettingsStorage *) self); + return nm_settings_storage_get_uuid((const NMSettingsStorage *) self); } static inline const char * -nms_keyfile_storage_get_filename (const NMSKeyfileStorage *self) +nms_keyfile_storage_get_filename(const NMSKeyfileStorage *self) { - return nm_settings_storage_get_filename ((const NMSettingsStorage *) self); + return nm_settings_storage_get_filename((const NMSettingsStorage *) self); } /*****************************************************************************/ static inline gboolean -nm_settings_storage_is_keyfile_run (const NMSettingsStorage *self) +nm_settings_storage_is_keyfile_run(const NMSettingsStorage *self) { - return NMS_IS_KEYFILE_STORAGE (self) - && (((NMSKeyfileStorage *) self)->storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN); + return NMS_IS_KEYFILE_STORAGE(self) + && (((NMSKeyfileStorage *) self)->storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN); } static inline gboolean -nm_settings_storage_is_keyfile_lib (const NMSettingsStorage *self) +nm_settings_storage_is_keyfile_lib(const NMSettingsStorage *self) { - return NMS_IS_KEYFILE_STORAGE (self) - && (((NMSKeyfileStorage *) self)->storage_type >= NMS_KEYFILE_STORAGE_TYPE_LIB_BASE); + return NMS_IS_KEYFILE_STORAGE(self) + && (((NMSKeyfileStorage *) self)->storage_type >= NMS_KEYFILE_STORAGE_TYPE_LIB_BASE); } static inline const NMSettingsMetaData * -nm_settings_storage_is_meta_data (const NMSettingsStorage *storage) +nm_settings_storage_is_meta_data(const NMSettingsStorage *storage) { - const NMSKeyfileStorage *self; + const NMSKeyfileStorage *self; - if (!NMS_IS_KEYFILE_STORAGE (storage)) - return NULL; + if (!NMS_IS_KEYFILE_STORAGE(storage)) + return NULL; - self = (NMSKeyfileStorage *) storage; + self = (NMSKeyfileStorage *) storage; - if (!self->is_meta_data) - return NULL; + if (!self->is_meta_data) + return NULL; - return &self->u.meta_data; + return &self->u.meta_data; } static inline const NMSettingsMetaData * -nm_settings_storage_is_meta_data_alive (const NMSettingsStorage *storage) +nm_settings_storage_is_meta_data_alive(const NMSettingsStorage *storage) { - const NMSettingsMetaData *meta_data; + const NMSettingsMetaData *meta_data; - meta_data = nm_settings_storage_is_meta_data (storage); + meta_data = nm_settings_storage_is_meta_data(storage); - if (!meta_data) - return NULL; + if (!meta_data) + return NULL; - /* Regular (all other) storages are alive as long as they report a NMConnection, and - * they will be dropped, once they have no more connection. - * - * Meta-data storages are special: they never report a NMConnection. - * So, a meta-data storage is alive as long as it is tracked by the - * settings plugin. - * - * This function is used to ckeck for that. */ + /* Regular (all other) storages are alive as long as they report a NMConnection, and + * they will be dropped, once they have no more connection. + * + * Meta-data storages are special: they never report a NMConnection. + * So, a meta-data storage is alive as long as it is tracked by the + * settings plugin. + * + * This function is used to ckeck for that. */ - if (c_list_is_empty (&storage->_storage_lst)) - return NULL; + if (c_list_is_empty(&storage->_storage_lst)) + return NULL; - return meta_data; + return meta_data; } static inline const char * -nm_settings_storage_get_shadowed_storage (const NMSettingsStorage *storage, - gboolean *out_shadowed_owned) +nm_settings_storage_get_shadowed_storage(const NMSettingsStorage *storage, + gboolean * out_shadowed_owned) { - if (NMS_IS_KEYFILE_STORAGE (storage)) { - const NMSKeyfileStorage *self = (const NMSKeyfileStorage *) storage; - - if (self->storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN) { - if (!self->is_meta_data) { - if (self->u.conn_data.shadowed_storage) { - NM_SET_OUT (out_shadowed_owned, self->u.conn_data.shadowed_owned); - return self->u.conn_data.shadowed_storage; - } - } else { - NM_SET_OUT (out_shadowed_owned, FALSE); - return self->u.meta_data.shadowed_storage; - } - } - } - - NM_SET_OUT (out_shadowed_owned, FALSE); - return NULL; + if (NMS_IS_KEYFILE_STORAGE(storage)) { + const NMSKeyfileStorage *self = (const NMSKeyfileStorage *) storage; + + if (self->storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN) { + if (!self->is_meta_data) { + if (self->u.conn_data.shadowed_storage) { + NM_SET_OUT(out_shadowed_owned, self->u.conn_data.shadowed_owned); + return self->u.conn_data.shadowed_storage; + } + } else { + NM_SET_OUT(out_shadowed_owned, FALSE); + return self->u.meta_data.shadowed_storage; + } + } + } + + NM_SET_OUT(out_shadowed_owned, FALSE); + return NULL; } static inline const char * -nm_settings_storage_get_filename_for_shadowed_storage (const NMSettingsStorage *storage) +nm_settings_storage_get_filename_for_shadowed_storage(const NMSettingsStorage *storage) { - g_return_val_if_fail (NM_IS_SETTINGS_STORAGE (storage), NULL); + g_return_val_if_fail(NM_IS_SETTINGS_STORAGE(storage), NULL); - if (!storage->_filename) - return NULL; + if (!storage->_filename) + return NULL; - if (NMS_IS_KEYFILE_STORAGE (storage)) { - const NMSKeyfileStorage *self = (const NMSKeyfileStorage *) storage; + if (NMS_IS_KEYFILE_STORAGE(storage)) { + const NMSKeyfileStorage *self = (const NMSKeyfileStorage *) storage; - if ( self->is_meta_data - || self->storage_type != NMS_KEYFILE_STORAGE_TYPE_ETC) - return NULL; - } + if (self->is_meta_data || self->storage_type != NMS_KEYFILE_STORAGE_TYPE_ETC) + return NULL; + } - return storage->_filename; + return storage->_filename; } /*****************************************************************************/ enum _NMSettingsConnectionIntFlags; -void nm_settings_storage_load_sett_flags (NMSettingsStorage *self, - enum _NMSettingsConnectionIntFlags *sett_flags, - enum _NMSettingsConnectionIntFlags *sett_mask); +void nm_settings_storage_load_sett_flags(NMSettingsStorage * self, + enum _NMSettingsConnectionIntFlags *sett_flags, + enum _NMSettingsConnectionIntFlags *sett_mask); #endif /* __NMS_KEYFILE_STORAGE_H__ */ diff --git a/src/settings/plugins/keyfile/nms-keyfile-utils.c b/src/settings/plugins/keyfile/nms-keyfile-utils.c index bc8dfd12..851e7815 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-utils.c +++ b/src/settings/plugins/keyfile/nms-keyfile-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2018 Red Hat, Inc. */ @@ -20,349 +20,370 @@ /*****************************************************************************/ -#define NMMETA_KF_GROUP_NAME_NMMETA "nmmeta" -#define NMMETA_KF_KEY_NAME_NMMETA_UUID "uuid" -#define NMMETA_KF_KEY_NAME_NMMETA_LOADED_PATH "loaded-path" -#define NMMETA_KF_KEY_NAME_NMMETA_SHADOWED_STORAGE "shadowed-storage" +#define NMMETA_KF_GROUP_NAME_NMMETA "nmmeta" +#define NMMETA_KF_KEY_NAME_NMMETA_UUID "uuid" +#define NMMETA_KF_KEY_NAME_NMMETA_LOADED_PATH "loaded-path" +#define NMMETA_KF_KEY_NAME_NMMETA_SHADOWED_STORAGE "shadowed-storage" /*****************************************************************************/ const char * -nms_keyfile_nmmeta_check_filename (const char *filename, - guint *out_uuid_len) +nms_keyfile_nmmeta_check_filename(const char *filename, guint *out_uuid_len) { - const char *uuid; - const char *s; - gsize len; - - s = strrchr (filename, '/'); - if (s) - filename = &s[1]; - - len = strlen (filename); - if ( len <= NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMMETA) - || memcmp (&filename[len - NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMMETA)], - NM_KEYFILE_PATH_SUFFIX_NMMETA, - NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMMETA)) != 0) { - /* the filename does not have the right suffix. */ - return NULL; - } - - len -= NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMMETA); - - if (!NM_IN_SET (len, 36, 40)) { - /* the remaining part of the filename has not the right length to - * contain a UUID (according to nm_utils_is_uuid()). */ - return NULL; - } - - uuid = nm_strndup_a (100, filename, len, NULL); - if (!nm_utils_is_uuid (uuid)) - return NULL; - - NM_SET_OUT (out_uuid_len, len); - return filename; + const char *uuid; + const char *s; + gsize len; + + s = strrchr(filename, '/'); + if (s) + filename = &s[1]; + + len = strlen(filename); + if (len <= NM_STRLEN(NM_KEYFILE_PATH_SUFFIX_NMMETA) + || memcmp(&filename[len - NM_STRLEN(NM_KEYFILE_PATH_SUFFIX_NMMETA)], + NM_KEYFILE_PATH_SUFFIX_NMMETA, + NM_STRLEN(NM_KEYFILE_PATH_SUFFIX_NMMETA)) + != 0) { + /* the filename does not have the right suffix. */ + return NULL; + } + + len -= NM_STRLEN(NM_KEYFILE_PATH_SUFFIX_NMMETA); + + if (!NM_IN_SET(len, 36, 40)) { + /* the remaining part of the filename has not the right length to + * contain a UUID (according to nm_utils_is_uuid()). */ + return NULL; + } + + uuid = nm_strndup_a(100, filename, len, NULL); + if (!nm_utils_is_uuid(uuid)) + return NULL; + + NM_SET_OUT(out_uuid_len, len); + return filename; } char * -nms_keyfile_nmmeta_filename (const char *dirname, - const char *uuid, - gboolean temporary) +nms_keyfile_nmmeta_filename(const char *dirname, const char *uuid, gboolean temporary) { - char filename[250]; - char *s; + char filename[250]; + char *s; - nm_assert (dirname && dirname[0] == '/'); - nm_assert ( nm_utils_is_uuid (uuid) - && !strchr (uuid, '/')); + nm_assert(dirname && dirname[0] == '/'); + nm_assert(nm_utils_is_uuid(uuid) && !strchr(uuid, '/')); - if (g_snprintf (filename, - sizeof (filename), - "%s%s%s", - uuid, - NM_KEYFILE_PATH_SUFFIX_NMMETA, - temporary ? "~" : "") >= sizeof (filename)) { - /* valid uuids are limited in length (nm_utils_is_uuid). The buffer should always - * be large enough. */ - nm_assert_not_reached (); - } + if (g_snprintf(filename, + sizeof(filename), + "%s%s%s", + uuid, + NM_KEYFILE_PATH_SUFFIX_NMMETA, + temporary ? "~" : "") + >= sizeof(filename)) { + /* valid uuids are limited in length (nm_utils_is_uuid). The buffer should always + * be large enough. */ + nm_assert_not_reached(); + } - s = g_build_filename (dirname, filename, NULL); + s = g_build_filename(dirname, filename, NULL); - nm_assert (nm_keyfile_utils_ignore_filename (s, FALSE)); + nm_assert(nm_keyfile_utils_ignore_filename(s, FALSE)); - return s; + return s; } gboolean -nms_keyfile_nmmeta_read (const char *dirname, - const char *filename, - char **out_full_filename, - char **out_uuid, - char **out_loaded_path, - char **out_shadowed_storage, - struct stat *out_st) +nms_keyfile_nmmeta_read(const char * dirname, + const char * filename, + char ** out_full_filename, + char ** out_uuid, + char ** out_loaded_path, + char ** out_shadowed_storage, + struct stat *out_st) { - const char *uuid; - guint uuid_len; - gs_free char *full_filename = NULL; - gs_free char *loaded_path = NULL; - gs_free char *shadowed_storage = NULL; - struct stat st_stack; - struct stat *st = out_st ?: &st_stack; - - nm_assert (dirname && dirname[0] == '/'); - nm_assert (filename && filename[0] && !strchr (filename, '/')); - - uuid = nms_keyfile_nmmeta_check_filename (filename, &uuid_len); - if (!uuid) - return FALSE; - - full_filename = g_build_filename (dirname, filename, NULL); - - if (!nms_keyfile_utils_check_file_permissions (NMS_KEYFILE_FILETYPE_NMMETA, - full_filename, - st, - NULL)) - return FALSE; - - if (S_ISREG (st->st_mode)) { - gs_unref_keyfile GKeyFile *kf = NULL; - gs_free char *v_uuid = NULL; - - kf = g_key_file_new (); - - if (!g_key_file_load_from_file (kf, full_filename, G_KEY_FILE_NONE, NULL)) - return FALSE; - - v_uuid = g_key_file_get_string (kf, NMMETA_KF_GROUP_NAME_NMMETA, NMMETA_KF_KEY_NAME_NMMETA_UUID, NULL); - if (!nm_streq0 (v_uuid, uuid)) - return FALSE; - - loaded_path = g_key_file_get_string (kf, NMMETA_KF_GROUP_NAME_NMMETA, NMMETA_KF_KEY_NAME_NMMETA_LOADED_PATH, NULL); - shadowed_storage = g_key_file_get_string (kf, NMMETA_KF_GROUP_NAME_NMMETA, NMMETA_KF_KEY_NAME_NMMETA_SHADOWED_STORAGE, NULL); - - if ( !loaded_path - && !shadowed_storage) { - /* if there is no useful information in the file, it is the same as if - * the file is not present. Signal failure. */ - return FALSE; - } - - } else { - loaded_path = nm_utils_read_link_absolute (full_filename, NULL); - if (!loaded_path) - return FALSE; - } - - NM_SET_OUT (out_uuid, g_strndup (uuid, uuid_len)); - NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename)); - NM_SET_OUT (out_loaded_path, g_steal_pointer (&loaded_path)); - NM_SET_OUT (out_shadowed_storage, g_steal_pointer (&shadowed_storage)); - return TRUE; + const char * uuid; + guint uuid_len; + gs_free char *full_filename = NULL; + gs_free char *loaded_path = NULL; + gs_free char *shadowed_storage = NULL; + struct stat st_stack; + struct stat * st = out_st ?: &st_stack; + + nm_assert(dirname && dirname[0] == '/'); + nm_assert(filename && filename[0] && !strchr(filename, '/')); + + uuid = nms_keyfile_nmmeta_check_filename(filename, &uuid_len); + if (!uuid) + return FALSE; + + full_filename = g_build_filename(dirname, filename, NULL); + + if (!nms_keyfile_utils_check_file_permissions(NMS_KEYFILE_FILETYPE_NMMETA, + full_filename, + st, + NULL)) + return FALSE; + + if (S_ISREG(st->st_mode)) { + nm_auto_unref_keyfile GKeyFile *kf = NULL; + gs_free char * v_uuid = NULL; + + kf = g_key_file_new(); + + if (!g_key_file_load_from_file(kf, full_filename, G_KEY_FILE_NONE, NULL)) + return FALSE; + + v_uuid = g_key_file_get_string(kf, + NMMETA_KF_GROUP_NAME_NMMETA, + NMMETA_KF_KEY_NAME_NMMETA_UUID, + NULL); + if (!nm_streq0(v_uuid, uuid)) + return FALSE; + + loaded_path = g_key_file_get_string(kf, + NMMETA_KF_GROUP_NAME_NMMETA, + NMMETA_KF_KEY_NAME_NMMETA_LOADED_PATH, + NULL); + shadowed_storage = g_key_file_get_string(kf, + NMMETA_KF_GROUP_NAME_NMMETA, + NMMETA_KF_KEY_NAME_NMMETA_SHADOWED_STORAGE, + NULL); + + if (!loaded_path && !shadowed_storage) { + /* if there is no useful information in the file, it is the same as if + * the file is not present. Signal failure. */ + return FALSE; + } + + } else { + loaded_path = nm_utils_read_link_absolute(full_filename, NULL); + if (!loaded_path) + return FALSE; + } + + NM_SET_OUT(out_uuid, g_strndup(uuid, uuid_len)); + NM_SET_OUT(out_full_filename, g_steal_pointer(&full_filename)); + NM_SET_OUT(out_loaded_path, g_steal_pointer(&loaded_path)); + NM_SET_OUT(out_shadowed_storage, g_steal_pointer(&shadowed_storage)); + return TRUE; } gboolean -nms_keyfile_nmmeta_read_from_file (const char *full_filename, - char **out_dirname, - char **out_filename, - char **out_uuid, - char **out_loaded_path, - char **out_shadowed_storage) +nms_keyfile_nmmeta_read_from_file(const char *full_filename, + char ** out_dirname, + char ** out_filename, + char ** out_uuid, + char ** out_loaded_path, + char ** out_shadowed_storage) { - gs_free char *dirname = NULL; - gs_free char *filename = NULL; - - nm_assert (full_filename && full_filename[0] == '/'); - - filename = g_path_get_basename (full_filename); - dirname = g_path_get_dirname (full_filename); - - if (!nms_keyfile_nmmeta_read (dirname, - filename, - NULL, - out_uuid, - out_loaded_path, - out_shadowed_storage, - NULL)) - return FALSE; - - NM_SET_OUT (out_dirname, g_steal_pointer (&dirname)); - NM_SET_OUT (out_filename, g_steal_pointer (&filename)); - return TRUE; + gs_free char *dirname = NULL; + gs_free char *filename = NULL; + + nm_assert(full_filename && full_filename[0] == '/'); + + filename = g_path_get_basename(full_filename); + dirname = g_path_get_dirname(full_filename); + + if (!nms_keyfile_nmmeta_read(dirname, + filename, + NULL, + out_uuid, + out_loaded_path, + out_shadowed_storage, + NULL)) + return FALSE; + + NM_SET_OUT(out_dirname, g_steal_pointer(&dirname)); + NM_SET_OUT(out_filename, g_steal_pointer(&filename)); + return TRUE; } int -nms_keyfile_nmmeta_write (const char *dirname, - const char *uuid, - const char *loaded_path, - gboolean loaded_path_allow_relative, - const char *shadowed_storage, - char **out_full_filename) +nms_keyfile_nmmeta_write(const char *dirname, + const char *uuid, + const char *loaded_path, + gboolean loaded_path_allow_relative, + const char *shadowed_storage, + char ** out_full_filename) { - gs_free char *full_filename_tmp = NULL; - gs_free char *full_filename = NULL; - int errsv; - - nm_assert (dirname && dirname[0] == '/'); - nm_assert ( nm_utils_is_uuid (uuid) - && !strchr (uuid, '/')); - nm_assert (!loaded_path || loaded_path[0] == '/'); - nm_assert (!shadowed_storage || loaded_path); - - full_filename_tmp = nms_keyfile_nmmeta_filename (dirname, uuid, TRUE); - - nm_assert (g_str_has_suffix (full_filename_tmp, "~")); - nm_assert (nm_utils_file_is_in_path (full_filename_tmp, dirname)); - - (void) unlink (full_filename_tmp); - - if (!loaded_path) { - full_filename_tmp[strlen (full_filename_tmp) - 1] = '\0'; - errsv = 0; - if (unlink (full_filename_tmp) != 0) { - errsv = -NM_ERRNO_NATIVE (errno); - if (errsv == -ENOENT) - errsv = 0; - } - NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename_tmp)); - return errsv; - } - - if (loaded_path_allow_relative) { - const char *f; - - f = nm_utils_file_is_in_path (loaded_path, dirname); - if (f) { - /* @loaded_path points to a file directly in @dirname. - * Don't use absolute paths. */ - loaded_path = f; - } - } - - full_filename = g_strndup (full_filename_tmp, strlen (full_filename_tmp) - 1); - - if (shadowed_storage) { - gs_unref_keyfile GKeyFile *kf = NULL; - gs_free char *contents = NULL; - gsize length; - - kf = g_key_file_new (); - - g_key_file_set_string (kf, NMMETA_KF_GROUP_NAME_NMMETA, NMMETA_KF_KEY_NAME_NMMETA_UUID, uuid); - g_key_file_set_string (kf, NMMETA_KF_GROUP_NAME_NMMETA, NMMETA_KF_KEY_NAME_NMMETA_LOADED_PATH, loaded_path); - g_key_file_set_string (kf, NMMETA_KF_GROUP_NAME_NMMETA, NMMETA_KF_KEY_NAME_NMMETA_SHADOWED_STORAGE, shadowed_storage); - - contents = g_key_file_to_data (kf, &length, NULL); - - if (!nm_utils_file_set_contents (full_filename, - contents, - length, - 0600, - &errsv, - NULL)) { - NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename_tmp)); - return -NM_ERRNO_NATIVE (errsv); - } - } else { - /* we only have the "loaded_path" to store. That is commonly used for the tombstones to - * link to /dev/null. A symlink is sufficient to store that ammount of information. - * No need to bother with a keyfile. */ - if (symlink (loaded_path, full_filename_tmp) != 0) { - errsv = -NM_ERRNO_NATIVE (errno); - full_filename_tmp[strlen (full_filename_tmp) - 1] = '\0'; - NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename_tmp)); - return errsv; - } - - if (rename (full_filename_tmp, full_filename) != 0) { - errsv = -NM_ERRNO_NATIVE (errno); - (void) unlink (full_filename_tmp); - NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename)); - return errsv; - } - } - - NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename)); - return 0; + gs_free char *full_filename_tmp = NULL; + gs_free char *full_filename = NULL; + int errsv; + + nm_assert(dirname && dirname[0] == '/'); + nm_assert(nm_utils_is_uuid(uuid) && !strchr(uuid, '/')); + nm_assert(!loaded_path || loaded_path[0] == '/'); + nm_assert(!shadowed_storage || loaded_path); + + full_filename_tmp = nms_keyfile_nmmeta_filename(dirname, uuid, TRUE); + + nm_assert(g_str_has_suffix(full_filename_tmp, "~")); + nm_assert(nm_utils_file_is_in_path(full_filename_tmp, dirname)); + + (void) unlink(full_filename_tmp); + + if (!loaded_path) { + full_filename_tmp[strlen(full_filename_tmp) - 1] = '\0'; + errsv = 0; + if (unlink(full_filename_tmp) != 0) { + errsv = -NM_ERRNO_NATIVE(errno); + if (errsv == -ENOENT) + errsv = 0; + } + NM_SET_OUT(out_full_filename, g_steal_pointer(&full_filename_tmp)); + return errsv; + } + + if (loaded_path_allow_relative) { + const char *f; + + f = nm_utils_file_is_in_path(loaded_path, dirname); + if (f) { + /* @loaded_path points to a file directly in @dirname. + * Don't use absolute paths. */ + loaded_path = f; + } + } + + full_filename = g_strndup(full_filename_tmp, strlen(full_filename_tmp) - 1); + + if (shadowed_storage) { + nm_auto_unref_keyfile GKeyFile *kf = NULL; + gs_free char * contents = NULL; + gsize length; + + kf = g_key_file_new(); + + g_key_file_set_string(kf, + NMMETA_KF_GROUP_NAME_NMMETA, + NMMETA_KF_KEY_NAME_NMMETA_UUID, + uuid); + g_key_file_set_string(kf, + NMMETA_KF_GROUP_NAME_NMMETA, + NMMETA_KF_KEY_NAME_NMMETA_LOADED_PATH, + loaded_path); + g_key_file_set_string(kf, + NMMETA_KF_GROUP_NAME_NMMETA, + NMMETA_KF_KEY_NAME_NMMETA_SHADOWED_STORAGE, + shadowed_storage); + + contents = g_key_file_to_data(kf, &length, NULL); + + if (!nm_utils_file_set_contents(full_filename, contents, length, 0600, &errsv, NULL)) { + NM_SET_OUT(out_full_filename, g_steal_pointer(&full_filename_tmp)); + return -NM_ERRNO_NATIVE(errsv); + } + } else { + /* we only have the "loaded_path" to store. That is commonly used for the tombstones to + * link to /dev/null. A symlink is sufficient to store that amount of information. + * No need to bother with a keyfile. */ + if (symlink(loaded_path, full_filename_tmp) != 0) { + errsv = -NM_ERRNO_NATIVE(errno); + full_filename_tmp[strlen(full_filename_tmp) - 1] = '\0'; + NM_SET_OUT(out_full_filename, g_steal_pointer(&full_filename_tmp)); + return errsv; + } + + if (rename(full_filename_tmp, full_filename) != 0) { + errsv = -NM_ERRNO_NATIVE(errno); + (void) unlink(full_filename_tmp); + NM_SET_OUT(out_full_filename, g_steal_pointer(&full_filename)); + return errsv; + } + } + + NM_SET_OUT(out_full_filename, g_steal_pointer(&full_filename)); + return 0; } /*****************************************************************************/ gboolean -nms_keyfile_utils_check_file_permissions_stat (NMSKeyfileFiletype filetype, - const struct stat *st, - GError **error) +nms_keyfile_utils_check_file_permissions_stat(NMSKeyfileFiletype filetype, + const struct stat *st, + GError ** error) { - g_return_val_if_fail (st, FALSE); - - if (filetype == NMS_KEYFILE_FILETYPE_KEYFILE) { - if (!S_ISREG (st->st_mode)) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "file is not a regular file"); - return FALSE; - } - } else if (filetype == NMS_KEYFILE_FILETYPE_NMMETA) { - if ( !S_ISLNK (st->st_mode) - && !S_ISREG (st->st_mode)) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "file is neither a symlink nor a regular file"); - return FALSE; - } - } else - g_return_val_if_reached (FALSE); - - if (!NM_FLAGS_HAS (nm_utils_get_testing (), NM_UTILS_TEST_NO_KEYFILE_OWNER_CHECK)) { - if (st->st_uid != 0) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "File owner (%lld) is insecure", - (long long) st->st_uid); - return FALSE; - } - - if ( S_ISREG (st->st_mode) - && (st->st_mode & 0077)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "File permissions (%03o) are insecure", - st->st_mode); - return FALSE; - } - } - - return TRUE; + g_return_val_if_fail(st, FALSE); + + if (filetype == NMS_KEYFILE_FILETYPE_KEYFILE) { + if (!S_ISREG(st->st_mode)) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "file is not a regular file"); + return FALSE; + } + } else if (filetype == NMS_KEYFILE_FILETYPE_NMMETA) { + if (!S_ISLNK(st->st_mode) && !S_ISREG(st->st_mode)) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "file is neither a symlink nor a regular file"); + return FALSE; + } + } else + g_return_val_if_reached(FALSE); + + if (!NM_FLAGS_HAS(nm_utils_get_testing(), NM_UTILS_TEST_NO_KEYFILE_OWNER_CHECK)) { + if (st->st_uid != 0) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "File owner (%lld) is insecure", + (long long) st->st_uid); + return FALSE; + } + + if (S_ISREG(st->st_mode) && (st->st_mode & 0077)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "File permissions (%03o) are insecure", + st->st_mode); + return FALSE; + } + } + + return TRUE; } gboolean -nms_keyfile_utils_check_file_permissions (NMSKeyfileFiletype filetype, - const char *filename, - struct stat *out_st, - GError **error) +nms_keyfile_utils_check_file_permissions(NMSKeyfileFiletype filetype, + const char * filename, + struct stat * out_st, + GError ** error) { - struct stat st; - int errsv; - - g_return_val_if_fail (filename && filename[0] == '/', FALSE); - - if (filetype == NMS_KEYFILE_FILETYPE_KEYFILE) { - if (stat (filename, &st) != 0) { - errsv = errno; - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "cannot access file: %s", nm_strerror_native (errsv)); - return FALSE; - } - } else if (filetype == NMS_KEYFILE_FILETYPE_NMMETA) { - if (lstat (filename, &st) != 0) { - errsv = errno; - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "cannot access file: %s", nm_strerror_native (errsv)); - return FALSE; - } - } else - g_return_val_if_reached (FALSE); - - if (!nms_keyfile_utils_check_file_permissions_stat (filetype, &st, error)) - return FALSE; - - NM_SET_OUT (out_st, st); - return TRUE; + struct stat st; + int errsv; + + g_return_val_if_fail(filename && filename[0] == '/', FALSE); + + if (filetype == NMS_KEYFILE_FILETYPE_KEYFILE) { + if (stat(filename, &st) != 0) { + errsv = errno; + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "cannot access file: %s", + nm_strerror_native(errsv)); + return FALSE; + } + } else if (filetype == NMS_KEYFILE_FILETYPE_NMMETA) { + if (lstat(filename, &st) != 0) { + errsv = errno; + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "cannot access file: %s", + nm_strerror_native(errsv)); + return FALSE; + } + } else + g_return_val_if_reached(FALSE); + + if (!nms_keyfile_utils_check_file_permissions_stat(filetype, &st, error)) + return FALSE; + + NM_SET_OUT(out_st, st); + return TRUE; } diff --git a/src/settings/plugins/keyfile/nms-keyfile-utils.h b/src/settings/plugins/keyfile/nms-keyfile-utils.h index f943d65c..4b5b4bb5 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-utils.h +++ b/src/settings/plugins/keyfile/nms-keyfile-utils.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2018 Red Hat, Inc. */ @@ -9,66 +9,63 @@ #include "NetworkManagerUtils.h" typedef enum { - NMS_KEYFILE_FILETYPE_KEYFILE, - NMS_KEYFILE_FILETYPE_NMMETA, + NMS_KEYFILE_FILETYPE_KEYFILE, + NMS_KEYFILE_FILETYPE_NMMETA, } NMSKeyfileFiletype; typedef enum { - NMS_KEYFILE_STORAGE_TYPE_RUN = 1, /* read-write, runtime only, e.g. /run */ - NMS_KEYFILE_STORAGE_TYPE_ETC = 2, /* read-write, persistent, e.g. /etc */ - NMS_KEYFILE_STORAGE_TYPE_LIB_BASE = 3, /* read-only, e.g. /usr/lib */ + NMS_KEYFILE_STORAGE_TYPE_RUN = 1, /* read-write, runtime only, e.g. /run */ + NMS_KEYFILE_STORAGE_TYPE_ETC = 2, /* read-write, persistent, e.g. /etc */ + NMS_KEYFILE_STORAGE_TYPE_LIB_BASE = 3, /* read-only, e.g. /usr/lib */ - _NMS_KEYFILE_STORAGE_TYPE_LIB_LAST = 1000, + _NMS_KEYFILE_STORAGE_TYPE_LIB_LAST = 1000, } NMSKeyfileStorageType; static inline NMSKeyfileStorageType -NMS_KEYFILE_STORAGE_TYPE_LIB (guint run_idx) +NMS_KEYFILE_STORAGE_TYPE_LIB(guint run_idx) { - nm_assert (run_idx <= (_NMS_KEYFILE_STORAGE_TYPE_LIB_LAST - NMS_KEYFILE_STORAGE_TYPE_LIB_BASE)); - return NMS_KEYFILE_STORAGE_TYPE_LIB_BASE + run_idx; + nm_assert(run_idx <= (_NMS_KEYFILE_STORAGE_TYPE_LIB_LAST - NMS_KEYFILE_STORAGE_TYPE_LIB_BASE)); + return NMS_KEYFILE_STORAGE_TYPE_LIB_BASE + run_idx; } /*****************************************************************************/ -const char *nms_keyfile_nmmeta_check_filename (const char *filename, - guint *out_uuid_len); - -char *nms_keyfile_nmmeta_filename (const char *dirname, - const char *uuid, - gboolean temporary); - -gboolean nms_keyfile_nmmeta_read (const char *dirname, - const char *filename, - char **out_full_filename, - char **out_uuid, - char **out_loaded_path, - char **out_shadowed_storage, - struct stat *out_st); - -gboolean nms_keyfile_nmmeta_read_from_file (const char *full_filename, - char **out_dirname, - char **out_filename, - char **out_uuid, - char **out_loaded_path, - char **out_shadowed_storage); - -int nms_keyfile_nmmeta_write (const char *dirname, - const char *uuid, - const char *loaded_path, - gboolean loaded_path_allow_relative, - const char *shadowed_storage, - char **out_full_filename); +const char *nms_keyfile_nmmeta_check_filename(const char *filename, guint *out_uuid_len); + +char *nms_keyfile_nmmeta_filename(const char *dirname, const char *uuid, gboolean temporary); + +gboolean nms_keyfile_nmmeta_read(const char * dirname, + const char * filename, + char ** out_full_filename, + char ** out_uuid, + char ** out_loaded_path, + char ** out_shadowed_storage, + struct stat *out_st); + +gboolean nms_keyfile_nmmeta_read_from_file(const char *full_filename, + char ** out_dirname, + char ** out_filename, + char ** out_uuid, + char ** out_loaded_path, + char ** out_shadowed_storage); + +int nms_keyfile_nmmeta_write(const char *dirname, + const char *uuid, + const char *loaded_path, + gboolean loaded_path_allow_relative, + const char *shadowed_storage, + char ** out_full_filename); /*****************************************************************************/ struct stat; -gboolean nms_keyfile_utils_check_file_permissions_stat (NMSKeyfileFiletype filetype, - const struct stat *st, - GError **error); - -gboolean nms_keyfile_utils_check_file_permissions (NMSKeyfileFiletype filetype, - const char *filename, - struct stat *out_st, - GError **error); +gboolean nms_keyfile_utils_check_file_permissions_stat(NMSKeyfileFiletype filetype, + const struct stat *st, + GError ** error); + +gboolean nms_keyfile_utils_check_file_permissions(NMSKeyfileFiletype filetype, + const char * filename, + struct stat * out_st, + GError ** error); #endif /* __NMS_KEYFILE_UTILS_H__ */ diff --git a/src/settings/plugins/keyfile/nms-keyfile-writer.c b/src/settings/plugins/keyfile/nms-keyfile-writer.c index feea6065..4b13cef4 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-writer.c +++ b/src/settings/plugins/keyfile/nms-keyfile-writer.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 Novell, Inc. * Copyright (C) 2008 - 2015 Red Hat, Inc. @@ -22,435 +22,460 @@ /*****************************************************************************/ typedef struct { - const char *keyfile_dir; + const char *keyfile_dir; } WriteInfo; static void -cert_writer (NMConnection *connection, - GKeyFile *file, - NMSetting8021x *setting, - const NMSetting8021xSchemeVtable *vtable, - WriteInfo *info, - GError **error) +cert_writer(NMConnection * connection, + GKeyFile * file, + NMSetting8021x * setting, + const NMSetting8021xSchemeVtable *vtable, + WriteInfo * info, + GError ** error) { - const char *setting_name = nm_setting_get_name (NM_SETTING (setting)); - NMSetting8021xCKScheme scheme; - NMSetting8021xCKFormat format; - const char *path = NULL, *ext = "pem"; - - scheme = vtable->scheme_func (setting); - if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { - char *tmp = NULL; - const char *accepted_path = NULL; - - path = vtable->path_func (setting); - g_assert (path); - - if (g_str_has_prefix (path, info->keyfile_dir)) { - const char *p = path + strlen (info->keyfile_dir); - - /* If the path is rooted in the keyfile directory, just use a - * relative path instead of an absolute one. - */ - if (*p == '/') { - while (*p == '/') - p++; - if (p[0]) { - /* If @p looks like an integer list, the following detection will fail too and - * we will file:// qualify the path below. We thus avoid writing a path string - * that would be interpreted as legacy binary format by reader. */ - tmp = nm_keyfile_detect_unqualified_path_scheme (info->keyfile_dir, p, -1, FALSE, NULL); - if (tmp) { - nm_clear_g_free (&tmp); - accepted_path = p; - } - } - } - } - if (!accepted_path) { - /* What we are about to write, must also be understood by the reader. - * Otherwise, add a file:// prefix */ - tmp = nm_keyfile_detect_unqualified_path_scheme (info->keyfile_dir, path, -1, FALSE, NULL); - if (tmp) { - nm_clear_g_free (&tmp); - accepted_path = path; - } - } - - 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, 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, vtable->setting_key, - vtable->uri_func (setting)); - } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { - GBytes *blob; - const guint8 *blob_data; - gsize blob_len; - gboolean success; - GError *local = NULL; - char *new_path; - - blob = vtable->blob_func (setting); - g_assert (blob); - blob_data = g_bytes_get_data (blob, &blob_len); - - if (vtable->format_func) { - /* Get the extension for a private key */ - format = vtable->format_func (setting); - if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) - ext = "p12"; - } else { - /* DER or PEM format certificate? */ - if (blob_len > 2 && blob_data[0] == 0x30 && blob_data[1] == 0x82) - ext = "der"; - } - - /* Write the raw data out to the standard file so that we can use paths - * 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), - 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 - * proceed. That means, while writing we must only collect the blogs in-memory, and write - * them all in the end together (or not at all). */ - success = nm_utils_file_set_contents (new_path, - (const char *) blob_data, - blob_len, - 0600, - NULL, - &local); - 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, 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, vtable->setting_key, new_path, local->message); - g_error_free (local); - } - g_free (new_path); - } else { - /* scheme_func() returns UNKNOWN in all other cases. The only valid case - * where a scheme is allowed to be UNKNOWN, is unsetting the value. In this - * case, we don't expect the writer to be called, because the default value - * will not be serialized. - * The only other reason for the scheme to be UNKNOWN is an invalid cert. - * But our connection verifies, so that cannot happen either. */ - g_return_if_reached (); - } + const char * setting_name = nm_setting_get_name(NM_SETTING(setting)); + NMSetting8021xCKScheme scheme; + NMSetting8021xCKFormat format; + const char * path = NULL, *ext = "pem"; + + scheme = vtable->scheme_func(setting); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + char * tmp = NULL; + const char *accepted_path = NULL; + + path = vtable->path_func(setting); + g_assert(path); + + if (g_str_has_prefix(path, info->keyfile_dir)) { + const char *p = path + strlen(info->keyfile_dir); + + /* If the path is rooted in the keyfile directory, just use a + * relative path instead of an absolute one. + */ + if (*p == '/') { + while (*p == '/') + p++; + if (p[0]) { + /* If @p looks like an integer list, the following detection will fail too and + * we will file:// qualify the path below. We thus avoid writing a path string + * that would be interpreted as legacy binary format by reader. */ + tmp = nm_keyfile_detect_unqualified_path_scheme(info->keyfile_dir, + p, + -1, + FALSE, + NULL); + if (tmp) { + nm_clear_g_free(&tmp); + accepted_path = p; + } + } + } + } + if (!accepted_path) { + /* What we are about to write, must also be understood by the reader. + * Otherwise, add a file:// prefix */ + tmp = + nm_keyfile_detect_unqualified_path_scheme(info->keyfile_dir, path, -1, FALSE, NULL); + if (tmp) { + nm_clear_g_free(&tmp); + accepted_path = path; + } + } + + 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, 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, + vtable->setting_key, + vtable->uri_func(setting)); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + GBytes * blob; + const guint8 *blob_data; + gsize blob_len; + gboolean success; + GError * local = NULL; + char * new_path; + + blob = vtable->blob_func(setting); + g_assert(blob); + blob_data = g_bytes_get_data(blob, &blob_len); + + if (vtable->format_func) { + /* Get the extension for a private key */ + format = vtable->format_func(setting); + if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) + ext = "p12"; + } else { + /* DER or PEM format certificate? */ + if (blob_len > 2 && blob_data[0] == 0x30 && blob_data[1] == 0x82) + ext = "der"; + } + + /* Write the raw data out to the standard file so that we can use paths + * 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), + 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 + * proceed. That means, while writing we must only collect the blogs in-memory, and write + * them all in the end together (or not at all). */ + success = nm_utils_file_set_contents(new_path, + (const char *) blob_data, + blob_len, + 0600, + NULL, + &local); + 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, + 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, + vtable->setting_key, + new_path, + local->message); + g_error_free(local); + } + g_free(new_path); + } else { + /* scheme_func() returns UNKNOWN in all other cases. The only valid case + * where a scheme is allowed to be UNKNOWN, is unsetting the value. In this + * case, we don't expect the writer to be called, because the default value + * will not be serialized. + * The only other reason for the scheme to be UNKNOWN is an invalid cert. + * But our connection verifies, so that cannot happen either. */ + g_return_if_reached(); + } } static gboolean -_handler_write (NMConnection *connection, - GKeyFile *keyfile, - NMKeyfileHandlerType type, - NMKeyfileHandlerData *type_data, - void *user_data) +_handler_write(NMConnection * connection, + GKeyFile * keyfile, + NMKeyfileHandlerType type, + NMKeyfileHandlerData *type_data, + void * user_data) { - 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; + 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; } 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, - const char *profile_dir, - gboolean with_extension, - uid_t owner_uid, - pid_t owner_grp, - const char *existing_path, - gboolean existing_path_read_only, - gboolean force_rename, - NMSKeyfileWriterAllowFilenameCb allow_filename_cb, - gpointer allow_filename_user_data, - char **out_path, - NMConnection **out_reread, - gboolean *out_reread_same, - GError **error) +_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, + const char * profile_dir, + gboolean with_extension, + uid_t owner_uid, + pid_t owner_grp, + const char * existing_path, + gboolean existing_path_read_only, + gboolean force_rename, + NMSKeyfileWriterAllowFilenameCb allow_filename_cb, + gpointer allow_filename_user_data, + char ** out_path, + NMConnection ** out_reread, + gboolean * out_reread_same, + GError ** error) { - gs_unref_keyfile GKeyFile *kf_file = NULL; - gs_free char *kf_content_buf = NULL; - gsize kf_content_len; - gs_free char *path = NULL; - const char *id; - WriteInfo info = { 0 }; - gs_free_error GError *local_err = NULL; - int errsv; - gboolean rename; - int i_path; - gs_unref_object NMConnection *reread = NULL; - gboolean reread_same = FALSE; - - g_return_val_if_fail (!out_path || !*out_path, FALSE); - g_return_val_if_fail (keyfile_dir && keyfile_dir[0] == '/', FALSE); - - nm_assert (_nm_connection_verify (connection, NULL) == NM_SETTING_VERIFY_SUCCESS); - - nm_assert (!shadowed_owned || shadowed_storage); - - rename = force_rename - || existing_path_read_only - || ( existing_path - && !nm_utils_file_is_in_path (existing_path, keyfile_dir)); - - id = nm_connection_get_id (connection); - nm_assert (id && *id); - - info.keyfile_dir = keyfile_dir; - - kf_file = nm_keyfile_write (connection, NM_KEYFILE_HANDLER_FLAGS_NONE, _handler_write, &info, error); - if (!kf_file) - return FALSE; - - if (is_nm_generated) { - g_key_file_set_boolean (kf_file, - NM_KEYFILE_GROUP_NMMETA, - NM_KEYFILE_KEY_NMMETA_NM_GENERATED, - TRUE); - } - - if (is_volatile) { - g_key_file_set_boolean (kf_file, - NM_KEYFILE_GROUP_NMMETA, - NM_KEYFILE_KEY_NMMETA_VOLATILE, - 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, - NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE, - shadowed_storage); - } - - if (shadowed_owned) { - g_key_file_set_boolean (kf_file, - NM_KEYFILE_GROUP_NMMETA, - NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED, - TRUE); - } - - kf_content_buf = g_key_file_to_data (kf_file, &kf_content_len, error); - if (!kf_content_buf) - return FALSE; - - if (!g_file_test (keyfile_dir, G_FILE_TEST_IS_DIR)) - (void) g_mkdir_with_parents (keyfile_dir, 0755); - - for (i_path = -2; i_path < 10000; i_path++) { - gs_free char *path_candidate = NULL; - gboolean is_existing_path; - - if (i_path == -2) { - if ( !existing_path - || rename) - continue; - path_candidate = g_strdup (existing_path); - } else if (i_path == -1) { - gs_free char *filename_escaped = NULL; - - filename_escaped = nm_keyfile_utils_create_filename (id, with_extension); - path_candidate = g_build_filename (keyfile_dir, filename_escaped, NULL); - } else { - gs_free char *filename_escaped = NULL; - gs_free char *filename = NULL; - - if (i_path == 0) - filename = g_strdup_printf ("%s-%s", id, nm_connection_get_uuid (connection)); - else - filename = g_strdup_printf ("%s-%s-%d", id, nm_connection_get_uuid (connection), i_path); - - filename_escaped = nm_keyfile_utils_create_filename (filename, with_extension); - - path_candidate = g_strdup_printf ("%s/%s", keyfile_dir, filename_escaped); - } - - is_existing_path = existing_path - && nm_streq (existing_path, path_candidate); - - if ( is_existing_path - && rename) - continue; - - if ( allow_filename_cb - && !allow_filename_cb (path_candidate, allow_filename_user_data)) - continue; - - if (!is_existing_path) { - if (g_file_test (path_candidate, G_FILE_TEST_EXISTS)) - continue; - } - - path = g_steal_pointer (&path_candidate); - break; - } - - if (!path) { - /* this really should not happen, we tried hard to find an unused name... bail out. */ - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "could not find suitable keyfile file name (%s already used)", path); - return FALSE; - } - - if ( out_reread - || out_reread_same) { - gs_free_error GError *reread_error = NULL; - - reread = nms_keyfile_reader_from_keyfile (kf_file, path, NULL, profile_dir, FALSE, &reread_error); - - if ( !reread - || !nm_connection_normalize (reread, NULL, NULL, &reread_error)) { - nm_log_err (LOGD_SETTINGS, "BUG: the profile cannot be stored in keyfile format without becoming unusable: %s", reread_error->message); - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "keyfile writer produces an invalid connection: %s", - reread_error->message); - nm_assert_not_reached (); - return FALSE; - } - - if (out_reread_same) { - reread_same = !!nm_connection_compare (reread, connection, NM_SETTING_COMPARE_FLAG_EXACT); - - nm_assert (reread_same == nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); - nm_assert (reread_same == ({ - gs_unref_hashtable GHashTable *_settings = NULL; - - ( nm_connection_diff (reread, connection, NM_SETTING_COMPARE_FLAG_EXACT, &_settings) - && !_settings); - })); - } - } - - nm_utils_file_set_contents (path, - kf_content_buf, - kf_content_len, - 0600, - NULL, - &local_err); - if (local_err) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "error writing to file '%s': %s", - path, local_err->message); - return FALSE; - } - - if (chown (path, owner_uid, owner_grp) < 0) { - errsv = errno; - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "error chowning '%s': %s (%d)", - path, nm_strerror_native (errsv), errsv); - unlink (path); - return FALSE; - } - - /* In case of updating the connection and changing the file path, - * we need to remove the old one, not to end up with two connections. - */ - if ( existing_path - && !existing_path_read_only - && !nm_streq (path, existing_path)) - unlink (existing_path); - - NM_SET_OUT (out_reread, g_steal_pointer (&reread)); - NM_SET_OUT (out_reread_same, reread_same); - NM_SET_OUT (out_path, g_steal_pointer (&path)); - - return TRUE; + nm_auto_unref_keyfile GKeyFile *kf_file = NULL; + gs_free char * kf_content_buf = NULL; + gsize kf_content_len; + gs_free char * path = NULL; + const char * id; + WriteInfo info = {0}; + gs_free_error GError *local_err = NULL; + int errsv; + gboolean rename; + int i_path; + gs_unref_object NMConnection *reread = NULL; + gboolean reread_same = FALSE; + + g_return_val_if_fail(!out_path || !*out_path, FALSE); + g_return_val_if_fail(keyfile_dir && keyfile_dir[0] == '/', FALSE); + + nm_assert(_nm_connection_verify(connection, NULL) == NM_SETTING_VERIFY_SUCCESS); + + nm_assert(!shadowed_owned || shadowed_storage); + + rename = force_rename || existing_path_read_only + || (existing_path && !nm_utils_file_is_in_path(existing_path, keyfile_dir)); + + id = nm_connection_get_id(connection); + nm_assert(id && *id); + + info.keyfile_dir = keyfile_dir; + + kf_file = + nm_keyfile_write(connection, NM_KEYFILE_HANDLER_FLAGS_NONE, _handler_write, &info, error); + if (!kf_file) + return FALSE; + + if (is_nm_generated) { + g_key_file_set_boolean(kf_file, + NM_KEYFILE_GROUP_NMMETA, + NM_KEYFILE_KEY_NMMETA_NM_GENERATED, + TRUE); + } + + if (is_volatile) { + g_key_file_set_boolean(kf_file, + NM_KEYFILE_GROUP_NMMETA, + NM_KEYFILE_KEY_NMMETA_VOLATILE, + 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, + NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE, + shadowed_storage); + } + + if (shadowed_owned) { + g_key_file_set_boolean(kf_file, + NM_KEYFILE_GROUP_NMMETA, + NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED, + TRUE); + } + + kf_content_buf = g_key_file_to_data(kf_file, &kf_content_len, error); + if (!kf_content_buf) + return FALSE; + + if (!g_file_test(keyfile_dir, G_FILE_TEST_IS_DIR)) + (void) g_mkdir_with_parents(keyfile_dir, 0755); + + for (i_path = -2; i_path < 10000; i_path++) { + gs_free char *path_candidate = NULL; + gboolean is_existing_path; + + if (i_path == -2) { + if (!existing_path || rename) + continue; + path_candidate = g_strdup(existing_path); + } else if (i_path == -1) { + gs_free char *filename_escaped = NULL; + + filename_escaped = nm_keyfile_utils_create_filename(id, with_extension); + path_candidate = g_build_filename(keyfile_dir, filename_escaped, NULL); + } else { + gs_free char *filename_escaped = NULL; + gs_free char *filename = NULL; + + if (i_path == 0) + filename = g_strdup_printf("%s-%s", id, nm_connection_get_uuid(connection)); + else + filename = + g_strdup_printf("%s-%s-%d", id, nm_connection_get_uuid(connection), i_path); + + filename_escaped = nm_keyfile_utils_create_filename(filename, with_extension); + + path_candidate = g_strdup_printf("%s/%s", keyfile_dir, filename_escaped); + } + + is_existing_path = existing_path && nm_streq(existing_path, path_candidate); + + if (is_existing_path && rename) + continue; + + if (allow_filename_cb && !allow_filename_cb(path_candidate, allow_filename_user_data)) + continue; + + if (!is_existing_path) { + if (g_file_test(path_candidate, G_FILE_TEST_EXISTS)) + continue; + } + + path = g_steal_pointer(&path_candidate); + break; + } + + if (!path) { + /* this really should not happen, we tried hard to find an unused name... bail out. */ + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "could not find suitable keyfile file name (%s already used)", + path); + return FALSE; + } + + if (out_reread || out_reread_same) { + gs_free_error GError *reread_error = NULL; + + reread = + nms_keyfile_reader_from_keyfile(kf_file, path, NULL, profile_dir, FALSE, &reread_error); + + if (!reread || !nm_connection_normalize(reread, NULL, NULL, &reread_error)) { + nm_log_err( + LOGD_SETTINGS, + "BUG: the profile cannot be stored in keyfile format without becoming unusable: %s", + reread_error->message); + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "keyfile writer produces an invalid connection: %s", + reread_error->message); + nm_assert_not_reached(); + return FALSE; + } + + if (out_reread_same) { + reread_same = + !!nm_connection_compare(reread, connection, NM_SETTING_COMPARE_FLAG_EXACT); + + nm_assert(reread_same + == nm_connection_compare(connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + nm_assert(reread_same == ({ + gs_unref_hashtable GHashTable *_settings = NULL; + + (nm_connection_diff(reread, + connection, + NM_SETTING_COMPARE_FLAG_EXACT, + &_settings) + && !_settings); + })); + } + } + + nm_utils_file_set_contents(path, kf_content_buf, kf_content_len, 0600, NULL, &local_err); + if (local_err) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "error writing to file '%s': %s", + path, + local_err->message); + return FALSE; + } + + if (chown(path, owner_uid, owner_grp) < 0) { + errsv = errno; + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_FAILED, + "error chowning '%s': %s (%d)", + path, + nm_strerror_native(errsv), + errsv); + unlink(path); + return FALSE; + } + + /* In case of updating the connection and changing the file path, + * we need to remove the old one, not to end up with two connections. + */ + if (existing_path && !existing_path_read_only && !nm_streq(path, existing_path)) + unlink(existing_path); + + NM_SET_OUT(out_reread, g_steal_pointer(&reread)); + NM_SET_OUT(out_reread_same, reread_same); + NM_SET_OUT(out_path, g_steal_pointer(&path)); + + return TRUE; } 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, - const char *profile_dir, - const char *existing_path, - gboolean existing_path_read_only, - gboolean force_rename, - NMSKeyfileWriterAllowFilenameCb allow_filename_cb, - gpointer allow_filename_user_data, - char **out_path, - NMConnection **out_reread, - gboolean *out_reread_same, - GError **error) +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, + const char * profile_dir, + const char * existing_path, + gboolean existing_path_read_only, + gboolean force_rename, + NMSKeyfileWriterAllowFilenameCb allow_filename_cb, + gpointer allow_filename_user_data, + char ** out_path, + NMConnection ** out_reread, + gboolean * out_reread_same, + GError ** error) { - return _internal_write_connection (connection, - is_nm_generated, - is_volatile, - is_external, - shadowed_storage, - shadowed_owned, - keyfile_dir, - profile_dir, - TRUE, - 0, - 0, - existing_path, - existing_path_read_only, - force_rename, - allow_filename_cb, - allow_filename_user_data, - out_path, - out_reread, - out_reread_same, - error); + return _internal_write_connection(connection, + is_nm_generated, + is_volatile, + is_external, + shadowed_storage, + shadowed_owned, + keyfile_dir, + profile_dir, + TRUE, + 0, + 0, + existing_path, + existing_path_read_only, + force_rename, + allow_filename_cb, + allow_filename_user_data, + out_path, + out_reread, + out_reread_same, + error); } gboolean -nms_keyfile_writer_test_connection (NMConnection *connection, - const char *keyfile_dir, - uid_t owner_uid, - pid_t owner_grp, - char **out_path, - NMConnection **out_reread, - gboolean *out_reread_same, - GError **error) +nms_keyfile_writer_test_connection(NMConnection * connection, + const char * keyfile_dir, + uid_t owner_uid, + pid_t owner_grp, + char ** out_path, + NMConnection **out_reread, + gboolean * out_reread_same, + GError ** error) { - return _internal_write_connection (connection, - FALSE, - FALSE, - FALSE, - NULL, - FALSE, - keyfile_dir, - keyfile_dir, - FALSE, - owner_uid, - owner_grp, - NULL, - FALSE, - FALSE, - NULL, - NULL, - out_path, - out_reread, - out_reread_same, - error); + return _internal_write_connection(connection, + FALSE, + FALSE, + FALSE, + NULL, + FALSE, + keyfile_dir, + keyfile_dir, + FALSE, + owner_uid, + owner_grp, + NULL, + FALSE, + FALSE, + NULL, + NULL, + out_path, + out_reread, + out_reread_same, + error); } diff --git a/src/settings/plugins/keyfile/nms-keyfile-writer.h b/src/settings/plugins/keyfile/nms-keyfile-writer.h index 73a2e333..07de6569 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-writer.h +++ b/src/settings/plugins/keyfile/nms-keyfile-writer.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 Novell, Inc. * Copyright (C) 2008 - 2011 Red Hat, Inc. @@ -9,34 +9,34 @@ #include "nm-connection.h" -typedef gboolean (*NMSKeyfileWriterAllowFilenameCb) (const char *check_filename, - gpointer allow_filename_user_data); +typedef gboolean (*NMSKeyfileWriterAllowFilenameCb)(const char *check_filename, + gpointer allow_filename_user_data); -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, - const char *profile_dir, - const char *existing_path, - gboolean existing_path_read_only, - gboolean force_rename, - NMSKeyfileWriterAllowFilenameCb allow_filename_cb, - gpointer allow_filename_user_data, - char **out_path, - NMConnection **out_reread, - gboolean *out_reread_same, - GError **error); +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, + const char * profile_dir, + const char * existing_path, + gboolean existing_path_read_only, + gboolean force_rename, + NMSKeyfileWriterAllowFilenameCb allow_filename_cb, + gpointer allow_filename_user_data, + char ** out_path, + NMConnection ** out_reread, + gboolean * out_reread_same, + GError ** error); -gboolean nms_keyfile_writer_test_connection (NMConnection *connection, - const char *keyfile_dir, - uid_t owner_uid, - pid_t owner_grp, - char **out_path, - NMConnection **out_reread, - gboolean *out_reread_same, - GError **error); +gboolean nms_keyfile_writer_test_connection(NMConnection * connection, + const char * keyfile_dir, + uid_t owner_uid, + pid_t owner_grp, + char ** out_path, + NMConnection **out_reread, + gboolean * out_reread_same, + GError ** error); #endif /* __NMS_KEYFILE_WRITER_H__ */ diff --git a/src/settings/plugins/keyfile/tests/test-keyfile-settings.c b/src/settings/plugins/keyfile/tests/test-keyfile-settings.c index 98820272..4e8d89b1 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile-settings.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile-settings.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2008 - 2017 Red Hat, Inc. */ @@ -21,2680 +21,2901 @@ #include "nm-test-utils-core.h" -#define TEST_KEYFILES_DIR NM_BUILD_SRCDIR"/src/settings/plugins/keyfile/tests/keyfiles" -#define TEST_SCRATCH_DIR NM_BUILD_BUILDDIR"/src/settings/plugins/keyfile/tests/keyfiles" +#define TEST_KEYFILES_DIR NM_BUILD_SRCDIR "/src/settings/plugins/keyfile/tests/keyfiles" +#define TEST_SCRATCH_DIR NM_BUILD_BUILDDIR "/src/settings/plugins/keyfile/tests/keyfiles" /*****************************************************************************/ static void -check_ip_address (NMSettingIPConfig *config, int idx, const char *address, int plen) +check_ip_address(NMSettingIPConfig *config, int idx, const char *address, int plen) { - NMIPAddress *ip4 = nm_setting_ip_config_get_address (config, idx); + NMIPAddress *ip4 = nm_setting_ip_config_get_address(config, idx); - g_assert (ip4); - g_assert_cmpstr (nm_ip_address_get_address (ip4), ==, address); - g_assert_cmpint (nm_ip_address_get_prefix (ip4), ==, plen); + g_assert(ip4); + g_assert_cmpstr(nm_ip_address_get_address(ip4), ==, address); + g_assert_cmpint(nm_ip_address_get_prefix(ip4), ==, plen); } static void -check_ip_route (NMSettingIPConfig *config, int idx, const char *destination, int plen, - const char *next_hop, gint64 metric) +check_ip_route(NMSettingIPConfig *config, + int idx, + const char * destination, + int plen, + const char * next_hop, + gint64 metric) { - NMIPRoute *route = nm_setting_ip_config_get_route (config, idx); + NMIPRoute *route = nm_setting_ip_config_get_route(config, idx); - g_assert (route); - g_assert_cmpstr (nm_ip_route_get_dest (route), ==, destination); - g_assert_cmpint (nm_ip_route_get_prefix (route), ==, plen); - g_assert_cmpstr (nm_ip_route_get_next_hop (route), ==, next_hop); - g_assert_cmpint (nm_ip_route_get_metric (route), ==, metric); + g_assert(route); + g_assert_cmpstr(nm_ip_route_get_dest(route), ==, destination); + g_assert_cmpint(nm_ip_route_get_prefix(route), ==, plen); + g_assert_cmpstr(nm_ip_route_get_next_hop(route), ==, next_hop); + g_assert_cmpint(nm_ip_route_get_metric(route), ==, metric); } -#define keyfile_read_connection_from_file(full_filename) \ -({ \ - gs_free_error GError *_error = NULL; \ - NMConnection *_connection; \ - \ - g_assert (full_filename && full_filename[0] == '/'); \ - \ - _connection = nms_keyfile_reader_from_file (full_filename, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - (nmtst_get_rand_uint32 () % 2) ? &_error : NULL); \ - nmtst_assert_success (_connection, _error); \ - nmtst_assert_connection_verifies_without_normalization (_connection); \ - \ - _connection; \ -}) +#define keyfile_read_connection_from_file(full_filename) \ + ({ \ + gs_free_error GError *_error = NULL; \ + NMConnection * _connection; \ + \ + g_assert(full_filename &&full_filename[0] == '/'); \ + \ + _connection = \ + nms_keyfile_reader_from_file(full_filename, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + (nmtst_get_rand_uint32() % 2) ? &_error : NULL); \ + nmtst_assert_success(_connection, _error); \ + nmtst_assert_connection_verifies_without_normalization(_connection); \ + \ + _connection; \ + }) static void -assert_reread (NMConnection *connection, gboolean normalize_connection, const char *testfile) +assert_reread(NMConnection *connection, gboolean normalize_connection, const char *testfile) { - gs_unref_object NMConnection *reread = NULL; - gs_unref_object NMConnection *connection_clone = NULL; - NMSettingConnection *s_con; + gs_unref_object NMConnection *reread = NULL; + gs_unref_object NMConnection *connection_clone = NULL; + NMSettingConnection * s_con; - g_assert (NM_IS_CONNECTION (connection)); + g_assert(NM_IS_CONNECTION(connection)); - reread = keyfile_read_connection_from_file (testfile); + reread = keyfile_read_connection_from_file(testfile); - if ( !normalize_connection - && (s_con = nm_connection_get_setting_connection (connection)) - && !nm_setting_connection_get_master (s_con) - && !nm_connection_get_setting_proxy (connection)) { - connection_clone = nmtst_clone_connection (connection); - connection = connection_clone; - nm_connection_add_setting (connection, nm_setting_proxy_new ()); - } + if (!normalize_connection && (s_con = nm_connection_get_setting_connection(connection)) + && !nm_setting_connection_get_master(s_con) + && !nm_connection_get_setting_proxy(connection)) { + connection_clone = nmtst_clone_connection(connection); + connection = connection_clone; + nm_connection_add_setting(connection, nm_setting_proxy_new()); + } - nmtst_assert_connection_equals (connection, normalize_connection, reread, FALSE); + nmtst_assert_connection_equals(connection, normalize_connection, reread, FALSE); } static void -assert_reread_and_unlink (NMConnection *connection, gboolean normalize_connection, const char *testfile) +assert_reread_and_unlink(NMConnection *connection, + gboolean normalize_connection, + const char * testfile) { - assert_reread (connection, normalize_connection, testfile); - unlink (testfile); + assert_reread(connection, normalize_connection, testfile); + unlink(testfile); } static void -assert_reread_same (NMConnection *connection, - NMConnection *reread) +assert_reread_same(NMConnection *connection, NMConnection *reread) { - nmtst_assert_connection_verifies_without_normalization (reread); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); + nmtst_assert_connection_verifies_without_normalization(reread); + nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); } static void -write_test_connection_reread (NMConnection *connection, - char **testfile, - NMConnection **out_reread, - gboolean *out_reread_same) +write_test_connection_reread(NMConnection * connection, + char ** testfile, + NMConnection **out_reread, + gboolean * out_reread_same) { - uid_t owner_uid; - gid_t owner_grp; - gboolean success; - GError *error = NULL; - GError **p_error = (nmtst_get_rand_uint32 () % 2) ? &error : NULL; - gs_unref_object NMConnection *connection_normalized = NULL; + uid_t owner_uid; + gid_t owner_grp; + gboolean success; + GError * error = NULL; + GError ** p_error = (nmtst_get_rand_uint32() % 2) ? &error : NULL; + gs_unref_object NMConnection *connection_normalized = NULL; - g_assert (NM_IS_CONNECTION (connection)); - g_assert (testfile && !*testfile); + g_assert(NM_IS_CONNECTION(connection)); + g_assert(testfile && !*testfile); - owner_uid = geteuid (); - owner_grp = getegid (); + owner_uid = geteuid(); + owner_grp = getegid(); - connection_normalized = nmtst_connection_duplicate_and_normalize (connection); + connection_normalized = nmtst_connection_duplicate_and_normalize(connection); - success = nms_keyfile_writer_test_connection (connection_normalized, - TEST_SCRATCH_DIR, - owner_uid, - owner_grp, - testfile, - out_reread, - out_reread_same, - p_error); - g_assert_no_error (error); - g_assert (success); - g_assert (*testfile && (*testfile)[0]); + success = nms_keyfile_writer_test_connection(connection_normalized, + TEST_SCRATCH_DIR, + owner_uid, + owner_grp, + testfile, + out_reread, + out_reread_same, + p_error); + g_assert_no_error(error); + g_assert(success); + g_assert(*testfile && (*testfile)[0]); } static void -write_test_connection (NMConnection *connection, char **testfile) +write_test_connection(NMConnection *connection, char **testfile) { - gs_unref_object NMConnection *reread = NULL; - gboolean reread_same = FALSE; + gs_unref_object NMConnection *reread = NULL; + gboolean reread_same = FALSE; - write_test_connection_reread (connection, testfile, &reread, &reread_same); - assert_reread_same (connection, reread); - g_assert (reread_same); + write_test_connection_reread(connection, testfile, &reread, &reread_same); + assert_reread_same(connection, reread); + g_assert(reread_same); } static void -write_test_connection_and_reread (NMConnection *connection, gboolean normalize_connection) +write_test_connection_and_reread(NMConnection *connection, gboolean normalize_connection) { - gs_free char *testfile = NULL; + gs_free char *testfile = NULL; - g_assert (NM_IS_CONNECTION (connection)); + g_assert(NM_IS_CONNECTION(connection)); - write_test_connection (connection, &testfile); - assert_reread_and_unlink (connection, normalize_connection, testfile); + write_test_connection(connection, &testfile); + assert_reread_and_unlink(connection, normalize_connection, testfile); } static GKeyFile * -keyfile_load_from_file (const char *testfile) +keyfile_load_from_file(const char *testfile) { - GKeyFile *keyfile; - GError *error = NULL; - gboolean success; + GKeyFile *keyfile; + GError * error = NULL; + gboolean success; - g_assert (testfile && *testfile); + g_assert(testfile && *testfile); - keyfile = g_key_file_new (); - success = g_key_file_load_from_file (keyfile, testfile, G_KEY_FILE_NONE, &error); - g_assert_no_error (error); - g_assert(success); + keyfile = g_key_file_new(); + success = g_key_file_load_from_file(keyfile, testfile, G_KEY_FILE_NONE, &error); + g_assert_no_error(error); + g_assert(success); - return keyfile; + return keyfile; } static void -_setting_copy_property_gbytes (NMConnection *src, NMConnection *dst, const char *setting_name, const char *property_name) +_setting_copy_property_gbytes(NMConnection *src, + NMConnection *dst, + const char * setting_name, + const char * property_name) { - gs_unref_bytes GBytes *blob = NULL; - NMSetting *s_src; - NMSetting *s_dst; + gs_unref_bytes GBytes *blob = NULL; + NMSetting * s_src; + NMSetting * s_dst; - g_assert (NM_IS_CONNECTION (src)); - g_assert (NM_IS_CONNECTION (dst)); - g_assert (setting_name); - g_assert (property_name); + g_assert(NM_IS_CONNECTION(src)); + g_assert(NM_IS_CONNECTION(dst)); + g_assert(setting_name); + g_assert(property_name); - s_src = nm_connection_get_setting_by_name (src, setting_name); - g_assert (NM_IS_SETTING (s_src)); - s_dst = nm_connection_get_setting_by_name (dst, setting_name); - g_assert (NM_IS_SETTING (s_dst)); + s_src = nm_connection_get_setting_by_name(src, setting_name); + g_assert(NM_IS_SETTING(s_src)); + s_dst = nm_connection_get_setting_by_name(dst, setting_name); + g_assert(NM_IS_SETTING(s_dst)); - g_object_get (s_src, property_name, &blob, NULL); - g_object_set (s_dst, property_name, blob, NULL); + g_object_get(s_src, property_name, &blob, NULL); + g_object_set(s_dst, property_name, blob, NULL); } /*****************************************************************************/ static void -test_read_valid_wired_connection (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMIPRoute *route; - const char *mac; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; - - NMTST_EXPECT_NM_INFO ("*ipv4.addresses:*semicolon at the end*addresses1*"); - NMTST_EXPECT_NM_INFO ("*ipv4.addresses:*semicolon at the end*addresses2*"); - NMTST_EXPECT_NM_WARN ("*missing prefix length*address4*"); - NMTST_EXPECT_NM_WARN ("*missing prefix length*address5*"); - NMTST_EXPECT_NM_WARN ("*ipv4.dns: ignoring invalid DNS server IPv4 address 'bogus'*"); - NMTST_EXPECT_NM_INFO ("*ipv4.routes*semicolon at the end*routes2*"); - NMTST_EXPECT_NM_INFO ("*ipv4.routes*semicolon at the end*routes3*"); - NMTST_EXPECT_NM_INFO ("*ipv4.routes*semicolon at the end*routes5*"); - NMTST_EXPECT_NM_INFO ("*ipv4.routes*semicolon at the end*routes8*"); - NMTST_EXPECT_NM_WARN ("*missing prefix length*address4*"); - NMTST_EXPECT_NM_INFO ("*ipv6.address*semicolon at the end*address5*"); - NMTST_EXPECT_NM_WARN ("*missing prefix length*address5*"); - NMTST_EXPECT_NM_INFO ("*ipv6.address*semicolon at the end*address7*"); - NMTST_EXPECT_NM_INFO ("*ipv6.routes*semicolon at the end*routes1*"); - NMTST_EXPECT_NM_INFO ("*ipv6.route*semicolon at the end*route6*"); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Wired_Connection"); - g_test_assert_expected_messages (); - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "Test Wired Connection"); - g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, "4e80a56d-c99f-4aad-a6dd-b449bc398c57"); - g_assert_cmpuint (nm_setting_connection_get_timestamp (s_con), ==, 6654332); - g_assert (nm_setting_connection_get_autoconnect (s_con)); - - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - - mac = nm_setting_wired_get_mac_address (s_wired); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address))); - g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 1400); - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "4.2.2.1"); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 1), ==, "4.2.2.2"); - - /* IPv4 addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 10); - check_ip_address (s_ip4, 0, "2.3.4.5", 24); - check_ip_address (s_ip4, 1, "192.168.0.5", 24); - check_ip_address (s_ip4, 2, "1.2.3.4", 16); - check_ip_address (s_ip4, 3, "3.4.5.6", 16); - check_ip_address (s_ip4, 4, "4.5.6.7", 24); - check_ip_address (s_ip4, 5, "5.6.7.8", 24); - check_ip_address (s_ip4, 6, "1.2.3.30", 24); - check_ip_address (s_ip4, 7, "1.2.3.30", 25); - check_ip_address (s_ip4, 8, "1.2.3.31", 24); - check_ip_address (s_ip4, 9, "1.2.3.31", 25); - - /* IPv4 gateway */ - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "2.3.4.6"); - - /* IPv4 routes */ - g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 14); - check_ip_route (s_ip4, 0, "5.6.7.8", 32, NULL, -1); - check_ip_route (s_ip4, 1, "1.2.3.0", 24, "2.3.4.8", 99); - check_ip_route (s_ip4, 2, "1.1.1.2", 12, NULL, -1); - check_ip_route (s_ip4, 3, "1.1.1.3", 13, NULL, -1); - check_ip_route (s_ip4, 4, "1.1.1.4", 14, "2.2.2.4", -1); - check_ip_route (s_ip4, 5, "1.1.1.5", 15, "2.2.2.5", -1); - check_ip_route (s_ip4, 6, "1.1.1.6", 16, "2.2.2.6", 0); - check_ip_route (s_ip4, 7, "1.1.1.7", 17, NULL, -1); - check_ip_route (s_ip4, 8, "1.1.1.8", 18, NULL, -1); - check_ip_route (s_ip4, 9, "1.1.1.9", 19, NULL, 0); - check_ip_route (s_ip4, 10, "1.1.1.10", 21, NULL, 0); - check_ip_route (s_ip4, 11, "1.1.1.10", 20, NULL, 0); - check_ip_route (s_ip4, 12, "1.1.1.11", 21, NULL, 21); - check_ip_route (s_ip4, 13, "1.2.3.4", 32, NULL, -1); - - /* Route attributes */ - route = nm_setting_ip_config_get_route (s_ip4, 12); - g_assert (route); - - nmtst_assert_route_attribute_uint32 (route, NM_IP_ROUTE_ATTRIBUTE_CWND, 10); - nmtst_assert_route_attribute_uint32 (route, NM_IP_ROUTE_ATTRIBUTE_MTU, 1430); - nmtst_assert_route_attribute_boolean (route, NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, TRUE); - nmtst_assert_route_attribute_string (route, NM_IP_ROUTE_ATTRIBUTE_SRC, "7.7.7.7"); - nmtst_assert_route_attribute_string (route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "unicast"); - - route = nm_setting_ip_config_get_route (s_ip4, 13); - g_assert (route); - - nmtst_assert_route_attribute_string (route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "local"); - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_MANUAL); - - g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip6), ==, 2); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 0), ==, "1111:dddd::aaaa"); - g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 1), ==, "1::cafe"); - g_assert_cmpint (nm_setting_ip_config_get_num_dns_searches (s_ip6), ==, 3); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 0), ==, "super-domain.com"); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 1), ==, "redhat.com"); - g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 2), ==, "gnu.org"); - - /* IPv6 addresses */ - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip6), ==, 10); - check_ip_address (s_ip6, 0, "2:3:4:5:6:7:8:9", 64); - check_ip_address (s_ip6, 1, "abcd:1234:ffff::cdde", 64); - check_ip_address (s_ip6, 2, "1:2:3:4:5:6:7:8", 96); - check_ip_address (s_ip6, 3, "3:4:5:6:7:8:9:0", 128); - check_ip_address (s_ip6, 4, "3:4:5:6:7:8:9:14", 64); - check_ip_address (s_ip6, 5, "3:4:5:6:7:8:9:15", 64); - check_ip_address (s_ip6, 6, "3:4:5:6:7:8:9:16", 66); - check_ip_address (s_ip6, 7, "3:4:5:6:7:8:9:17", 67); - check_ip_address (s_ip6, 8, "3:4:5:6:7:8:9:18", 68); - check_ip_address (s_ip6, 9, "3:4:5:6:7:8:9:19", 69); - - /* IPv6 gateway */ - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, "2:3:4:5:1:2:3:4"); - - /* Routes */ - g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip6), ==, 7); - check_ip_route (s_ip6, 0, "d:e:f:0:1:2:3:4", 64, "f:e:d:c:1:2:3:4", -1); - check_ip_route (s_ip6, 1, "a:b:c:d::", 64, "f:e:d:c:1:2:3:4", 99); - check_ip_route (s_ip6, 2, "8:7:6:5:4:3:2:1", 128, NULL, -1); - check_ip_route (s_ip6, 3, "6:7:8:9:0:1:2:3", 126, NULL, 1); - check_ip_route (s_ip6, 4, "7:8:9:0:1:2:3:4", 125, NULL, 5); - check_ip_route (s_ip6, 5, "8:9:0:1:2:3:4:5", 124, NULL, 6); - check_ip_route (s_ip6, 6, "8:9:0:1:2:3:4:6", 123, NULL, -1); - - /* Route attributes */ - route = nm_setting_ip_config_get_route (s_ip6, 6); - g_assert (route); - nmtst_assert_route_attribute_string (route, NM_IP_ROUTE_ATTRIBUTE_FROM, "abce::/63"); -} - -static void -add_one_ip_address (NMSettingIPConfig *s_ip, - const char *addr, - guint32 prefix) -{ - NMIPAddress *ip_addr; - gs_free_error GError *error = NULL; - - ip_addr = nm_ip_address_new (NM_IS_SETTING_IP4_CONFIG (s_ip) ? AF_INET : AF_INET6, - addr, prefix, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip, ip_addr); - nm_ip_address_unref (ip_addr); -} - -static void -add_one_ip_route (NMSettingIPConfig *s_ip, - const char *dest, - const char *nh, - guint32 prefix, - gint64 metric) -{ - NMIPRoute *route; - gs_free_error GError *error = NULL; - - g_assert (prefix > 0); - route = nm_ip_route_new (NM_IS_SETTING_IP4_CONFIG (s_ip) ? AF_INET : AF_INET6, - dest, prefix, nh, metric, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_route (s_ip, route); - nm_ip_route_unref (route); -} - -static void -test_write_wired_connection (void) -{ - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMIPRoute *rt; - const char *mac = "99:88:77:66:55:44"; - const char *dns1 = "4.2.2.1"; - const char *dns2 = "4.2.2.2"; - const char *address1 = "192.168.0.5"; - const char *address2 = "1.2.3.4"; - const char *gw = "192.168.0.1"; - const char *route1 = "10.10.10.2"; - 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 = NULL; - const char *route4 = "3.3.3.3"; - const char *route4_nh = NULL; - const char *dns6_1 = "1::cafe"; - const char *dns6_2 = "2::cafe"; - const char *address6_1 = "abcd::beef"; - const char *address6_2 = "dcba::beef"; - const char *route6_1 = "1:2:3:4:5:6:7:8"; - 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; - GError *error = NULL; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Work Wired", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_TIMESTAMP, timestamp, - NULL); - - /* Wired setting */ - - s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - g_object_set (s_wired, - NM_SETTING_WIRED_MAC_ADDRESS, mac, - NM_SETTING_WIRED_MTU, 900, - NULL); - - /* IP4 setting */ - - s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, gw, - NULL); - - /* Addresses */ - add_one_ip_address (s_ip4, address1, 24); - add_one_ip_address (s_ip4, address2, 8); - - /* Routes */ - add_one_ip_route (s_ip4, route1, route1_nh, 24, 3); - add_one_ip_route (s_ip4, route2, route2_nh, 8, 1); - add_one_ip_route (s_ip4, route3, route3_nh, 7, -1); - - rt = nm_ip_route_new (AF_INET, route4, 6, route4_nh, 4, &error); - g_assert_no_error (error); - nm_ip_route_set_attribute (rt, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32 (10)); - nm_ip_route_set_attribute (rt, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32 (1492)); - nm_ip_route_set_attribute (rt, NM_IP_ROUTE_ATTRIBUTE_SRC, g_variant_new_string ("1.2.3.4")); - g_assert (nm_setting_ip_config_add_route (s_ip4, rt)); - nm_ip_route_unref (rt); - - /* DNS servers */ - nm_setting_ip_config_add_dns (s_ip4, dns1); - nm_setting_ip_config_add_dns (s_ip4, dns2); - - /* IP6 setting */ - - s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NULL); - - /* Addresses */ - add_one_ip_address (s_ip6, address6_1, 64); - add_one_ip_address (s_ip6, address6_2, 56); - - /* Routes */ - add_one_ip_route (s_ip6, route6_1, route6_1_nh, 64, 3); - add_one_ip_route (s_ip6, route6_2, route6_2_nh, 56, 1); - add_one_ip_route (s_ip6, route6_3, route6_3_nh, 63, 5); - add_one_ip_route (s_ip6, route6_4, route6_4_nh, 62, -1); - - /* DNS servers */ - nm_setting_ip_config_add_dns (s_ip6, dns6_1); - nm_setting_ip_config_add_dns (s_ip6, dns6_2); - - /* DNS searches */ - nm_setting_ip_config_add_dns_search (s_ip6, "wallaceandgromit.com"); - - write_test_connection_and_reread (connection, FALSE); +test_read_valid_wired_connection(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMIPRoute * route; + const char * mac; + char expected_mac_address[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; + + NMTST_EXPECT_NM_INFO("*ipv4.addresses:*semicolon at the end*addresses1*"); + NMTST_EXPECT_NM_INFO("*ipv4.addresses:*semicolon at the end*addresses2*"); + NMTST_EXPECT_NM_WARN("*missing prefix length*address4*"); + NMTST_EXPECT_NM_WARN("*missing prefix length*address5*"); + NMTST_EXPECT_NM_WARN("*ipv4.dns: ignoring invalid DNS server IPv4 address 'bogus'*"); + NMTST_EXPECT_NM_INFO("*ipv4.routes*semicolon at the end*routes2*"); + NMTST_EXPECT_NM_INFO("*ipv4.routes*semicolon at the end*routes3*"); + NMTST_EXPECT_NM_INFO("*ipv4.routes*semicolon at the end*routes5*"); + NMTST_EXPECT_NM_INFO("*ipv4.routes*semicolon at the end*routes8*"); + NMTST_EXPECT_NM_WARN("*missing prefix length*address4*"); + NMTST_EXPECT_NM_INFO("*ipv6.address*semicolon at the end*address5*"); + NMTST_EXPECT_NM_WARN("*missing prefix length*address5*"); + NMTST_EXPECT_NM_INFO("*ipv6.address*semicolon at the end*address7*"); + NMTST_EXPECT_NM_INFO("*ipv6.routes*semicolon at the end*routes1*"); + NMTST_EXPECT_NM_INFO("*ipv6.route*semicolon at the end*route6*"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_Connection"); + g_test_assert_expected_messages(); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "Test Wired Connection"); + g_assert_cmpstr(nm_setting_connection_get_uuid(s_con), + ==, + "4e80a56d-c99f-4aad-a6dd-b449bc398c57"); + g_assert_cmpuint(nm_setting_connection_get_timestamp(s_con), ==, 6654332); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + mac = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, sizeof(expected_mac_address))); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 1400); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 0), ==, "4.2.2.1"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 1), ==, "4.2.2.2"); + + /* IPv4 addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 10); + check_ip_address(s_ip4, 0, "2.3.4.5", 24); + check_ip_address(s_ip4, 1, "192.168.0.5", 24); + check_ip_address(s_ip4, 2, "1.2.3.4", 16); + check_ip_address(s_ip4, 3, "3.4.5.6", 16); + check_ip_address(s_ip4, 4, "4.5.6.7", 24); + check_ip_address(s_ip4, 5, "5.6.7.8", 24); + check_ip_address(s_ip4, 6, "1.2.3.30", 24); + check_ip_address(s_ip4, 7, "1.2.3.30", 25); + check_ip_address(s_ip4, 8, "1.2.3.31", 24); + check_ip_address(s_ip4, 9, "1.2.3.31", 25); + + /* IPv4 gateway */ + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "2.3.4.6"); + + /* IPv4 routes */ + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 14); + check_ip_route(s_ip4, 0, "5.6.7.8", 32, NULL, -1); + check_ip_route(s_ip4, 1, "1.2.3.0", 24, "2.3.4.8", 99); + check_ip_route(s_ip4, 2, "1.1.1.2", 12, NULL, -1); + check_ip_route(s_ip4, 3, "1.1.1.3", 13, NULL, -1); + check_ip_route(s_ip4, 4, "1.1.1.4", 14, "2.2.2.4", -1); + check_ip_route(s_ip4, 5, "1.1.1.5", 15, "2.2.2.5", -1); + check_ip_route(s_ip4, 6, "1.1.1.6", 16, "2.2.2.6", 0); + check_ip_route(s_ip4, 7, "1.1.1.7", 17, NULL, -1); + check_ip_route(s_ip4, 8, "1.1.1.8", 18, NULL, -1); + check_ip_route(s_ip4, 9, "1.1.1.9", 19, NULL, 0); + check_ip_route(s_ip4, 10, "1.1.1.10", 21, NULL, 0); + check_ip_route(s_ip4, 11, "1.1.1.10", 20, NULL, 0); + check_ip_route(s_ip4, 12, "1.1.1.11", 21, NULL, 21); + check_ip_route(s_ip4, 13, "1.2.3.4", 32, NULL, -1); + + /* Route attributes */ + route = nm_setting_ip_config_get_route(s_ip4, 12); + g_assert(route); + + nmtst_assert_route_attribute_uint32(route, NM_IP_ROUTE_ATTRIBUTE_CWND, 10); + nmtst_assert_route_attribute_uint32(route, NM_IP_ROUTE_ATTRIBUTE_MTU, 1430); + nmtst_assert_route_attribute_boolean(route, NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, TRUE); + nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_SRC, "7.7.7.7"); + nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "unicast"); + + route = nm_setting_ip_config_get_route(s_ip4, 13); + g_assert(route); + + nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "local"); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL); + + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 0), ==, "1111:dddd::aaaa"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 1), ==, "1::cafe"); + g_assert_cmpint(nm_setting_ip_config_get_num_dns_searches(s_ip6), ==, 3); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 0), ==, "super-domain.com"); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 1), ==, "redhat.com"); + g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 2), ==, "gnu.org"); + + /* IPv6 addresses */ + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 10); + check_ip_address(s_ip6, 0, "2:3:4:5:6:7:8:9", 64); + check_ip_address(s_ip6, 1, "abcd:1234:ffff::cdde", 64); + check_ip_address(s_ip6, 2, "1:2:3:4:5:6:7:8", 96); + check_ip_address(s_ip6, 3, "3:4:5:6:7:8:9:0", 128); + check_ip_address(s_ip6, 4, "3:4:5:6:7:8:9:14", 64); + check_ip_address(s_ip6, 5, "3:4:5:6:7:8:9:15", 64); + check_ip_address(s_ip6, 6, "3:4:5:6:7:8:9:16", 66); + check_ip_address(s_ip6, 7, "3:4:5:6:7:8:9:17", 67); + check_ip_address(s_ip6, 8, "3:4:5:6:7:8:9:18", 68); + check_ip_address(s_ip6, 9, "3:4:5:6:7:8:9:19", 69); + + /* IPv6 gateway */ + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip6), ==, "2:3:4:5:1:2:3:4"); + + /* Routes */ + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 7); + check_ip_route(s_ip6, 0, "d:e:f:0:1:2:3:4", 64, "f:e:d:c:1:2:3:4", -1); + check_ip_route(s_ip6, 1, "a:b:c:d::", 64, "f:e:d:c:1:2:3:4", 99); + check_ip_route(s_ip6, 2, "8:7:6:5:4:3:2:1", 128, NULL, -1); + check_ip_route(s_ip6, 3, "6:7:8:9:0:1:2:3", 126, NULL, 1); + check_ip_route(s_ip6, 4, "7:8:9:0:1:2:3:4", 125, NULL, 5); + check_ip_route(s_ip6, 5, "8:9:0:1:2:3:4:5", 124, NULL, 6); + check_ip_route(s_ip6, 6, "8:9:0:1:2:3:4:6", 123, NULL, -1); + + /* Route attributes */ + route = nm_setting_ip_config_get_route(s_ip6, 6); + g_assert(route); + nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_FROM, "abce::/63"); +} + +static void +add_one_ip_address(NMSettingIPConfig *s_ip, const char *addr, guint32 prefix) +{ + NMIPAddress * ip_addr; + gs_free_error GError *error = NULL; + + ip_addr = nm_ip_address_new(NM_IS_SETTING_IP4_CONFIG(s_ip) ? AF_INET : AF_INET6, + addr, + prefix, + &error); + g_assert_no_error(error); + nm_setting_ip_config_add_address(s_ip, ip_addr); + nm_ip_address_unref(ip_addr); +} + +static void +add_one_ip_route(NMSettingIPConfig *s_ip, + const char * dest, + const char * nh, + guint32 prefix, + gint64 metric) +{ + NMIPRoute * route; + gs_free_error GError *error = NULL; + + g_assert(prefix > 0); + route = nm_ip_route_new(NM_IS_SETTING_IP4_CONFIG(s_ip) ? AF_INET : AF_INET6, + dest, + prefix, + nh, + metric, + &error); + g_assert_no_error(error); + nm_setting_ip_config_add_route(s_ip, route); + nm_ip_route_unref(route); +} + +static void +test_write_wired_connection(void) +{ + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMIPRoute * rt; + const char * mac = "99:88:77:66:55:44"; + const char * dns1 = "4.2.2.1"; + const char * dns2 = "4.2.2.2"; + const char * address1 = "192.168.0.5"; + const char * address2 = "1.2.3.4"; + const char * gw = "192.168.0.1"; + const char * route1 = "10.10.10.2"; + 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 = NULL; + const char * route4 = "3.3.3.3"; + const char * route4_nh = NULL; + const char * dns6_1 = "1::cafe"; + const char * dns6_2 = "2::cafe"; + const char * address6_1 = "abcd::beef"; + const char * address6_2 = "dcba::beef"; + const char * route6_1 = "1:2:3:4:5:6:7:8"; + 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; + GError * error = NULL; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Work Wired", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP, + timestamp, + NULL); + + /* Wired setting */ + + s_wired = NM_SETTING_WIRED(nm_setting_wired_new()); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, 900, NULL); + + /* IP4 setting */ + + s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + gw, + NULL); + + /* Addresses */ + add_one_ip_address(s_ip4, address1, 24); + add_one_ip_address(s_ip4, address2, 8); + + /* Routes */ + add_one_ip_route(s_ip4, route1, route1_nh, 24, 3); + add_one_ip_route(s_ip4, route2, route2_nh, 8, 1); + add_one_ip_route(s_ip4, route3, route3_nh, 7, -1); + + rt = nm_ip_route_new(AF_INET, route4, 6, route4_nh, 4, &error); + g_assert_no_error(error); + nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32(10)); + nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32(1492)); + nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_SRC, g_variant_new_string("1.2.3.4")); + g_assert(nm_setting_ip_config_add_route(s_ip4, rt)); + nm_ip_route_unref(rt); + + /* DNS servers */ + nm_setting_ip_config_add_dns(s_ip4, dns1); + nm_setting_ip_config_add_dns(s_ip4, dns2); + + /* IP6 setting */ + + s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NULL); + + /* Addresses */ + add_one_ip_address(s_ip6, address6_1, 64); + add_one_ip_address(s_ip6, address6_2, 56); + + /* Routes */ + add_one_ip_route(s_ip6, route6_1, route6_1_nh, 64, 3); + add_one_ip_route(s_ip6, route6_2, route6_2_nh, 56, 1); + add_one_ip_route(s_ip6, route6_3, route6_3_nh, 63, 5); + add_one_ip_route(s_ip6, route6_4, route6_4_nh, 62, -1); + + /* DNS servers */ + nm_setting_ip_config_add_dns(s_ip6, dns6_1); + nm_setting_ip_config_add_dns(s_ip6, dns6_2); + + /* DNS searches */ + nm_setting_ip_config_add_dns_search(s_ip6, "wallaceandgromit.com"); + + write_test_connection_and_reread(connection, FALSE); } static void -test_read_ip6_wired_connection (void) +test_read_ip6_wired_connection(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Wired_Connection_IP6"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_Connection_IP6"); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "Test Wired Connection IP6"); - g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, "4e80a56d-c99f-4aad-a6dd-b449bc398c57"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "Test Wired Connection IP6"); + g_assert_cmpstr(nm_setting_connection_get_uuid(s_con), + ==, + "4e80a56d-c99f-4aad-a6dd-b449bc398c57"); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 0); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 0); - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_MANUAL); - g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip6), ==, 1); - check_ip_address (s_ip6, 0, "abcd:1234:ffff::cdde", 64); - g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, "abcd:1234:ffff::cdd1"); + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 1); + check_ip_address(s_ip6, 0, "abcd:1234:ffff::cdde", 64); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip6), ==, "abcd:1234:ffff::cdd1"); } static void -test_write_ip6_wired_connection (void) +test_write_ip6_wired_connection(void) { - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - const char *dns = "1::cafe"; - const char *address = "abcd::beef"; - const char *gw = "dcba::beef"; + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + const char * dns = "1::cafe"; + const char * address = "abcd::beef"; + const char * gw = "dcba::beef"; - connection = nm_simple_connection_new (); + connection = nm_simple_connection_new(); - /* Connection setting */ + /* Connection setting */ - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Work Wired IP6", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Work Wired IP6", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); - /* Wired setting */ + /* Wired setting */ - s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + s_wired = NM_SETTING_WIRED(nm_setting_wired_new()); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); - /* IP4 setting */ + /* IP4 setting */ - s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, - NULL); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NULL); - /* IP6 setting */ + /* IP6 setting */ - s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, gw, - NULL); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + gw, + NULL); - /* Addresses */ - add_one_ip_address (s_ip6, address, 64); + /* Addresses */ + add_one_ip_address(s_ip6, address, 64); - /* DNS servers */ - nm_setting_ip_config_add_dns (s_ip6, dns); + /* DNS servers */ + nm_setting_ip_config_add_dns(s_ip6, dns); - /* DNS searches */ - nm_setting_ip_config_add_dns_search (s_ip6, "wallaceandgromit.com"); + /* DNS searches */ + nm_setting_ip_config_add_dns_search(s_ip6, "wallaceandgromit.com"); - write_test_connection_and_reread (connection, FALSE); + write_test_connection_and_reread(connection, FALSE); } static void -test_read_wired_mac_case (void) +test_read_wired_mac_case(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - const char *mac; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55 }; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + const char * mac; + char expected_mac_address[ETH_ALEN] = {0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55}; - NMTST_EXPECT_NM_INFO ("*ipv4.addresses*semicolon at the end*addresses1*"); - NMTST_EXPECT_NM_INFO ("*ipv4.addresses*semicolon at the end*addresses2*"); - NMTST_EXPECT_NM_INFO ("*ipv6.routes*semicolon at the end*routes1*"); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Wired_Connection_MAC_Case"); - g_test_assert_expected_messages (); + NMTST_EXPECT_NM_INFO("*ipv4.addresses*semicolon at the end*addresses1*"); + NMTST_EXPECT_NM_INFO("*ipv4.addresses*semicolon at the end*addresses2*"); + NMTST_EXPECT_NM_INFO("*ipv6.routes*semicolon at the end*routes1*"); + connection = + keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_Connection_MAC_Case"); + g_test_assert_expected_messages(); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "Test Wired Connection MAC Case"); - g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, "4e80a56d-c99f-4aad-a6dd-b449bc398c57"); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "Test Wired Connection MAC Case"); + g_assert_cmpstr(nm_setting_connection_get_uuid(s_con), + ==, + "4e80a56d-c99f-4aad-a6dd-b449bc398c57"); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - mac = nm_setting_wired_get_mac_address (s_wired); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address))); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + mac = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, sizeof(expected_mac_address))); } static void -test_read_mac_old_format (void) +test_read_mac_old_format(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingWired *s_wired; - const char *mac; - char expected_mac[ETH_ALEN] = { 0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55 }; - char expected_cloned_mac[ETH_ALEN] = { 0x00, 0x16, 0xaa, 0xbb, 0xcc, 0xfe }; + gs_unref_object NMConnection *connection = NULL; + NMSettingWired * s_wired; + const char * mac; + char expected_mac[ETH_ALEN] = {0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55}; + char expected_cloned_mac[ETH_ALEN] = {0x00, 0x16, 0xaa, 0xbb, 0xcc, 0xfe}; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_MAC_Old_Format"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_MAC_Old_Format"); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); - mac = nm_setting_wired_get_mac_address (s_wired); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac, ETH_ALEN)); + mac = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac, ETH_ALEN)); - mac = nm_setting_wired_get_cloned_mac_address (s_wired); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_cloned_mac, ETH_ALEN)); + mac = nm_setting_wired_get_cloned_mac_address(s_wired); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_cloned_mac, ETH_ALEN)); } static void -test_read_mac_ib_old_format (void) +test_read_mac_ib_old_format(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingInfiniband *s_ib; - const char *mac; - 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 }; + gs_unref_object NMConnection *connection = NULL; + NMSettingInfiniband * s_ib; + const char * mac; + 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 = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_MAC_IB_Old_Format"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_MAC_IB_Old_Format"); - s_ib = nm_connection_get_setting_infiniband (connection); - g_assert (s_ib); + s_ib = nm_connection_get_setting_infiniband(connection); + g_assert(s_ib); - /* MAC address */ - mac = nm_setting_infiniband_get_mac_address (s_ib); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac, sizeof (expected_mac))); + /* MAC address */ + mac = nm_setting_infiniband_get_mac_address(s_ib); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac, sizeof(expected_mac))); } static void -test_read_valid_wireless_connection (void) +test_read_valid_wireless_connection(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingIPConfig *s_ip4; - const char *bssid; - const guint8 expected_bssid[ETH_ALEN] = { 0x00, 0x1a, 0x33, 0x44, 0x99, 0x82 }; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingIPConfig * s_ip4; + const char * bssid; + const guint8 expected_bssid[ETH_ALEN] = {0x00, 0x1a, 0x33, 0x44, 0x99, 0x82}; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Wireless_Connection"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wireless_Connection"); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "Test Wireless Connection"); - g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, "2f962388-e5f3-45af-a62c-ac220b8f7baa"); - g_assert_cmpuint (nm_setting_connection_get_timestamp (s_con), ==, 1226604314); - g_assert (nm_setting_connection_get_autoconnect (s_con) == FALSE); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "Test Wireless Connection"); + g_assert_cmpstr(nm_setting_connection_get_uuid(s_con), + ==, + "2f962388-e5f3-45af-a62c-ac220b8f7baa"); + g_assert_cmpuint(nm_setting_connection_get_timestamp(s_con), ==, 1226604314); + g_assert(nm_setting_connection_get_autoconnect(s_con) == FALSE); - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); - bssid = nm_setting_wireless_get_bssid (s_wireless); - g_assert (bssid); - g_assert (nm_utils_hwaddr_matches (bssid, -1, expected_bssid, sizeof (expected_bssid))); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); + bssid = nm_setting_wireless_get_bssid(s_wireless); + g_assert(bssid); + g_assert(nm_utils_hwaddr_matches(bssid, -1, expected_bssid, sizeof(expected_bssid))); - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); } static void -test_write_wireless_connection (void) +test_write_wireless_connection(void) { - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - const char *bssid = "aa:b9:a1:74:55:44"; - GBytes *ssid; - unsigned char tmpssid[] = { 0x31, 0x33, 0x33, 0x37 }; - guint64 timestamp = 0x12344433L; + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + const char * bssid = "aa:b9:a1:74:55:44"; + GBytes * ssid; + unsigned char tmpssid[] = {0x31, 0x33, 0x33, 0x37}; + guint64 timestamp = 0x12344433L; - connection = nm_simple_connection_new (); + connection = nm_simple_connection_new(); - /* Connection setting */ + /* Connection setting */ - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Work Wireless", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_CONNECTION_TIMESTAMP, timestamp, - NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Work Wireless", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP, + timestamp, + NULL); - /* Wireless setting */ + /* Wireless setting */ - s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_wireless)); + s_wireless = NM_SETTING_WIRELESS(nm_setting_wireless_new()); + nm_connection_add_setting(connection, NM_SETTING(s_wireless)); - ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); + ssid = g_bytes_new(tmpssid, sizeof(tmpssid)); - g_object_set (s_wireless, - NM_SETTING_WIRELESS_BSSID, bssid, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRED_MTU, 1000, - NULL); + g_object_set(s_wireless, + NM_SETTING_WIRELESS_BSSID, + bssid, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRED_MTU, + 1000, + NULL); - g_bytes_unref (ssid); + g_bytes_unref(ssid); - /* IP4 setting */ + /* IP4 setting */ - s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - /* IP6 setting */ + /* IP6 setting */ - s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NULL); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); - write_test_connection_and_reread (connection, FALSE); + write_test_connection_and_reread(connection, FALSE); } static void -test_read_string_ssid (void) +test_read_string_ssid(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingWireless *s_wireless; - GBytes *ssid; - const guint8 *ssid_data; - gsize ssid_len; - const char *expected_ssid = "blah blah ssid 1234"; + gs_unref_object NMConnection *connection = NULL; + NMSettingWireless * s_wireless; + GBytes * ssid; + const guint8 * ssid_data; + gsize ssid_len; + const char * expected_ssid = "blah blah ssid 1234"; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_String_SSID"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_String_SSID"); - s_wireless = nm_connection_get_setting_wireless (connection); - g_assert (s_wireless); + s_wireless = nm_connection_get_setting_wireless(connection); + g_assert(s_wireless); - ssid = nm_setting_wireless_get_ssid (s_wireless); - g_assert (ssid); + ssid = nm_setting_wireless_get_ssid(s_wireless); + g_assert(ssid); - ssid_data = g_bytes_get_data (ssid, &ssid_len); - g_assert_cmpmem (ssid_data, ssid_len, expected_ssid, strlen (expected_ssid)); + ssid_data = g_bytes_get_data(ssid, &ssid_len); + g_assert_cmpmem(ssid_data, ssid_len, expected_ssid, strlen(expected_ssid)); } static void -test_write_string_ssid (void) +test_write_string_ssid(void) { - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wireless; - NMSettingIPConfig *s_ip4; - char *tmp; - gs_free char *testfile = NULL; - GBytes *ssid; - unsigned char tmpssid[] = { 65, 49, 50, 51, 32, 46, 92, 46, 36, 37, 126, 93 }; - gs_unref_keyfile GKeyFile *keyfile = NULL; + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wireless; + NMSettingIPConfig * s_ip4; + char * tmp; + gs_free char * testfile = NULL; + GBytes * ssid; + unsigned char tmpssid[] = {65, 49, 50, 51, 32, 46, 92, 46, 36, 37, 126, 93}; + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; - connection = nm_simple_connection_new (); + connection = nm_simple_connection_new(); - /* Connection setting */ + /* Connection setting */ - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "String SSID Test", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "String SSID Test", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); - /* Wireless setting */ + /* Wireless setting */ - s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_wireless)); + s_wireless = NM_SETTING_WIRELESS(nm_setting_wireless_new()); + nm_connection_add_setting(connection, NM_SETTING(s_wireless)); - ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); - g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, ssid, NULL); - g_bytes_unref (ssid); + ssid = g_bytes_new(tmpssid, sizeof(tmpssid)); + g_object_set(s_wireless, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_bytes_unref(ssid); - /* IP4 setting */ + /* IP4 setting */ - s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - write_test_connection (connection, &testfile); + write_test_connection(connection, &testfile); - /* Ensure the SSID was written out as a string */ - keyfile = keyfile_load_from_file (testfile); - tmp = g_key_file_get_string (keyfile, "wifi", NM_SETTING_WIRELESS_SSID, NULL); - g_assert (tmp); - g_assert_cmpmem (tmp, strlen (tmp), tmpssid, sizeof (tmpssid)); - g_free (tmp); + /* Ensure the SSID was written out as a string */ + keyfile = keyfile_load_from_file(testfile); + tmp = g_key_file_get_string(keyfile, "wifi", NM_SETTING_WIRELESS_SSID, NULL); + g_assert(tmp); + g_assert_cmpmem(tmp, strlen(tmp), tmpssid, sizeof(tmpssid)); + g_free(tmp); - assert_reread_and_unlink (connection, TRUE, testfile); + assert_reread_and_unlink(connection, TRUE, testfile); } static void -test_read_intlist_ssid (void) +test_read_intlist_ssid(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingWireless *s_wifi; - GBytes *ssid; - const guint8 *ssid_data; - gsize ssid_len; - const char *expected_ssid = "blah1234"; + gs_unref_object NMConnection *connection = NULL; + NMSettingWireless * s_wifi; + GBytes * ssid; + const guint8 * ssid_data; + gsize ssid_len; + const char * expected_ssid = "blah1234"; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Intlist_SSID"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Intlist_SSID"); - s_wifi = nm_connection_get_setting_wireless (connection); - g_assert (s_wifi); + s_wifi = nm_connection_get_setting_wireless(connection); + g_assert(s_wifi); - ssid = nm_setting_wireless_get_ssid (s_wifi); - g_assert (ssid != NULL); - ssid_data = g_bytes_get_data (ssid, &ssid_len); - g_assert_cmpmem (ssid_data, ssid_len, expected_ssid, strlen (expected_ssid)); + ssid = nm_setting_wireless_get_ssid(s_wifi); + g_assert(ssid != NULL); + ssid_data = g_bytes_get_data(ssid, &ssid_len); + g_assert_cmpmem(ssid_data, ssid_len, expected_ssid, strlen(expected_ssid)); } static void -test_write_intlist_ssid (void) +test_write_intlist_ssid(void) { - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingIPConfig *s_ip4; - gs_free char *testfile = NULL; - GBytes *ssid; - unsigned char tmpssid[] = { 65, 49, 50, 51, 0, 50, 50 }; - gs_free_error GError *error = NULL; - gs_unref_keyfile GKeyFile *keyfile = NULL; - int *intlist; - gsize len = 0, i; - - connection = nm_simple_connection_new (); - g_assert (connection); - - /* Connection setting */ + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingIPConfig * s_ip4; + gs_free char * testfile = NULL; + GBytes * ssid; + unsigned char tmpssid[] = {65, 49, 50, 51, 0, 50, 50}; + gs_free_error GError *error = NULL; + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + int * intlist; + gsize len = 0, i; - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - g_assert (s_con); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + connection = nm_simple_connection_new(); + g_assert(connection); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Intlist SSID Test", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + /* Connection setting */ - /* Wireless setting */ - s_wifi = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - g_assert (s_wifi); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + g_assert(s_con); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); - g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); - g_bytes_unref (ssid); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Intlist SSID Test", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); - /* IP4 setting */ - s_ip4 = NM_SETTING_IP_CONFIG (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_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + /* Wireless setting */ + s_wifi = NM_SETTING_WIRELESS(nm_setting_wireless_new()); + g_assert(s_wifi); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - write_test_connection (connection, &testfile); + ssid = g_bytes_new(tmpssid, sizeof(tmpssid)); + g_object_set(s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_bytes_unref(ssid); - /* Ensure the SSID was written out as an int list */ - keyfile = keyfile_load_from_file (testfile); + /* IP4 setting */ + s_ip4 = NM_SETTING_IP_CONFIG(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_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - 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)); + write_test_connection(connection, &testfile); - for (i = 0; i < len; i++) - g_assert_cmpint (intlist[i], ==, tmpssid[i]); - g_free (intlist); - - assert_reread_and_unlink (connection, TRUE, testfile); -} - -static void -test_read_intlike_ssid (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSettingWireless *s_wifi; - GBytes *ssid; - const char *expected_ssid = "101"; + /* Ensure the SSID was written out as an int list */ + keyfile = keyfile_load_from_file(testfile); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Intlike_SSID"); + 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)); - s_wifi = nm_connection_get_setting_wireless (connection); - g_assert (s_wifi); + for (i = 0; i < len; i++) + g_assert_cmpint(intlist[i], ==, tmpssid[i]); + g_free(intlist); - ssid = nm_setting_wireless_get_ssid (s_wifi); - g_assert (ssid); - g_assert (nm_utils_gbytes_equal_mem (ssid, expected_ssid, strlen (expected_ssid))); + assert_reread_and_unlink(connection, TRUE, testfile); } static void -test_read_intlike_ssid_2 (void) +test_read_intlike_ssid(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingWireless *s_wifi; - GBytes *ssid; - const char *expected_ssid = "11;12;13;"; + gs_unref_object NMConnection *connection = NULL; + NMSettingWireless * s_wifi; + GBytes * ssid; + const char * expected_ssid = "101"; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Intlike_SSID_2"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Intlike_SSID"); - s_wifi = nm_connection_get_setting_wireless (connection); - g_assert (s_wifi); + s_wifi = nm_connection_get_setting_wireless(connection); + g_assert(s_wifi); - ssid = nm_setting_wireless_get_ssid (s_wifi); - g_assert (ssid); - g_assert (nm_utils_gbytes_equal_mem (ssid, expected_ssid, strlen (expected_ssid))); + ssid = nm_setting_wireless_get_ssid(s_wifi); + g_assert(ssid); + g_assert(nm_utils_gbytes_equal_mem(ssid, expected_ssid, strlen(expected_ssid))); } static void -test_write_intlike_ssid (void) +test_read_intlike_ssid_2(void) { - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingIPConfig *s_ip4; - gs_free char *testfile = NULL; - GBytes *ssid; - unsigned char tmpssid[] = { 49, 48, 49 }; - gs_free_error GError *error = NULL; - gs_unref_keyfile GKeyFile *keyfile = NULL; - char *tmp; + gs_unref_object NMConnection *connection = NULL; + NMSettingWireless * s_wifi; + GBytes * ssid; + const char * expected_ssid = "11;12;13;"; - connection = nm_simple_connection_new (); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Intlike_SSID_2"); - /* Connection setting */ + s_wifi = nm_connection_get_setting_wireless(connection); + g_assert(s_wifi); - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - g_assert (s_con); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Intlike SSID Test", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); - - /* Wireless setting */ - s_wifi = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - g_assert (s_wifi); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); - g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); - g_bytes_unref (ssid); - - /* IP4 setting */ - s_ip4 = NM_SETTING_IP_CONFIG (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_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - - write_test_connection (connection, &testfile); - - /* Ensure the SSID was written out as a plain "101" */ - keyfile = keyfile_load_from_file (testfile); - - 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"); - g_free (tmp); - - assert_reread_and_unlink (connection, TRUE, testfile); + ssid = nm_setting_wireless_get_ssid(s_wifi); + g_assert(ssid); + g_assert(nm_utils_gbytes_equal_mem(ssid, expected_ssid, strlen(expected_ssid))); } static void -test_write_intlike_ssid_2 (void) +test_write_intlike_ssid(void) { - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingIPConfig *s_ip4; - gs_free char *testfile = NULL; - GBytes *ssid; - unsigned char tmpssid[] = { 49, 49, 59, 49, 50, 59, 49, 51, 59}; - gs_free_error GError *error = NULL; - gs_unref_keyfile GKeyFile *keyfile = NULL; - char *tmp; - - connection = nm_simple_connection_new (); - g_assert (connection); - - /* Connection setting */ - - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - g_assert (s_con); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingIPConfig * s_ip4; + gs_free char * testfile = NULL; + GBytes * ssid; + unsigned char tmpssid[] = {49, 48, 49}; + gs_free_error GError *error = NULL; + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + char * tmp; - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Intlike SSID Test 2", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); + connection = nm_simple_connection_new(); - /* Wireless setting */ - s_wifi = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - g_assert (s_wifi); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + /* Connection setting */ - ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); - g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); - g_bytes_unref (ssid); + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + g_assert(s_con); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - /* IP4 setting */ - s_ip4 = NM_SETTING_IP_CONFIG (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_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Intlike SSID Test", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); - write_test_connection (connection, &testfile); + /* Wireless setting */ + s_wifi = NM_SETTING_WIRELESS(nm_setting_wireless_new()); + g_assert(s_wifi); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - /* Ensure the SSID was written out as a plain "11;12;13;" */ - keyfile = keyfile_load_from_file (testfile); + ssid = g_bytes_new(tmpssid, sizeof(tmpssid)); + g_object_set(s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_bytes_unref(ssid); - 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\\;"); - g_free (tmp); + /* IP4 setting */ + s_ip4 = NM_SETTING_IP_CONFIG(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_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - assert_reread_and_unlink (connection, TRUE, testfile); -} - -static void -test_read_bt_dun_connection (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingBluetooth *s_bluetooth; - NMSettingSerial *s_serial; - NMSettingGsm *s_gsm; - const char *bdaddr; - const guint8 expected_bdaddr[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; - - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/ATT_Data_Connect_BT"); - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "AT&T Data Connect BT"); - g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, "089130ab-ce28-46e4-ad77-d44869b03d19"); + write_test_connection(connection, &testfile); - s_bluetooth = nm_connection_get_setting_bluetooth (connection); - g_assert (s_bluetooth); - bdaddr = nm_setting_bluetooth_get_bdaddr (s_bluetooth); - g_assert (bdaddr); - g_assert (nm_utils_hwaddr_matches (bdaddr, -1, expected_bdaddr, sizeof (expected_bdaddr))); - g_assert_cmpstr (nm_setting_bluetooth_get_connection_type (s_bluetooth), ==, NM_SETTING_BLUETOOTH_TYPE_DUN); + /* Ensure the SSID was written out as a plain "101" */ + keyfile = keyfile_load_from_file(testfile); - s_gsm = nm_connection_get_setting_gsm (connection); - g_assert (s_gsm); - g_assert_cmpstr (nm_setting_gsm_get_apn (s_gsm), ==, "ISP.CINGULAR"); - g_assert_cmpstr (nm_setting_gsm_get_username (s_gsm), ==, "ISP@CINGULARGPRS.COM"); - g_assert_cmpstr (nm_setting_gsm_get_password (s_gsm), ==, "CINGULAR1"); + 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"); + g_free(tmp); - s_serial = nm_connection_get_setting_serial (connection); - g_assert (s_serial); - g_assert (nm_setting_serial_get_parity (s_serial) == NM_SETTING_SERIAL_PARITY_ODD); + assert_reread_and_unlink(connection, TRUE, testfile); } static void -test_write_bt_dun_connection (void) +test_write_intlike_ssid_2(void) { - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingBluetooth *s_bt; - NMSettingIPConfig *s_ip4; - NMSettingGsm *s_gsm; - const char *bdaddr = "aa:b9:a1:74:55:44"; - guint64 timestamp = 0x12344433L; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "T-Mobile Funkadelic", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_SETTING_NAME, - NM_SETTING_CONNECTION_TIMESTAMP, timestamp, - NULL); - - /* Bluetooth setting */ + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingIPConfig * s_ip4; + gs_free char * testfile = NULL; + GBytes * ssid; + unsigned char tmpssid[] = {49, 49, 59, 49, 50, 59, 49, 51, 59}; + gs_free_error GError *error = NULL; + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + char * tmp; - s_bt = NM_SETTING_BLUETOOTH (nm_setting_bluetooth_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_bt)); + connection = nm_simple_connection_new(); + g_assert(connection); - g_object_set (s_bt, - NM_SETTING_BLUETOOTH_BDADDR, bdaddr, - NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_DUN, - NULL); + /* Connection setting */ - /* IP4 setting */ + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + g_assert(s_con); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Intlike SSID Test 2", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + /* Wireless setting */ + s_wifi = NM_SETTING_WIRELESS(nm_setting_wireless_new()); + g_assert(s_wifi); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + + ssid = g_bytes_new(tmpssid, sizeof(tmpssid)); + g_object_set(s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); + g_bytes_unref(ssid); + + /* IP4 setting */ + s_ip4 = NM_SETTING_IP_CONFIG(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_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + write_test_connection(connection, &testfile); + + /* Ensure the SSID was written out as a plain "11;12;13;" */ + keyfile = keyfile_load_from_file(testfile); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + 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\\;"); + g_free(tmp); + + assert_reread_and_unlink(connection, TRUE, testfile); +} + +static void +test_read_bt_dun_connection(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingBluetooth * s_bluetooth; + NMSettingSerial * s_serial; + NMSettingGsm * s_gsm; + const char * bdaddr; + const guint8 expected_bdaddr[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; - /* GSM setting */ - s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_gsm)); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/ATT_Data_Connect_BT"); - g_object_set (s_gsm, - NM_SETTING_GSM_APN, "internet2.voicestream.com", - NM_SETTING_GSM_USERNAME, "george.clinton", - NM_SETTING_GSM_PASSWORD, "parliament", - NULL); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "AT&T Data Connect BT"); + g_assert_cmpstr(nm_setting_connection_get_uuid(s_con), + ==, + "089130ab-ce28-46e4-ad77-d44869b03d19"); - write_test_connection_and_reread (connection, TRUE); -} + s_bluetooth = nm_connection_get_setting_bluetooth(connection); + g_assert(s_bluetooth); + bdaddr = nm_setting_bluetooth_get_bdaddr(s_bluetooth); + g_assert(bdaddr); + g_assert(nm_utils_hwaddr_matches(bdaddr, -1, expected_bdaddr, sizeof(expected_bdaddr))); + g_assert_cmpstr(nm_setting_bluetooth_get_connection_type(s_bluetooth), + ==, + NM_SETTING_BLUETOOTH_TYPE_DUN); -static void -test_read_gsm_connection (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingSerial *s_serial; - NMSettingGsm *s_gsm; + s_gsm = nm_connection_get_setting_gsm(connection); + g_assert(s_gsm); + g_assert_cmpstr(nm_setting_gsm_get_apn(s_gsm), ==, "ISP.CINGULAR"); + g_assert_cmpstr(nm_setting_gsm_get_username(s_gsm), ==, "ISP@CINGULARGPRS.COM"); + g_assert_cmpstr(nm_setting_gsm_get_password(s_gsm), ==, "CINGULAR1"); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/ATT_Data_Connect_Plain"); + s_serial = nm_connection_get_setting_serial(connection); + g_assert(s_serial); + g_assert(nm_setting_serial_get_parity(s_serial) == NM_SETTING_SERIAL_PARITY_ODD); +} + +static void +test_write_bt_dun_connection(void) +{ + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingBluetooth * s_bt; + NMSettingIPConfig * s_ip4; + NMSettingGsm * s_gsm; + const char * bdaddr = "aa:b9:a1:74:55:44"; + guint64 timestamp = 0x12344433L; - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "AT&T Data Connect"); - g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_GSM_SETTING_NAME); + connection = nm_simple_connection_new(); + + /* Connection setting */ - /* Plain GSM, so no BT setting expected */ - g_assert (nm_connection_get_setting_bluetooth (connection) == NULL); + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - s_gsm = nm_connection_get_setting_gsm (connection); - g_assert (s_gsm); - g_assert_cmpstr (nm_setting_gsm_get_apn (s_gsm), ==, "ISP.CINGULAR"); - g_assert_cmpstr (nm_setting_gsm_get_username (s_gsm), ==, "ISP@CINGULARGPRS.COM"); - g_assert_cmpstr (nm_setting_gsm_get_password (s_gsm), ==, "CINGULAR1"); - g_assert_cmpstr (nm_setting_gsm_get_network_id (s_gsm), ==, "24005"); - g_assert_cmpstr (nm_setting_gsm_get_pin (s_gsm), ==, "2345"); - g_assert_cmpstr (nm_setting_gsm_get_device_id (s_gsm), ==, "da812de91eec16620b06cd0ca5cbc7ea25245222"); - g_assert_cmpstr (nm_setting_gsm_get_sim_id (s_gsm), ==, "89148000000060671234"); - g_assert_cmpstr (nm_setting_gsm_get_sim_operator_id (s_gsm), ==, "310260"); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "T-Mobile Funkadelic", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP, + timestamp, + NULL); + + /* Bluetooth setting */ + + s_bt = NM_SETTING_BLUETOOTH(nm_setting_bluetooth_new()); + nm_connection_add_setting(connection, NM_SETTING(s_bt)); - s_serial = nm_connection_get_setting_serial (connection); - g_assert (s_serial); - g_assert_cmpint (nm_setting_serial_get_parity (s_serial), ==, NM_SETTING_SERIAL_PARITY_ODD); -} + g_object_set(s_bt, + NM_SETTING_BLUETOOTH_BDADDR, + bdaddr, + NM_SETTING_BLUETOOTH_TYPE, + NM_SETTING_BLUETOOTH_TYPE_DUN, + NULL); -static void -test_write_gsm_connection (void) -{ - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMSettingGsm *s_gsm; - guint64 timestamp = 0x12344433L; + /* IP4 setting */ - connection = nm_simple_connection_new (); + s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - /* Connection setting */ + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + /* GSM setting */ + s_gsm = NM_SETTING_GSM(nm_setting_gsm_new()); + nm_connection_add_setting(connection, NM_SETTING(s_gsm)); + + g_object_set(s_gsm, + NM_SETTING_GSM_APN, + "internet2.voicestream.com", + NM_SETTING_GSM_USERNAME, + "george.clinton", + NM_SETTING_GSM_PASSWORD, + "parliament", + NULL); + + write_test_connection_and_reread(connection, TRUE); +} + +static void +test_read_gsm_connection(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingSerial * s_serial; + NMSettingGsm * s_gsm; + + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/ATT_Data_Connect_Plain"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "AT&T Data Connect"); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_GSM_SETTING_NAME); + + /* Plain GSM, so no BT setting expected */ + g_assert(nm_connection_get_setting_bluetooth(connection) == NULL); + + s_gsm = nm_connection_get_setting_gsm(connection); + g_assert(s_gsm); + g_assert_cmpstr(nm_setting_gsm_get_apn(s_gsm), ==, "ISP.CINGULAR"); + g_assert_cmpstr(nm_setting_gsm_get_username(s_gsm), ==, "ISP@CINGULARGPRS.COM"); + g_assert_cmpstr(nm_setting_gsm_get_password(s_gsm), ==, "CINGULAR1"); + g_assert_cmpstr(nm_setting_gsm_get_network_id(s_gsm), ==, "24005"); + g_assert_cmpstr(nm_setting_gsm_get_pin(s_gsm), ==, "2345"); + g_assert_cmpstr(nm_setting_gsm_get_device_id(s_gsm), + ==, + "da812de91eec16620b06cd0ca5cbc7ea25245222"); + g_assert_cmpstr(nm_setting_gsm_get_sim_id(s_gsm), ==, "89148000000060671234"); + g_assert_cmpstr(nm_setting_gsm_get_sim_operator_id(s_gsm), ==, "310260"); + + s_serial = nm_connection_get_setting_serial(connection); + g_assert(s_serial); + g_assert_cmpint(nm_setting_serial_get_parity(s_serial), ==, NM_SETTING_SERIAL_PARITY_ODD); +} + +static void +test_write_gsm_connection(void) +{ + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingGsm * s_gsm; + guint64 timestamp = 0x12344433L; + + connection = nm_simple_connection_new(); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "T-Mobile Funkadelic 2", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP, + timestamp, + NULL); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "T-Mobile Funkadelic 2", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_GSM_SETTING_NAME, - NM_SETTING_CONNECTION_TIMESTAMP, timestamp, - NULL); + /* IP4 setting */ - /* IP4 setting */ + s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); - s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + /* GSM setting */ + s_gsm = NM_SETTING_GSM(nm_setting_gsm_new()); + nm_connection_add_setting(connection, NM_SETTING(s_gsm)); - /* GSM setting */ - s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_gsm)); + g_object_set(s_gsm, + NM_SETTING_GSM_APN, + "internet2.voicestream.com", + NM_SETTING_GSM_USERNAME, + "george.clinton.again", + NM_SETTING_GSM_PASSWORD, + "parliament2", + NM_SETTING_GSM_PIN, + "123456", + NM_SETTING_GSM_NETWORK_ID, + "254098", + NM_SETTING_GSM_HOME_ONLY, + TRUE, + NM_SETTING_GSM_DEVICE_ID, + "da812de91eec16620b06cd0ca5cbc7ea25245222", + NM_SETTING_GSM_SIM_ID, + "89148000000060671234", + NM_SETTING_GSM_SIM_OPERATOR_ID, + "310260", + NULL); - g_object_set (s_gsm, - NM_SETTING_GSM_APN, "internet2.voicestream.com", - NM_SETTING_GSM_USERNAME, "george.clinton.again", - NM_SETTING_GSM_PASSWORD, "parliament2", - NM_SETTING_GSM_PIN, "123456", - NM_SETTING_GSM_NETWORK_ID, "254098", - NM_SETTING_GSM_HOME_ONLY, TRUE, - NM_SETTING_GSM_DEVICE_ID, "da812de91eec16620b06cd0ca5cbc7ea25245222", - NM_SETTING_GSM_SIM_ID, "89148000000060671234", - NM_SETTING_GSM_SIM_OPERATOR_ID, "310260", - NULL); - - write_test_connection_and_reread (connection, TRUE); + write_test_connection_and_reread(connection, TRUE); } static void -test_read_wired_8021x_tls_blob_connection (void) +test_read_wired_8021x_tls_blob_connection(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingWired *s_wired; - NMSetting8021x *s_8021x; - const char *tmp; - GBytes *blob; + gs_unref_object NMConnection *connection = NULL; + NMSettingWired * s_wired; + NMSetting8021x * s_8021x; + const char * tmp; + GBytes * blob; - NMTST_EXPECT_NM_WARN ("keyfile: 802-1x.client-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); - NMTST_EXPECT_NM_WARN ("keyfile: 802-1x.private-key: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Wired_TLS_Blob"); + NMTST_EXPECT_NM_WARN("keyfile: 802-1x.client-cert: certificate or key file " + "'/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); + NMTST_EXPECT_NM_WARN("keyfile: 802-1x.private-key: certificate or key file " + "'/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_TLS_Blob"); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired != NULL); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired != NULL); - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x != NULL); + 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); - tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0); - g_assert (g_strcmp0 (tmp, "tls") == 0); + g_assert(nm_setting_802_1x_get_num_eap_methods(s_8021x) == 1); + tmp = nm_setting_802_1x_get_eap_method(s_8021x, 0); + g_assert(g_strcmp0(tmp, "tls") == 0); - tmp = nm_setting_802_1x_get_identity (s_8021x); - g_assert (g_strcmp0 (tmp, "Bill Smith") == 0); + tmp = nm_setting_802_1x_get_identity(s_8021x); + g_assert(g_strcmp0(tmp, "Bill Smith") == 0); - tmp = nm_setting_802_1x_get_private_key_password (s_8021x); - g_assert (g_strcmp0 (tmp, "12345testing") == 0); + tmp = nm_setting_802_1x_get_private_key_password(s_8021x); + g_assert(g_strcmp0(tmp, "12345testing") == 0); - g_assert_cmpint (nm_setting_802_1x_get_ca_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_BLOB); + 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 */ - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (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); + /* Make sure it's not a path, since it's a blob */ + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(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 */ - blob = nm_setting_802_1x_get_ca_cert_blob (s_8021x); - g_assert (blob != NULL); - g_assert_cmpint (g_bytes_get_size (blob), ==, 568); + /* Validate the path */ + blob = nm_setting_802_1x_get_ca_cert_blob(s_8021x); + g_assert(blob != NULL); + g_assert_cmpint(g_bytes_get_size(blob), ==, 568); - tmp = nm_setting_802_1x_get_client_cert_path (s_8021x); - g_assert_cmpstr (tmp, ==, "/CASA/dcbw/Desktop/certinfra/client.pem"); + tmp = nm_setting_802_1x_get_client_cert_path(s_8021x); + g_assert_cmpstr(tmp, ==, "/CASA/dcbw/Desktop/certinfra/client.pem"); - tmp = nm_setting_802_1x_get_private_key_path (s_8021x); - g_assert_cmpstr (tmp, ==, "/CASA/dcbw/Desktop/certinfra/client.pem"); + tmp = nm_setting_802_1x_get_private_key_path(s_8021x); + g_assert_cmpstr(tmp, ==, "/CASA/dcbw/Desktop/certinfra/client.pem"); } static void -test_read_wired_8021x_tls_bad_path_connection (void) +test_read_wired_8021x_tls_bad_path_connection(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingWired *s_wired; - NMSetting8021x *s_8021x; - const char *tmp; - char *tmp2; + gs_unref_object NMConnection *connection = NULL; + NMSettingWired * s_wired; + NMSetting8021x * s_8021x; + const char * tmp; + char * tmp2; - NMTST_EXPECT_NM_WARN ("*does not exist*"); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Wired_TLS_Path_Missing"); - g_test_assert_expected_messages (); + NMTST_EXPECT_NM_WARN("*does not exist*"); + connection = + keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_TLS_Path_Missing"); + g_test_assert_expected_messages(); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired != NULL); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired != NULL); - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x != NULL); + 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); - tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0); - g_assert (g_strcmp0 (tmp, "tls") == 0); + g_assert(nm_setting_802_1x_get_num_eap_methods(s_8021x) == 1); + tmp = nm_setting_802_1x_get_eap_method(s_8021x, 0); + g_assert(g_strcmp0(tmp, "tls") == 0); - tmp = nm_setting_802_1x_get_identity (s_8021x); - g_assert (g_strcmp0 (tmp, "Bill Smith") == 0); + tmp = nm_setting_802_1x_get_identity(s_8021x); + g_assert(g_strcmp0(tmp, "Bill Smith") == 0); - tmp = nm_setting_802_1x_get_private_key_password (s_8021x); - g_assert (g_strcmp0 (tmp, "12345testing") == 0); + tmp = nm_setting_802_1x_get_private_key_password(s_8021x); + g_assert(g_strcmp0(tmp, "12345testing") == 0); - g_assert_cmpint (nm_setting_802_1x_get_ca_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert_cmpint(nm_setting_802_1x_get_ca_cert_scheme(s_8021x), + ==, + NM_SETTING_802_1X_CK_SCHEME_PATH); - tmp = nm_setting_802_1x_get_ca_cert_path (s_8021x); - g_assert_cmpstr (tmp, ==, "/some/random/cert/path.pem"); + tmp = nm_setting_802_1x_get_ca_cert_path(s_8021x); + g_assert_cmpstr(tmp, ==, "/some/random/cert/path.pem"); - tmp2 = g_strdup_printf (TEST_KEYFILES_DIR "/test-key-and-cert.pem"); + tmp2 = g_strdup_printf(TEST_KEYFILES_DIR "/test-key-and-cert.pem"); - tmp = nm_setting_802_1x_get_client_cert_path (s_8021x); - g_assert_cmpstr (tmp, ==, tmp2); + tmp = nm_setting_802_1x_get_client_cert_path(s_8021x); + g_assert_cmpstr(tmp, ==, tmp2); - tmp = nm_setting_802_1x_get_private_key_path (s_8021x); - g_assert_cmpstr (tmp, ==, tmp2); + tmp = nm_setting_802_1x_get_private_key_path(s_8021x); + g_assert_cmpstr(tmp, ==, tmp2); - g_free (tmp2); + g_free(tmp2); } static void -test_read_wired_8021x_tls_old_connection (void) +test_read_wired_8021x_tls_old_connection(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingWired *s_wired; - NMSetting8021x *s_8021x; - const char *tmp; + gs_unref_object NMConnection *connection = NULL; + NMSettingWired * s_wired; + NMSetting8021x * s_8021x; + const char * tmp; - NMTST_EXPECT_NM_WARN ("keyfile: 802-1x.ca-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem' does not exist*"); - NMTST_EXPECT_NM_WARN ("keyfile: 802-1x.client-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); - NMTST_EXPECT_NM_WARN ("keyfile: 802-1x.private-key: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Wired_TLS_Old"); + NMTST_EXPECT_NM_WARN("keyfile: 802-1x.ca-cert: certificate or key file " + "'/CASA/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem' does not exist*"); + NMTST_EXPECT_NM_WARN("keyfile: 802-1x.client-cert: certificate or key file " + "'/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); + NMTST_EXPECT_NM_WARN("keyfile: 802-1x.private-key: certificate or key file " + "'/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_TLS_Old"); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired != NULL); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired != NULL); - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x != NULL); + 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); - tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0); - g_assert (g_strcmp0 (tmp, "tls") == 0); + g_assert(nm_setting_802_1x_get_num_eap_methods(s_8021x) == 1); + tmp = nm_setting_802_1x_get_eap_method(s_8021x, 0); + g_assert(g_strcmp0(tmp, "tls") == 0); - tmp = nm_setting_802_1x_get_identity (s_8021x); - g_assert (g_strcmp0 (tmp, "Bill Smith") == 0); + tmp = nm_setting_802_1x_get_identity(s_8021x); + g_assert(g_strcmp0(tmp, "Bill Smith") == 0); - tmp = nm_setting_802_1x_get_private_key_password (s_8021x); - g_assert (g_strcmp0 (tmp, "12345testing") == 0); + tmp = nm_setting_802_1x_get_private_key_password(s_8021x); + g_assert(g_strcmp0(tmp, "12345testing") == 0); - tmp = nm_setting_802_1x_get_ca_cert_path (s_8021x); - g_assert (g_strcmp0 (tmp, "/CASA/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem") == 0); + tmp = nm_setting_802_1x_get_ca_cert_path(s_8021x); + g_assert(g_strcmp0(tmp, "/CASA/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem") == 0); - tmp = nm_setting_802_1x_get_client_cert_path (s_8021x); - g_assert (g_strcmp0 (tmp, "/CASA/dcbw/Desktop/certinfra/client.pem") == 0); + tmp = nm_setting_802_1x_get_client_cert_path(s_8021x); + g_assert(g_strcmp0(tmp, "/CASA/dcbw/Desktop/certinfra/client.pem") == 0); - tmp = nm_setting_802_1x_get_private_key_path (s_8021x); - g_assert (g_strcmp0 (tmp, "/CASA/dcbw/Desktop/certinfra/client.pem") == 0); + tmp = nm_setting_802_1x_get_private_key_path(s_8021x); + g_assert(g_strcmp0(tmp, "/CASA/dcbw/Desktop/certinfra/client.pem") == 0); } static void -test_read_wired_8021x_tls_new_connection (void) +test_read_wired_8021x_tls_new_connection(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingWired *s_wired; - NMSetting8021x *s_8021x; - const char *tmp; - char *tmp2; + gs_unref_object NMConnection *connection = NULL; + NMSettingWired * s_wired; + NMSetting8021x * s_8021x; + const char * tmp; + char * tmp2; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Wired_TLS_New"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_TLS_New"); - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired != NULL); + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired != NULL); - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x != NULL); + 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); - tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0); - g_assert (g_strcmp0 (tmp, "tls") == 0); + g_assert(nm_setting_802_1x_get_num_eap_methods(s_8021x) == 1); + tmp = nm_setting_802_1x_get_eap_method(s_8021x, 0); + g_assert(g_strcmp0(tmp, "tls") == 0); - tmp = nm_setting_802_1x_get_identity (s_8021x); - g_assert (g_strcmp0 (tmp, "Bill Smith") == 0); + tmp = nm_setting_802_1x_get_identity(s_8021x); + g_assert(g_strcmp0(tmp, "Bill Smith") == 0); - tmp = nm_setting_802_1x_get_private_key_password (s_8021x); - g_assert (g_strcmp0 (tmp, "12345testing") == 0); + tmp = nm_setting_802_1x_get_private_key_password(s_8021x); + g_assert(g_strcmp0(tmp, "12345testing") == 0); - tmp2 = g_strdup_printf (TEST_KEYFILES_DIR "/test-ca-cert.pem"); - tmp = nm_setting_802_1x_get_ca_cert_path (s_8021x); - g_assert_cmpstr (tmp, ==, tmp2); - g_free (tmp2); + tmp2 = g_strdup_printf(TEST_KEYFILES_DIR "/test-ca-cert.pem"); + tmp = nm_setting_802_1x_get_ca_cert_path(s_8021x); + g_assert_cmpstr(tmp, ==, tmp2); + g_free(tmp2); - tmp2 = g_strdup_printf (TEST_KEYFILES_DIR "/test-key-and-cert.pem"); + tmp2 = g_strdup_printf(TEST_KEYFILES_DIR "/test-key-and-cert.pem"); - tmp = nm_setting_802_1x_get_client_cert_path (s_8021x); - g_assert_cmpstr (tmp, ==, tmp2); + tmp = nm_setting_802_1x_get_client_cert_path(s_8021x); + g_assert_cmpstr(tmp, ==, tmp2); - tmp = nm_setting_802_1x_get_private_key_path (s_8021x); - g_assert_cmpstr (tmp, ==, tmp2); + tmp = nm_setting_802_1x_get_private_key_path(s_8021x); + g_assert_cmpstr(tmp, ==, tmp2); - g_free (tmp2); + g_free(tmp2); } -#define TEST_WIRED_TLS_CA_CERT TEST_KEYFILES_DIR"/test-ca-cert.pem" -#define TEST_WIRED_TLS_CLIENT_CERT TEST_KEYFILES_DIR"/test-key-and-cert.pem" -#define TEST_WIRED_TLS_PRIVKEY TEST_KEYFILES_DIR"/test-key-and-cert.pem" +#define TEST_WIRED_TLS_CA_CERT TEST_KEYFILES_DIR "/test-ca-cert.pem" +#define TEST_WIRED_TLS_CLIENT_CERT TEST_KEYFILES_DIR "/test-key-and-cert.pem" +#define TEST_WIRED_TLS_PRIVKEY TEST_KEYFILES_DIR "/test-key-and-cert.pem" static NMConnection * -create_wired_tls_connection (NMSetting8021xCKScheme scheme) -{ - NMTST_UUID_INIT (uuid); - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMSetting *s_wired; - NMSetting8021x *s_8021x; - gboolean success; - gs_free_error GError *error = NULL; - - connection = nm_simple_connection_new (); - g_assert (connection != NULL); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - g_assert (s_con); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Wired Really Secure TLS", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - g_assert (s_ip4); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - /* Wired setting */ - s_wired = nm_setting_wired_new (); - g_assert (s_wired); - nm_connection_add_setting (connection, s_wired); - - /* 802.1x setting */ - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - g_assert (s_8021x); - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - nm_setting_802_1x_add_eap_method (s_8021x, "tls"); - g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); - - success = nm_setting_802_1x_set_ca_cert (s_8021x, - TEST_WIRED_TLS_CA_CERT, - scheme, - NULL, - &error); - g_assert_no_error (error); - g_assert (success); - - success = nm_setting_802_1x_set_client_cert (s_8021x, - TEST_WIRED_TLS_CLIENT_CERT, - scheme, - NULL, - &error); - g_assert_no_error (error); - g_assert (success); - - success = nm_setting_802_1x_set_private_key (s_8021x, - TEST_WIRED_TLS_PRIVKEY, - "test1", - scheme, - NULL, - &error); - g_assert_no_error (error); - g_assert (success); - - return connection; +create_wired_tls_connection(NMSetting8021xCKScheme scheme) +{ + NMTST_UUID_INIT(uuid); + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4; + NMSetting * s_wired; + NMSetting8021x * s_8021x; + gboolean success; + gs_free_error GError *error = NULL; + + connection = nm_simple_connection_new(); + g_assert(connection != NULL); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + g_assert(s_con); + nm_connection_add_setting(connection, NM_SETTING(s_con)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Wired Really Secure TLS", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_assert(s_ip4); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting(connection, NM_SETTING(s_ip4)); + + /* Wired setting */ + s_wired = nm_setting_wired_new(); + g_assert(s_wired); + nm_connection_add_setting(connection, s_wired); + + /* 802.1x setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + g_assert(s_8021x); + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + + nm_setting_802_1x_add_eap_method(s_8021x, "tls"); + g_object_set(s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + + success = nm_setting_802_1x_set_ca_cert(s_8021x, TEST_WIRED_TLS_CA_CERT, scheme, NULL, &error); + g_assert_no_error(error); + g_assert(success); + + success = nm_setting_802_1x_set_client_cert(s_8021x, + TEST_WIRED_TLS_CLIENT_CERT, + scheme, + NULL, + &error); + g_assert_no_error(error); + g_assert(success); + + success = nm_setting_802_1x_set_private_key(s_8021x, + TEST_WIRED_TLS_PRIVKEY, + "test1", + scheme, + NULL, + &error); + g_assert_no_error(error); + g_assert(success); + + return connection; } static char * -get_path (const char *file, gboolean relative) -{ - return relative ? g_path_get_basename (file) : g_strdup (file); -} - -static void -test_write_wired_8021x_tls_connection_path (void) -{ - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - char *tmp, *tmp2; - gboolean success; - gs_free char *testfile = NULL; - gs_unref_keyfile GKeyFile *keyfile = NULL; - gboolean relative = FALSE; - gboolean reread_same = FALSE; - - connection = create_wired_tls_connection (NM_SETTING_802_1X_CK_SCHEME_PATH); - g_assert (connection != NULL); - - write_test_connection_reread (connection, &testfile, &reread, &reread_same); - nmtst_assert_connection_verifies_without_normalization (reread); - _setting_copy_property_gbytes (connection, reread, NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CA_CERT); - _setting_copy_property_gbytes (connection, reread, NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CLIENT_CERT); - _setting_copy_property_gbytes (connection, reread, NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PRIVATE_KEY); - assert_reread_same (connection, reread); - g_clear_object (&reread); - - /* Read the connection back in and compare it to the one we just wrote out */ - reread = keyfile_read_connection_from_file (testfile); - - success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); - if (!reread) { - g_warning ("Written and re-read connection weren't the same"); - g_assert (success); - } - - /* Ensure the cert and key values are properly written out */ - keyfile = keyfile_load_from_file (testfile); - - /* Depending on whether this test is being run from 'make check' or - * 'make distcheck' we might be using relative paths (check) or - * absolute ones (distcheck). - */ - tmp2 = g_path_get_dirname (testfile); - if (g_strcmp0 (tmp2, TEST_KEYFILES_DIR) == 0) - relative = TRUE; - g_free (tmp2); - - /* CA cert */ - tmp = g_key_file_get_string (keyfile, - NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_CA_CERT, - NULL); - tmp2 = get_path (TEST_WIRED_TLS_CA_CERT, relative); - g_assert_cmpstr (tmp, ==, tmp2); - g_free (tmp2); - g_free (tmp); - - /* Client cert */ - tmp = g_key_file_get_string (keyfile, - NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_CLIENT_CERT, - NULL); - tmp2 = get_path (TEST_WIRED_TLS_CLIENT_CERT, relative); - g_assert_cmpstr (tmp, ==, tmp2); - g_free (tmp2); - g_free (tmp); - - /* Private key */ - tmp = g_key_file_get_string (keyfile, - NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_PRIVATE_KEY, - NULL); - tmp2 = get_path (TEST_WIRED_TLS_PRIVKEY, relative); - g_assert_cmpstr (tmp, ==, tmp2); - g_free (tmp2); - g_free (tmp); - - unlink (testfile); -} - -static void -test_write_wired_8021x_tls_connection_blob (void) -{ - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSetting8021x *s_8021x; - gs_free char *testfile = NULL; - char *new_ca_cert; - char *new_client_cert; - char *new_priv_key; - const char *uuid; - gboolean reread_same = FALSE; - GBytes *password_raw; +get_path(const char *file, gboolean relative) +{ + return relative ? g_path_get_basename(file) : g_strdup(file); +} + +static void +test_write_wired_8021x_tls_connection_path(void) +{ + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + char * tmp, *tmp2; + gboolean success; + gs_free char * testfile = NULL; + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + gboolean relative = FALSE; + gboolean reread_same = FALSE; + + connection = create_wired_tls_connection(NM_SETTING_802_1X_CK_SCHEME_PATH); + g_assert(connection != NULL); + + write_test_connection_reread(connection, &testfile, &reread, &reread_same); + nmtst_assert_connection_verifies_without_normalization(reread); + _setting_copy_property_gbytes(connection, + reread, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CA_CERT); + _setting_copy_property_gbytes(connection, + reread, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CLIENT_CERT); + _setting_copy_property_gbytes(connection, + reread, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PRIVATE_KEY); + assert_reread_same(connection, reread); + g_clear_object(&reread); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = keyfile_read_connection_from_file(testfile); + + success = nm_connection_compare(connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); + if (!reread) { + g_warning("Written and re-read connection weren't the same"); + g_assert(success); + } + + /* Ensure the cert and key values are properly written out */ + keyfile = keyfile_load_from_file(testfile); + + /* Depending on whether this test is being run from 'make check' or + * 'make distcheck' we might be using relative paths (check) or + * absolute ones (distcheck). + */ + tmp2 = g_path_get_dirname(testfile); + if (g_strcmp0(tmp2, TEST_KEYFILES_DIR) == 0) + relative = TRUE; + g_free(tmp2); + + /* CA cert */ + tmp = g_key_file_get_string(keyfile, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CA_CERT, + NULL); + tmp2 = get_path(TEST_WIRED_TLS_CA_CERT, relative); + g_assert_cmpstr(tmp, ==, tmp2); + g_free(tmp2); + g_free(tmp); + + /* Client cert */ + tmp = g_key_file_get_string(keyfile, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CLIENT_CERT, + NULL); + tmp2 = get_path(TEST_WIRED_TLS_CLIENT_CERT, relative); + g_assert_cmpstr(tmp, ==, tmp2); + g_free(tmp2); + g_free(tmp); + + /* Private key */ + tmp = g_key_file_get_string(keyfile, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PRIVATE_KEY, + NULL); + tmp2 = get_path(TEST_WIRED_TLS_PRIVKEY, relative); + g_assert_cmpstr(tmp, ==, tmp2); + g_free(tmp2); + g_free(tmp); + + unlink(testfile); +} + +static void +test_write_wired_8021x_tls_connection_blob(void) +{ + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *reread = NULL; + NMSettingConnection * s_con; + NMSetting8021x * s_8021x; + gs_free char * testfile = NULL; + char * new_ca_cert; + char * new_client_cert; + char * new_priv_key; + const char * uuid; + gboolean reread_same = FALSE; + GBytes * password_raw; #define PASSWORD_RAW "password-raw\0test" - connection = create_wired_tls_connection (NM_SETTING_802_1X_CK_SCHEME_BLOB); - g_assert (connection != NULL); + connection = create_wired_tls_connection(NM_SETTING_802_1X_CK_SCHEME_BLOB); + g_assert(connection != NULL); - s_8021x = nm_connection_get_setting_802_1x (connection); - g_assert (s_8021x); + s_8021x = nm_connection_get_setting_802_1x(connection); + g_assert(s_8021x); - password_raw = g_bytes_new (PASSWORD_RAW, NM_STRLEN (PASSWORD_RAW)); - g_object_set (s_8021x, - NM_SETTING_802_1X_PASSWORD_RAW, - password_raw, - NULL); - g_bytes_unref (password_raw); + password_raw = g_bytes_new(PASSWORD_RAW, NM_STRLEN(PASSWORD_RAW)); + g_object_set(s_8021x, NM_SETTING_802_1X_PASSWORD_RAW, password_raw, NULL); + g_bytes_unref(password_raw); - write_test_connection_reread (connection, &testfile, &reread, &reread_same); - nmtst_assert_connection_verifies_without_normalization (reread); - _setting_copy_property_gbytes (connection, reread, NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CA_CERT); - _setting_copy_property_gbytes (connection, reread, NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CLIENT_CERT); - _setting_copy_property_gbytes (connection, reread, NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PRIVATE_KEY); - assert_reread_same (connection, reread); - g_clear_object (&reread); + write_test_connection_reread(connection, &testfile, &reread, &reread_same); + nmtst_assert_connection_verifies_without_normalization(reread); + _setting_copy_property_gbytes(connection, + reread, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CA_CERT); + _setting_copy_property_gbytes(connection, + reread, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_CLIENT_CERT); + _setting_copy_property_gbytes(connection, + reread, + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_PRIVATE_KEY); + assert_reread_same(connection, reread); + g_clear_object(&reread); - /* Check that the new certs got written out */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - uuid = nm_setting_connection_get_uuid (s_con); - g_assert (uuid); + /* Check that the new certs got written out */ + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + uuid = nm_setting_connection_get_uuid(s_con); + g_assert(uuid); - new_ca_cert = g_strdup_printf ("%s/%s-ca-cert.pem", TEST_SCRATCH_DIR, uuid); - g_assert (new_ca_cert); - g_assert (g_file_test (new_ca_cert, G_FILE_TEST_EXISTS)); + new_ca_cert = g_strdup_printf("%s/%s-ca-cert.pem", TEST_SCRATCH_DIR, uuid); + g_assert(new_ca_cert); + g_assert(g_file_test(new_ca_cert, G_FILE_TEST_EXISTS)); - new_client_cert = g_strdup_printf ("%s/%s-client-cert.pem", TEST_SCRATCH_DIR, uuid); - g_assert (new_client_cert); - g_assert (g_file_test (new_client_cert, G_FILE_TEST_EXISTS)); + new_client_cert = g_strdup_printf("%s/%s-client-cert.pem", TEST_SCRATCH_DIR, uuid); + g_assert(new_client_cert); + g_assert(g_file_test(new_client_cert, G_FILE_TEST_EXISTS)); - new_priv_key = g_strdup_printf ("%s/%s-private-key.pem", TEST_SCRATCH_DIR, uuid); - g_assert (new_priv_key); - g_assert (g_file_test (new_priv_key, G_FILE_TEST_EXISTS)); + new_priv_key = g_strdup_printf("%s/%s-private-key.pem", TEST_SCRATCH_DIR, uuid); + g_assert(new_priv_key); + g_assert(g_file_test(new_priv_key, G_FILE_TEST_EXISTS)); - /* Read the connection back in and compare it to the one we just wrote out */ - reread = keyfile_read_connection_from_file (testfile); + /* Read the connection back in and compare it to the one we just wrote out */ + reread = keyfile_read_connection_from_file(testfile); - /* Ensure the re-read connection's certificates use the path scheme */ - 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); - g_assert (nm_setting_802_1x_get_private_key_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); + /* Ensure the re-read connection's certificates use the path scheme */ + 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); + g_assert(nm_setting_802_1x_get_private_key_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH); - password_raw = nm_setting_802_1x_get_password_raw (s_8021x); - g_assert (password_raw); - g_assert (nm_utils_gbytes_equal_mem (password_raw, PASSWORD_RAW, NM_STRLEN (PASSWORD_RAW))); + password_raw = nm_setting_802_1x_get_password_raw(s_8021x); + g_assert(password_raw); + g_assert(nm_utils_gbytes_equal_mem(password_raw, PASSWORD_RAW, NM_STRLEN(PASSWORD_RAW))); - unlink (testfile); + unlink(testfile); - /* Clean up written certs */ - unlink (new_ca_cert); - g_free (new_ca_cert); + /* Clean up written certs */ + unlink(new_ca_cert); + g_free(new_ca_cert); - unlink (new_client_cert); - g_free (new_client_cert); + unlink(new_client_cert); + g_free(new_client_cert); - unlink (new_priv_key); - g_free (new_priv_key); + unlink(new_priv_key); + g_free(new_priv_key); } static void -test_read_dcb_connection (void) +test_read_dcb_connection(void) { - gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *connection = NULL; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_dcb_connection"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_dcb_connection"); } static void -test_read_infiniband_connection (void) +test_read_infiniband_connection(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingInfiniband *s_ib; - const char *mac; - 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"; + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingInfiniband * s_ib; + const char * mac; + 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"; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_InfiniBand_Connection"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_InfiniBand_Connection"); - 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); + 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); - s_ib = nm_connection_get_setting_infiniband (connection); - g_assert (s_ib); + s_ib = nm_connection_get_setting_infiniband(connection); + g_assert(s_ib); - mac = nm_setting_infiniband_get_mac_address (s_ib); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac, sizeof (expected_mac))); + mac = nm_setting_infiniband_get_mac_address(s_ib); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac, sizeof(expected_mac))); } static void -test_write_infiniband_connection (void) +test_write_infiniband_connection(void) { - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingInfiniband *s_ib; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - const char *mac = "99:88:77:66:55:44:ab:bc:cd:de:ef:f0:0a:1b:2c:3d:4e:5f:6f:ba"; + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingInfiniband * s_ib; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + const char *mac = "99:88:77:66:55:44:ab:bc:cd:de:ef:f0:0a:1b:2c:3d:4e:5f:6f:ba"; - connection = nm_simple_connection_new (); + connection = nm_simple_connection_new(); - /* Connection setting */ + /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - g_assert (s_con); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + s_con = (NMSettingConnection *) nm_setting_connection_new(); + g_assert(s_con); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - 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_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); - /* InfiniBand setting */ - s_ib = (NMSettingInfiniband *) nm_setting_infiniband_new (); - g_assert (s_ib); - nm_connection_add_setting (connection, NM_SETTING (s_ib)); + /* InfiniBand setting */ + s_ib = (NMSettingInfiniband *) nm_setting_infiniband_new(); + g_assert(s_ib); + nm_connection_add_setting(connection, NM_SETTING(s_ib)); - g_object_set (s_ib, - NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, - NM_SETTING_INFINIBAND_MTU, 900, - NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", - NULL); + g_object_set(s_ib, + NM_SETTING_INFINIBAND_MAC_ADDRESS, + mac, + NM_SETTING_INFINIBAND_MTU, + 900, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, + "datagram", + NULL); - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) 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_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) 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_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) 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_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) 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_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); - write_test_connection_and_reread (connection, FALSE); + write_test_connection_and_reread(connection, FALSE); } static void -test_read_bridge_main (void) +test_read_bridge_main(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMSettingBridge *s_bridge; - const char *expected_id = "Test Bridge Main"; - const char *expected_uuid = "8f061643-fe41-4d4c-a8d9-097d26e2ad3a"; - - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Bridge_Main"); - - 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); - g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, "br0"); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingBridge * s_bridge; + const char * expected_id = "Test Bridge Main"; + const char * expected_uuid = "8f061643-fe41-4d4c-a8d9-097d26e2ad3a"; + + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Bridge_Main"); + + 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); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "br0"); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + s_bridge = nm_connection_get_setting_bridge(connection); + g_assert(s_bridge); + g_assert_cmpuint(nm_setting_bridge_get_forward_delay(s_bridge), ==, 2); + g_assert_cmpuint(nm_setting_bridge_get_stp(s_bridge), ==, TRUE); + g_assert_cmpuint(nm_setting_bridge_get_priority(s_bridge), ==, 32744); + g_assert_cmpuint(nm_setting_bridge_get_hello_time(s_bridge), ==, 7); + g_assert_cmpuint(nm_setting_bridge_get_max_age(s_bridge), ==, 39); + g_assert_cmpuint(nm_setting_bridge_get_ageing_time(s_bridge), ==, 235352); + g_assert_cmpuint(nm_setting_bridge_get_multicast_snooping(s_bridge), ==, FALSE); +} + +static void +test_write_bridge_main(void) +{ + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingBridge * s_bridge; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connection = nm_simple_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)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Bridge Main", + 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); + + /* Bridge setting */ + s_bridge = (NMSettingBridge *) nm_setting_bridge_new(); + g_assert(s_bridge); + nm_connection_add_setting(connection, NM_SETTING(s_bridge)); + + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) 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_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP_CONFIG_GATEWAY, + "1.1.1.1", + NULL); + + add_one_ip_address(s_ip4, "1.2.3.4", 24); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) 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_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + + write_test_connection_and_reread(connection, FALSE); +} + +static void +test_read_bridge_component(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingBridgePort * s_port; + NMSettingWired * s_wired; + const char * mac; + guint8 expected_mac[ETH_ALEN] = {0x00, 0x22, 0x15, 0x59, 0x62, 0x97}; + const char * expected_id = "Test Bridge Component"; + const char * expected_uuid = "d7b4f96c-c45e-4298-bef8-f48574f8c1c0"; + + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Bridge_Component"); + + 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); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, "br0"); + g_assert(nm_setting_connection_is_slave_type(s_con, NM_SETTING_BRIDGE_SETTING_NAME)); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + mac = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac, sizeof(expected_mac))); + + s_port = nm_connection_get_setting_bridge_port(connection); + g_assert(s_port); + g_assert(nm_setting_bridge_port_get_hairpin_mode(s_port)); + g_assert_cmpuint(nm_setting_bridge_port_get_priority(s_port), ==, 28); + g_assert_cmpuint(nm_setting_bridge_port_get_path_cost(s_port), ==, 100); +} + +static void +test_write_bridge_component(void) +{ + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingBridgePort * s_port; + NMSettingWired * s_wired; + const char * mac = "99:88:77:66:55:44"; + + connection = nm_simple_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)); + + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Bridge Component", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_MASTER, + "br0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BRIDGE_SETTING_NAME, + NULL); + + /* Wired setting */ + s_wired = NM_SETTING_WIRED(nm_setting_wired_new()); + g_assert(s_wired); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, 1300, NULL); + + /* BridgePort setting */ + s_port = (NMSettingBridgePort *) nm_setting_bridge_port_new(); + g_assert(s_port); + nm_connection_add_setting(connection, NM_SETTING(s_port)); - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + g_object_set(s_port, + NM_SETTING_BRIDGE_PORT_PRIORITY, + 3, + NM_SETTING_BRIDGE_PORT_PATH_COST, + 99, + NULL); - s_bridge = nm_connection_get_setting_bridge (connection); - g_assert (s_bridge); - g_assert_cmpuint (nm_setting_bridge_get_forward_delay (s_bridge), ==, 2); - g_assert_cmpuint (nm_setting_bridge_get_stp (s_bridge), ==, TRUE); - g_assert_cmpuint (nm_setting_bridge_get_priority (s_bridge), ==, 32744); - g_assert_cmpuint (nm_setting_bridge_get_hello_time (s_bridge), ==, 7); - g_assert_cmpuint (nm_setting_bridge_get_max_age (s_bridge), ==, 39); - g_assert_cmpuint (nm_setting_bridge_get_ageing_time (s_bridge), ==, 235352); - g_assert_cmpuint (nm_setting_bridge_get_multicast_snooping (s_bridge), ==, FALSE); + write_test_connection_and_reread(connection, FALSE); } static void -test_write_bridge_main (void) -{ - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingBridge *s_bridge; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - - connection = nm_simple_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)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Bridge Main", - 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); - - /* Bridge setting */ - s_bridge = (NMSettingBridge *) nm_setting_bridge_new (); - g_assert (s_bridge); - nm_connection_add_setting (connection, NM_SETTING (s_bridge)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) 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_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NULL); - - add_one_ip_address (s_ip4, "1.2.3.4", 24); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) 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_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); - - write_test_connection_and_reread (connection, FALSE); -} - -static void -test_read_bridge_component (void) +test_read_new_wired_group_name(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingBridgePort *s_port; - NMSettingWired *s_wired; - const char *mac; - guint8 expected_mac[ETH_ALEN] = { 0x00, 0x22, 0x15, 0x59, 0x62, 0x97 }; - const char *expected_id = "Test Bridge Component"; - const char *expected_uuid = "d7b4f96c-c45e-4298-bef8-f48574f8c1c0"; + gs_unref_object NMConnection *connection = NULL; + NMSettingWired * s_wired; + const char * mac; + guint8 expected_mac[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_Bridge_Component"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_New_Wired_Group_Name"); - 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); - g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, "br0"); - g_assert (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BRIDGE_SETTING_NAME)); - - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - mac = nm_setting_wired_get_mac_address (s_wired); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac, sizeof (expected_mac))); - - s_port = nm_connection_get_setting_bridge_port (connection); - g_assert (s_port); - g_assert (nm_setting_bridge_port_get_hairpin_mode (s_port)); - g_assert_cmpuint (nm_setting_bridge_port_get_priority (s_port), ==, 28); - g_assert_cmpuint (nm_setting_bridge_port_get_path_cost (s_port), ==, 100); -} - -static void -test_write_bridge_component (void) -{ - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingBridgePort *s_port; - NMSettingWired *s_wired; - const char *mac = "99:88:77:66:55:44"; + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 1400); - connection = nm_simple_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)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Bridge Component", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, "br0", - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); - g_assert (s_wired); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - g_object_set (s_wired, - NM_SETTING_WIRED_MAC_ADDRESS, mac, - NM_SETTING_WIRED_MTU, 1300, - NULL); - - /* BridgePort setting */ - s_port = (NMSettingBridgePort *) nm_setting_bridge_port_new (); - g_assert (s_port); - nm_connection_add_setting (connection, NM_SETTING (s_port)); - - g_object_set (s_port, - NM_SETTING_BRIDGE_PORT_PRIORITY, 3, - NM_SETTING_BRIDGE_PORT_PATH_COST, 99, - NULL); - - write_test_connection_and_reread (connection, FALSE); -} - -static void -test_read_new_wired_group_name (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSettingWired *s_wired; - const char *mac; - guint8 expected_mac[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; - - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_New_Wired_Group_Name"); - - s_wired = nm_connection_get_setting_wired (connection); - g_assert (s_wired); - g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 1400); - - mac = nm_setting_wired_get_mac_address (s_wired); - g_assert (mac); - g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac, sizeof (expected_mac))); + mac = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac); + g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac, sizeof(expected_mac))); } static void -test_write_new_wired_group_name (void) +test_write_new_wired_group_name(void) { - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - gs_unref_keyfile GKeyFile *kf = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - gs_free char *testfile = NULL; - gs_free_error GError *error = NULL; - char *s; - int mtu; - - connection = nm_simple_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)); - - 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); - - /* 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)); + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + nm_auto_unref_keyfile GKeyFile *kf = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + gs_free char * testfile = NULL; + gs_free_error GError *error = NULL; + char * s; + int mtu; - write_test_connection (connection, &testfile); + connection = nm_simple_connection_new(); + g_assert(connection); - assert_reread (connection, TRUE, testfile); + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new(); + g_assert(s_con); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - /* Look at the keyfile itself to ensure we wrote out the new group names and type */ - kf = keyfile_load_from_file (testfile); + 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); + + /* 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_test_connection(connection, &testfile); + + assert_reread(connection, TRUE, testfile); + + /* Look at the keyfile itself to ensure we wrote out the new group names and type */ + kf = keyfile_load_from_file(testfile); + + 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); - 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); - 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); + unlink(testfile); } static void -test_read_new_wireless_group_names (void) +test_read_new_wireless_group_names(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - GBytes *ssid; - const char *expected_ssid = "foobar"; + gs_unref_object NMConnection *connection = NULL; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + GBytes * ssid; + const char * expected_ssid = "foobar"; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_New_Wireless_Group_Names"); + connection = + keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_New_Wireless_Group_Names"); - s_wifi = nm_connection_get_setting_wireless (connection); - g_assert (s_wifi); + s_wifi = nm_connection_get_setting_wireless(connection); + g_assert(s_wifi); - ssid = nm_setting_wireless_get_ssid (s_wifi); - g_assert (ssid); - g_assert (nm_utils_gbytes_equal_mem (ssid, expected_ssid, strlen (expected_ssid))); + ssid = nm_setting_wireless_get_ssid(s_wifi); + g_assert(ssid); + g_assert(nm_utils_gbytes_equal_mem(ssid, expected_ssid, strlen(expected_ssid))); - g_assert_cmpstr (nm_setting_wireless_get_mode (s_wifi), ==, NM_SETTING_WIRELESS_MODE_INFRA); + g_assert_cmpstr(nm_setting_wireless_get_mode(s_wifi), ==, NM_SETTING_WIRELESS_MODE_INFRA); - 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"); + 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"); } static void -test_write_new_wireless_group_names (void) +test_write_new_wireless_group_names(void) { - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - gs_unref_keyfile GKeyFile *kf = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - GBytes *ssid; - unsigned char tmpssid[] = { 0x31, 0x33, 0x33, 0x37 }; - const char *expected_psk = "asdfasdfasdfa12315"; - gs_free char *testfile = NULL; - gs_free_error GError *error = NULL; - char *s; + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + nm_auto_unref_keyfile GKeyFile *kf = NULL; + NMSettingConnection * s_con; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity * s_wsec; + GBytes * ssid; + unsigned char tmpssid[] = {0x31, 0x33, 0x33, 0x37}; + const char * expected_psk = "asdfasdfasdfa12315"; + gs_free char * testfile = NULL; + gs_free_error GError *error = NULL; + char * s; - connection = nm_simple_connection_new (); + connection = nm_simple_connection_new(); - /* Connection setting */ + /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + s_con = (NMSettingConnection *) nm_setting_connection_new(); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - 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_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); - /* Wi-Fi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + /* Wi-Fi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA, - NULL); - g_bytes_unref (ssid); + ssid = g_bytes_new(tmpssid, sizeof(tmpssid)); + g_object_set(s_wifi, + NM_SETTING_WIRELESS_SSID, + ssid, + NM_SETTING_WIRELESS_MODE, + NM_SETTING_WIRELESS_MODE_INFRA, + NULL); + g_bytes_unref(ssid); - /* Wi-Fi 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); + /* Wi-Fi 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_test_connection (connection, &testfile); + write_test_connection(connection, &testfile); - assert_reread (connection, TRUE, testfile); + assert_reread(connection, TRUE, testfile); - /* Look at the keyfile itself to ensure we wrote out the new group names and type */ - kf = keyfile_load_from_file (testfile); + /* Look at the keyfile itself to ensure we wrote out the new group names and type */ + kf = keyfile_load_from_file(testfile); - 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, + 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", 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); + 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); + unlink(testfile); } static void -test_read_missing_vlan_setting (void) +test_read_missing_vlan_setting(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingVlan *s_vlan; + gs_unref_object NMConnection *connection = NULL; + NMSettingVlan * s_vlan; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_Missing_Vlan_Setting"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Missing_Vlan_Setting"); - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); - g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 0); - g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 0); + g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS); } static void -test_read_missing_vlan_flags (void) +test_read_missing_vlan_flags(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingVlan *s_vlan; - - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_Missing_Vlan_Flags"); + gs_unref_object NMConnection *connection = NULL; + NMSettingVlan * s_vlan; - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Missing_Vlan_Flags"); + + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); + + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 444); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "em1"); + g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS); +} - g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 444); - g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "em1"); - g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS); +static void +test_read_missing_id_uuid(void) +{ + gs_unref_object NMConnection *connection = NULL; + gs_free char * expected_uuid = NULL; + const char * FILENAME = TEST_KEYFILES_DIR "/Test_Missing_ID_UUID"; + + expected_uuid = _nm_utils_uuid_generate_from_strings("keyfile", FILENAME, NULL); + + connection = keyfile_read_connection_from_file(FILENAME); + + g_assert_cmpstr(nm_connection_get_id(connection), ==, "Test_Missing_ID_UUID"); + g_assert_cmpstr(nm_connection_get_uuid(connection), ==, expected_uuid); } static void -test_read_missing_id_uuid (void) +test_read_minimal(void) { - gs_unref_object NMConnection *connection = NULL; - gs_free char *expected_uuid = NULL; - const char *FILENAME = TEST_KEYFILES_DIR"/Test_Missing_ID_UUID"; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *con_archetype = NULL; + NMSettingConnection * s_con; - expected_uuid = _nm_utils_uuid_generate_from_strings ("keyfile", FILENAME, NULL); + con_archetype = nmtst_create_minimal_connection("Test_minimal_x", + "a15bd68f-c32b-40b8-8d27-49e472a85919", + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + nmtst_connection_normalize(con_archetype); - connection = keyfile_read_connection_from_file (FILENAME); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_1"); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + nm_connection_get_id(connection), + NM_SETTING_CONNECTION_UUID, + nm_connection_get_uuid(connection), + NULL); + nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE); + g_clear_object(&connection); - g_assert_cmpstr (nm_connection_get_id (connection), ==, "Test_Missing_ID_UUID"); - g_assert_cmpstr (nm_connection_get_uuid (connection), ==, expected_uuid); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_2"); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + nm_connection_get_id(connection), + NM_SETTING_CONNECTION_UUID, + nm_connection_get_uuid(connection), + NULL); + nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE); + g_clear_object(&connection); } static void -test_read_minimal (void) +test_read_minimal_slave(void) { - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *con_archetype = NULL; - NMSettingConnection *s_con; + gs_unref_object NMConnection *connection = NULL; + gs_unref_object NMConnection *con_archetype = NULL; + NMSettingConnection * s_con; - con_archetype = nmtst_create_minimal_connection ("Test_minimal_x", - "a15bd68f-c32b-40b8-8d27-49e472a85919", - NM_SETTING_WIRED_SETTING_NAME, - &s_con); - nmtst_connection_normalize (con_archetype); + con_archetype = nmtst_create_minimal_connection("Test_minimal_slave_x", + "a56b4ca5-7075-43d4-82c7-5d0cb15f7654", + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + "br0", + NM_SETTING_CONNECTION_SLAVE_TYPE, + "bridge", + NULL); + nmtst_connection_normalize(con_archetype); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_1"); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), - NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), - NULL); - nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); - g_clear_object (&connection); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_slave_1"); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + nm_connection_get_id(connection), + NM_SETTING_CONNECTION_UUID, + nm_connection_get_uuid(connection), + NULL); + nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE); + g_clear_object(&connection); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_2"); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), - NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), - NULL); - nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); - g_clear_object (&connection); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_slave_2"); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + nm_connection_get_id(connection), + NM_SETTING_CONNECTION_UUID, + nm_connection_get_uuid(connection), + NULL); + nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE); + g_clear_object(&connection); + + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_slave_3"); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + nm_connection_get_id(connection), + NM_SETTING_CONNECTION_UUID, + nm_connection_get_uuid(connection), + NULL); + nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE); + g_clear_object(&connection); + + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_slave_4"); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + nm_connection_get_id(connection), + NM_SETTING_CONNECTION_UUID, + nm_connection_get_uuid(connection), + NULL); + nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE); + g_clear_object(&connection); } static void -test_read_minimal_slave (void) -{ - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *con_archetype = NULL; - NMSettingConnection *s_con; +test_read_enum_property(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSettingIPConfig * s_ip6; + + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Enum_Property"); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpint(nm_setting_ip6_config_get_ip6_privacy(NM_SETTING_IP6_CONFIG(s_ip6)), + ==, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); +} + +static void +test_write_enum_property(void) +{ + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip6; + + connection = nm_simple_connection_new(); - con_archetype = nmtst_create_minimal_connection ("Test_minimal_slave_x", - "a56b4ca5-7075-43d4-82c7-5d0cb15f7654", - NM_SETTING_WIRED_SETTING_NAME, - &s_con); - g_object_set (s_con, - NM_SETTING_CONNECTION_MASTER, "br0", - NM_SETTING_CONNECTION_SLAVE_TYPE, "bridge", - NULL); - nmtst_connection_normalize (con_archetype); + /* Connection setting */ - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_1"); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), - NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), - NULL); - nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); - g_clear_object (&connection); + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_2"); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), - NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), - NULL); - nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); - g_clear_object (&connection); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Enum Property", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NULL); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_3"); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), - NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), - NULL); - nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); - g_clear_object (&connection); + /* Wired setting */ + s_wired = NM_SETTING_WIRED(nm_setting_wired_new()); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + + /* IP6 setting */ + s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new()); + nm_connection_add_setting(connection, NM_SETTING(s_ip6)); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NULL); - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_4"); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), - NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), - NULL); - nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); - g_clear_object (&connection); + nmtst_connection_normalize(connection); + + write_test_connection_and_reread(connection, FALSE); } static void -test_read_enum_property (void) +test_read_flags_property(void) { - gs_unref_object NMConnection *connection = NULL; - NMSettingIPConfig *s_ip6; + gs_unref_object NMConnection *connection = NULL; + NMSettingGsm * s_gsm; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_Enum_Property"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Flags_Property"); - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - g_assert_cmpint (nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)), ==, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); + s_gsm = nm_connection_get_setting_gsm(connection); + g_assert(s_gsm); + g_assert_cmpint(nm_setting_gsm_get_password_flags(s_gsm), + ==, + NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED); } static void -test_write_enum_property (void) +test_write_flags_property(void) { - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIPConfig *s_ip6; - - connection = nm_simple_connection_new (); + NMTST_UUID_INIT(uuid); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSetting * s_gsm; - /* Connection setting */ + connection = nm_simple_connection_new(); - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + /* Connection setting */ - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Enum Property", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); + s_con = NM_SETTING_CONNECTION(nm_setting_connection_new()); + nm_connection_add_setting(connection, NM_SETTING(s_con)); - /* Wired setting */ - s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + g_object_set(s_con, + NM_SETTING_CONNECTION_ID, + "Test Write Flags Property", + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_GSM_SETTING_NAME, + NULL); - /* IP6 setting */ - s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_IP6_PRIVACY, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, - NULL); + /* GSM setting */ + s_gsm = nm_setting_gsm_new(); + nm_connection_add_setting(connection, s_gsm); + g_object_set(s_gsm, + NM_SETTING_GSM_APN, + "myapn", + NM_SETTING_GSM_USERNAME, + "adfasdfasdf", + NM_SETTING_GSM_PASSWORD_FLAGS, + NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED, + NULL); - nmtst_connection_normalize (connection); + nmtst_connection_normalize(connection); - write_test_connection_and_reread (connection, FALSE); + write_test_connection_and_reread(connection, FALSE); } +/*****************************************************************************/ + static void -test_read_flags_property (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSettingGsm *s_gsm; +test_read_tc_config(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSettingTCConfig * s_tc; + NMTCQdisc * qdisc1, *qdisc2; + NMTCAction * action1, *action2; + NMTCTfilter * tfilter1, *tfilter2; - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_Flags_Property"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_TC_Config"); - s_gsm = nm_connection_get_setting_gsm (connection); - g_assert (s_gsm); - g_assert_cmpint (nm_setting_gsm_get_password_flags (s_gsm), ==, - NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED); -} + s_tc = nm_connection_get_setting_tc_config(connection); + g_assert(s_tc); -static void -test_write_flags_property (void) -{ - NMTST_UUID_INIT (uuid); - gs_unref_object NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSetting *s_gsm; + g_assert(nm_setting_tc_config_get_num_qdiscs(s_tc) == 2); - connection = nm_simple_connection_new (); + qdisc1 = nm_setting_tc_config_get_qdisc(s_tc, 0); + g_assert(qdisc1); + g_assert(g_strcmp0(nm_tc_qdisc_get_kind(qdisc1), "fq_codel") == 0); + g_assert(nm_tc_qdisc_get_handle(qdisc1) == TC_H_MAKE(0x1234 << 16, 0x0000)); + g_assert(nm_tc_qdisc_get_parent(qdisc1) == TC_H_ROOT); - /* Connection setting */ + qdisc2 = nm_setting_tc_config_get_qdisc(s_tc, 1); + g_assert(qdisc2); + g_assert(g_strcmp0(nm_tc_qdisc_get_kind(qdisc2), "ingress") == 0); + g_assert(nm_tc_qdisc_get_handle(qdisc2) == TC_H_MAKE(TC_H_INGRESS, 0)); + g_assert(nm_tc_qdisc_get_parent(qdisc2) == TC_H_INGRESS); - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_con)); + g_assert(nm_setting_tc_config_get_num_tfilters(s_tc) == 2); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Flags Property", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_GSM_SETTING_NAME, - NULL); + tfilter1 = nm_setting_tc_config_get_tfilter(s_tc, 0); + g_assert(tfilter1); + g_assert(g_strcmp0(nm_tc_tfilter_get_kind(tfilter1), "matchall") == 0); + g_assert(nm_tc_tfilter_get_handle(tfilter1) == TC_H_UNSPEC); + g_assert(nm_tc_tfilter_get_parent(tfilter1) == TC_H_MAKE(0x1234 << 16, 0x0000)); - /* GSM setting */ - s_gsm = nm_setting_gsm_new (); - nm_connection_add_setting (connection, s_gsm); - g_object_set (s_gsm, - NM_SETTING_GSM_APN, "myapn", - NM_SETTING_GSM_USERNAME, "adfasdfasdf", - NM_SETTING_GSM_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED, - NULL); + action1 = nm_tc_tfilter_get_action(tfilter1); + g_assert(action1); + g_assert(g_strcmp0(nm_tc_action_get_kind(action1), "drop") == 0); - nmtst_connection_normalize (connection); + tfilter2 = nm_setting_tc_config_get_tfilter(s_tc, 1); + g_assert(tfilter2); + g_assert(g_strcmp0(nm_tc_tfilter_get_kind(tfilter2), "matchall") == 0); + g_assert(nm_tc_tfilter_get_handle(tfilter2) == TC_H_UNSPEC); + g_assert(nm_tc_tfilter_get_parent(tfilter2) == TC_H_MAKE(TC_H_INGRESS, 0)); - write_test_connection_and_reread (connection, FALSE); + action2 = nm_tc_tfilter_get_action(tfilter2); + g_assert(action2); + g_assert(g_strcmp0(nm_tc_action_get_kind(action2), "simple") == 0); + g_assert( + g_strcmp0(g_variant_get_bytestring(nm_tc_action_get_attribute(action2, "sdata")), "Hello") + == 0); } -/*****************************************************************************/ - static void -test_read_tc_config (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSettingTCConfig *s_tc; - NMTCQdisc *qdisc1, *qdisc2; - NMTCAction *action1, *action2; - NMTCTfilter *tfilter1, *tfilter2; - - connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR "/Test_TC_Config"); - - s_tc = nm_connection_get_setting_tc_config (connection); - g_assert (s_tc); - - g_assert (nm_setting_tc_config_get_num_qdiscs (s_tc) == 2); - - qdisc1 = nm_setting_tc_config_get_qdisc (s_tc, 0); - g_assert (qdisc1); - g_assert (g_strcmp0 (nm_tc_qdisc_get_kind (qdisc1), "fq_codel") == 0); - g_assert (nm_tc_qdisc_get_handle (qdisc1) == TC_H_MAKE (0x1234 << 16, 0x0000)); - g_assert (nm_tc_qdisc_get_parent (qdisc1) == TC_H_ROOT); - - qdisc2 = nm_setting_tc_config_get_qdisc (s_tc, 1); - g_assert (qdisc2); - g_assert (g_strcmp0 (nm_tc_qdisc_get_kind (qdisc2), "ingress") == 0); - g_assert (nm_tc_qdisc_get_handle (qdisc2) == TC_H_MAKE (TC_H_INGRESS, 0)); - g_assert (nm_tc_qdisc_get_parent (qdisc2) == TC_H_INGRESS); - - g_assert (nm_setting_tc_config_get_num_tfilters (s_tc) == 2); - - tfilter1 = nm_setting_tc_config_get_tfilter (s_tc, 0); - g_assert (tfilter1); - g_assert (g_strcmp0 (nm_tc_tfilter_get_kind (tfilter1), "matchall") == 0); - g_assert (nm_tc_tfilter_get_handle (tfilter1) == TC_H_UNSPEC); - g_assert (nm_tc_tfilter_get_parent (tfilter1) == TC_H_MAKE (0x1234 << 16, 0x0000)); - - action1 = nm_tc_tfilter_get_action (tfilter1); - g_assert (action1); - g_assert (g_strcmp0 (nm_tc_action_get_kind (action1), "drop") == 0); - - tfilter2 = nm_setting_tc_config_get_tfilter (s_tc, 1); - g_assert (tfilter2); - g_assert (g_strcmp0 (nm_tc_tfilter_get_kind (tfilter2), "matchall") == 0); - g_assert (nm_tc_tfilter_get_handle (tfilter2) == TC_H_UNSPEC); - g_assert (nm_tc_tfilter_get_parent (tfilter2) == TC_H_MAKE (TC_H_INGRESS, 0)); - - action2 = nm_tc_tfilter_get_action (tfilter2); - g_assert (action2); - g_assert (g_strcmp0 (nm_tc_action_get_kind (action2), "simple") == 0); - g_assert (g_strcmp0 (g_variant_get_bytestring (nm_tc_action_get_attribute (action2, "sdata")), - "Hello") == 0); -} - -static void -test_write_tc_config (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSetting *s_tc; - NMTCQdisc *qdisc1, *qdisc2; - NMTCTfilter *tfilter1, *tfilter2; - NMTCAction *action; - GError *error = NULL; - - connection = nmtst_create_minimal_connection ("Test TC", - NULL, - NM_SETTING_WIRED_SETTING_NAME, - NULL); - s_tc = nm_setting_tc_config_new (); - - qdisc1 = nm_tc_qdisc_new ("fq_codel", TC_H_ROOT, &error); - nmtst_assert_success (qdisc1, error); - nm_tc_qdisc_set_handle (qdisc1, TC_H_MAKE (0x1234 << 16, 0x0000)); - nm_setting_tc_config_add_qdisc (NM_SETTING_TC_CONFIG (s_tc), qdisc1); - - qdisc2 = nm_tc_qdisc_new ("ingress", TC_H_INGRESS, &error); - nmtst_assert_success (qdisc2, error); - nm_tc_qdisc_set_handle (qdisc2, TC_H_MAKE (TC_H_INGRESS, 0)); - nm_setting_tc_config_add_qdisc (NM_SETTING_TC_CONFIG (s_tc), qdisc2); - - tfilter1 = nm_tc_tfilter_new ("matchall", - TC_H_MAKE (0x1234 << 16, 0x0000), - &error); - nmtst_assert_success (tfilter1, error); - action = nm_tc_action_new ("drop", &error); - nmtst_assert_success (action, error); - nm_tc_tfilter_set_action (tfilter1, action); - nm_tc_action_unref (action); - nm_setting_tc_config_add_tfilter (NM_SETTING_TC_CONFIG (s_tc), tfilter1); - nm_tc_tfilter_unref (tfilter1); - - tfilter2 = nm_tc_tfilter_new ("matchall", - TC_H_MAKE (TC_H_INGRESS, 0), - &error); - nmtst_assert_success (tfilter2, error); - action = nm_tc_action_new ("simple", &error); - nmtst_assert_success (action, error); - nm_tc_action_set_attribute (action, "sdata", g_variant_new_bytestring ("Hello")); - nm_tc_tfilter_set_action (tfilter2, action); - nm_tc_action_unref (action); - nm_setting_tc_config_add_tfilter (NM_SETTING_TC_CONFIG (s_tc), tfilter2); - nm_tc_tfilter_unref (tfilter2); - - nm_connection_add_setting (connection, s_tc); - - nmtst_connection_normalize (connection); - write_test_connection_and_reread (connection, FALSE); - - nm_tc_qdisc_unref (qdisc1); - nm_tc_qdisc_unref (qdisc2); +test_write_tc_config(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSetting * s_tc; + NMTCQdisc * qdisc1, *qdisc2; + NMTCTfilter * tfilter1, *tfilter2; + NMTCAction * action; + GError * error = NULL; + + connection = + nmtst_create_minimal_connection("Test TC", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_tc = nm_setting_tc_config_new(); + + qdisc1 = nm_tc_qdisc_new("fq_codel", TC_H_ROOT, &error); + nmtst_assert_success(qdisc1, error); + nm_tc_qdisc_set_handle(qdisc1, TC_H_MAKE(0x1234 << 16, 0x0000)); + nm_setting_tc_config_add_qdisc(NM_SETTING_TC_CONFIG(s_tc), qdisc1); + + qdisc2 = nm_tc_qdisc_new("ingress", TC_H_INGRESS, &error); + nmtst_assert_success(qdisc2, error); + nm_tc_qdisc_set_handle(qdisc2, TC_H_MAKE(TC_H_INGRESS, 0)); + nm_setting_tc_config_add_qdisc(NM_SETTING_TC_CONFIG(s_tc), qdisc2); + + tfilter1 = nm_tc_tfilter_new("matchall", TC_H_MAKE(0x1234 << 16, 0x0000), &error); + nmtst_assert_success(tfilter1, error); + action = nm_tc_action_new("drop", &error); + nmtst_assert_success(action, error); + nm_tc_tfilter_set_action(tfilter1, action); + nm_tc_action_unref(action); + nm_setting_tc_config_add_tfilter(NM_SETTING_TC_CONFIG(s_tc), tfilter1); + nm_tc_tfilter_unref(tfilter1); + + tfilter2 = nm_tc_tfilter_new("matchall", TC_H_MAKE(TC_H_INGRESS, 0), &error); + nmtst_assert_success(tfilter2, error); + action = nm_tc_action_new("simple", &error); + nmtst_assert_success(action, error); + nm_tc_action_set_attribute(action, "sdata", g_variant_new_bytestring("Hello")); + nm_tc_tfilter_set_action(tfilter2, action); + nm_tc_action_unref(action); + nm_setting_tc_config_add_tfilter(NM_SETTING_TC_CONFIG(s_tc), tfilter2); + nm_tc_tfilter_unref(tfilter2); + + nm_connection_add_setting(connection, s_tc); + + nmtst_connection_normalize(connection); + write_test_connection_and_reread(connection, FALSE); + + nm_tc_qdisc_unref(qdisc1); + nm_tc_qdisc_unref(qdisc2); } /*****************************************************************************/ static void -_escape_filename (gboolean with_extension, const char *filename, gboolean would_be_ignored) +_escape_filename(gboolean with_extension, const char *filename, gboolean would_be_ignored) { - gs_free char *esc = NULL; + gs_free char *esc = NULL; - g_assert (filename && filename[0]); + g_assert(filename && filename[0]); - if (!!would_be_ignored != !!nm_keyfile_utils_ignore_filename (filename, with_extension)) { - if (would_be_ignored) - g_error ("We expect filename \"%s\" to be ignored, but it isn't", filename); - else - g_error ("We expect filename \"%s\" not to be ignored, but it is", filename); - } + if (!!would_be_ignored != !!nm_keyfile_utils_ignore_filename(filename, with_extension)) { + if (would_be_ignored) + g_error("We expect filename \"%s\" to be ignored, but it isn't", filename); + else + g_error("We expect filename \"%s\" not to be ignored, but it is", filename); + } - esc = nm_keyfile_utils_create_filename (filename, with_extension); - g_assert (esc && esc[0]); - g_assert (!strchr (esc, '/')); + esc = nm_keyfile_utils_create_filename(filename, with_extension); + g_assert(esc && esc[0]); + g_assert(!strchr(esc, '/')); - if (nm_keyfile_utils_ignore_filename (esc, with_extension)) - g_error ("Escaping filename \"%s\" yielded \"%s\", but this is ignored", filename, esc); + if (nm_keyfile_utils_ignore_filename(esc, with_extension)) + g_error("Escaping filename \"%s\" yielded \"%s\", but this is ignored", filename, esc); } static void -test_nm_keyfile_plugin_utils_escape_filename (void) +test_nm_keyfile_plugin_utils_escape_filename(void) { - _escape_filename (FALSE, "ab", FALSE); - _escape_filename (FALSE, ".vim-file.swp", TRUE); - _escape_filename (FALSE, ".vim-file.Swp", TRUE); - _escape_filename (FALSE, ".vim-file.SWP", TRUE); - _escape_filename (FALSE, ".vim-file.swpx", TRUE); - _escape_filename (FALSE, ".vim-file.Swpx", TRUE); - _escape_filename (FALSE, ".vim-file.SWPX", TRUE); - _escape_filename (FALSE, ".pem-file.pem", TRUE); - _escape_filename (FALSE, ".pem-file.Pem", TRUE); - _escape_filename (FALSE, ".pem-file.PEM", TRUE); - _escape_filename (FALSE, ".pem-file.der", TRUE); - _escape_filename (FALSE, ".pem-file.Der", TRUE); - _escape_filename (FALSE, ".mkstemp.ABCEDF", TRUE); - _escape_filename (FALSE, ".mkstemp.abcdef", TRUE); - _escape_filename (FALSE, ".mkstemp.123456", TRUE); - _escape_filename (FALSE, ".mkstemp.A23456", TRUE); - _escape_filename (FALSE, ".#emacs-locking", TRUE); - _escape_filename (FALSE, "file-with-tilde~", TRUE); - _escape_filename (FALSE, ".file-with-dot", TRUE); - _escape_filename (FALSE, "/some/path/with/trailing/slash/", TRUE); - _escape_filename (FALSE, "/some/path/without/trailing/slash", FALSE); + _escape_filename(FALSE, "ab", FALSE); + _escape_filename(FALSE, ".vim-file.swp", TRUE); + _escape_filename(FALSE, ".vim-file.Swp", TRUE); + _escape_filename(FALSE, ".vim-file.SWP", TRUE); + _escape_filename(FALSE, ".vim-file.swpx", TRUE); + _escape_filename(FALSE, ".vim-file.Swpx", TRUE); + _escape_filename(FALSE, ".vim-file.SWPX", TRUE); + _escape_filename(FALSE, ".pem-file.pem", TRUE); + _escape_filename(FALSE, ".pem-file.Pem", TRUE); + _escape_filename(FALSE, ".pem-file.PEM", TRUE); + _escape_filename(FALSE, ".pem-file.der", TRUE); + _escape_filename(FALSE, ".pem-file.Der", TRUE); + _escape_filename(FALSE, ".mkstemp.ABCEDF", TRUE); + _escape_filename(FALSE, ".mkstemp.abcdef", TRUE); + _escape_filename(FALSE, ".mkstemp.123456", TRUE); + _escape_filename(FALSE, ".mkstemp.A23456", TRUE); + _escape_filename(FALSE, ".#emacs-locking", TRUE); + _escape_filename(FALSE, "file-with-tilde~", TRUE); + _escape_filename(FALSE, ".file-with-dot", TRUE); + _escape_filename(FALSE, "/some/path/with/trailing/slash/", TRUE); + _escape_filename(FALSE, "/some/path/without/trailing/slash", FALSE); - _escape_filename (TRUE, "lala", TRUE); + _escape_filename(TRUE, "lala", TRUE); } /*****************************************************************************/ static void -_assert_keyfile_nmmeta (const char *dirname, - const char *uuid, - const char *loaded_path, - gboolean allow_relative, - const char *exp_full_filename, - const char *exp_uuid, - const char *exp_symlink_target, - const char *exp_loaded_path) -{ - gs_free char *full_filename = NULL; - gs_free char *symlink_target = NULL; - gs_free char *uuid2 = NULL; - gs_free char *loaded_path2 = NULL; - gs_free char *dirname3 = NULL; - gs_free char *filename3 = NULL; - gs_free char *uuid3 = NULL; - gs_free char *loaded_path3 = NULL; - gboolean success; - gs_free char *filename = NULL; - - g_assert (dirname && dirname[0] == '/'); - g_assert (exp_full_filename && exp_full_filename[0]); - g_assert (!exp_loaded_path || exp_loaded_path[0] == '/'); - - filename = g_path_get_basename (exp_full_filename); - - full_filename = nms_keyfile_nmmeta_filename (dirname, uuid, FALSE); - g_assert_cmpstr (full_filename, ==, full_filename); - nm_clear_g_free (&full_filename); - - - g_assert_cmpint (nms_keyfile_nmmeta_write (dirname, uuid, loaded_path, allow_relative, NULL, &full_filename), ==, 0); - g_assert_cmpstr (full_filename, ==, exp_full_filename); - nm_clear_g_free (&full_filename); - - if (exp_symlink_target) - g_assert (g_file_test (exp_full_filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_SYMLINK)); - else - g_assert (!g_file_test (exp_full_filename, G_FILE_TEST_EXISTS)); - symlink_target = g_file_read_link (exp_full_filename, NULL); - g_assert_cmpstr (symlink_target, ==, exp_symlink_target); - - - success = nms_keyfile_nmmeta_read (dirname, filename, &full_filename, &uuid2, &loaded_path2, NULL, NULL); - g_assert_cmpint (!!exp_uuid, ==, success); - if (success) - g_assert_cmpstr (full_filename, ==, exp_full_filename); - else - g_assert_cmpstr (full_filename, ==, NULL); - nm_clear_g_free (&full_filename); - g_assert_cmpstr (uuid2, ==, exp_uuid); - g_assert_cmpstr (loaded_path2, ==, exp_loaded_path); - - - success = nms_keyfile_nmmeta_read_from_file (exp_full_filename, &dirname3, &filename3, &uuid3, &loaded_path3, NULL); - g_assert_cmpint (!!exp_uuid, ==, success); - if (success) { - g_assert_cmpstr (dirname3, ==, dirname); - g_assert_cmpstr (filename3, ==, filename); - } else { - g_assert_cmpstr (dirname3, ==, NULL); - g_assert_cmpstr (filename3, ==, NULL); - } - g_assert_cmpstr (uuid3, ==, exp_uuid); - g_assert_cmpstr (loaded_path3, ==, exp_loaded_path); -} - -static void -test_nmmeta (void) -{ - const char *uuid = "3c03fd17-ddc3-4100-a954-88b6fafff959"; - gs_free char *filename = g_strdup_printf ("%s%s", - uuid, - NM_KEYFILE_PATH_SUFFIX_NMMETA); - gs_free char *full_filename = g_strdup_printf ("%s/%s", - TEST_SCRATCH_DIR, - filename); - const char *loaded_path0 = NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL; - const char *loaded_path1 = "/some/where/but/not/scratch/dir"; - const char *filename2 = "foo1"; - gs_free char *loaded_path2 = g_strdup_printf ("%s/%s", - TEST_SCRATCH_DIR, - filename2); - - _assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, NULL, FALSE, full_filename, NULL, NULL, NULL); - _assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, NULL, TRUE, full_filename, NULL, NULL, NULL); - - _assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path0, FALSE, full_filename, uuid, loaded_path0, loaded_path0); - _assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path0, TRUE, full_filename, uuid, loaded_path0, loaded_path0); - - _assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path1, FALSE, full_filename, uuid, loaded_path1, loaded_path1); - _assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path1, TRUE, full_filename, uuid, loaded_path1, loaded_path1); - - _assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path2, FALSE, full_filename, uuid, loaded_path2, loaded_path2); - _assert_keyfile_nmmeta (TEST_SCRATCH_DIR, uuid, loaded_path2, TRUE, full_filename, uuid, filename2, loaded_path2); - - (void) unlink (full_filename); +_assert_keyfile_nmmeta(const char *dirname, + const char *uuid, + const char *loaded_path, + gboolean allow_relative, + const char *exp_full_filename, + const char *exp_uuid, + const char *exp_symlink_target, + const char *exp_loaded_path) +{ + gs_free char *full_filename = NULL; + gs_free char *symlink_target = NULL; + gs_free char *uuid2 = NULL; + gs_free char *loaded_path2 = NULL; + gs_free char *dirname3 = NULL; + gs_free char *filename3 = NULL; + gs_free char *uuid3 = NULL; + gs_free char *loaded_path3 = NULL; + gboolean success; + gs_free char *filename = NULL; + + g_assert(dirname && dirname[0] == '/'); + g_assert(exp_full_filename && exp_full_filename[0]); + g_assert(!exp_loaded_path || exp_loaded_path[0] == '/'); + + filename = g_path_get_basename(exp_full_filename); + + full_filename = nms_keyfile_nmmeta_filename(dirname, uuid, FALSE); + g_assert_cmpstr(full_filename, ==, full_filename); + nm_clear_g_free(&full_filename); + + g_assert_cmpint( + nms_keyfile_nmmeta_write(dirname, uuid, loaded_path, allow_relative, NULL, &full_filename), + ==, + 0); + g_assert_cmpstr(full_filename, ==, exp_full_filename); + nm_clear_g_free(&full_filename); + + if (exp_symlink_target) + g_assert(g_file_test(exp_full_filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_SYMLINK)); + else + g_assert(!g_file_test(exp_full_filename, G_FILE_TEST_EXISTS)); + symlink_target = g_file_read_link(exp_full_filename, NULL); + g_assert_cmpstr(symlink_target, ==, exp_symlink_target); + + success = nms_keyfile_nmmeta_read(dirname, + filename, + &full_filename, + &uuid2, + &loaded_path2, + NULL, + NULL); + g_assert_cmpint(!!exp_uuid, ==, success); + if (success) + g_assert_cmpstr(full_filename, ==, exp_full_filename); + else + g_assert_cmpstr(full_filename, ==, NULL); + nm_clear_g_free(&full_filename); + g_assert_cmpstr(uuid2, ==, exp_uuid); + g_assert_cmpstr(loaded_path2, ==, exp_loaded_path); + + success = nms_keyfile_nmmeta_read_from_file(exp_full_filename, + &dirname3, + &filename3, + &uuid3, + &loaded_path3, + NULL); + g_assert_cmpint(!!exp_uuid, ==, success); + if (success) { + g_assert_cmpstr(dirname3, ==, dirname); + g_assert_cmpstr(filename3, ==, filename); + } else { + g_assert_cmpstr(dirname3, ==, NULL); + g_assert_cmpstr(filename3, ==, NULL); + } + g_assert_cmpstr(uuid3, ==, exp_uuid); + g_assert_cmpstr(loaded_path3, ==, exp_loaded_path); +} + +static void +test_nmmeta(void) +{ + const char * uuid = "3c03fd17-ddc3-4100-a954-88b6fafff959"; + gs_free char *filename = g_strdup_printf("%s%s", uuid, NM_KEYFILE_PATH_SUFFIX_NMMETA); + gs_free char *full_filename = g_strdup_printf("%s/%s", TEST_SCRATCH_DIR, filename); + const char * loaded_path0 = NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL; + const char * loaded_path1 = "/some/where/but/not/scratch/dir"; + const char * filename2 = "foo1"; + gs_free char *loaded_path2 = g_strdup_printf("%s/%s", TEST_SCRATCH_DIR, filename2); + + _assert_keyfile_nmmeta(TEST_SCRATCH_DIR, uuid, NULL, FALSE, full_filename, NULL, NULL, NULL); + _assert_keyfile_nmmeta(TEST_SCRATCH_DIR, uuid, NULL, TRUE, full_filename, NULL, NULL, NULL); + + _assert_keyfile_nmmeta(TEST_SCRATCH_DIR, + uuid, + loaded_path0, + FALSE, + full_filename, + uuid, + loaded_path0, + loaded_path0); + _assert_keyfile_nmmeta(TEST_SCRATCH_DIR, + uuid, + loaded_path0, + TRUE, + full_filename, + uuid, + loaded_path0, + loaded_path0); + + _assert_keyfile_nmmeta(TEST_SCRATCH_DIR, + uuid, + loaded_path1, + FALSE, + full_filename, + uuid, + loaded_path1, + loaded_path1); + _assert_keyfile_nmmeta(TEST_SCRATCH_DIR, + uuid, + loaded_path1, + TRUE, + full_filename, + uuid, + loaded_path1, + loaded_path1); + + _assert_keyfile_nmmeta(TEST_SCRATCH_DIR, + uuid, + loaded_path2, + FALSE, + full_filename, + uuid, + loaded_path2, + loaded_path2); + _assert_keyfile_nmmeta(TEST_SCRATCH_DIR, + uuid, + loaded_path2, + TRUE, + full_filename, + uuid, + filename2, + loaded_path2); + + (void) unlink(full_filename); } /*****************************************************************************/ -NMTST_DEFINE (); +NMTST_DEFINE(); -int main (int argc, char **argv) +int +main(int argc, char **argv) { - int errsv; + int errsv; - _nm_utils_set_testing (NM_UTILS_TEST_NO_KEYFILE_OWNER_CHECK); + _nm_utils_set_testing(NM_UTILS_TEST_NO_KEYFILE_OWNER_CHECK); - nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); + nmtst_init_assert_logging(&argc, &argv, "INFO", "DEFAULT"); - if (g_mkdir_with_parents (TEST_SCRATCH_DIR, 0755) != 0) { - errsv = errno; - g_error ("failure to create test directory \"%s\": %s", TEST_SCRATCH_DIR, nm_strerror_native (errsv)); - } + if (g_mkdir_with_parents(TEST_SCRATCH_DIR, 0755) != 0) { + errsv = errno; + g_error("failure to create test directory \"%s\": %s", + TEST_SCRATCH_DIR, + nm_strerror_native(errsv)); + } - /* The tests */ - g_test_add_func ("/keyfile/test_read_valid_wired_connection", test_read_valid_wired_connection); - g_test_add_func ("/keyfile/test_write_wired_connection", test_write_wired_connection); + /* The tests */ + g_test_add_func("/keyfile/test_read_valid_wired_connection", test_read_valid_wired_connection); + g_test_add_func("/keyfile/test_write_wired_connection", test_write_wired_connection); - g_test_add_func ("/keyfile/test_read_ip6_wired_connection", test_read_ip6_wired_connection); - g_test_add_func ("/keyfile/test_write_ip6_wired_connection", test_write_ip6_wired_connection); + g_test_add_func("/keyfile/test_read_ip6_wired_connection", test_read_ip6_wired_connection); + g_test_add_func("/keyfile/test_write_ip6_wired_connection", test_write_ip6_wired_connection); - g_test_add_func ("/keyfile/test_read_wired_mac_case", test_read_wired_mac_case); - g_test_add_func ("/keyfile/test_read_mac_old_format", test_read_mac_old_format); - g_test_add_func ("/keyfile/test_read_mac_ib_old_format", test_read_mac_ib_old_format); + g_test_add_func("/keyfile/test_read_wired_mac_case", test_read_wired_mac_case); + g_test_add_func("/keyfile/test_read_mac_old_format", test_read_mac_old_format); + g_test_add_func("/keyfile/test_read_mac_ib_old_format", test_read_mac_ib_old_format); - g_test_add_func ("/keyfile/test_read_valid_wireless_connection", test_read_valid_wireless_connection); - g_test_add_func ("/keyfile/test_write_wireless_connection", test_write_wireless_connection); + g_test_add_func("/keyfile/test_read_valid_wireless_connection", + test_read_valid_wireless_connection); + g_test_add_func("/keyfile/test_write_wireless_connection", test_write_wireless_connection); - g_test_add_func ("/keyfile/test_read_string_ssid", test_read_string_ssid); - g_test_add_func ("/keyfile/test_write_string_ssid", test_write_string_ssid); + g_test_add_func("/keyfile/test_read_string_ssid", test_read_string_ssid); + g_test_add_func("/keyfile/test_write_string_ssid", test_write_string_ssid); - g_test_add_func ("/keyfile/test_read_intlist_ssid", test_read_intlist_ssid); - g_test_add_func ("/keyfile/test_write_intlist_ssid", test_write_intlist_ssid); + g_test_add_func("/keyfile/test_read_intlist_ssid", test_read_intlist_ssid); + g_test_add_func("/keyfile/test_write_intlist_ssid", test_write_intlist_ssid); - g_test_add_func ("/keyfile/test_read_intlike_ssid", test_read_intlike_ssid); - g_test_add_func ("/keyfile/test_write_intlike_ssid", test_write_intlike_ssid); + g_test_add_func("/keyfile/test_read_intlike_ssid", test_read_intlike_ssid); + g_test_add_func("/keyfile/test_write_intlike_ssid", test_write_intlike_ssid); - g_test_add_func ("/keyfile/test_read_intlike_ssid_2", test_read_intlike_ssid_2); - g_test_add_func ("/keyfile/test_write_intlike_ssid_2", test_write_intlike_ssid_2); + g_test_add_func("/keyfile/test_read_intlike_ssid_2", test_read_intlike_ssid_2); + g_test_add_func("/keyfile/test_write_intlike_ssid_2", test_write_intlike_ssid_2); - g_test_add_func ("/keyfile/test_read_bt_dun_connection", test_read_bt_dun_connection); - g_test_add_func ("/keyfile/test_write_bt_dun_connection", test_write_bt_dun_connection); + g_test_add_func("/keyfile/test_read_bt_dun_connection", test_read_bt_dun_connection); + g_test_add_func("/keyfile/test_write_bt_dun_connection", test_write_bt_dun_connection); - g_test_add_func ("/keyfile/test_read_gsm_connection", test_read_gsm_connection); - g_test_add_func ("/keyfile/test_write_gsm_connection", test_write_gsm_connection); + g_test_add_func("/keyfile/test_read_gsm_connection", test_read_gsm_connection); + g_test_add_func("/keyfile/test_write_gsm_connection", test_write_gsm_connection); - g_test_add_func ("/keyfile/test_read_wired_8021x_tls_blob_connection", test_read_wired_8021x_tls_blob_connection); - g_test_add_func ("/keyfile/test_read_wired_8021x_tls_bad_path_connection", test_read_wired_8021x_tls_bad_path_connection); + g_test_add_func("/keyfile/test_read_wired_8021x_tls_blob_connection", + test_read_wired_8021x_tls_blob_connection); + g_test_add_func("/keyfile/test_read_wired_8021x_tls_bad_path_connection", + test_read_wired_8021x_tls_bad_path_connection); - g_test_add_func ("/keyfile/test_read_wired_8021x_tls_old_connection", test_read_wired_8021x_tls_old_connection); - g_test_add_func ("/keyfile/test_read_wired_8021x_tls_new_connection", test_read_wired_8021x_tls_new_connection); - g_test_add_func ("/keyfile/test_write_wired_8021x_tls_connection_path", test_write_wired_8021x_tls_connection_path); - g_test_add_func ("/keyfile/test_write_wired_8021x_tls_connection_blob", test_write_wired_8021x_tls_connection_blob); + g_test_add_func("/keyfile/test_read_wired_8021x_tls_old_connection", + test_read_wired_8021x_tls_old_connection); + g_test_add_func("/keyfile/test_read_wired_8021x_tls_new_connection", + test_read_wired_8021x_tls_new_connection); + g_test_add_func("/keyfile/test_write_wired_8021x_tls_connection_path", + test_write_wired_8021x_tls_connection_path); + g_test_add_func("/keyfile/test_write_wired_8021x_tls_connection_blob", + test_write_wired_8021x_tls_connection_blob); - g_test_add_func ("/keyfile/test_read_dcb_connection", test_read_dcb_connection); + g_test_add_func("/keyfile/test_read_dcb_connection", test_read_dcb_connection); - g_test_add_func ("/keyfile/test_read_infiniband_connection", test_read_infiniband_connection); - g_test_add_func ("/keyfile/test_write_infiniband_connection", test_write_infiniband_connection); + g_test_add_func("/keyfile/test_read_infiniband_connection", test_read_infiniband_connection); + g_test_add_func("/keyfile/test_write_infiniband_connection", test_write_infiniband_connection); - g_test_add_func ("/keyfile/test_read_bridge_main", test_read_bridge_main); - g_test_add_func ("/keyfile/test_write_bridge_main", test_write_bridge_main); - g_test_add_func ("/keyfile/test_read_bridge_component", test_read_bridge_component); - g_test_add_func ("/keyfile/test_write_bridge_component", test_write_bridge_component); + g_test_add_func("/keyfile/test_read_bridge_main", test_read_bridge_main); + g_test_add_func("/keyfile/test_write_bridge_main", test_write_bridge_main); + g_test_add_func("/keyfile/test_read_bridge_component", test_read_bridge_component); + g_test_add_func("/keyfile/test_write_bridge_component", test_write_bridge_component); - g_test_add_func ("/keyfile/test_read_new_wired_group_name", test_read_new_wired_group_name); - g_test_add_func ("/keyfile/test_write_new_wired_group_name", test_write_new_wired_group_name); - g_test_add_func ("/keyfile/test_read_new_wireless_group_names", test_read_new_wireless_group_names); - g_test_add_func ("/keyfile/test_write_new_wireless_group_names", test_write_new_wireless_group_names); + g_test_add_func("/keyfile/test_read_new_wired_group_name", test_read_new_wired_group_name); + g_test_add_func("/keyfile/test_write_new_wired_group_name", test_write_new_wired_group_name); + g_test_add_func("/keyfile/test_read_new_wireless_group_names", + test_read_new_wireless_group_names); + g_test_add_func("/keyfile/test_write_new_wireless_group_names", + test_write_new_wireless_group_names); - g_test_add_func ("/keyfile/test_read_missing_vlan_setting", test_read_missing_vlan_setting); - g_test_add_func ("/keyfile/test_read_missing_vlan_flags", test_read_missing_vlan_flags); - g_test_add_func ("/keyfile/test_read_missing_id_uuid", test_read_missing_id_uuid); + g_test_add_func("/keyfile/test_read_missing_vlan_setting", test_read_missing_vlan_setting); + g_test_add_func("/keyfile/test_read_missing_vlan_flags", test_read_missing_vlan_flags); + g_test_add_func("/keyfile/test_read_missing_id_uuid", test_read_missing_id_uuid); - g_test_add_func ("/keyfile/test_read_minimal", test_read_minimal); - g_test_add_func ("/keyfile/test_read_minimal_slave", test_read_minimal_slave); + g_test_add_func("/keyfile/test_read_minimal", test_read_minimal); + g_test_add_func("/keyfile/test_read_minimal_slave", test_read_minimal_slave); - g_test_add_func ("/keyfile/test_read_enum_property", test_read_enum_property); - g_test_add_func ("/keyfile/test_write_enum_property", test_write_enum_property); - g_test_add_func ("/keyfile/test_read_flags_property", test_read_flags_property); - g_test_add_func ("/keyfile/test_write_flags_property", test_write_flags_property); + g_test_add_func("/keyfile/test_read_enum_property", test_read_enum_property); + g_test_add_func("/keyfile/test_write_enum_property", test_write_enum_property); + g_test_add_func("/keyfile/test_read_flags_property", test_read_flags_property); + g_test_add_func("/keyfile/test_write_flags_property", test_write_flags_property); - g_test_add_func ("/keyfile/test_read_tc_config", test_read_tc_config); - g_test_add_func ("/keyfile/test_write_tc_config", test_write_tc_config); + g_test_add_func("/keyfile/test_read_tc_config", test_read_tc_config); + g_test_add_func("/keyfile/test_write_tc_config", test_write_tc_config); - g_test_add_func ("/keyfile/test_nm_keyfile_plugin_utils_escape_filename", test_nm_keyfile_plugin_utils_escape_filename); + g_test_add_func("/keyfile/test_nm_keyfile_plugin_utils_escape_filename", + test_nm_keyfile_plugin_utils_escape_filename); - g_test_add_func ("/keyfile/test_nmmeta", test_nmmeta); + g_test_add_func("/keyfile/test_nmmeta", test_nmmeta); - return g_test_run (); + return g_test_run(); } -- cgit 1.3.0-6-gf8a5 From 65f86e8f56267192d42f2b629fc6b0c99fb9cd0c Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Sun, 6 Dec 2020 21:57:59 +0100 Subject: New upstream version 1.28.0 --- src/settings/plugins/ifcfg-rh/meson.build | 1 + 1 file changed, 1 insertion(+) (limited to 'src/settings') diff --git a/src/settings/plugins/ifcfg-rh/meson.build b/src/settings/plugins/ifcfg-rh/meson.build index e193ff96..10b93d0a 100644 --- a/src/settings/plugins/ifcfg-rh/meson.build +++ b/src/settings/plugins/ifcfg-rh/meson.build @@ -18,6 +18,7 @@ libnmdbus_ifcfg_rh = static_library( name, sources: dbus_sources, dependencies: glib_dep, + c_args: introspection_extra_cflags, ) core_sources = files( -- cgit 1.3.0-6-gf8a5