From ee9c73a923909e23a649407be77e25235d769e25 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Fri, 11 May 2018 22:08:45 +0200 Subject: New upstream version 1.10.8 --- src/settings/nm-agent-manager.c | 160 +- src/settings/nm-agent-manager.h | 2 +- src/settings/nm-secret-agent.c | 140 +- src/settings/nm-settings-connection.c | 664 ++--- src/settings/nm-settings-connection.h | 61 +- src/settings/nm-settings.c | 769 +++--- src/settings/nm-settings.h | 10 + src/settings/plugins/ibft/meson.build | 48 - src/settings/plugins/ibft/tests/meson.build | 22 - src/settings/plugins/ibft/tests/test-ibft.c | 2 +- src/settings/plugins/ifcfg-rh/meson.build | 77 - src/settings/plugins/ifcfg-rh/nm-inotify-helper.c | 2 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c | 134 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 162 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 66 +- src/settings/plugins/ifcfg-rh/shvar.c | 4 +- src/settings/plugins/ifcfg-rh/tests/meson.build | 22 - .../ifcfg-Test_Write_WiFi_Hidden.cexpected | 1 + .../ifcfg-Test_Write_Wired_Static_Routes.cexpected | 2 - .../ifcfg-rh/tests/network-scripts/ifcfg-test-tc | 16 - .../network-scripts/ifcfg-test-tc-write.cexpected | 16 - .../network-scripts/ifcfg-test-wired-ipv4-manual-1 | 2 - .../network-scripts/ifcfg-test-wired-ipv4-manual-2 | 2 - .../network-scripts/ifcfg-test-wired-ipv4-manual-3 | 2 - .../network-scripts/ifcfg-test-wired-ipv4-manual-4 | 2 - .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 195 +- .../plugins/ifnet/nms-ifnet-connection-parser.c | 2912 ++++++++++++++++++++ .../plugins/ifnet/nms-ifnet-connection-parser.h | 55 + src/settings/plugins/ifnet/nms-ifnet-connection.c | 233 ++ src/settings/plugins/ifnet/nms-ifnet-connection.h | 46 + src/settings/plugins/ifnet/nms-ifnet-net-parser.c | 734 +++++ src/settings/plugins/ifnet/nms-ifnet-net-parser.h | 42 + src/settings/plugins/ifnet/nms-ifnet-net-utils.c | 830 ++++++ src/settings/plugins/ifnet/nms-ifnet-net-utils.h | 71 + src/settings/plugins/ifnet/nms-ifnet-plugin.c | 524 ++++ src/settings/plugins/ifnet/nms-ifnet-plugin.h | 38 + src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c | 584 ++++ src/settings/plugins/ifnet/nms-ifnet-wpa-parser.h | 41 + src/settings/plugins/ifnet/tests/net | 158 ++ src/settings/plugins/ifnet/tests/net.all | 864 ++++++ .../plugins/ifnet/tests/nm-system-settings.conf | 5 + src/settings/plugins/ifnet/tests/test-ifnet.c | 396 +++ src/settings/plugins/ifnet/tests/test_ca_cert.pem | 27 + .../plugins/ifnet/tests/wpa_supplicant.conf | 70 + src/settings/plugins/ifupdown/meson.build | 53 - .../ifupdown/nms-ifupdown-interface-parser.c | 6 +- src/settings/plugins/ifupdown/tests/meson.build | 17 - .../plugins/ifupdown/tests/test-ifupdown.c | 2 +- src/settings/plugins/keyfile/nms-keyfile-plugin.c | 2 +- .../keyfile/tests/keyfiles/Test_Wired_Connection | 10 +- src/settings/plugins/keyfile/tests/meson.build | 21 - src/settings/plugins/keyfile/tests/test-keyfile.c | 88 +- src/settings/plugins/meson.build | 15 - 53 files changed, 8610 insertions(+), 1817 deletions(-) delete mode 100644 src/settings/plugins/ibft/meson.build delete mode 100644 src/settings/plugins/ibft/tests/meson.build delete mode 100644 src/settings/plugins/ifcfg-rh/meson.build delete mode 100644 src/settings/plugins/ifcfg-rh/tests/meson.build delete mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc delete mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc-write.cexpected create mode 100644 src/settings/plugins/ifnet/nms-ifnet-connection-parser.c create mode 100644 src/settings/plugins/ifnet/nms-ifnet-connection-parser.h create mode 100644 src/settings/plugins/ifnet/nms-ifnet-connection.c create mode 100644 src/settings/plugins/ifnet/nms-ifnet-connection.h create mode 100644 src/settings/plugins/ifnet/nms-ifnet-net-parser.c create mode 100644 src/settings/plugins/ifnet/nms-ifnet-net-parser.h create mode 100644 src/settings/plugins/ifnet/nms-ifnet-net-utils.c create mode 100644 src/settings/plugins/ifnet/nms-ifnet-net-utils.h create mode 100644 src/settings/plugins/ifnet/nms-ifnet-plugin.c create mode 100644 src/settings/plugins/ifnet/nms-ifnet-plugin.h create mode 100644 src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c create mode 100644 src/settings/plugins/ifnet/nms-ifnet-wpa-parser.h create mode 100644 src/settings/plugins/ifnet/tests/net create mode 100644 src/settings/plugins/ifnet/tests/net.all create mode 100644 src/settings/plugins/ifnet/tests/nm-system-settings.conf create mode 100644 src/settings/plugins/ifnet/tests/test-ifnet.c create mode 100644 src/settings/plugins/ifnet/tests/test_ca_cert.pem create mode 100644 src/settings/plugins/ifnet/tests/wpa_supplicant.conf delete mode 100644 src/settings/plugins/ifupdown/meson.build delete mode 100644 src/settings/plugins/ifupdown/tests/meson.build delete mode 100644 src/settings/plugins/keyfile/tests/meson.build delete mode 100644 src/settings/plugins/meson.build (limited to 'src/settings') diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 453136e4..a68db47e 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -31,12 +31,14 @@ #include "nm-auth-utils.h" #include "nm-setting-vpn.h" #include "nm-auth-manager.h" -#include "nm-dbus-manager.h" +#include "nm-bus-manager.h" #include "nm-session-monitor.h" #include "nm-simple-connection.h" #include "NetworkManagerUtils.h" #include "nm-core-internal.h" -#include "c-list/src/c-list.h" +#include "nm-utils/c-list.h" + +#include "introspection/org.freedesktop.NetworkManager.AgentManager.h" /*****************************************************************************/ @@ -65,15 +67,15 @@ typedef struct { } NMAgentManagerPrivate; struct _NMAgentManager { - NMDBusObject parent; + NMExportedObject parent; NMAgentManagerPrivate _priv; }; struct _NMAgentManagerClass { - NMDBusObjectClass parent; + NMExportedObjectClass parent; }; -G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, NM_TYPE_DBUS_OBJECT) +G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, NM_TYPE_EXPORTED_OBJECT) #define NM_AGENT_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMAgentManager, NM_IS_AGENT_MANAGER) @@ -360,7 +362,7 @@ agent_register_permissions_done (NMAuthChain *chain, request_add_agent (c_list_entry (iter, Request, lst_request), agent); } - nm_auth_chain_destroy (chain); + nm_auth_chain_unref (chain); } static NMSecretAgent * @@ -390,10 +392,10 @@ agent_disconnected_cb (NMSecretAgent *agent, gpointer user_data) } static void -agent_manager_register_with_capabilities (NMAgentManager *self, - GDBusMethodInvocation *context, - const char *identifier, - guint32 capabilities) +impl_agent_manager_register_with_capabilities (NMAgentManager *self, + GDBusMethodInvocation *context, + const char *identifier, + guint32 capabilities) { NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); NMAuthSubject *subject; @@ -458,56 +460,45 @@ done: } 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 (NMAgentManager *self, + GDBusMethodInvocation *context, + const char *identifier) { - const char *identifier; - - g_variant_get (parameters, "(&s)", &identifier); - agent_manager_register_with_capabilities (NM_AGENT_MANAGER (obj), invocation, identifier, 0); + impl_agent_manager_register_with_capabilities (self, context, 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_unregister (NMAgentManager *self, + GDBusMethodInvocation *context) { - const char *identifier; - guint32 capabilities; - - g_variant_get (parameters, "(&su)", &identifier, &capabilities); - agent_manager_register_with_capabilities (NM_AGENT_MANAGER (obj), invocation, identifier, capabilities); -} + GError *error = NULL; + char *sender = NULL; -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) -{ - NMAgentManager *self = NM_AGENT_MANAGER (obj); + if (!nm_bus_manager_get_caller_info (nm_bus_manager_get (), + context, + &sender, + NULL, + NULL)) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to determine request sender."); + goto done; + } + /* Found the agent, unregister and remove it */ if (!remove_agent (self, sender)) { - 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; + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, + "Caller is not registered as an Agent"); + goto done; } - g_dbus_method_invocation_return_value (invocation, NULL); + g_dbus_method_invocation_return_value (context, NULL); + +done: + if (error) + g_dbus_method_invocation_take_error (context, error); + g_free (sender); } /*****************************************************************************/ @@ -539,7 +530,7 @@ request_free (Request *req) g_object_unref (req->con.connection); g_free (req->con.path); if (req->con.chain) - nm_auth_chain_destroy (req->con.chain); + nm_auth_chain_unref (req->con.chain); if (req->request_type == REQUEST_TYPE_CON_GET) { g_free (req->con.get.setting_name); g_strfreev (req->con.get.hints); @@ -810,7 +801,7 @@ request_remove_agent (Request *req, NMSecretAgent *agent) case REQUEST_TYPE_CON_DEL: if (req->con.chain) { /* This cancels the pending authorization requests. */ - nm_auth_chain_destroy (req->con.chain); + nm_auth_chain_unref (req->con.chain); req->con.chain = NULL; } break; @@ -1047,7 +1038,7 @@ _con_get_request_start_validated (NMAuthChain *chain, _con_get_request_start_proceed (req, req->con.current_has_modify); } - nm_auth_chain_destroy (chain); + nm_auth_chain_unref (chain); } static void @@ -1541,7 +1532,7 @@ agent_permissions_changed_done (NMAuthChain *chain, nm_secret_agent_add_permission (agent, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, share_protected); nm_secret_agent_add_permission (agent, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, share_open); - nm_auth_chain_destroy (chain); + nm_auth_chain_unref (chain); } static void @@ -1595,7 +1586,7 @@ constructed (GObject *object) 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_exported_object_export (NM_EXPORTED_OBJECT (object)); g_signal_connect (priv->auth_mgr, NM_AUTH_MANAGER_SIGNAL_CHANGED, @@ -1616,7 +1607,7 @@ cancel_more: goto cancel_more; } - g_slist_free_full (priv->chains, (GDestroyNotify) nm_auth_chain_destroy); + g_slist_free_full (priv->chains, (GDestroyNotify) nm_auth_chain_unref); priv->chains = NULL; if (priv->agents) { @@ -1631,64 +1622,20 @@ cancel_more: g_clear_object (&priv->auth_mgr); } - nm_dbus_object_unexport (NM_DBUS_OBJECT (object)); + nm_exported_object_unexport (NM_EXPORTED_OBJECT (object)); g_clear_object (&priv->session_monitor); 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 ( - "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) { GObjectClass *object_class = G_OBJECT_CLASS (agent_manager_class); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (agent_manager_class); + NMExportedObjectClass *exported_object_class = NM_EXPORTED_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); + exported_object_class->export_path = NM_DBUS_PATH_AGENT_MANAGER; object_class->constructed = constructed; object_class->dispose = dispose; @@ -1702,4 +1649,11 @@ nm_agent_manager_class_init (NMAgentManagerClass *agent_manager_class) g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); + + nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (agent_manager_class), + NMDBUS_TYPE_AGENT_MANAGER_SKELETON, + "Register", impl_agent_manager_register, + "RegisterWithCapabilities", impl_agent_manager_register_with_capabilities, + "Unregister", impl_agent_manager_unregister, + NULL); } diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h index 8c27f26b..f6845818 100644 --- a/src/settings/nm-agent-manager.h +++ b/src/settings/nm-agent-manager.h @@ -23,7 +23,7 @@ #include "nm-connection.h" -#include "nm-dbus-object.h" +#include "nm-exported-object.h" #include "nm-secret-agent.h" #define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ()) diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index af6d7017..192e9877 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -26,12 +26,13 @@ #include #include "nm-dbus-interface.h" -#include "nm-dbus-manager.h" -#include "nm-core-internal.h" +#include "nm-bus-manager.h" #include "nm-auth-subject.h" #include "nm-simple-connection.h" #include "NetworkManagerUtils.h" -#include "c-list/src/c-list.h" +#include "nm-utils/c-list.h" + +#include "introspection/org.freedesktop.NetworkManager.SecretAgent.h" /*****************************************************************************/ @@ -50,8 +51,8 @@ typedef struct { char *dbus_owner; NMSecretAgentCapabilities capabilities; GSList *permissions; - GDBusProxy *proxy; - NMDBusManager *bus_mgr; + NMDBusSecretAgent *proxy; + NMBusManager *bus_mgr; GDBusConnection *connection; CList requests; gulong on_disconnected_id; @@ -299,7 +300,7 @@ nm_secret_agent_add_permission (NMSecretAgent *agent, * @permission: The name of the permission to check for * * Returns whether or not the agent has the given permission. - * + * * Returns: %TRUE if the agent has the given permission, %FALSE if it does not * or if the permission was not previous recorded with * nm_secret_agent_add_permission(). @@ -335,17 +336,11 @@ get_callback (GObject *proxy, if (request_check_return (r)) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); gs_free_error GError *error = NULL; - gs_unref_variant GVariant *ret = NULL; gs_unref_variant GVariant *secrets = NULL; - ret = _nm_dbus_proxy_call_finish (priv->proxy, result, G_VARIANT_TYPE ("(a{sa{sv}})"), &error); - if (!ret) + nmdbus_secret_agent_call_get_secrets_finish (priv->proxy, &secrets, result, &error); + if (error) g_dbus_error_strip_remote_error (error); - else { - g_variant_get (ret, - "(@a{sa{sv}})", - &secrets); - } r->callback (r->agent, r, secrets, error, r->callback_data); } @@ -363,6 +358,7 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, gpointer callback_data) { NMSecretAgentPrivate *priv; + static const char *no_hints[] = { NULL }; GVariant *dict; NMSecretAgentCallId *r; @@ -383,20 +379,16 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, r = request_new (self, "GetSecrets", path, setting_name, callback, callback_data); r->is_get_secrets = TRUE; - g_dbus_proxy_call (priv->proxy, - "GetSecrets", - g_variant_new ("(@a{sa{sv}}os^asu)", - dict, - path, - setting_name, - hints ?: NM_PTRARRAY_EMPTY (const char *), - (guint32) flags), - G_DBUS_CALL_FLAGS_NONE, - 120000, - r->cancellable, - get_callback, - r); - + /* Increase the timeout only for this call */ + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (priv->proxy), 120000); + nmdbus_secret_agent_call_get_secrets (priv->proxy, + dict, + path, + setting_name, + hints ? hints : no_hints, + flags, + r->cancellable, + get_callback, r); g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (priv->proxy), -1); return r; @@ -407,16 +399,17 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, static void cancel_done (GObject *proxy, GAsyncResult *result, gpointer user_data) { - gs_free char *description = user_data; - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *ret = NULL; + char *description = user_data; + GError *error = NULL; - ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, G_VARIANT_TYPE ("()"), &error); - if (!ret) { + if (!nmdbus_secret_agent_call_cancel_get_secrets_finish (NMDBUS_SECRET_AGENT (proxy), result, &error)) { nm_log_dbg (LOGD_AGENTS, "%s%s%s: agent failed to cancel secrets: %s", NM_PRINT_FMT_QUOTED (description, "(", description, ")", "???"), error->message); + g_clear_error (&error); } + + g_free (description); } static void @@ -433,16 +426,11 @@ do_cancel_secrets (NMSecretAgent *self, NMSecretAgentCallId *r, gboolean disposi if ( r->is_get_secrets && priv->proxy) { /* for GetSecrets call, we must cancel the request. */ - g_dbus_proxy_call (G_DBUS_PROXY (priv->proxy), - "CancelGetSecrets", - g_variant_new ("(os)", - r->path, - r->setting_name), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - cancel_done, - g_strdup (nm_secret_agent_get_description (self))); + nmdbus_secret_agent_call_cancel_get_secrets (priv->proxy, + r->path, r->setting_name, + NULL, + cancel_done, + g_strdup (nm_secret_agent_get_description (self))); } cancellable = r->cancellable; @@ -506,11 +494,11 @@ agent_save_cb (GObject *proxy, NMSecretAgentCallId *r = user_data; if (request_check_return (r)) { + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); gs_free_error GError *error = NULL; - gs_unref_variant GVariant *ret = NULL; - ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, G_VARIANT_TYPE ("()"), &error); - if (!ret) + nmdbus_secret_agent_call_save_secrets_finish (priv->proxy, result, &error); + if (error) g_dbus_error_strip_remote_error (error); r->callback (r->agent, r, NULL, error, r->callback_data); } @@ -539,16 +527,11 @@ nm_secret_agent_save_secrets (NMSecretAgent *self, dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); r = request_new (self, "SaveSecrets", path, NULL, callback, callback_data); - g_dbus_proxy_call (priv->proxy, - "SaveSecrets", - g_variant_new ("(@a{sa{sv}}o)", - dict, - path), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, /* cancelling the request does *not* cancel the D-Bus call. */ - agent_save_cb, - r); + nmdbus_secret_agent_call_save_secrets (priv->proxy, + dict, + path, + NULL, /* cancelling the request does *not* cancel the D-Bus call. */ + agent_save_cb, r); return r; } @@ -563,11 +546,11 @@ agent_delete_cb (GObject *proxy, NMSecretAgentCallId *r = user_data; if (request_check_return (r)) { + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); gs_free_error GError *error = NULL; - gs_unref_variant GVariant *ret = NULL; - ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, G_VARIANT_TYPE ("()"), &error); - if (!ret) + nmdbus_secret_agent_call_delete_secrets_finish (priv->proxy, result, &error); + if (error) g_dbus_error_strip_remote_error (error); r->callback (r->agent, r, NULL, error, r->callback_data); } @@ -596,16 +579,12 @@ nm_secret_agent_delete_secrets (NMSecretAgent *self, dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); r = request_new (self, "DeleteSecrets", path, NULL, callback, callback_data); - g_dbus_proxy_call (priv->proxy, - "DeleteSecrets", - g_variant_new ("(@a{sa{sv}}o)", - dict, - path), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, /* cancelling the request does *not* cancel the D-Bus call. */ - agent_delete_cb, - r); + nmdbus_secret_agent_call_delete_secrets (priv->proxy, + dict, + path, + NULL, /* cancelling the request does *not* cancel the D-Bus call. */ + agent_delete_cb, r); + return r; } @@ -631,7 +610,7 @@ _on_disconnected_cleanup (NMSecretAgentPrivate *priv) } static void -_on_disconnected_private_connection (NMDBusManager *mgr, +_on_disconnected_private_connection (NMBusManager *mgr, GDBusConnection *connection, NMSecretAgent *self) { @@ -687,6 +666,7 @@ nm_secret_agent_new (GDBusMethodInvocation *context, NMSecretAgentPrivate *priv; const char *dbus_owner; struct passwd *pw; + GDBusProxy *proxy; char *owner_username = NULL; char *description = NULL; char buf_subject[64]; @@ -715,9 +695,9 @@ nm_secret_agent_new (GDBusMethodInvocation *context, priv = NM_SECRET_AGENT_GET_PRIVATE (self); - priv->bus_mgr = g_object_ref (nm_dbus_manager_get ()); + priv->bus_mgr = g_object_ref (nm_bus_manager_get ()); priv->connection = g_object_ref (connection); - priv->connection_is_private = !!nm_dbus_manager_connection_get_private_name (priv->bus_mgr, connection); + priv->connection_is_private = !!nm_bus_manager_connection_get_private_name (priv->bus_mgr, connection); _LOGt ("constructed: %s, owner=%s%s%s (%s), private-connection=%d, unique-name=%s%s%s, capabilities=%s", (description = _create_description (dbus_owner, identifier, uid)), @@ -734,18 +714,20 @@ nm_secret_agent_new (GDBusMethodInvocation *context, priv->capabilities = capabilities; priv->subject = g_object_ref (subject); - priv->proxy = nm_dbus_manager_new_proxy (priv->bus_mgr, - priv->connection, - G_TYPE_DBUS_PROXY, - priv->dbus_owner, - NM_DBUS_PATH_SECRET_AGENT, - NM_DBUS_INTERFACE_SECRET_AGENT); + proxy = nm_bus_manager_new_proxy (priv->bus_mgr, + priv->connection, + NMDBUS_TYPE_SECRET_AGENT_PROXY, + priv->dbus_owner, + NM_DBUS_PATH_SECRET_AGENT, + NM_DBUS_INTERFACE_SECRET_AGENT); + g_assert (proxy); + priv->proxy = NMDBUS_SECRET_AGENT (proxy); /* we cannot subscribe to notify::g-name-owner because that doesn't work * for unique names and it doesn't work for private connections. */ if (priv->connection_is_private) { priv->on_disconnected_id = g_signal_connect (priv->bus_mgr, - NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED, + NM_BUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED, G_CALLBACK (_on_disconnected_private_connection), self); } else { diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 0b998372..58626372 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -25,14 +25,13 @@ #include -#include "c-list/src/c-list.h" +#include "nm-utils/c-list.h" #include "nm-common-macros.h" #include "nm-config.h" #include "nm-config-data.h" #include "nm-dbus-interface.h" #include "nm-session-monitor.h" -#include "nm-auth-manager.h" #include "nm-auth-utils.h" #include "nm-auth-subject.h" #include "nm-agent-manager.h" @@ -40,6 +39,8 @@ #include "nm-core-internal.h" #include "nm-audit-manager.h" +#include "introspection/org.freedesktop.NetworkManager.Settings.Connection.h" + #define SETTINGS_TIMESTAMPS_FILE NMSTATEDIR "/timestamps" #define SETTINGS_SEEN_BSSIDS_FILE NMSTATEDIR "/seen-bssids" @@ -59,9 +60,9 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSettingsConnection, ); enum { + UPDATED, REMOVED, UPDATED_INTERNAL, - FLAGS_CHANGED, LAST_SIGNAL }; @@ -73,7 +74,7 @@ typedef struct _NMSettingsConnectionPrivate { NMSessionMonitor *session_monitor; gulong session_changed_id; - NMSettingsConnectionIntFlags flags:5; + NMSettingsConnectionFlags flags:5; bool removed:1; bool ready:1; @@ -82,8 +83,7 @@ typedef struct _NMSettingsConnectionPrivate { NMSettingsAutoconnectBlockedReason autoconnect_blocked_reason:4; - /* List of pending authentication requests */ - CList auth_lst_head; + GSList *pending_auths; /* List of pending authentication requests */ CList call_ids_lst_head; /* in-progress secrets requests */ @@ -115,7 +115,7 @@ typedef struct _NMSettingsConnectionPrivate { } NMSettingsConnectionPrivate; -G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_DBUS_OBJECT, +G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_EXPORTED_OBJECT, G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION, nm_settings_connection_connection_interface_init) ) @@ -146,9 +146,12 @@ G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_D /*****************************************************************************/ -static const GDBusSignalInfo signal_info_updated; -static const GDBusSignalInfo signal_info_removed; -static const NMDBusInterfaceInfoExtended interface_info_settings_connection; +static void +_emit_updated (NMSettingsConnection *self, gboolean by_user) +{ + g_signal_emit (self, signals[UPDATED], 0); + g_signal_emit (self, signals[UPDATED_INTERNAL], 0, by_user); +} /*****************************************************************************/ @@ -317,7 +320,7 @@ static void set_visible (NMSettingsConnection *self, gboolean new_visible) { nm_settings_connection_set_flags (self, - NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE, + NM_SETTINGS_CONNECTION_FLAGS_VISIBLE, new_visible); } @@ -387,7 +390,7 @@ nm_settings_connection_check_permission (NMSettingsConnection *self, priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); if (!NM_FLAGS_HAS (nm_settings_connection_get_flags (self), - NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) + NM_SETTINGS_CONNECTION_FLAGS_VISIBLE)) return FALSE; s_con = nm_connection_get_setting_connection (NM_CONNECTION (self)); @@ -487,30 +490,30 @@ secrets_cleared_cb (NMSettingsConnection *self) static void set_persist_mode (NMSettingsConnection *self, NMSettingsConnectionPersistMode persist_mode) { - NMSettingsConnectionIntFlags flags = NM_SETTINGS_CONNECTION_INT_FLAGS_NONE; - const NMSettingsConnectionIntFlags ALL = NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED - | NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE; + NMSettingsConnectionFlags flags = NM_SETTINGS_CONNECTION_FLAGS_NONE; + const NMSettingsConnectionFlags ALL = NM_SETTINGS_CONNECTION_FLAGS_UNSAVED + | NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_FLAGS_VOLATILE; switch (persist_mode) { case NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK: - flags = NM_SETTINGS_CONNECTION_INT_FLAGS_NONE; + flags = NM_SETTINGS_CONNECTION_FLAGS_NONE; break; case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY: case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED: case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY: - flags = NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED; + flags = NM_SETTINGS_CONNECTION_FLAGS_UNSAVED; break; case NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_DETACHED: case NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_ONLY: - flags = NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED | - NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE; + flags = NM_SETTINGS_CONNECTION_FLAGS_UNSAVED | + NM_SETTINGS_CONNECTION_FLAGS_VOLATILE; break; case NM_SETTINGS_CONNECTION_PERSIST_MODE_UNSAVED: /* only set the connection as unsaved, but preserve the nm-generated * and volatile flag. */ nm_settings_connection_set_flags (self, - NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED, + NM_SETTINGS_CONNECTION_FLAGS_UNSAVED, TRUE); return; case NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP: @@ -522,16 +525,6 @@ set_persist_mode (NMSettingsConnection *self, NMSettingsConnectionPersistMode pe nm_settings_connection_set_flags_full (self, ALL, flags); } -static void -_emit_updated (NMSettingsConnection *self, gboolean by_user) -{ - nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), - &interface_info_settings_connection, - &signal_info_updated, - "()"); - g_signal_emit (self, signals[UPDATED_INTERNAL], 0, by_user); -} - static void connection_changed_cb (NMSettingsConnection *self, gpointer unused) { @@ -578,13 +571,17 @@ _update_prepare (NMSettingsConnection *self, NMConnection *new_connection, GError **error) { + NMSettingsConnectionPrivate *priv; + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (new_connection), FALSE); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + if (!nm_connection_normalize (new_connection, NULL, NULL, error)) return FALSE; - if ( nm_dbus_object_get_path (NM_DBUS_OBJECT (self)) + if ( nm_connection_get_path (NM_CONNECTION (self)) && g_strcmp0 (nm_settings_connection_get_uuid (self), nm_connection_get_uuid (new_connection)) != 0) { /* Updating the UUID is not allowed once the path is exported. */ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, @@ -664,10 +661,8 @@ nm_settings_connection_update (NMSettingsConnection *self, NM_SETTING_COMPARE_FLAG_EXACT)) { gs_unref_object NMConnection *simple = NULL; - if (log_diff_name) { - nm_utils_log_connection_diff (replace_connection, NM_CONNECTION (self), LOGL_DEBUG, LOGD_CORE, log_diff_name, "++ ", - nm_dbus_object_get_path (NM_DBUS_OBJECT (self))); - } + if (log_diff_name) + nm_utils_log_connection_diff (replace_connection, NM_CONNECTION (self), LOGL_DEBUG, LOGD_CORE, log_diff_name, "++ "); /* Make a copy of agent-owned secrets because they won't be present in * the connection returned by plugins, as plugins return only what was @@ -684,7 +679,7 @@ nm_settings_connection_update (NMSettingsConnection *self, } nm_settings_connection_set_flags (self, - NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE, + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_FLAGS_VOLATILE, FALSE); if (replaced) { @@ -803,7 +798,7 @@ nm_settings_connection_delete (NMSettingsConnection *self, for_agents = nm_simple_connection_new_clone (NM_CONNECTION (self)); nm_connection_clear_secrets (for_agents); nm_agent_manager_delete_secrets (priv->agent_mgr, - nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), + nm_connection_get_path (NM_CONNECTION (self)), for_agents); g_object_unref (for_agents); @@ -1300,7 +1295,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, priv->last_secret_agent_version_id = nm_agent_manager_get_agent_version_id (priv->agent_mgr); call_id_a = nm_agent_manager_get_secrets (priv->agent_mgr, - nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), + nm_connection_get_path (NM_CONNECTION (self)), NM_CONNECTION (self), subject, existing_secrets, @@ -1364,7 +1359,7 @@ nm_settings_connection_cancel_secrets (NMSettingsConnection *self, _get_secrets_cancel (self, call_id, FALSE); } -/*****************************************************************************/ +/**** User authorization **************************************/ typedef void (*AuthCallback) (NMSettingsConnection *self, GDBusMethodInvocation *context, @@ -1372,61 +1367,46 @@ typedef void (*AuthCallback) (NMSettingsConnection *self, GError *error, gpointer data); -typedef struct { - 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, +pk_auth_cb (NMAuthChain *chain, + GError *chain_error, + GDBusMethodInvocation *context, 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; + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + GError *error = NULL; + NMAuthCallResult result; + const char *perm; + AuthCallback callback; + gpointer callback_data; + NMAuthSubject *subject; - auth_data->call_id = NULL; + priv->pending_auths = g_slist_remove (priv->pending_auths, chain); - c_list_unlink (&auth_data->auth_lst); + perm = nm_auth_chain_get_data (chain, "perm"); + g_assert (perm); + result = nm_auth_chain_get_result (chain, perm); - 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) { + /* If our NMSettingsConnection is already gone, do nothing */ + if (chain_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) { + chain_error->message ? chain_error->message : "(unknown)"); + } else if (result != NM_AUTH_CALL_RESULT_YES) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Insufficient privileges"); + "Insufficient privileges."); } - auth_data->callback (self, - auth_data->invocation, - auth_data->subject, - error, - auth_data->callback_data); + 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, context, subject, error, callback_data); - g_object_unref (auth_data->invocation); - g_object_unref (auth_data->subject); - g_slice_free (AuthData, auth_data); + g_clear_error (&error); + nm_auth_chain_unref (chain); } /** @@ -1454,52 +1434,59 @@ _new_auth_subject (GDBusMethodInvocation *context, GError **error) return subject; } -/* may either invoke callback synchronously or asynchronously. */ static void auth_start (NMSettingsConnection *self, - GDBusMethodInvocation *invocation, + GDBusMethodInvocation *context, NMAuthSubject *subject, const char *check_permission, AuthCallback callback, gpointer callback_data) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - AuthData *auth_data; + NMAuthChain *chain; GError *error = NULL; + char *error_desc = 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)); + g_return_if_fail (context != NULL); + g_return_if_fail (NM_IS_AUTH_SUBJECT (subject)); - if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (self), - subject, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - &error)) { - callback (self, invocation, subject, error, callback_data); + /* Ensure the caller can view this connection */ + if (!nm_auth_is_subject_in_acl (NM_CONNECTION (self), + subject, + &error_desc)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + error_desc); + g_free (error_desc); + + callback (self, context, 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); + callback (self, context, subject, NULL, callback_data); + return; + } + + chain = nm_auth_chain_new_subject (subject, context, pk_auth_cb, self); + if (!chain) { + g_set_error_literal (&error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + "Unable to authenticate the request."); + callback (self, context, subject, error, callback_data); + g_clear_error (&error); 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); + priv->pending_auths = g_slist_append (priv->pending_auths, chain); + nm_auth_chain_set_data (chain, "perm", (gpointer) check_permission, NULL); + nm_auth_chain_set_data (chain, "callback", callback, NULL); + nm_auth_chain_set_data (chain, "callback-data", callback_data, NULL); + nm_auth_chain_set_data (chain, "subject", g_object_ref (subject), g_object_unref); + nm_auth_chain_add_call (chain, check_permission, TRUE); } /**** DBus method handlers ************************************/ @@ -1536,7 +1523,7 @@ check_writable (NMConnection *self, GError **error) } static void -get_settings_auth_cb (NMSettingsConnection *self, +get_settings_auth_cb (NMSettingsConnection *self, GDBusMethodInvocation *context, NMAuthSubject *subject, GError *error, @@ -1590,25 +1577,18 @@ get_settings_auth_cb (NMSettingsConnection *self, } 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) -{ - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); - gs_unref_object NMAuthSubject *subject = NULL; +impl_settings_connection_get_settings (NMSettingsConnection *self, + GDBusMethodInvocation *context) +{ + NMAuthSubject *subject; GError *error = NULL; - 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); + subject = _new_auth_subject (context, &error); + if (subject) { + auth_start (self, context, subject, NULL, get_settings_auth_cb, NULL); + g_object_unref (subject); + } else + g_dbus_method_invocation_take_error (context, error); } typedef struct { @@ -1802,7 +1782,7 @@ update_auth_cb (NMSettingsConnection *self, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); nm_agent_manager_save_secrets (info->agent_mgr, - nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), + nm_connection_get_path (NM_CONNECTION (self)), for_agent, info->subject); } @@ -1850,6 +1830,7 @@ settings_connection_update (NMSettingsConnection *self, GError *error = NULL; UpdateInfo *info; const char *permission; + char *error_desc = NULL; /* If the connection is read-only, that has to be changed at the source of * the problem (ex a system settings plugin that can't write connections out) @@ -1886,12 +1867,15 @@ settings_connection_update (NMSettingsConnection *self, * 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 ? tmp : NM_CONNECTION (self), - subject, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - &error)) + if (!nm_auth_is_subject_in_acl (tmp ? tmp : NM_CONNECTION (self), + subject, + &error_desc)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + error_desc); + g_free (error_desc); goto error; + } info = g_slice_new0 (UpdateInfo); info->is_update2 = is_update2; @@ -1917,87 +1901,54 @@ 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 (NMSettingsConnection *self, + GDBusMethodInvocation *context, + GVariant *new_settings) { - 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); + settings_connection_update (self, FALSE, context, new_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 (NMSettingsConnection *self, + GDBusMethodInvocation *context, + GVariant *new_settings) { - 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); + settings_connection_update (self, FALSE, context, new_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 (NMSettingsConnection *self, + GDBusMethodInvocation *context) { - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); - - settings_connection_update (self, FALSE, invocation, NULL, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); + settings_connection_update (self, FALSE, context, 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; +impl_settings_connection_update2 (NMSettingsConnection *self, + GDBusMethodInvocation *context, + GVariant *settings, + guint32 flags_u, + GVariant *args) +{ GError *error = NULL; GVariantIter iter; const char *args_name; - NMSettingsUpdate2Flags flags; + const NMSettingsUpdate2Flags flags = (NMSettingsUpdate2Flags) flags_u; const NMSettingsUpdate2Flags ALL_PERSIST_MODES = 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; - g_variant_get (parameters, "(@a{sa{sv}}u@a{sv})", &settings, &flags_u, &args); - if (NM_FLAGS_ANY (flags_u, ~((guint32) (ALL_PERSIST_MODES | NM_SETTINGS_UPDATE2_FLAG_VOLATILE | NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT)))) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "Unknown flags"); - g_dbus_method_invocation_take_error (invocation, error); + g_dbus_method_invocation_take_error (context, error); return; } - flags = (NMSettingsUpdate2Flags) flags_u; - if ( ( NM_FLAGS_ANY (flags, ALL_PERSIST_MODES) && !nm_utils_is_power_of_two (flags & ALL_PERSIST_MODES)) || ( NM_FLAGS_HAS (flags, NM_SETTINGS_UPDATE2_FLAG_VOLATILE) @@ -2006,7 +1957,7 @@ impl_settings_connection_update2 (NMDBusObject *obj, error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "Conflicting flags"); - g_dbus_method_invocation_take_error (invocation, error); + g_dbus_method_invocation_take_error (context, error); return; } @@ -2014,7 +1965,7 @@ impl_settings_connection_update2 (NMDBusObject *obj, error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "args is of invalid type"); - g_dbus_method_invocation_take_error (invocation, error); + g_dbus_method_invocation_take_error (context, error); return; } @@ -2023,13 +1974,13 @@ impl_settings_connection_update2 (NMDBusObject *obj, 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); + g_dbus_method_invocation_take_error (context, error); return; } settings_connection_update (self, TRUE, - invocation, + context, settings, flags); } @@ -2074,7 +2025,7 @@ get_modify_permission_basic (NMSettingsConnection *self) * request affects more than just the caller, require 'modify.system'. */ s_con = nm_connection_get_setting_connection (NM_CONNECTION (self)); - nm_assert (s_con); + g_assert (s_con); if (nm_setting_connection_get_num_permissions (s_con) == 1) return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; @@ -2082,30 +2033,26 @@ get_modify_permission_basic (NMSettingsConnection *self) } 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; +impl_settings_connection_delete (NMSettingsConnection *self, + GDBusMethodInvocation *context) +{ + NMAuthSubject *subject = NULL; GError *error = NULL; if (!check_writable (NM_CONNECTION (self), &error)) - goto err; + goto out_err; - subject = _new_auth_subject (invocation, &error); - if (!subject) - goto err; + subject = _new_auth_subject (context, &error); + if (subject) { + auth_start (self, context, subject, get_modify_permission_basic (self), delete_auth_cb, NULL); + g_object_unref (subject); + } else + goto out_err; - auth_start (self, invocation, subject, get_modify_permission_basic (self), delete_auth_cb, NULL); return; -err: +out_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); + g_dbus_method_invocation_take_error (context, error); } /*****************************************************************************/ @@ -2164,33 +2111,24 @@ dbus_get_secrets_auth_cb (NMSettingsConnection *self, } 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; +impl_settings_connection_get_secrets (NMSettingsConnection *self, + GDBusMethodInvocation *context, + const gchar *setting_name) +{ + NMAuthSubject *subject; 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)); + subject = _new_auth_subject (context, &error); + if (subject) { + auth_start (self, + context, + subject, + get_modify_permission_basic (self), + dbus_get_secrets_auth_cb, + g_strdup (setting_name)); + g_object_unref (subject); + } else + g_dbus_method_invocation_take_error (context, error); } static void @@ -2219,7 +2157,7 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self, /* 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_connection_get_path (NM_CONNECTION (self)), NM_CONNECTION (self)); nm_settings_connection_update (self, @@ -2239,31 +2177,26 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self, } 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; +impl_settings_connection_clear_secrets (NMSettingsConnection *self, + GDBusMethodInvocation *context) +{ + NMAuthSubject *subject; GError *error = NULL; - subject = _new_auth_subject (invocation, &error); - if (!subject) { + subject = _new_auth_subject (context, &error); + if (subject) { + auth_start (self, + context, + subject, + get_modify_permission_basic (self), + dbus_clear_secrets_auth_cb, + NULL); + g_object_unref (subject); + } else { 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; + g_dbus_method_invocation_take_error (context, error); } - auth_start (self, - invocation, - subject, - get_modify_permission_basic (self), - dbus_clear_secrets_auth_cb, - NULL); } /*****************************************************************************/ @@ -2283,64 +2216,55 @@ void nm_settings_connection_signal_remove (NMSettingsConnection *self) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - AuthData *auth_data; if (priv->removed) return; priv->removed = TRUE; - - while ((auth_data = c_list_first_entry (&priv->auth_lst_head, AuthData, auth_lst))) - nm_auth_manager_check_authorization_cancel (auth_data->call_id); - - nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), - &interface_info_settings_connection, - &signal_info_removed, - "()"); - g_signal_emit (self, signals[REMOVED], 0); + g_signal_emit_by_name (self, NM_SETTINGS_CONNECTION_REMOVED); } gboolean 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_FLAGS_UNSAVED); } /*****************************************************************************/ -NM_UTILS_FLAGS2STR_DEFINE_STATIC (_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_DEFINE_STATIC (_settings_connection_flags_to_string, NMSettingsConnectionFlags, + NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_NONE, "none"), + NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_UNSAVED, "unsaved"), + NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED, "nm-generated"), + NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_VOLATILE, "volatile"), + NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_VISIBLE, "visible"), ); -NMSettingsConnectionIntFlags +NMSettingsConnectionFlags 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_FLAGS_NONE); return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->flags; } -NMSettingsConnectionIntFlags -nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionIntFlags flags, gboolean set) +NMSettingsConnectionFlags +nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionFlags flags, gboolean set) { return nm_settings_connection_set_flags_full (self, flags, - set ? flags : NM_SETTINGS_CONNECTION_INT_FLAGS_NONE); + set ? flags : NM_SETTINGS_CONNECTION_FLAGS_NONE); } -NMSettingsConnectionIntFlags +NMSettingsConnectionFlags nm_settings_connection_set_flags_full (NMSettingsConnection *self, - NMSettingsConnectionIntFlags mask, - NMSettingsConnectionIntFlags value) + NMSettingsConnectionFlags mask, + NMSettingsConnectionFlags value) { NMSettingsConnectionPrivate *priv; - NMSettingsConnectionIntFlags old_flags; + NMSettingsConnectionFlags old_flags; - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_INT_FLAGS_NONE); - nm_assert (mask && !NM_FLAGS_ANY (mask, ~NM_SETTINGS_CONNECTION_INT_FLAGS_ALL)); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_FLAGS_NONE); + nm_assert (mask && !NM_FLAGS_ANY (mask, ~NM_SETTINGS_CONNECTION_FLAGS_ALL)); nm_assert (!NM_FLAGS_ANY (value, ~mask)); priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); @@ -2349,7 +2273,6 @@ nm_settings_connection_set_flags_full (NMSettingsConnection *self, 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)", @@ -2357,17 +2280,9 @@ nm_settings_connection_set_flags_full (NMSettingsConnection *self, _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)); - - g_signal_emit (self, signals[FLAGS_CHANGED], 0); + if (NM_FLAGS_HAS (old_flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED) != NM_FLAGS_HAS (value, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED)) + _notify (self, PROP_UNSAVED); } return old_flags; } @@ -2788,7 +2703,7 @@ _autoconnect_retries_set (NMSettingsConnection *self, if (retries) priv->autoconnect_retries_blocked_until = 0; else { - /* NOTE: the blocked time must be identical for all connections, otherwise + /* XXX: 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 everytime a connection gets blocked). */ @@ -2883,7 +2798,7 @@ gboolean nm_settings_connection_autoconnect_is_blocked (NMSettingsConnection *self) { NMSettingsConnectionPrivate *priv; - NMSettingsConnectionIntFlags flags; + NMSettingsConnectionFlags flags; g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), TRUE); @@ -2895,9 +2810,9 @@ nm_settings_connection_autoconnect_is_blocked (NMSettingsConnection *self) return TRUE; flags = priv->flags; - if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)) + if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_VOLATILE)) return TRUE; - if (!NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) + if (!NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_VISIBLE)) return TRUE; return FALSE; @@ -2985,11 +2900,8 @@ nm_settings_connection_init (NMSettingsConnection *self) priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionPrivate); self->_priv = priv; - c_list_init (&self->_connections_lst); - priv->ready = TRUE; c_list_init (&priv->call_ids_lst_head); - c_list_init (&priv->auth_lst_head); priv->session_monitor = g_object_ref (nm_session_monitor_get ()); priv->session_changed_id = g_signal_connect (priv->session_monitor, @@ -3025,9 +2937,6 @@ dispose (GObject *object) _LOGD ("disposing"); - 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) @@ -3045,7 +2954,11 @@ dispose (GObject *object) g_clear_object (&priv->system_secrets); g_clear_object (&priv->agent_secrets); - g_clear_pointer (&priv->seen_bssids, g_hash_table_destroy); + /* Cancel PolicyKit requests */ + g_slist_free_full (priv->pending_auths, (GDestroyNotify) nm_auth_chain_unref); + priv->pending_auths = NULL; + + g_clear_pointer (&priv->seen_bssids, (GDestroyNotify) g_hash_table_destroy); set_visible (self, FALSE); @@ -3073,8 +2986,7 @@ get_property (GObject *object, guint prop_id, g_value_set_boolean (value, nm_settings_connection_get_ready (self)); break; case PROP_FLAGS: - g_value_set_uint (value, - nm_settings_connection_get_flags (self) & NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK); + g_value_set_uint (value, nm_settings_connection_get_flags (self)); break; case PROP_FILENAME: g_value_set_string (value, nm_settings_connection_get_filename (self)); @@ -3102,120 +3014,22 @@ set_property (GObject *object, guint prop_id, } } -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 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), - ), - ), - .legacy_property_changed = TRUE, -}; - static void -nm_settings_connection_class_init (NMSettingsConnectionClass *klass) +nm_settings_connection_class_init (NMSettingsConnectionClass *class) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (class); + NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (class); - g_type_class_add_private (klass, sizeof (NMSettingsConnectionPrivate)); + g_type_class_add_private (class, 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); + exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH_SETTINGS); object_class->constructed = constructed; object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; - klass->supports_secrets = supports_secrets; + class->supports_secrets = supports_secrets; obj_properties[PROP_UNSAVED] = g_param_spec_boolean (NM_SETTINGS_CONNECTION_UNSAVED, "", "", @@ -3231,7 +3045,9 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *klass) obj_properties[PROP_FLAGS] = g_param_spec_uint (NM_SETTINGS_CONNECTION_FLAGS, "", "", - 0, G_MAXUINT32, 0, + NM_SETTINGS_CONNECTION_FLAGS_NONE, + NM_SETTINGS_CONNECTION_FLAGS_ALL, + NM_SETTINGS_CONNECTION_FLAGS_NONE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); @@ -3244,10 +3060,20 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *klass) g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + signals[UPDATED] = + g_signal_new (NM_SETTINGS_CONNECTION_UPDATED, + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + /* internal signal, with an argument (gboolean by_user). */ signals[UPDATED_INTERNAL] = g_signal_new (NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, - G_TYPE_FROM_CLASS (klass), + G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, @@ -3255,20 +3081,24 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *klass) signals[REMOVED] = g_signal_new (NM_SETTINGS_CONNECTION_REMOVED, - G_TYPE_FROM_CLASS (klass), + G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - 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_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class), + NMDBUS_TYPE_SETTINGS_CONNECTION_SKELETON, + "Update", impl_settings_connection_update, + "UpdateUnsaved", impl_settings_connection_update_unsaved, + "Delete", impl_settings_connection_delete, + "GetSettings", impl_settings_connection_get_settings, + "GetSecrets", impl_settings_connection_get_secrets, + "ClearSecrets", impl_settings_connection_clear_secrets, + "Save", impl_settings_connection_save, + "Update2", impl_settings_connection_update2, + NULL); } static void diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index 58901699..29ec05dd 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -24,7 +24,7 @@ #include -#include "nm-dbus-object.h" +#include "nm-exported-object.h" #include "nm-connection.h" #define NM_TYPE_SETTINGS_CONNECTION (nm_settings_connection_get_type ()) @@ -34,11 +34,14 @@ #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)) +/* Signals */ +#define NM_SETTINGS_CONNECTION_UPDATED "updated" #define NM_SETTINGS_CONNECTION_REMOVED "removed" #define NM_SETTINGS_CONNECTION_GET_SECRETS "get-secrets" #define NM_SETTINGS_CONNECTION_CANCEL_SECRETS "cancel-secrets" + +/* Internal signals */ #define NM_SETTINGS_CONNECTION_UPDATED_INTERNAL "updated-internal" -#define NM_SETTINGS_CONNECTION_FLAGS_CHANGED "flags-changed" /* Properties */ #define NM_SETTINGS_CONNECTION_UNSAVED "unsaved" @@ -50,45 +53,32 @@ /** - * NMSettingsConnectionIntFlags: - * @NM_SETTINGS_CONNECTION_INT_FLAGS_NONE: no flag set - * @NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED: the connection is not saved to disk. - * See also #NM_SETTINGS_CONNECTION_FLAG_UNSAVED. - * @NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED: A connection is "nm-generated" if + * NMSettingsConnectionFlags: + * @NM_SETTINGS_CONNECTION_FLAGS_NONE: no flag set + * @NM_SETTINGS_CONNECTION_FLAGS_UNSAVED: the connection is not saved to disk + * @NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED: A connection is "nm-generated" if * it was generated by NetworkManger. If the connection gets modified or saved * by the user, the flag gets cleared. A nm-generated is implicitly unsaved. - * See also #NM_SETTINGS_CONNECTION_FLAG_NM_GENERATED. - * @NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE: The connection will be deleted + * @NM_SETTINGS_CONNECTION_FLAGS_VOLATILE: The connection will be deleted * when it disconnects. That is for in-memory connections (unsaved), which are * currently active but cleanup on disconnect. - * See also #NM_SETTINGS_CONNECTION_FLAG_VOLATILE. - * @NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE: The connection is visible - * @NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK: the entire enum is - * internal, however, parts of it is public API as #NMSettingsConnectionFlags. - * This mask, are the public flags. - * @NM_SETTINGS_CONNECTION_INT_FLAGS_ALL: special mask, for all known flags + * @NM_SETTINGS_CONNECTION_FLAGS_VISIBLE: The connection is visible + * @NM_SETTINGS_CONNECTION_FLAGS_ALL: special mask, for all known flags * * #NMSettingsConnection flags. **/ typedef enum { - 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_VISIBLE = (1LL << 3), + NM_SETTINGS_CONNECTION_FLAGS_NONE = 0, - __NM_SETTINGS_CONNECTION_INT_FLAGS_LAST, + NM_SETTINGS_CONNECTION_FLAGS_UNSAVED = (1LL << 0), + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED = (1LL << 1), + NM_SETTINGS_CONNECTION_FLAGS_VOLATILE = (1LL << 2), - 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 - | 0, + NM_SETTINGS_CONNECTION_FLAGS_VISIBLE = (1LL << 3), - NM_SETTINGS_CONNECTION_INT_FLAGS_ALL = ((__NM_SETTINGS_CONNECTION_INT_FLAGS_LAST - 1) << 1) - 1, -} NMSettingsConnectionIntFlags; + __NM_SETTINGS_CONNECTION_FLAGS_LAST, + NM_SETTINGS_CONNECTION_FLAGS_ALL = ((__NM_SETTINGS_CONNECTION_FLAGS_LAST - 1) << 1) - 1, +} NMSettingsConnectionFlags; typedef enum { NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE = 0, @@ -116,13 +106,12 @@ typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass; struct _NMSettingsConnectionPrivate; struct _NMSettingsConnection { - NMDBusObject parent; + NMExportedObject parent; struct _NMSettingsConnectionPrivate *_priv; - CList _connections_lst; }; struct _NMSettingsConnectionClass { - NMDBusObjectClass parent; + NMExportedObjectClass parent; gboolean (*commit_changes) (NMSettingsConnection *self, NMConnection *new_connection, @@ -210,9 +199,9 @@ void nm_settings_connection_signal_remove (NMSettingsConnection *self); gboolean nm_settings_connection_get_unsaved (NMSettingsConnection *self); -NMSettingsConnectionIntFlags nm_settings_connection_get_flags (NMSettingsConnection *self); -NMSettingsConnectionIntFlags nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionIntFlags flags, gboolean set); -NMSettingsConnectionIntFlags nm_settings_connection_set_flags_full (NMSettingsConnection *self, NMSettingsConnectionIntFlags mask, NMSettingsConnectionIntFlags value); +NMSettingsConnectionFlags nm_settings_connection_get_flags (NMSettingsConnection *self); +NMSettingsConnectionFlags nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionFlags flags, gboolean set); +NMSettingsConnectionFlags nm_settings_connection_set_flags_full (NMSettingsConnection *self, NMSettingsConnectionFlags mask, NMSettingsConnectionFlags value); 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); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 2c6b7101..8e3fc582 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -62,12 +62,10 @@ #include "nm-utils.h" #include "nm-core-internal.h" -#include "nm-utils/nm-c-list.h" -#include "nm-dbus-object.h" #include "devices/nm-device-ethernet.h" #include "nm-settings-connection.h" #include "nm-settings-plugin.h" -#include "nm-dbus-manager.h" +#include "nm-bus-manager.h" #include "nm-auth-utils.h" #include "nm-auth-subject.h" #include "nm-session-monitor.h" @@ -79,6 +77,8 @@ #include "nm-dispatcher.h" #include "nm-hostname-manager.h" +#include "introspection/org.freedesktop.NetworkManager.Settings.h" + /*****************************************************************************/ #define EXPORT(sym) void * __export_##sym = &sym; @@ -107,6 +107,7 @@ enum { CONNECTION_UPDATED, CONNECTION_REMOVED, CONNECTION_FLAGS_CHANGED, + NEW_CONNECTION, /* exported, not used internally */ LAST_SIGNAL }; @@ -120,33 +121,29 @@ typedef struct { GSList *auths; GSList *plugins; - - CList connections_lst_head; - + gboolean connections_loaded; + GHashTable *connections; NMSettingsConnection **connections_cached_list; GSList *unmanaged_specs; GSList *unrecognized_specs; - NMHostnameManager *hostname_manager; - - guint connections_len; + gboolean started; + gboolean startup_complete; - bool started:1; - bool startup_complete:1; - bool connections_loaded:1; + NMHostnameManager *hostname_manager; } NMSettingsPrivate; struct _NMSettings { - NMDBusObject parent; + NMExportedObject parent; NMSettingsPrivate _priv; }; struct _NMSettingsClass { - NMDBusObjectClass parent; + NMExportedObjectClass parent; }; -G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_DBUS_OBJECT); +G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT); #define NM_SETTINGS_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSettings, NM_IS_SETTINGS) @@ -157,10 +154,6 @@ G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_DBUS_OBJECT); /*****************************************************************************/ -static const NMDBusInterfaceInfoExtended interface_info_settings; -static const GDBusSignalInfo signal_info_new_connection; -static const GDBusSignalInfo signal_info_connection_removed; - static void claim_connection (NMSettings *self, NMSettingsConnection *connection); @@ -171,29 +164,27 @@ static void connection_ready_changed (NMSettingsConnection *conn, GParamSpec *pspec, gpointer user_data); -static void default_wired_clear_tag (NMSettings *self, - NMDevice *device, - NMSettingsConnection *connection, - gboolean add_to_no_auto_default); - /*****************************************************************************/ static void check_startup_complete (NMSettings *self) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GHashTableIter iter; NMSettingsConnection *conn; if (priv->startup_complete) return; - c_list_for_each_entry (conn, &priv->connections_lst_head, _connections_lst) { + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn)) { if (!nm_settings_connection_get_ready (conn)) return; } /* the connection_ready_changed signal handler is no longer needed. */ - c_list_for_each_entry (conn, &priv->connections_lst_head, _connections_lst) + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn)) g_signal_handlers_disconnect_by_func (conn, G_CALLBACK (connection_ready_changed), self); priv->startup_complete = TRUE; @@ -256,25 +247,43 @@ load_connections (NMSettings *self) unrecognized_specs_changed (NULL, self); } +void +nm_settings_for_each_connection (NMSettings *self, + NMSettingsForEachFunc for_each_func, + gpointer user_data) +{ + NMSettingsPrivate *priv; + GHashTableIter iter; + gpointer data; + + g_return_if_fail (NM_IS_SETTINGS (self)); + g_return_if_fail (for_each_func != NULL); + + priv = NM_SETTINGS_GET_PRIVATE (self); + + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) + for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data); +} + 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 (NMSettings *self, + GDBusMethodInvocation *context) { - 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)); + GPtrArray *connections; + GHashTableIter iter; + gpointer key; + + connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1); + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, &key, NULL)) + g_ptr_array_add (connections, key); + g_ptr_array_add (connections, NULL); + + g_dbus_method_invocation_return_value (context, + g_variant_new ("(^ao)", connections->pdata)); + g_ptr_array_unref (connections); } NMSettingsConnection * @@ -282,14 +291,16 @@ nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid) { NMSettingsPrivate *priv; NMSettingsConnection *candidate; + GHashTableIter iter; g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); g_return_val_if_fail (uuid != NULL, NULL); priv = NM_SETTINGS_GET_PRIVATE (self); - c_list_for_each_entry (candidate, &priv->connections_lst_head, _connections_lst) { - if (nm_streq (uuid, nm_settings_connection_get_uuid (candidate))) + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) { + if (g_strcmp0 (uuid, nm_settings_connection_get_uuid (candidate)) == 0) return candidate; } @@ -297,21 +308,14 @@ nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid) } 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 (NMSettings *self, + GDBusMethodInvocation *context, + const char *uuid) { - NMSettings *self = NM_SETTINGS (obj); NMSettingsConnection *connection = NULL; - gs_unref_object NMAuthSubject *subject = NULL; + NMAuthSubject *subject = NULL; GError *error = NULL; - const char *uuid; - - g_variant_get (parameters, "(&s)", &uuid); + char *error_desc = NULL; connection = nm_settings_get_connection_by_uuid (self, uuid); if (!connection) { @@ -321,7 +325,7 @@ impl_settings_get_connection_by_uuid (NMDBusObject *obj, goto error; } - subject = nm_auth_subject_new_unix_process_from_context (invocation); + subject = nm_auth_subject_new_unix_process_from_context (context); if (!subject) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, @@ -329,40 +333,26 @@ impl_settings_get_connection_by_uuid (NMDBusObject *obj, goto error; } - if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (connection), - subject, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - &error)) + if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection), + subject, + &error_desc)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + error_desc); + g_free (error_desc); goto error; + } - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)))); + g_clear_object (&subject); + g_dbus_method_invocation_return_value ( + context, + g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection)))); return; error: - g_dbus_method_invocation_take_error (invocation, error); -} - -static void -_clear_connections_cached_list (NMSettingsPrivate *priv) -{ - if (!priv->connections_cached_list) - return; - - 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, - 0xdeaddead, - sizeof (NMSettingsConnection *) * (priv->connections_len + 1)); -#endif - nm_clear_g_free (&priv->connections_cached_list); + g_assert (error); + g_dbus_method_invocation_take_error (context, error); + g_clear_object (&subject); } /** @@ -380,33 +370,37 @@ _clear_connections_cached_list (NMSettingsPrivate *priv) NMSettingsConnection *const* nm_settings_get_connections (NMSettings *self, guint *out_len) { + GHashTableIter iter; NMSettingsPrivate *priv; + guint l, i; NMSettingsConnection **v; NMSettingsConnection *con; - guint i; g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); priv = NM_SETTINGS_GET_PRIVATE (self); - nm_assert (priv->connections_len == c_list_length (&priv->connections_lst_head)); + if (G_LIKELY (priv->connections_cached_list)) { + NM_SET_OUT (out_len, g_hash_table_size (priv->connections)); + return priv->connections_cached_list; + } - if (G_UNLIKELY (!priv->connections_cached_list)) { - v = g_new (NMSettingsConnection *, priv->connections_len + 1); + l = g_hash_table_size (priv->connections); - 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; + v = g_new (NMSettingsConnection *, (gsize) l + 1); - priv->connections_cached_list = v; + i = 0; + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &con)) { + nm_assert (i < l); + v[i++] = con; } + nm_assert (i == l); + v[i] = NULL; - NM_SET_OUT (out_len, priv->connections_len); - return priv->connections_cached_list; + NM_SET_OUT (out_len, l); + priv->connections_cached_list = v; + return v; } /** @@ -473,41 +467,28 @@ NMSettingsConnection * nm_settings_get_connection_by_path (NMSettings *self, const char *path) { 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 (path != NULL, NULL); priv = NM_SETTINGS_GET_PRIVATE (self); - connection = (NMSettingsConnection *) 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; + return (NMSettingsConnection *) g_hash_table_lookup (priv->connections, path); } gboolean nm_settings_has_connection (NMSettings *self, NMSettingsConnection *connection) { - NMSettingsConnection *candidate = NULL; - const char *path; - - g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), FALSE); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GHashTableIter iter; + gpointer data; - path = nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)); - if (path) - candidate = nm_settings_get_connection_by_path (self, path); + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) + if (data == connection) + return TRUE; - nm_assert (!candidate || candidate == connection); - nm_assert (!!candidate == nm_c_list_contains_entry (&NM_SETTINGS_GET_PRIVATE (self)->connections_lst_head, - connection, - _connections_lst)); - return !!candidate; + return FALSE; } const GSList * @@ -519,7 +500,7 @@ nm_settings_get_unmanaged_specs (NMSettings *self) } static NMSettingsPlugin * -get_plugin (NMSettings *self, NMSettingsPluginCapabilities capability) +get_plugin (NMSettings *self, guint32 capability) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; @@ -696,8 +677,8 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) continue; } - if (NM_IN_STRSET (pname, "ifcfg-suse", "ifnet")) { - _LOGW ("skipping deprecated plugin %s", pname); + if (!strcmp (pname, "ifcfg-suse")) { + _LOGW ("skipping deprecated plugin ifcfg-suse"); continue; } @@ -825,6 +806,7 @@ connection_updated (NMSettingsConnection *connection, gboolean by_user, gpointer static void connection_flags_changed (NMSettingsConnection *connection, + GParamSpec *pspec, gpointer user_data) { g_signal_emit (NM_SETTINGS (user_data), @@ -838,20 +820,11 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) { NMSettings *self = NM_SETTINGS (user_data); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - NMDevice *device; + const char *cpath = nm_connection_get_path (NM_CONNECTION (connection)); - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); - g_return_if_fail (!c_list_is_empty (&connection->_connections_lst)); - nm_assert (c_list_contains (&priv->connections_lst_head, &connection->_connections_lst)); - - /* When the default wired connection is removed (either deleted or saved to - * a new persistent connection by a plugin), write the MAC address of the - * wired device to the config file and don't create a new default wired - * connection for that device again. - */ - device = g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ()); - if (device) - default_wired_clear_tag (self, device, connection, TRUE); + if (!g_hash_table_lookup (priv->connections, cpath)) + g_return_if_reached (); + g_object_ref (connection); /* Disconnect signal handlers, as plugins might still keep references * to the connection (and thus the signal handlers would still be live) @@ -863,30 +836,23 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_flags_changed), self); if (!priv->startup_complete) g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_ready_changed), self); + g_object_unref (self); /* Forget about the connection internally */ - _clear_connections_cached_list (priv); - priv->connections_len--; - c_list_unlink (&connection->_connections_lst); - - if (priv->connections_loaded) { - _notify (self, PROP_CONNECTIONS); + g_hash_table_remove (priv->connections, (gpointer) cpath); + g_clear_pointer (&priv->connections_cached_list, g_free); - 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 (connection))); - } + /* Notify D-Bus */ + g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection); - nm_dbus_object_unexport (NM_DBUS_OBJECT (connection)); + /* Re-emit for listeners like NMPolicy */ + _notify (self, PROP_CONNECTIONS); + if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (connection))) + nm_exported_object_unexport (NM_EXPORTED_OBJECT (connection)); - if (priv->connections_loaded) - g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection); + check_startup_complete (self); g_object_unref (connection); - - check_startup_complete (self); } #define NM_DBUS_SERVICE_OPENCONNECT "org.freedesktop.NetworkManager.openconnect" @@ -934,16 +900,19 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GError *error = NULL; + GHashTableIter iter; + gpointer data; const char *path; NMSettingsConnection *existing; g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); - g_return_if_fail (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (connection))); + g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); - /* prevent duplicates */ - if (!c_list_is_empty (&connection->_connections_lst)) { - nm_assert (c_list_contains (&priv->connections_lst_head, &connection->_connections_lst)); - return; + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + /* prevent duplicates */ + if (data == connection) + return; } if (!nm_connection_normalize (NM_CONNECTION (connection), NULL, NULL, &error)) { @@ -975,19 +944,20 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) /* Read seen-bssids from look-aside file and put it into the connection's data */ nm_settings_connection_read_and_fill_seen_bssids (connection); - /* Ensure its initial visibility is up-to-date */ + /* Ensure it's initial visibility is up-to-date */ nm_settings_connection_recheck_visibility (connection); /* Evil openconnect migration hack */ openconnect_migrate_hack (NM_CONNECTION (connection)); + g_object_ref (self); /* This one unexports the connection, it needs to run late to give the active * connection a chance to deal with its reference to this settings connection. */ g_signal_connect_after (connection, NM_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, G_CALLBACK (connection_updated), self); - g_signal_connect (connection, NM_SETTINGS_CONNECTION_FLAGS_CHANGED, + g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_FLAGS, G_CALLBACK (connection_flags_changed), self); if (!priv->startup_complete) { @@ -996,29 +966,28 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) self); } - _clear_connections_cached_list (priv); + /* Export the connection over D-Bus */ + g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); + path = nm_exported_object_export (NM_EXPORTED_OBJECT (connection)); + nm_connection_set_path (NM_CONNECTION (connection), path); - g_object_ref (connection); - priv->connections_len++; - c_list_link_tail (&priv->connections_lst_head, &connection->_connections_lst); - - path = nm_dbus_object_export (NM_DBUS_OBJECT (connection)); + g_hash_table_insert (priv->connections, + (gpointer) nm_connection_get_path (NM_CONNECTION (connection)), + g_object_ref (connection)); + g_clear_pointer (&priv->connections_cached_list, g_free); - nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ ", - path); + nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ "); /* Only emit the individual connection-added signal after connections * have been initially loaded. */ if (priv->connections_loaded) { - nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), - &interface_info_settings, - &signal_info_new_connection, - "(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (connection))); - + /* Internal added signal */ g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); _notify (self, PROP_CONNECTIONS); + + /* Exported D-Bus signal */ + g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); } nm_settings_connection_added (connection); @@ -1066,14 +1035,14 @@ nm_settings_add_connection (NMSettings *self, NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; NMSettingsConnection *added = NULL; - NMSettingsConnection *candidate = NULL; - const char *uuid; - - uuid = nm_connection_get_uuid (connection); + GHashTableIter citer; + NMConnection *candidate = NULL; /* Make sure a connection with this UUID doesn't already exist */ - c_list_for_each_entry (candidate, &priv->connections_lst_head, _connections_lst) { - if (nm_streq0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate)))) { + g_hash_table_iter_init (&citer, priv->connections); + while (g_hash_table_iter_next (&citer, NULL, (gpointer *) &candidate)) { + if (g_strcmp0 (nm_connection_get_uuid (connection), + nm_connection_get_uuid (candidate)) == 0) { g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_UUID_EXISTS, @@ -1130,7 +1099,7 @@ send_agent_owned_secrets (NMSettings *self, NMAuthSubject *subject) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - gs_unref_object NMConnection *for_agent = NULL; + NMConnection *for_agent; /* 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. @@ -1141,9 +1110,10 @@ send_agent_owned_secrets (NMSettings *self, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); nm_agent_manager_save_secrets (priv->agent_mgr, - nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)), + nm_connection_get_path (NM_CONNECTION (connection)), for_agent, subject); + g_object_unref (for_agent); } static void @@ -1200,7 +1170,7 @@ pk_add_cb (NMAuthChain *chain, send_agent_owned_secrets (self, added, subject); g_clear_error (&error); - nm_auth_chain_destroy (chain); + nm_auth_chain_unref (chain); } /* FIXME: remove if/when kernel supports adhoc wpa */ @@ -1248,6 +1218,7 @@ nm_settings_add_connection_dbus (NMSettings *self, NMAuthSubject *subject = NULL; NMAuthChain *chain; GError *error = NULL, *tmp_error = NULL; + char *error_desc = NULL; const char *perm; g_return_if_fail (connection != NULL); @@ -1290,12 +1261,18 @@ nm_settings_add_connection_dbus (NMSettings *self, goto done; } - if (!nm_auth_is_subject_in_acl_set_error (connection, - subject, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - &error)) + /* 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 (connection, + subject, + &error_desc)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + error_desc); + g_free (error_desc); 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 @@ -1335,30 +1312,30 @@ done: } static void -settings_add_connection_add_cb (NMSettings *self, - NMSettingsConnection *connection, - GError *error, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - gpointer user_data) +impl_settings_add_connection_add_cb (NMSettings *self, + NMSettingsConnection *connection, + GError *error, + GDBusMethodInvocation *context, + NMAuthSubject *subject, + gpointer 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); } else { - g_dbus_method_invocation_return_value (context, - g_variant_new ("(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)))); + g_dbus_method_invocation_return_value ( + context, + g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (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, - GVariant *settings, - gboolean save_to_disk) +impl_settings_add_connection_helper (NMSettings *self, + GDBusMethodInvocation *context, + GVariant *settings, + gboolean save_to_disk) { gs_unref_object NMConnection *connection = NULL; GError *error = NULL; @@ -1378,111 +1355,77 @@ settings_add_connection_helper (NMSettings *self, connection, save_to_disk, context, - settings_add_connection_add_cb, + impl_settings_add_connection_add_cb, NULL); } 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 (NMSettings *self, + GDBusMethodInvocation *context, + GVariant *settings) { - 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, settings, TRUE); + impl_settings_add_connection_helper (self, context, settings, TRUE); } 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 (NMSettings *self, + GDBusMethodInvocation *context, + GVariant *settings) { - 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, settings, FALSE); + impl_settings_add_connection_helper (self, context, settings, FALSE); } static void -impl_settings_load_connections (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_settings_load_connections (NMSettings *self, + GDBusMethodInvocation *context, + char **filenames) { - NMSettings *self = NM_SETTINGS (obj); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - gs_unref_ptrarray GPtrArray *failures = NULL; + GPtrArray *failures; GSList *iter; - guint i; - gs_free const char **filenames = NULL; - - g_variant_get (parameters, "(^a&s)", &filenames); + int i; /* 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)) + if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (), + context, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) return; - if (filenames) { - for (i = 0; filenames[i]; i++) { - for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { - NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); + failures = g_ptr_array_new (); - if (nm_settings_plugin_load_connection (plugin, filenames[i])) - break; - } + for (i = 0; filenames[i]; i++) { + for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { + NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); - if (!iter) { - if (!g_path_is_absolute (filenames[i])) - _LOGW ("connection filename '%s' is not an absolute path", filenames[i]); - if (!failures) - failures = g_ptr_array_new (); - g_ptr_array_add (failures, (char *) filenames[i]); - } + if (nm_settings_plugin_load_connection (plugin, filenames[i])) + break; } - } - if (failures) - g_ptr_array_add (failures, NULL); + if (!iter) { + if (!g_path_is_absolute (filenames[i])) + _LOGW ("connection filename '%s' is not an absolute path", filenames[i]); + g_ptr_array_add (failures, (char *) filenames[i]); + } + } - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(b^as)", - (gboolean) (!!failures), - failures - ? (const char **) failures->pdata - : NM_PTRARRAY_EMPTY (const char *))); + g_ptr_array_add (failures, NULL); + g_dbus_method_invocation_return_value ( + context, + g_variant_new ("(b^as)", + failures->len == 1, + failures->pdata)); + g_ptr_array_unref (failures); } 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 (NMSettings *self, + GDBusMethodInvocation *context) { - NMSettings *self = NM_SETTINGS (obj); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; @@ -1490,11 +1433,11 @@ impl_settings_reload_connections (NMDBusObject *obj, * 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)) + if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (), + context, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) return; for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { @@ -1503,7 +1446,7 @@ impl_settings_reload_connections (NMDBusObject *obj, nm_settings_plugin_reload_connections (plugin); } - g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", TRUE)); + g_dbus_method_invocation_return_value (context, g_variant_new ("(b)", TRUE)); } /*****************************************************************************/ @@ -1551,46 +1494,41 @@ pk_hostname_cb (NMAuthChain *chain, else g_dbus_method_invocation_return_value (context, NULL); - nm_auth_chain_destroy (chain); + nm_auth_chain_unref (chain); } 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 (NMSettings *self, + GDBusMethodInvocation *context, + const char *hostname) { - NMSettings *self = NM_SETTINGS (obj); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMAuthChain *chain; - const char *hostname; - - g_variant_get (parameters, "(&s)", &hostname); + GError *error = NULL; /* Minimal validation of the hostname */ if (!nm_hostname_manager_validate_hostname (hostname)) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_HOSTNAME, - "The hostname was too long or contained invalid characters."); - return; + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_HOSTNAME, + "The hostname was too long or contained invalid characters."); + goto done; } - chain = nm_auth_chain_new_context (invocation, pk_hostname_cb, self); + chain = nm_auth_chain_new_context (context, pk_hostname_cb, self); if (!chain) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Unable to authenticate the request."); - return; + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + "Unable to authenticate the request."); + goto done; } priv->auths = g_slist_append (priv->auths, 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); + +done: + if (error) + g_dbus_method_invocation_take_error (context, error); } /*****************************************************************************/ @@ -1599,24 +1537,27 @@ static gboolean have_connection_for_device (NMSettings *self, NMDevice *device) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GHashTableIter iter; + gpointer data; NMSettingConnection *s_con; NMSettingWired *s_wired; const char *setting_hwaddr; const char *perm_hw_addr; - NMSettingsConnection *connection; g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); perm_hw_addr = nm_device_get_permanent_hw_address (device); /* Find a wired connection locked to the given MAC address, if any */ - c_list_for_each_entry (connection, &priv->connections_lst_head, _connections_lst) { + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + NMConnection *connection = NM_CONNECTION (data); const char *ctype, *iface; - if (!nm_device_check_connection_compatible (device, NM_CONNECTION (connection))) + if (!nm_device_check_connection_compatible (device, connection)) continue; - s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); + s_con = nm_connection_get_setting_connection (connection); iface = nm_setting_connection_get_interface_name (s_con); if (iface && strcmp (iface, nm_device_get_iface (device)) != 0) @@ -1627,7 +1568,7 @@ have_connection_for_device (NMSettings *self, NMDevice *device) && strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) continue; - s_wired = nm_connection_get_setting_wired (NM_CONNECTION (connection)); + s_wired = nm_connection_get_setting_wired (connection); if (!s_wired && !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) { /* No wired setting; therefore the PPPoE connection applies to any device */ @@ -1655,6 +1596,26 @@ have_connection_for_device (NMSettings *self, NMDevice *device) return FALSE; } +static void default_wired_clear_tag (NMSettings *self, + NMDevice *device, + NMSettingsConnection *connection, + gboolean add_to_no_auto_default); + +static void +default_wired_connection_removed_cb (NMSettingsConnection *connection, NMSettings *self) +{ + NMDevice *device; + + /* When the default wired connection is removed (either deleted or saved to + * a new persistent connection by a plugin), write the MAC address of the + * wired device to the config file and don't create a new default wired + * connection for that device again. + */ + device = g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ()); + if (device) + default_wired_clear_tag (self, device, connection, TRUE); +} + static void default_wired_connection_updated_by_user_cb (NMSettingsConnection *connection, gboolean by_user, NMSettings *self) { @@ -1687,6 +1648,7 @@ default_wired_clear_tag (NMSettings *self, g_object_set_qdata (G_OBJECT (connection), _default_wired_device_quark (), NULL); g_object_set_qdata (G_OBJECT (device), _default_wired_connection_quark (), NULL); + g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_removed_cb), self); g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_updated_by_user_cb), self); if (add_to_no_auto_default) @@ -1738,6 +1700,8 @@ device_realized (NMDevice *device, GParamSpec *pspec, NMSettings *self) g_signal_connect (added, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, G_CALLBACK (default_wired_connection_updated_by_user_cb), self); + g_signal_connect (added, NM_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (default_wired_connection_removed_cb), self); _LOGI ("(%s): created default wired connection '%s'", nm_device_get_iface (device), @@ -1810,8 +1774,10 @@ nm_settings_start (NMSettings *self, GError **error) /* 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 **) plugins, error)) + if (!load_plugins (self, (const char **) plugins, error)) { + g_object_unref (self); return FALSE; + } load_connections (self); check_startup_complete (self); @@ -1836,19 +1802,18 @@ get_property (GObject *object, guint prop_id, NMSettings *self = NM_SETTINGS (object); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); const GSList *specs, *iter; - guint i; - char **strvs; - const char **strv; + GHashTableIter citer; + GPtrArray *array; + const char *path; switch (prop_id) { case PROP_UNMANAGED_SPECS: + array = g_ptr_array_new (); specs = nm_settings_get_unmanaged_specs (self); - strvs = g_new (char *, g_slist_length ((GSList *) specs) + 1); - i = 0; - for (iter = specs; iter; iter = iter->next) - strvs[i++] = g_strdup (iter->data); - strvs[i] = NULL; - g_value_take_boxed (value, strvs); + for (iter = specs; iter; iter = g_slist_next (iter)) + g_ptr_array_add (array, g_strdup (iter->data)); + g_ptr_array_add (array, NULL); + g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE)); break; case PROP_HOSTNAME: g_value_set_string (value, @@ -1860,14 +1825,12 @@ get_property (GObject *object, guint prop_id, g_value_set_boolean (value, !!get_plugin (self, NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS)); break; case PROP_CONNECTIONS: - if (priv->connections_loaded) { - 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)); - } else - g_value_set_boxed (value, NULL); + array = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1); + g_hash_table_iter_init (&citer, priv->connections); + while (g_hash_table_iter_next (&citer, (gpointer) &path, NULL)) + g_ptr_array_add (array, g_strdup (path)); + g_ptr_array_add (array, NULL); + g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE)); break; case PROP_STARTUP_COMPLETE: g_value_set_boolean (value, nm_settings_get_startup_complete (self)); @@ -1885,7 +1848,7 @@ nm_settings_init (NMSettings *self) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - c_list_init (&priv->connections_lst_head); + priv->connections = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref); priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); priv->config = g_object_ref (nm_config_get ()); @@ -1903,9 +1866,11 @@ dispose (GObject *object) NMSettings *self = NM_SETTINGS (object); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - g_slist_free_full (priv->auths, (GDestroyNotify) nm_auth_chain_destroy); + g_slist_free_full (priv->auths, (GDestroyNotify) nm_auth_chain_unref); priv->auths = NULL; + g_object_unref (priv->agent_mgr); + if (priv->hostname_manager) { g_signal_handlers_disconnect_by_func (priv->hostname_manager, G_CALLBACK (_hostname_changed_cb), @@ -1922,139 +1887,26 @@ finalize (GObject *object) NMSettings *self = NM_SETTINGS (object); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - _clear_connections_cached_list (priv); - - nm_assert (c_list_is_empty (&priv->connections_lst_head)); + g_hash_table_destroy (priv->connections); + g_clear_pointer (&priv->connections_cached_list, g_free); g_slist_free_full (priv->unmanaged_specs, g_free); g_slist_free_full (priv->unrecognized_specs, g_free); g_slist_free_full (priv->plugins, g_object_unref); - g_clear_object (&priv->agent_mgr); - g_clear_object (&priv->config); G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object); } -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 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 ( - "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) { GObjectClass *object_class = G_OBJECT_CLASS (class); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (class); + NMExportedObjectClass *exported_object_class = NM_EXPORTED_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); + exported_object_class->export_path = NM_DBUS_PATH_SETTINGS; object_class->get_property = get_property; object_class->dispose = dispose; @@ -2123,4 +1975,23 @@ nm_settings_class_init (NMSettingsClass *class) 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION); + + signals[NEW_CONNECTION] = + g_signal_new ("new-connection", + 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); + + nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class), + NMDBUS_TYPE_SETTINGS_SKELETON, + "ListConnections", impl_settings_list_connections, + "GetConnectionByUuid", impl_settings_get_connection_by_uuid, + "AddConnection", impl_settings_add_connection, + "AddConnectionUnsaved", impl_settings_add_connection_unsaved, + "LoadConnections", impl_settings_load_connections, + "ReloadConnections", impl_settings_reload_connections, + "SaveHostname", impl_settings_save_hostname, + NULL); } + diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 7d56f7b4..0ecffb70 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -28,6 +28,8 @@ #include "nm-connection.h" +#include "nm-exported-object.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)) @@ -70,6 +72,14 @@ NMSettings *nm_settings_get (void); NMSettings *nm_settings_new (void); gboolean nm_settings_start (NMSettings *self, GError **error); +typedef void (*NMSettingsForEachFunc) (NMSettings *settings, + NMSettingsConnection *connection, + gpointer user_data); + +void nm_settings_for_each_connection (NMSettings *settings, + NMSettingsForEachFunc for_each_func, + gpointer user_data); + typedef void (*NMSettingsAddCallback) (NMSettings *settings, NMSettingsConnection *connection, GError *error, diff --git a/src/settings/plugins/ibft/meson.build b/src/settings/plugins/ibft/meson.build deleted file mode 100644 index da9f5566..00000000 --- a/src/settings/plugins/ibft/meson.build +++ /dev/null @@ -1,48 +0,0 @@ -name = 'nm-settings-plugin-ibft' - -cflags = [ - '-DSBINDIR="@0@"'.format(nm_sbindir), - '-DSYSCONFDIR="@0@"'.format(nm_sysconfdir) -] - -libnms_ibft_core = static_library( - 'nms-ibft-core', - 'nms-ibft-reader.c', - dependencies: nm_dep, - c_args: cflags -) - -sources = files( - 'nms-ibft-connection.c', - 'nms-ibft-plugin.c' -) - -libnm_settings_plugin_ibft = shared_module( - name, - sources: sources, - dependencies: nm_dep, - c_args: cflags, - link_with: libnms_ibft_core, - link_args: ldflags_linker_script_settings, - link_depends: linker_script_settings, - install: true, - install_dir: nm_pkglibdir -) - -core_plugins += libnm_settings_plugin_ibft - -# FIXME: check_so_symbols replacement -''' -run_target( - 'check-local-symbols-settings-ibft', - command: [check_so_symbols, libnm_settings_plugin_ibft.full_path()], - depends: libnm_settings_plugin_ibft -) - -check-local-symbols-settings-ibft: src/settings/plugins/ibft/libnm-settings-plugin-ibft.la - $(call check_so_symbols,$(builddir)/src/settings/plugins/ibft/.libs/libnm-settings-plugin-ibft.so) -''' - -if enable_tests - subdir('tests') -endif diff --git a/src/settings/plugins/ibft/tests/meson.build b/src/settings/plugins/ibft/tests/meson.build deleted file mode 100644 index 7a9445dd..00000000 --- a/src/settings/plugins/ibft/tests/meson.build +++ /dev/null @@ -1,22 +0,0 @@ -test_unit = 'test-ibft' - -test_ibft_dir = meson.current_source_dir() - -cflags = [ - '-DTEST_IBFT_DIR="@0@"'.format(test_ibft_dir), - '-DTEST_SCRATCH_DIR="@0@"'.format(test_ibft_dir) -] - -exe = executable( - test_unit, - test_unit + '.c', - dependencies: test_nm_dep, - c_args: cflags, - link_with: libnms_ibft_core -) - -test( - 'ibft/' + test_unit, - test_script, - args: test_args + [exe.full_path()] -) diff --git a/src/settings/plugins/ibft/tests/test-ibft.c b/src/settings/plugins/ibft/tests/test-ibft.c index fd2ec61b..72d1a7db 100644 --- a/src/settings/plugins/ibft/tests/test-ibft.c +++ b/src/settings/plugins/ibft/tests/test-ibft.c @@ -181,7 +181,7 @@ test_read_ibft_malformed (gconstpointer user_data) g_assert (g_file_test (iscsiadm_path, G_FILE_TEST_EXISTS)); - NMTST_EXPECT_NM_WARN ("*malformed iscsiadm record*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*malformed iscsiadm record*"); success = nms_ibft_reader_load_blocks (iscsiadm_path, &blocks, &error); g_assert_no_error (error); diff --git a/src/settings/plugins/ifcfg-rh/meson.build b/src/settings/plugins/ifcfg-rh/meson.build deleted file mode 100644 index fdf308be..00000000 --- a/src/settings/plugins/ifcfg-rh/meson.build +++ /dev/null @@ -1,77 +0,0 @@ -install_data( - 'nm-ifcfg-rh.conf', - install_dir: dbus_conf_dir -) - -cflags = [ - '-DSBINDIR="@0@"'.format(nm_sbindir), - '-DSYSCONFDIR="@0@"'.format(nm_sysconfdir) -] - -name = 'nmdbus-ifcfg-rh' - -dbus_sources = gnome.gdbus_codegen( - name, - 'nm-ifcfg-rh.xml', - interface_prefix: 'com.redhat', - namespace: 'NMDBus' -) - -libnmdbus_ifcfg_rh = static_library( - name, - sources: dbus_sources, - dependencies: glib_dep, - c_args: cflags -) - -sources = files( - 'nm-inotify-helper.c', - 'nms-ifcfg-rh-reader.c', - 'nms-ifcfg-rh-utils.c', - 'nms-ifcfg-rh-writer.c', - 'shvar.c' -) - -deps = [ - crypto_dep, - nm_dep -] - -libnms_ifcfg_rh_core = static_library( - 'nms-ifcfg-rh-core', - sources: sources, - dependencies: deps, - c_args: cflags -) - -sources = [dbus_sources] + files('nms-ifcfg-rh-connection.c') - -libnm_settings_plugin_ifcfg_rh = shared_module( - 'nm-settings-plugin-ifcfg-rh', - sources: sources, - dependencies: deps, - c_args: cflags, - link_with: [libnms_ifcfg_rh_core], - link_args: ldflags_linker_script_settings, - link_depends: linker_script_settings, - install: true, - install_dir: nm_pkglibdir -) - -core_plugins += libnm_settings_plugin_ifcfg_rh - -# FIXME: check_so_symbols replacement -''' -run_target( - 'check-local-symbols-settings-ifcfg-rh', - command: [check_so_symbols, libnm_settings_plugin_ifcfg_rh.full_path()], - depends: libnm_settings_plugin_ifcfg_rh -) - -check-local-symbols-settings-ifcfg-rh: src/settings/plugins/ifcfg-rh/libnm-settings-plugin-ifcfg-rh.la - $(call check_so_symbols,$(builddir)/src/settings/plugins/ifcfg-rh/.libs/libnm-settings-plugin-ifcfg-rh.so) -''' - -if enable_tests - subdir('tests') -endif diff --git a/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c index 2863df64..97417db9 100644 --- a/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c +++ b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c @@ -172,7 +172,7 @@ nm_inotify_helper_init (NMInotifyHelper *self) { NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); - priv->wd_refs = g_hash_table_new (nm_direct_hash, NULL); + priv->wd_refs = g_hash_table_new (g_direct_hash, g_direct_equal); } static void 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 c7207297..0743fc9f 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c @@ -37,6 +37,7 @@ #include "settings/nm-settings-plugin.h" #include "nm-config.h" #include "NetworkManagerUtils.h" +#include "nm-exported-object.h" #include "nms-ifcfg-rh-connection.h" #include "nms-ifcfg-rh-common.h" @@ -45,10 +46,10 @@ #include "nms-ifcfg-rh-utils.h" #include "shvar.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" +#include "settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.h" + +#define IFCFGRH1_DBUS_SERVICE_NAME "com.redhat.ifcfgrh1" +#define IFCFGRH1_DBUS_OBJECT_PATH "/com/redhat/ifcfgrh1" /*****************************************************************************/ @@ -57,9 +58,9 @@ typedef struct { struct { GDBusConnection *connection; + GDBusInterfaceSkeleton *interface; GCancellable *cancellable; gulong signal_id; - guint regist_id; } dbus; GHashTable *connections; /* uuid::connection */ @@ -326,21 +327,21 @@ update_connection (SettingsPluginIfcfg *self, if (new_unmanaged || new_unrecognized) { if (!old_unmanaged && !old_unrecognized) { - /* ref connection first, because we put it into priv->connections below. - * Emitting signal-removed might otherwise delete it. */ g_object_ref (connection_by_uuid); - /* Unexport the connection by telling the settings service it's * been removed. */ nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection_by_uuid)); + /* Remove the path so that claim_connection() doesn't complain later when + * interface gets managed and connection is re-added. */ + nm_connection_set_path (NM_CONNECTION (connection_by_uuid), NULL); /* signal_remove() will end up removing the connection from our hash, * so add it back now. */ g_hash_table_insert (priv->connections, g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection_by_uuid))), - connection_by_uuid /* we took reference above and pass it on */); + connection_by_uuid); } } else { if (old_unmanaged /* && !new_unmanaged */) { @@ -372,9 +373,7 @@ update_connection (SettingsPluginIfcfg *self, _LOGI ("add connection "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); else _LOGI ("new connection "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); - g_hash_table_insert (priv->connections, - g_strdup (uuid), - connection_new /* take reference */); + g_hash_table_insert (priv->connections, g_strdup (uuid), connection_new); g_signal_connect (connection_new, NM_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed_cb), @@ -517,7 +516,7 @@ read_connections (SettingsPluginIfcfg *plugin) return; } - alive_connections = g_hash_table_new (nm_direct_hash, NULL); + alive_connections = g_hash_table_new (NULL, NULL); filenames = g_ptr_array_new_with_free_func (g_free); while ((item = g_dir_read_name (dir))) { @@ -750,7 +749,7 @@ impl_ifcfgrh_get_ifcfg_details (SettingsPluginIfcfg *plugin, return; } - path = nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)); + path = nm_connection_get_path (NM_CONNECTION (connection)); if (!path) { g_dbus_method_invocation_return_error (context, NM_SETTINGS_ERROR, @@ -769,15 +768,15 @@ static void _dbus_clear (SettingsPluginIfcfg *self) { SettingsPluginIfcfgPrivate *priv = SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self); - guint id; nm_clear_g_signal_handler (priv->dbus.connection, &priv->dbus.signal_id); 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 (priv->dbus.interface) { + g_dbus_interface_skeleton_unexport (priv->dbus.interface); + nm_exported_object_skeleton_release (priv->dbus.interface); + priv->dbus.interface = NULL; } g_clear_object (&priv->dbus.connection); @@ -789,55 +788,12 @@ _dbus_connection_closed (GDBusConnection *connection, GError *error, gpointer user_data) { - _LOGW ("dbus: %s bus closed", IFCFGRH1_BUS_NAME); + _LOGW ("dbus: %s bus closed", IFCFGRH1_DBUS_SERVICE_NAME); _dbus_clear (SETTINGS_PLUGIN_IFCFG (user_data)); /* 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) -{ - SettingsPluginIfcfg *self = SETTINGS_PLUGIN_IFCFG (user_data); - const char *ifcfg; - - if ( !nm_streq (interface_name, IFCFGRH1_IFACE1_NAME) - || !nm_streq (method_name, IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS)) { - g_dbus_method_invocation_return_error (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_UNKNOWN_METHOD, - "Unknown method %s", - method_name); - return; - } - - g_variant_get (parameters, "(&s)", &ifcfg); - impl_ifcfgrh_get_ifcfg_details (self, invocation, ifcfg); -} - -static GDBusInterfaceInfo *const interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO ( - IFCFGRH1_BUS_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, @@ -874,27 +830,36 @@ _dbus_request_name_done (GObject *source_object, } { - static const GDBusInterfaceVTable interface_vtable = { - .method_call = _method_call, + GType skeleton_type = NMDBUS_TYPE_IFCFGRH1_SKELETON; + gs_free char *method_name_get_ifcfg_details = NULL; + NMExportedObjectDBusMethodImpl methods[] = { + { + .method_name = (method_name_get_ifcfg_details = nm_exported_object_skeletonify_method_name ("GetIfcfgDetails")), + .impl = G_CALLBACK (impl_ifcfgrh_get_ifcfg_details), + }, }; - 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); + priv->dbus.interface = nm_exported_object_skeleton_create (skeleton_type, + g_type_class_peek (SETTINGS_TYPE_PLUGIN_IFCFG), + methods, + G_N_ELEMENTS (methods), + (GObject *) self); + + if (!g_dbus_interface_skeleton_export (priv->dbus.interface, + priv->dbus.connection, + IFCFGRH1_DBUS_OBJECT_PATH, + &error)) { + nm_exported_object_skeleton_release (priv->dbus.interface); + priv->dbus.interface = NULL; + _LOGW ("dbus: failed exporting interface: %s", error->message); _dbus_clear (self); return; } } _LOGD ("dbus: aquired D-Bus service %s and exported %s object", - IFCFGRH1_BUS_NAME, - IFCFGRH1_OBJECT_PATH); + IFCFGRH1_DBUS_SERVICE_NAME, + IFCFGRH1_DBUS_OBJECT_PATH); } static void @@ -935,7 +900,7 @@ _dbus_create_done (GObject *source_object, DBUS_INTERFACE_DBUS, "RequestName", g_variant_new ("(su)", - IFCFGRH1_BUS_NAME, + IFCFGRH1_DBUS_SERVICE_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE), G_VARIANT_TYPE ("(u)"), G_DBUS_CALL_FLAGS_NONE, @@ -952,7 +917,7 @@ _dbus_setup (SettingsPluginIfcfg *self) gs_free char *address = NULL; gs_free_error GError *error = NULL; - _dbus_clear (self); + g_return_if_fail (!priv->dbus.connection); address = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (address == NULL) { @@ -978,22 +943,17 @@ config_changed_cb (NMConfig *config, NMConfigData *old_data, SettingsPluginIfcfg *self) { - SettingsPluginIfcfgPrivate *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 conneciton 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 = SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self); - if ( !priv->dbus.connection - && !priv->dbus.cancellable) - _dbus_setup (self); + if (NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_CAUSE_SIGHUP + | NM_CONFIG_CHANGE_CAUSE_SIGUSR1)) { + if (!SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self)->dbus.connection) + _dbus_setup (self); + } } /*****************************************************************************/ 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 6ef3f660..c91cd253 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -181,7 +181,7 @@ make_connection_setting (const char *file, const char *v; gs_free char *stable_id = NULL; const char *const *iter; - int vint64, i_val; + int vint64; ifcfg_name = utils_get_ifcfg_name (file, TRUE); if (!ifcfg_name) @@ -338,13 +338,6 @@ make_connection_setting (const char *file, vint64 = svGetValueInt64 (ifcfg, "AUTH_RETRIES", 10, -1, G_MAXINT32, -1); g_object_set (s_con, NM_SETTING_CONNECTION_AUTH_RETRIES, (gint) vint64, 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); - return NM_SETTING (s_con); } @@ -934,7 +927,7 @@ next: : "")); break; case PARSE_LINE_TYPE_FLAG: - /* NOTE: the flag (for "onlink") only allows to explictly set "TRUE". + /* XXX: the flag (for "onlink") only allows to explictly set "TRUE". * There is no way to express an explicit "FALSE" setting * of this attribute, hence, the file format cannot encode * that configuration. */ @@ -1345,7 +1338,29 @@ make_ip4_setting (shvarFile *ifcfg, } 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; + int idx; + + g_object_set (s_ip4, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, + NULL); + /* 1 IP address is allowed for shared connections. Read it. */ + if (is_any_ip4_address_defined (ifcfg, &idx)) { + guint32 gw; + NMIPAddress *addr = NULL; + + if (!read_full_ip4_address (ifcfg, idx, NULL, &addr, NULL, error)) + return NULL; + if (!read_ip4_address (ifcfg, "GATEWAY", NULL, &gw, error)) + return NULL; + (void) nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + if (never_default) + PARSE_WARNING ("GATEWAY will be ignored when DEFROUTE is disabled"); + gateway = g_strdup (nm_utils_inet4_ntop (gw, inet_buf)); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL); + } + return g_steal_pointer (&s_ip4); } else { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown BOOTPROTO '%s'", v); @@ -1372,7 +1387,7 @@ make_ip4_setting (shvarFile *ifcfg, NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) route_table, NULL); - if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) return g_steal_pointer (&s_ip4); /* Handle DHCP settings */ @@ -1449,47 +1464,39 @@ make_ip4_setting (shvarFile *ifcfg, 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_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_valid (AF_INET6, v)) { - /* Ignore IPv6 addresses */ - } else { - PARSE_WARNING ("invalid DNS server address %s", v); - return NULL; - } - } - } + /* DNS servers + * Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting()) + */ + for (i = 1; i <= 10; i++) { + char tag[256]; - /* DNS searches */ + numbered_tag (tag, "DNS", i); nm_clear_g_free (&value); - v = svGetValueStr (ifcfg, "DOMAIN", &value); + v = svGetValueStr (ifcfg, tag, &value); if (v) { - gs_free const char **searches = NULL; + if (nm_utils_ipaddr_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_valid (AF_INET6, v)) { + /* Ignore IPv6 addresses */ + } else { + PARSE_WARNING ("invalid DNS server address %s", v); + return 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 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); } } } @@ -1538,8 +1545,7 @@ make_ip4_setting (shvarFile *ifcfg, } /* 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)) { + if (!nm_setting_ip_config_get_num_dns_searches (s_ip4)) { nm_clear_g_free (&value); v = svGetValueStr (ifcfg, "SEARCH", &value); if (v) { @@ -1555,14 +1561,10 @@ make_ip4_setting (shvarFile *ifcfg, } } - timeout = svGetValueInt64 (ifcfg, "ACD_TIMEOUT", 10, -1, NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, -2); - if (timeout == -2) { - timeout = svGetValueInt64 (ifcfg, "ARPING_WAIT", 10, -1, - NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX / 1000, -1); - if (timeout > 0) - timeout *= 1000; - } - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DAD_TIMEOUT, (gint) timeout, NULL); + timeout = svGetValueInt64 (ifcfg, "ARPING_WAIT", 10, -1, + NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX / 1000, -1); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DAD_TIMEOUT, + (gint) (timeout <= 0 ? timeout : timeout * 1000), NULL); return g_steal_pointer (&s_ip4); } @@ -1640,7 +1642,7 @@ read_aliases (NMSettingIPConfig *s_ip4, gboolean read_defroute, const char *file read_defroute ? &gateway : NULL, &err); if (ok) { - nm_ip_address_set_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL, g_variant_new_string (device)); + nm_ip_address_set_attribute (addr, "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)) @@ -1999,15 +2001,11 @@ make_tc_setting (shvarFile *ifcfg) 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 (!qdisc) + PARSE_WARNING ("ignoring bad qdisc: '%s': %s", value, local->message); if (!nm_setting_tc_config_add_qdisc (s_tc, qdisc)) - PARSE_WARNING ("duplicate tc qdisc"); - - nm_tc_qdisc_unref (qdisc); + PARSE_WARNING ("duplicate qdisc"); } for (i = 1;; i++) { @@ -2021,15 +2019,11 @@ make_tc_setting (shvarFile *ifcfg) 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 (!tfilter) + PARSE_WARNING ("ignoring bad tfilter: '%s': %s", value, local->message); if (!nm_setting_tc_config_add_tfilter (s_tc, tfilter)) - PARSE_WARNING ("duplicate tc filter"); - - nm_tc_tfilter_unref (tfilter); + PARSE_WARNING ("duplicate filter"); } if ( nm_setting_tc_config_get_num_qdiscs (s_tc) > 0 @@ -3558,13 +3552,6 @@ make_wpa_setting (shvarFile *ifcfg, 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")) @@ -5334,8 +5321,6 @@ connection_from_file_full (const char *filename, 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"; @@ -5356,7 +5341,6 @@ connection_from_file_full (const char *filename, if (!svGetValueBoolean (parsed, "NM_CONTROLLED", TRUE)) { connection = create_unhandled_connection (filename, parsed, "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"); } @@ -5366,7 +5350,8 @@ connection_from_file_full (const char *filename, /* iBFT is handled by the iBFT settings plugin */ bootproto = svGetValueStr_cp (parsed, "BOOTPROTO"); if (bootproto && !g_ascii_strcasecmp (bootproto, "ibft")) { - NM_SET_OUT (out_ignore_error, TRUE); + if (out_ignore_error) + *out_ignore_error = TRUE; g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Ignoring iBFT configuration"); g_free (bootproto); @@ -5412,7 +5397,8 @@ connection_from_file_full (const char *filename, char *device; if ((tmp = svGetValueStr_cp (parsed, "IPV6TUNNELIPV4"))) { - NM_SET_OUT (out_ignore_error, TRUE); + if (out_ignore_error) + *out_ignore_error = TRUE; g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Ignoring unsupported connection due to IPV6TUNNELIPV4"); return NULL; @@ -5426,7 +5412,8 @@ connection_from_file_full (const char *filename, } if (!strcmp (device, "lo")) { - NM_SET_OUT (out_ignore_error, TRUE); + if (out_ignore_error) + *out_ignore_error = TRUE; g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Ignoring loopback device config."); g_free (device); @@ -5473,7 +5460,8 @@ connection_from_file_full (const char *filename, 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); + if (out_ignore_error) + *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); 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 8584772e..e9dd08b7 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -148,7 +148,16 @@ write_secrets (shvarFile *ifcfg, /* we purge all existing secrets. */ svUnsetAll (keyfile, SV_KEY_TYPE_ANY); - secrets_keys = nm_utils_strdict_get_keys (secrets, TRUE, &secrets_keys_n); + /* sort the keys. */ + secrets_keys = (const char **) g_hash_table_get_keys_as_array (secrets, &secrets_keys_n); + if (secrets_keys_n > 1) { + g_qsort_with_data (secrets_keys, + secrets_keys_n, + sizeof (const char *), + nm_strcmp_p_with_data, + NULL); + } + for (i = 0; i < secrets_keys_n; i++) { const char *k = secrets_keys[i]; const char *v = g_hash_table_lookup (secrets, k); @@ -785,13 +794,6 @@ write_wireless_security_setting (NMConnection *connection, nm_setting_wireless_security_get_pmf (s_wsec)); } - if (nm_setting_wireless_security_get_fils (s_wsec) == NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT) - svUnsetValue (ifcfg, "FILS"); - else { - svSetValueEnum (ifcfg, "FILS", nm_setting_wireless_security_fils_get_type (), - nm_setting_wireless_security_get_fils (s_wsec)); - } - return TRUE; } @@ -897,16 +899,14 @@ write_wireless_setting (NMConnection *connection, } mode = nm_setting_wireless_get_mode (s_wireless); - if (!mode) - svUnsetValue(ifcfg, "MODE"); - else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_INFRA)) + if (!mode || !strcmp (mode, "infrastructure")) { svSetValueStr (ifcfg, "MODE", "Managed"); - else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { + } else if (!strcmp (mode, "adhoc")) { svSetValueStr (ifcfg, "MODE", "Ad-Hoc"); adhoc = TRUE; - } else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_AP)) + } else if (!strcmp (mode, "ap")) { svSetValueStr (ifcfg, "MODE", "Ap"); - else { + } else { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Invalid mode '%s' in '%s' setting", mode, NM_SETTING_WIRELESS_SETTING_NAME); @@ -1728,7 +1728,6 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) GString *str; const char *master, *master_iface = NULL, *type; gint vint; - NMSettingConnectionMdns mdns; guint32 vuint32; const char *tmp; @@ -1750,7 +1749,9 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) /* Only save the value for master connections */ type = nm_setting_connection_get_connection_type (s_con); - if (_nm_connection_type_is_master (type)) { + if ( !g_strcmp0 (type, NM_SETTING_BOND_SETTING_NAME) + || !g_strcmp0 (type, NM_SETTING_TEAM_SETTING_NAME) + || !g_strcmp0 (type, NM_SETTING_BRIDGE_SETTING_NAME)) { NMSettingConnectionAutoconnectSlaves autoconnect_slaves; autoconnect_slaves = nm_setting_connection_get_autoconnect_slaves (s_con); svSetValueStr (ifcfg, "AUTOCONNECT_SLAVES", @@ -1887,13 +1888,6 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) vint = nm_setting_connection_get_auth_retries (s_con); svSetValueInt64_cond (ifcfg, "AUTH_RETRIES", vint >= 0, vint); - - 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); - } else - svUnsetValue (ifcfg, "MDNS"); } static char * @@ -2287,7 +2281,7 @@ write_ip4_setting (NMConnection *connection, if (i > 0) { GVariant *label; - label = nm_ip_address_get_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + label = nm_ip_address_get_attribute (addr, "label"); if (label) continue; } @@ -2417,15 +2411,12 @@ write_ip4_setting (NMConnection *connection, NM_SET_OUT (out_route_content, write_route_file (s_ip4)); timeout = nm_setting_ip_config_get_dad_timeout (s_ip4); - if (timeout < 0) { - svUnsetValue (ifcfg, "ACD_TIMEOUT"); + if (timeout < 0) svUnsetValue (ifcfg, "ARPING_WAIT"); - } else if (timeout == 0) { - svSetValueStr (ifcfg, "ACD_TIMEOUT", "0"); + else if (timeout == 0) svSetValueStr (ifcfg, "ARPING_WAIT", "0"); - } else { - svSetValueInt64 (ifcfg, "ACD_TIMEOUT", timeout); - /* Round the value up to next integer for initscripts */ + else { + /* Round the value up to next integer */ svSetValueInt64 (ifcfg, "ARPING_WAIT", (timeout - 1) / 1000 + 1); } @@ -2493,7 +2484,7 @@ write_ip4_aliases (NMConnection *connection, const char *base_ifcfg_path) addr = nm_setting_ip_config_get_address (s_ip4, i); - label_var = nm_ip_address_get_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); + label_var = nm_ip_address_get_attribute (addr, "label"); if (!label_var) continue; label = g_variant_get_string (label_var, NULL); @@ -2996,7 +2987,7 @@ do_write_to_disk (NMConnection *connection, { /* 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). */ + * new settings (in-momory). */ if (!svWriteFile (ifcfg, 0644, error)) return FALSE; @@ -3147,10 +3138,10 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection, * does not yet allow to inject the configuration. */ if (out_reread || out_reread_same) { if (!do_write_reread (connection, - svFileGetName (ifcfg), - out_reread, - out_reread_same, - &local)) { + svFileGetName (ifcfg), + out_reread, + out_reread_same, + &local)) { _LOGW ("write: failure to re-read connection \"%s\": %s", svFileGetName (ifcfg), local->message); g_clear_error (&local); @@ -3197,3 +3188,4 @@ nms_ifcfg_rh_writer_can_write_connection (NMConnection *connection, GError **err NM_PRINT_FMT_QUOTE_STRING (type)); return FALSE; } + diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index 9120b870..2b64f3fc 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -39,7 +39,7 @@ #include "nm-core-internal.h" #include "nm-core-utils.h" #include "nm-utils/nm-enum-utils.h" -#include "c-list/src/c-list.h" +#include "nm-utils/c-list.h" /*****************************************************************************/ @@ -1278,7 +1278,7 @@ svSetValueEnum (shvarFile *s, const char *key, GType gtype, int value) { gs_free char *v = NULL; - v = _nm_utils_enum_to_str_full (gtype, value, " ", NULL); + v = _nm_utils_enum_to_str_full (gtype, value, " "); return svSetValueStr (s, key, v); } diff --git a/src/settings/plugins/ifcfg-rh/tests/meson.build b/src/settings/plugins/ifcfg-rh/tests/meson.build deleted file mode 100644 index 3596b642..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/meson.build +++ /dev/null @@ -1,22 +0,0 @@ -test_unit = 'test-ifcfg-rh' - -test_ifcfg_dir = meson.current_source_dir() - -cflags = [ - '-DTEST_IFCFG_DIR="@0@"'.format(test_ifcfg_dir), - '-DTEST_SCRATCH_DIR="@0@"'.format(test_ifcfg_dir) -] - -exe = executable( - test_unit, - test_unit + '.c', - dependencies: test_nm_dep, - c_args: cflags, - link_with: libnms_ifcfg_rh_core -) - -test( - 'ifcfg-rh/' + test_unit, - test_script, - args: test_args + [exe.full_path()] -) diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected index cf325f35..026993b8 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected @@ -1,4 +1,5 @@ ESSID="Test SSID" +MODE=Managed SSID_HIDDEN=yes MAC_ADDRESS_RANDOMIZATION=default TYPE=Wireless diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected index cd8fc96f..c0e47c48 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected @@ -14,8 +14,6 @@ DNS2=4.2.2.2 DOMAIN="foobar.com lab.foobar.com" DEFROUTE=yes IPV4_FAILURE_FATAL=no -ACD_TIMEOUT=400 -ARPING_WAIT=1 IPV6INIT=no NAME="Test Write Wired Static Routes" UUID=${UUID} diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc deleted file mode 100644 index d0a3c254..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc +++ /dev/null @@ -1,16 +0,0 @@ -TYPE=Ethernet -DEVICE=eth0 -HWADDR=00:11:22:33:44:55 -BOOTPROTO=none -ONBOOT=yes -DNS1=4.2.2.1 -DNS2=4.2.2.2 -IPADDR=192.168.1.5 -PREFIX=24 -NETMASK=255.255.255.0 -GATEWAY=192.168.1.1 -IPV6INIT=no -QDISC1="root fq_codel" -FILTER1="parent 1234: matchall action simple sdata Hello" -NAME=ethernet-tc -UUID=a42c8d4e-11a2-4144-92d2-5cbce8c6b2c4 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc-write.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc-write.cexpected deleted file mode 100644 index a67ca598..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc-write.cexpected +++ /dev/null @@ -1,16 +0,0 @@ -TYPE=Ethernet -PROXY_METHOD=none -BROWSER_ONLY=no -QDISC1="parent 2468:2 pfifo_fast" -FILTER1="parent 1234: matchall action simple sdata Hello" -BOOTPROTO=none -IPADDR=1.1.1.3 -PREFIX=24 -GATEWAY=1.1.1.1 -DEFROUTE=yes -IPV4_FAILURE_FATAL=no -IPV6INIT=no -NAME="Test Write TC config" -UUID=${UUID} -DEVICE=eth0 -ONBOOT=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 index db09afdb..1bc3d524 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 @@ -10,5 +10,3 @@ PREFIX1=16 IPADDR2=3.3.3.3 PREFIX2=8 GATEWAY=1.1.1.1 -ACD_TIMEOUT=2000 -ARPING_WAIT=1 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 index 6972e279..d7273e36 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 @@ -9,5 +9,3 @@ IPADDR2=9.8.7.6 PREFIX2=16 IPADDR3=3.3.3.3 PREFIX3=8 -ACD_TIMEOUT=2000 -ARPING_WAIT=1 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-3 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-3 index d9065994..f2457bd2 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-3 +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-3 @@ -9,5 +9,3 @@ IPADDR3=9.8.7.6 PREFIX3=16 IPADDR4=3.3.3.3 PREFIX4=8 -ACD_TIMEOUT=2000 -ARPING_WAIT=1 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-4 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-4 index 935267f7..e6b77141 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-4 +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-4 @@ -9,5 +9,3 @@ IPADDR1=9.8.7.6 PREFIX1=16 IPADDR2=3.3.3.3 PREFIX2=8 -ACD_TIMEOUT=2000 -ARPING_WAIT=1 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 57bd96e9..6bf27556 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -606,7 +605,8 @@ test_read_miscellaneous_variables (void) int mac_blacklist_num, i; guint64 expected_timestamp = 0; - NMTST_EXPECT_NM_WARN ("*invalid MAC in HWADDR_BLACKLIST 'XX:aa:invalid'*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*invalid MAC in HWADDR_BLACKLIST 'XX:aa:invalid'*"); connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-misc-variables", NULL, TYPE_ETHERNET, NULL); g_test_assert_expected_messages (); @@ -859,7 +859,8 @@ test_read_wired_static_no_prefix (gconstpointer user_data) file = g_strdup_printf (TEST_IFCFG_DIR "/network-scripts/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*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*missing PREFIX, assuming*"); connection = _connection_from_file (file, NULL, TYPE_ETHERNET, NULL); g_test_assert_expected_messages (); @@ -1080,7 +1081,8 @@ test_read_wired_global_gateway_ignore (void) NMSettingIPConfig *s_ip4; char *unmanaged = NULL; - NMTST_EXPECT_NM_WARN ("*ignoring GATEWAY (/etc/sysconfig/network) for * because the connection has no static addresses"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ignoring GATEWAY (/etc/sysconfig/network) for * because the connection has no static addresses"); connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-global-gateway-ignore", TEST_IFCFG_DIR"/network-scripts/network-test-wired-global-gateway-ignore", TYPE_ETHERNET, &unmanaged); @@ -1474,7 +1476,6 @@ test_read_wired_ipv4_manual (gconstpointer data) 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); @@ -1512,7 +1513,8 @@ test_read_wired_ipv6_manual (void) NMIPAddress *ip6_addr; NMIPRoute *ip6_route; - NMTST_EXPECT_NM_WARN ("*ignoring manual default route*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ignoring manual default route*"); connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ipv6-manual", NULL, TYPE_ETHERNET, &unmanaged); g_test_assert_expected_messages (); @@ -1895,7 +1897,8 @@ test_read_write_802_1X_subj_matches (void) gs_unref_object NMConnection *reread = NULL; NMSetting8021x *s_8021x; - NMTST_EXPECT_NM_WARN ("*missing IEEE_8021X_CA_CERT*peap*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*missing IEEE_8021X_CA_CERT*peap*"); connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-802-1X-subj-matches", NULL, TYPE_ETHERNET, NULL); g_test_assert_expected_messages (); @@ -1916,14 +1919,16 @@ test_read_write_802_1X_subj_matches (void) 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"); - NMTST_EXPECT_NM_WARN ("*missing IEEE_8021X_CA_CERT for EAP method 'peap'; this is insecure!"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*missing IEEE_8021X_CA_CERT for EAP method 'peap'; this is insecure!"); _writer_new_connec_exp (connection, TEST_SCRATCH_DIR "/network-scripts/", TEST_IFCFG_DIR "/network-scripts/ifcfg-System_test-wired-802-1X-subj-matches.cexpected", &testfile); g_test_assert_expected_messages (); - NMTST_EXPECT_NM_WARN ("*missing IEEE_8021X_CA_CERT for EAP method 'peap'; this is insecure!"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*missing IEEE_8021X_CA_CERT for EAP method 'peap'; this is insecure!"); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); g_test_assert_expected_messages (); @@ -2074,7 +2079,7 @@ test_read_wired_aliases_good (gconstpointer test_data) 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); + label = nm_ip_address_get_attribute (ip4_addr, "label"); if (expected_label[j]) g_assert_cmpstr (g_variant_get_string (label, NULL), ==, expected_label[j]); else @@ -2126,7 +2131,7 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id) 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); + g_assert (nm_ip_address_get_attribute (ip4_addr, "label") == NULL); /* Gateway */ g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1"); @@ -2137,14 +2142,16 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id) static void test_read_wired_aliases_bad_1 (void) { - NMTST_EXPECT_NM_WARN ("*aliasem1:1*has no DEVICE*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*aliasem1:1*has no DEVICE*"); test_read_wired_aliases_bad (TEST_IFCFG_DIR "/network-scripts/ifcfg-aliasem1", "System aliasem1"); } static void test_read_wired_aliases_bad_2 (void) { - NMTST_EXPECT_NM_WARN ("*aliasem2:1*has invalid DEVICE*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*aliasem2:1*has invalid DEVICE*"); test_read_wired_aliases_bad (TEST_IFCFG_DIR "/network-scripts/ifcfg-aliasem2", "System aliasem2"); } @@ -3515,6 +3522,7 @@ test_write_wifi_hidden (void) g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); @@ -4766,7 +4774,6 @@ test_write_wired_static_routes (void) 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); @@ -5134,7 +5141,7 @@ test_write_wired_aliases (void) 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_ip_address_set_attribute (addr, "label", g_variant_new_string (label[i])); nm_setting_ip_config_add_address (s_ip4, addr); nm_ip_address_unref (addr); } @@ -5193,9 +5200,9 @@ test_write_wired_aliases (void) 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]); + g_assert_cmpstr (g_variant_get_string (nm_ip_address_get_attribute (addr, "label"), NULL), ==, label[j]); else - g_assert (nm_ip_address_get_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL) == NULL); + g_assert (nm_ip_address_get_attribute (addr, "label") == NULL); ip[j] = NULL; } } @@ -6278,9 +6285,7 @@ test_write_wifi_wpa_eap_tls (void) 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); + 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_pairwise (s_wsec, "tkip"); nm_setting_wireless_security_add_group (s_wsec, "tkip"); @@ -7028,7 +7033,7 @@ test_write_wired_ctc_dhcp (void) TEST_SCRATCH_DIR "/network-scripts/", &testfile); - /* Ensure the CTCPROT item gets written out as its own option */ + /* Ensure the CTCPROT item gets written out as it's own option */ ifcfg = _svOpenFile (testfile); _svGetValue_check (ifcfg, "CTCPROT", "0"); @@ -7708,7 +7713,8 @@ test_read_vlan_reorder_hdr_1 (void) NMConnection *connection; NMSettingVlan *s_vlan; - NMTST_EXPECT_NM_WARN ("*REORDER_HDR key is deprecated, use VLAN_FLAGS*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*REORDER_HDR key is deprecated, use VLAN_FLAGS*"); connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-reorder-hdr-1", NULL, TYPE_ETHERNET, NULL); g_test_assert_expected_messages (); @@ -8502,7 +8508,8 @@ 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*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*invalid DCB_PG_STRICT value*not all 0s and 1s*"); _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-booleans", NULL, TYPE_ETHERNET, &error); g_test_assert_expected_messages (); @@ -8516,7 +8523,8 @@ test_read_dcb_short_booleans (void) { gs_free_error GError *error = NULL; - NMTST_EXPECT_NM_WARN ("*DCB_PG_STRICT value*8 characters*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*DCB_PG_STRICT value*8 characters*"); _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-booleans", NULL, TYPE_ETHERNET, &error); g_test_assert_expected_messages (); @@ -8530,7 +8538,8 @@ test_read_dcb_bad_uints (void) { gs_free_error GError *error = NULL; - NMTST_EXPECT_NM_WARN ("*invalid DCB_PG_UP2TC value*not 0 - 7*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*invalid DCB_PG_UP2TC value*not 0 - 7*"); _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-uints", NULL, TYPE_ETHERNET, &error); g_test_assert_expected_messages (); @@ -8544,7 +8553,8 @@ test_read_dcb_short_uints (void) { gs_free_error GError *error = NULL; - NMTST_EXPECT_NM_WARN ("*DCB_PG_UP2TC value*8 characters*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*DCB_PG_UP2TC value*8 characters*"); _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-uints", NULL, TYPE_ETHERNET, &error); g_test_assert_expected_messages (); @@ -8558,7 +8568,8 @@ test_read_dcb_bad_percent (void) { gs_free_error GError *error = NULL; - NMTST_EXPECT_NM_WARN ("*invalid DCB_PG_PCT percentage value*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*invalid DCB_PG_PCT percentage value*"); _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-percent", NULL, TYPE_ETHERNET, &error); g_test_assert_expected_messages (); @@ -8572,7 +8583,8 @@ test_read_dcb_short_percent (void) { gs_free_error GError *error = NULL; - NMTST_EXPECT_NM_WARN ("*invalid DCB_PG_PCT percentage list value*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*invalid DCB_PG_PCT percentage list value*"); _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-percent", NULL, TYPE_ETHERNET, &error); g_test_assert_expected_messages (); @@ -8586,7 +8598,8 @@ 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*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*DCB_PG_PCT percentages do not equal 100*"); _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-pgpct-not-100", NULL, TYPE_ETHERNET, &error); g_test_assert_expected_messages (); @@ -8707,7 +8720,7 @@ test_read_team_master_invalid (gconstpointer user_data) NMSettingConnection *s_con; NMSettingTeam *s_team; - NMTST_EXPECT_NM_WARN ("*ignoring invalid team configuration*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*ignoring invalid team configuration*"); connection = _connection_from_file (PATH_NAME, NULL, TYPE_ETHERNET, NULL); g_test_assert_expected_messages (); @@ -9632,125 +9645,6 @@ test_utils_ignore (void) do_test_utils_ignored ("ignored-augtmp", "ifcfg-FooBar" AUGTMP_TAG, TRUE); } -static void -test_tc_read (void) -{ - NMConnection *connection; - NMSettingTCConfig *s_tc; - NMTCQdisc *qdisc; - NMTCTfilter *filter; - char *str; - - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/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_object_unref (connection); -} - -static 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)); - - /* 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); - - /* TC setting */ - s_tc = (NMSettingTCConfig *) nm_setting_tc_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_tc)); - - 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); - - nm_connection_add_setting (connection, nm_setting_proxy_new ()); - - nmtst_assert_connection_verifies_without_normalization (connection); - - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-test-tc-write.cexpected", - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_BOND, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - /*****************************************************************************/ #define TPATH "/settings/plugins/ifcfg-rh/" @@ -10033,8 +9927,5 @@ int main (int argc, char **argv) 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 "tc/read", test_tc_read); - g_test_add_func (TPATH "tc/write", test_tc_write); - return g_test_run (); } diff --git a/src/settings/plugins/ifnet/nms-ifnet-connection-parser.c b/src/settings/plugins/ifnet/nms-ifnet-connection-parser.c new file mode 100644 index 00000000..ed0a757f --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-connection-parser.c @@ -0,0 +1,2912 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include "nm-default.h" + +#include "nms-ifnet-connection-parser.h" + +#include +#include +#include +#include + +#include "settings/nm-settings-plugin.h" +#include "nm-core-internal.h" +#include "NetworkManagerUtils.h" +#include "nm-meta-setting.h" + +#include "nms-ifnet-net-utils.h" +#include "nms-ifnet-wpa-parser.h" +#include "nms-ifnet-connection.h" + +static char * +connection_id_from_ifnet_name (const char *conn_name) +{ + int name_len = strlen (conn_name); + + /* Convert a hex-encoded conn_name (only used for wifi SSIDs) to human-readable one */ + if ((name_len > 2) && (g_str_has_prefix (conn_name, "0x"))) { + GBytes *bytes = nm_utils_hexstr2bin (conn_name); + char *buf; + + if (bytes) { + buf = g_strndup (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes)); + g_bytes_unref (bytes); + return buf; + } + } + + return g_strdup (conn_name); +} + +static gboolean eap_simple_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + const char *basepath, + GError **error); + +static gboolean eap_tls_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + const char *basepath, + GError **error); + +static gboolean eap_peap_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + const char *basepath, + GError **error); + +static gboolean eap_ttls_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + const char *basepath, + GError **error); + +typedef struct { + const char *method; + gboolean (*reader) (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + const char *basepath, + GError **error); + gboolean wifi_phase2_only; +} EAPReader; + +static EAPReader eap_readers[] = { + {"md5", eap_simple_reader, TRUE}, + {"pwd", 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, TRUE}, + {"tls", eap_tls_reader, FALSE}, + {"peap", eap_peap_reader, FALSE}, + {"ttls", eap_ttls_reader, FALSE}, + {NULL, NULL} +}; + +/* reading identity and password */ +static gboolean +eap_simple_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + const char *basepath, + GError **error) +{ + const char *value; + + /* identity */ + value = wpa_get_value (ssid, "identity"); + if (!value) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", + eap_method); + return FALSE; + } + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); + + /* password */ + value = wpa_get_value (ssid, "password"); + if (!value) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IEEE_8021X_PASSWORD for EAP method '%s'.", + eap_method); + return FALSE; + } + + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL); + + return TRUE; +} + +static char * +get_cert (const char *ssid, const char *key, const char *basepath) +{ + const char *orig; + + /* If it's a relative path, convert to absolute using 'basepath' */ + orig = wpa_get_value (ssid, key); + if (g_path_is_absolute (orig)) + return g_strdup (orig); + return g_strdup_printf ("%s/%s", basepath, orig); +} + +static gboolean +eap_tls_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + const char *basepath, + GError **error) +{ + const char *value; + char *ca_cert = NULL; + char *client_cert = NULL; + char *privkey = NULL; + const char *privkey_password = NULL; + gboolean success = FALSE; + NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + + /* identity */ + value = wpa_get_value (ssid, "identity"); + if (!value) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", + eap_method); + return FALSE; + } + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); + + /* ca cert */ + ca_cert = get_cert (ssid, phase2 ? "ca_cert2" : "ca_cert", basepath); + if (ca_cert) { + if (phase2) { + if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, + ca_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, error)) + goto done; + } else { + if (!nm_setting_802_1x_set_ca_cert (s_8021x, + ca_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, error)) + goto done; + } + } else { + nm_log_warn (LOGD_SETTINGS, " missing %s for EAP method '%s'; this is insecure!", + phase2 ? "IEEE_8021X_INNER_CA_CERT" : + "IEEE_8021X_CA_CERT", eap_method); + } + + /* Private key password */ + privkey_password = wpa_get_value (ssid, + phase2 ? "private_key2_passwd" : + "private_key_passwd"); + + if (!privkey_password) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing %s for EAP method '%s'.", + phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD" : + "IEEE_8021X_PRIVATE_KEY_PASSWORD", eap_method); + goto done; + } + + /* The private key itself */ + privkey = get_cert (ssid, phase2 ? "private_key2" : "private_key", basepath); + if (!privkey) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing %s for EAP method '%s'.", + phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : + "IEEE_8021X_PRIVATE_KEY", eap_method); + goto done; + } + + if (phase2) { + if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, + privkey, + privkey_password, + NM_SETTING_802_1X_CK_SCHEME_PATH, + &privkey_format, + error)) + goto done; + } else { + if (!nm_setting_802_1x_set_private_key (s_8021x, + privkey, + privkey_password, + NM_SETTING_802_1X_CK_SCHEME_PATH, + &privkey_format, error)) + goto done; + } + + /* Only set the client certificate if the private key is not PKCS#12 format, + * as NM (due to supplicant restrictions) requires. If the key was PKCS#12, + * then nm_setting_802_1x_set_private_key() already set the client certificate + * to the same value as the private key. + */ + if (privkey_format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY + || privkey_format == NM_SETTING_802_1X_CK_FORMAT_X509) { + client_cert = get_cert (ssid, phase2 ? "client_cert2" : "client_cert", basepath); + if (!client_cert) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing %s for EAP method '%s'.", + phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : + "IEEE_8021X_CLIENT_CERT", eap_method); + goto done; + } + + if (phase2) { + if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, + client_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + error)) + goto done; + } else { + if (!nm_setting_802_1x_set_client_cert (s_8021x, + client_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, error)) + goto done; + } + } + + success = TRUE; + +done: + g_free (ca_cert); + g_free (client_cert); + g_free (privkey); + return success; +} + +static gboolean +eap_peap_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + const char *basepath, + GError **error) +{ + char *ca_cert = NULL; + const char *inner_auth = NULL; + const char *peapver = NULL; + char **list = NULL, **iter, *lower; + gboolean success = FALSE; + + ca_cert = get_cert (ssid, "ca_cert", basepath); + if (ca_cert) { + if (!nm_setting_802_1x_set_ca_cert (s_8021x, + ca_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, error)) + goto done; + } else { + nm_log_warn (LOGD_SETTINGS, " missing IEEE_8021X_CA_CERT for EAP method '%s'; this is insecure!", + eap_method); + } + + peapver = wpa_get_value (ssid, "phase1"); + /* peap version, default is automatic */ + if (peapver && strstr (peapver, "peapver")) { + if (strstr (peapver, "peapver=0")) + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, + "0", NULL); + else if (strstr (peapver, "peapver=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'", + peapver); + goto done; + } + } + + /* peaplabel */ + if (peapver && strstr (peapver, "peaplabel=1")) + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1", + NULL); + + inner_auth = wpa_get_value (ssid, "phase2"); + if (!inner_auth) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IEEE_8021X_INNER_AUTH_METHODS."); + goto done; + } + /* Handle options for the inner auth method */ + list = g_strsplit (inner_auth, " ", 0); + for (iter = list; iter && *iter; iter++) { + gchar *pos = NULL; + + if (!strlen (*iter)) + continue; + + if (!(pos = strstr (*iter, "MSCHAPV2")) + || !(pos = strstr (*iter, "MD5")) + || !(pos = strstr (*iter, "GTC"))) { + if (!eap_simple_reader (pos, ssid, s_8021x, TRUE, basepath, error)) + goto done; + } else if (!(pos = strstr (*iter, "TLS"))) { + if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, basepath, error)) + goto done; + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", + *iter); + goto done; + } + + pos = strchr (*iter, '='); + if (pos && *pos) { + pos++; + lower = g_ascii_strdown (pos, -1); + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, lower, + NULL); + g_free (lower); + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "No IEEE_8021X_INNER_AUTH_METHOD."); + goto done; + } + break; + } + + if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "No valid IEEE_8021X_INNER_AUTH_METHODS found."); + goto done; + } + + success = TRUE; + +done: + g_free (ca_cert); + if (list) + g_strfreev (list); + return success; +} + +static gboolean +eap_ttls_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + const char *basepath, + GError **error) +{ + gboolean success = FALSE; + const char *anon_ident = NULL; + char *ca_cert = NULL; + const char *tmp; + char **list = NULL, **iter, *inner_auth = NULL; + + /* ca cert */ + ca_cert = get_cert (ssid, "ca_cert", basepath); + if (ca_cert) { + if (!nm_setting_802_1x_set_ca_cert (s_8021x, + ca_cert, + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, error)) + goto done; + } else { + nm_log_warn (LOGD_SETTINGS, " missing IEEE_8021X_CA_CERT for EAP method '%s'; this is insecure!", + eap_method); + } + + /* anonymous indentity for tls */ + anon_ident = wpa_get_value (ssid, "anonymous_identity"); + if (anon_ident && strlen (anon_ident)) + g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, + anon_ident, NULL); + + tmp = wpa_get_value (ssid, "phase2"); + if (!tmp) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IEEE_8021X_INNER_AUTH_METHODS."); + goto done; + } + + /* Handle options for the inner auth method */ + inner_auth = g_ascii_strdown (tmp, -1); + list = g_strsplit (inner_auth, " ", 0); + for (iter = list; iter && *iter; iter++) { + gchar *pos = NULL; + + if (!strlen (*iter)) + continue; + if ((pos = strstr (*iter, "mschapv2")) != NULL + || (pos = strstr (*iter, "mschap")) != NULL + || (pos = strstr (*iter, "pap")) != NULL + || (pos = strstr (*iter, "chap")) != NULL) { + if (!eap_simple_reader (pos, ssid, s_8021x, TRUE, basepath, error)) + goto done; + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, + pos, NULL); + } else if ((pos = strstr (*iter, "tls")) != NULL) { + if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, basepath, error)) + goto done; + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, + "tls", NULL); + } else if ((pos = strstr (*iter, "mschapv2")) != NULL + || (pos = strstr (*iter, "md5")) != NULL) { + if (!eap_simple_reader (pos, ssid, s_8021x, TRUE, basepath, error)) { + nm_log_warn (LOGD_SETTINGS, "SIMPLE ERROR"); + goto done; + } + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, + pos, NULL); + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", + *iter); + goto done; + } + break; + } + + success = TRUE; +done: + g_free (ca_cert); + if (list) + g_strfreev (list); + g_free (inner_auth); + return success; +} + +/* type is already decided by net_parser, this function is just used to + * doing tansformation*/ +static const gchar * +guess_connection_type (const char *conn_name) +{ + const gchar *type = ifnet_get_data (conn_name, "type"); + const gchar *ret_type = NULL; + + if (!g_strcmp0 (type, "ppp")) + ret_type = NM_SETTING_PPPOE_SETTING_NAME; + + if (!g_strcmp0 (type, "wireless")) + ret_type = NM_SETTING_WIRELESS_SETTING_NAME; + + if (!ret_type) + ret_type = NM_SETTING_WIRED_SETTING_NAME; + + nm_log_info (LOGD_SETTINGS, "guessed connection type (%s) = %s", conn_name, ret_type); + return ret_type; +} + +/* Reading mac address for setting connection option. + * Unmanaged device mac address is required by NetworkManager*/ +static gboolean +read_mac_address (const char *conn_name, const char **mac, GError **error) +{ + const char *value = ifnet_get_data (conn_name, "mac"); + + if (!value || !strlen (value)) + return TRUE; + + if (!nm_utils_hwaddr_valid (value, ETH_ALEN)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "The MAC address '%s' was invalid.", value); + return FALSE; + } + + *mac = value; + return TRUE; +} + +static gboolean +make_wired_connection_setting (NMConnection *connection, + const char *conn_name, + GError **error) +{ + const char *mac = NULL; + NMSettingWired *s_wired = NULL; + const char *value = NULL; + + s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); + + /* mtu_xxx */ + value = ifnet_get_data (conn_name, "mtu"); + if (value) { + long int mtu; + + errno = 0; + mtu = strtol (value, NULL, 10); + if (errno || mtu < 0 || mtu > 65535) { + nm_log_warn (LOGD_SETTINGS, " invalid MTU '%s' for %s", value, conn_name); + } else + g_object_set (s_wired, NM_SETTING_WIRED_MTU, + (guint32) mtu, NULL); + } + + if (!read_mac_address (conn_name, &mac, error)) { + g_object_unref (s_wired); + return FALSE; + } + + if (mac) + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + return TRUE; +} + +/* add NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, + * NM_SETTING_IP_CONFIG_DHCP_CLIENT_ID in future*/ +static gboolean +make_ip4_setting (NMConnection *connection, + const char *conn_name, + GError **error) +{ + + NMSettingIPConfig *ip4_setting = + NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); + const char *value, *method = NULL; + gboolean is_static_block = is_static_ip4 (conn_name); + ip_block *iblock = NULL; + + /* set dhcp options (dhcp_xxx) */ + value = ifnet_get_data (conn_name, "dhcp"); + g_object_set (ip4_setting, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, value + && strstr (value, "nodns") ? TRUE : FALSE, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, value + && strstr (value, "nogateway") ? TRUE : FALSE, NULL); + + if (!is_static_block) { + method = ifnet_get_data (conn_name, "config"); + if (!method){ + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Unknown config for %s", conn_name); + g_object_unref (ip4_setting); + return FALSE; + } + if (strstr (method, "dhcp")) + g_object_set (ip4_setting, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, FALSE, NULL); + else if (strstr (method, "autoip")) { + g_object_set (ip4_setting, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, FALSE, NULL); + nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); + return TRUE; + } else if (strstr (method, "shared")) { + g_object_set (ip4_setting, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_SHARED, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, FALSE, NULL); + nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); + return TRUE; + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Unknown config for %s", conn_name); + g_object_unref (ip4_setting); + return FALSE; + } + nm_log_info (LOGD_SETTINGS, "Using %s method for %s", method, conn_name); + }else { + iblock = convert_ip4_config_block (conn_name); + if (!iblock) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Ifnet plugin: can't aquire ip configuration for %s", + conn_name); + g_object_unref (ip4_setting); + return FALSE; + } + /************** add all ip settings to the connection**********/ + while (iblock) { + ip_block *current_iblock; + NMIPAddress *ip4_addr; + GError *local = NULL; + + ip4_addr = nm_ip_address_new (AF_INET, iblock->ip, iblock->prefix, &local); + if (iblock->next_hop) + g_object_set (ip4_setting, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, + TRUE, NULL); + + if (ip4_addr) { + if (!nm_setting_ip_config_add_address (ip4_setting, ip4_addr)) + nm_log_warn (LOGD_SETTINGS, "ignoring duplicate IP4 address"); + nm_ip_address_unref (ip4_addr); + } else { + nm_log_warn (LOGD_SETTINGS, " ignoring invalid address entry: %s", local->message); + g_clear_error (&local); + } + + current_iblock = iblock; + iblock = iblock->next; + destroy_ip_block (current_iblock); + + } + g_object_set (ip4_setting, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, !has_default_ip4_route (conn_name), + NULL); + } + + /* add dhcp hostname and client id */ + if (!is_static_block && strstr (method, "dhcp")) { + gchar *dhcp_hostname, *client_id; + + get_dhcp_hostname_and_client_id (&dhcp_hostname, &client_id); + if (dhcp_hostname) { + g_object_set (ip4_setting, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, + dhcp_hostname, NULL); + nm_log_info (LOGD_SETTINGS, "DHCP hostname: %s", dhcp_hostname); + g_free (dhcp_hostname); + } + if (client_id) { + g_object_set (ip4_setting, + NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, + client_id, NULL); + nm_log_info (LOGD_SETTINGS, "DHCP client id: %s", client_id); + g_free (client_id); + } + } + + /* add all IPv4 dns servers, IPv6 servers will be ignored */ + set_ip4_dns_servers (ip4_setting, conn_name); + + /* DNS searches */ + value = ifnet_get_data (conn_name, "dns_search"); + if (value) { + gs_free char *stripped = g_strdup (value); + char **searches = NULL; + + strip_string (stripped, '"'); + + searches = g_strsplit (stripped, " ", 0); + if (searches) { + char **item; + + for (item = searches; *item; item++) { + if (strlen (*item)) { + if (!nm_setting_ip_config_add_dns_search (ip4_setting, *item)) + nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *item); + } + } + g_strfreev (searches); + } + } + + /* static routes */ + iblock = convert_ip4_routes_block (conn_name); + while (iblock) { + ip_block *current_iblock = iblock; + const char *metric_str; + char *stripped; + gint64 metric; + NMIPRoute *route; + GError *local = NULL; + + if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) { + metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); + } else { + metric_str = ifnet_get_global_data ("metric"); + if (metric_str) { + stripped = g_strdup (metric_str); + strip_string (stripped, '"'); + metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); + g_free (stripped); + } else + metric = -1; + } + + route = nm_ip_route_new (AF_INET, iblock->ip, iblock->prefix, iblock->next_hop, metric, &local); + if (route) { + if (nm_setting_ip_config_add_route (ip4_setting, route)) + nm_log_info (LOGD_SETTINGS, "new IP4 route:%s\n", iblock->ip); + else + nm_log_warn (LOGD_SETTINGS, "duplicate IP4 route"); + nm_ip_route_unref (route); + } else { + nm_log_warn (LOGD_SETTINGS, " ignoring invalid route entry: %s", local->message); + g_clear_error (&local); + } + + current_iblock = iblock; + iblock = iblock->next; + destroy_ip_block (current_iblock); + } + + /* Finally add setting to connection */ + nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); + + return TRUE; +} + +static gboolean +make_ip6_setting (NMConnection *connection, + const char *conn_name, + GError **error) +{ + NMSettingIPConfig *s_ip6 = NULL; + gboolean is_static_block = is_static_ip6 (conn_name); + + // used to disable IPv6 + gboolean ipv6_enabled = FALSE; + gchar *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + const char *value; + ip_block *iblock; + gboolean never_default = !has_default_ip6_route (conn_name); + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); + + value = ifnet_get_data (conn_name, "enable_ipv6"); + if (value && is_true (value)) + ipv6_enabled = TRUE; + + //FIXME Handle other methods that NM supports in future + // Currently only Manual and DHCP are supported + if (!ipv6_enabled) { + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + goto done; + } else if (!is_static_block) { + // config_eth* contains "dhcp6" + method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; + never_default = FALSE; + } + // else if (!has_ip6_address(conn_name)) + // doesn't have "dhcp6" && doesn't have any ipv6 address + // method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; + else + // doesn't have "dhcp6" && has at least one ipv6 address + method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + nm_log_info (LOGD_SETTINGS, "IPv6 for %s enabled, using %s", conn_name, method); + + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_METHOD, method, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, FALSE, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, FALSE, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NULL); + + /* Make manual settings */ + if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + ip_block *current_iblock; + + iblock = convert_ip6_config_block (conn_name); + if (!iblock) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Ifnet plugin: can't aquire ip6 configuration for %s", + conn_name); + goto error; + } + /* add all IPv6 addresses */ + while (iblock) { + NMIPAddress *ip6_addr; + GError *local = NULL; + + ip6_addr = nm_ip_address_new (AF_INET6, iblock->ip, iblock->prefix, &local); + if (ip6_addr) { + if (nm_setting_ip_config_add_address (s_ip6, ip6_addr)) { + nm_log_info (LOGD_SETTINGS, "ipv6 addresses count: %d", + nm_setting_ip_config_get_num_addresses (s_ip6)); + } else { + nm_log_warn (LOGD_SETTINGS, "ignoring duplicate IP6 address"); + } + nm_ip_address_unref (ip6_addr); + } else { + nm_log_warn (LOGD_SETTINGS, " ignoring invalid address entry: %s", local->message); + g_clear_error (&local); + } + + current_iblock = iblock; + iblock = iblock->next; + destroy_ip_block (current_iblock); + } + + } else if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { + /* - autoconf or DHCPv6 stuff goes here */ + } + // DNS Servers, set NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS TRUE here + set_ip6_dns_servers (s_ip6, conn_name); + + /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIPConfig */ + + // Add routes + iblock = convert_ip6_routes_block (conn_name); + if (iblock) + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, + TRUE, NULL); + /* Add all IPv6 routes */ + while (iblock) { + ip_block *current_iblock = iblock; + const char *metric_str; + char *stripped; + gint64 metric; + NMIPRoute *route; + GError *local = NULL; + + /* metric is not per routes configuration right now + * global metric is also supported (metric="x") */ + if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) + metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); + else { + metric_str = ifnet_get_global_data ("metric"); + if (metric_str) { + stripped = g_strdup (metric_str); + strip_string (stripped, '"'); + metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); + g_free (stripped); + } else + metric = 1; + } + + route = nm_ip_route_new (AF_INET6, iblock->ip, iblock->prefix, iblock->next_hop, metric, &local); + if (route) { + if (nm_setting_ip_config_add_route (s_ip6, route)) + nm_log_info (LOGD_SETTINGS, " new IP6 route"); + else + nm_log_warn (LOGD_SETTINGS, " duplicate IP6 route"); + nm_ip_route_unref (route); + } else { + nm_log_warn (LOGD_SETTINGS, " ignoring invalid route entry: %s", local->message); + g_clear_error (&local); + } + + current_iblock = iblock; + iblock = iblock->next; + destroy_ip_block (current_iblock); + } + +done: + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + return TRUE; + +error: + g_object_unref (s_ip6); + nm_log_warn (LOGD_SETTINGS, " Ignore IPv6 for %s", conn_name); + return FALSE; +} + +static NMSetting * +make_wireless_connection_setting (const char *conn_name, + NMSetting8021x **s_8021x, + GError **error) +{ + const char *mac = NULL; + NMSettingWireless *wireless_setting = NULL; + gboolean adhoc = FALSE; + const char *value; + const char *type; + + /* PPP over WIFI is not supported yet */ + g_return_val_if_fail (conn_name != NULL + && strcmp (ifnet_get_data (conn_name, "type"), + "ppp") != 0, NULL); + type = ifnet_get_data (conn_name, "type"); + if (strcmp (type, "ppp") == 0) { + nm_log_warn (LOGD_SETTINGS, "PPP over WIFI is not supported yet"); + return NULL; + } + + wireless_setting = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); + if (read_mac_address (conn_name, &mac, error)) { + if (mac) { + g_object_set (wireless_setting, + NM_SETTING_WIRELESS_MAC_ADDRESS, mac, + NULL); + } + } else { + g_object_unref (wireless_setting); + return NULL; + } + + /* handle ssid (hex and ascii) */ + if (conn_name) { + GBytes *bytes; + gsize ssid_len = 0, value_len = strlen (conn_name); + + ssid_len = value_len; + if ((value_len > 2) && (g_str_has_prefix (conn_name, "0x"))) { + /* Hex representation */ + if (value_len % 2) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid SSID '%s' size (looks like hex but length not multiple of 2)", + conn_name); + goto error; + } + + bytes = nm_utils_hexstr2bin (conn_name); + if (!bytes) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid SSID '%s' (looks like hex SSID but isn't)", + conn_name); + goto error; + } + } else + bytes = g_bytes_new (conn_name, 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)", + conn_name, ssid_len); + goto error; + } + + g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, bytes, NULL); + g_bytes_unref (bytes); + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing SSID"); + goto error; + } + + /* mode=0: infrastructure + * mode=1: adhoc */ + value = wpa_get_value (conn_name, "mode"); + if (value) + adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE; + + if (exist_ssid (conn_name)) { + const char *mode = adhoc ? "adhoc" : "infrastructure"; + + g_object_set (wireless_setting, NM_SETTING_WIRELESS_MODE, mode, + NULL); + nm_log_info (LOGD_SETTINGS, "Using mode: %s", mode); + } + + /* BSSID setting */ + value = wpa_get_value (conn_name, "bssid"); + if (value) { + if (!nm_utils_hwaddr_valid (value, ETH_ALEN)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid BSSID '%s'", value); + goto error; + } + + g_object_set (wireless_setting, NM_SETTING_WIRELESS_BSSID, + value, NULL); + + } + + /* mtu_ssid="xx" */ + value = ifnet_get_data (conn_name, "mtu"); + if (value) { + long int mtu; + + errno = 0; + mtu = strtol (value, NULL, 10); + if (errno || mtu < 0 || mtu > 50000) { + nm_log_warn (LOGD_SETTINGS, " invalid MTU '%s' for %s", value, conn_name); + } else + g_object_set (wireless_setting, NM_SETTING_WIRELESS_MTU, + (guint32) mtu, NULL); + + } + + nm_log_info (LOGD_SETTINGS, "wireless_setting added for %s", conn_name); + return NM_SETTING (wireless_setting); +error: + if (wireless_setting) + g_object_unref (wireless_setting); + return NULL; + +} + +static NMSettingWirelessSecurity * +make_leap_setting (const char *ssid, GError **error) +{ + NMSettingWirelessSecurity *wsec; + const char *value; + + wsec = + NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); + + value = wpa_get_value (ssid, "password"); + if (value && strlen (value)) + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, + value, NULL); + + value = wpa_get_value (ssid, "identity"); + if (!value || !strlen (value)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing LEAP identity"); + goto error; + } + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, value, + NULL); + + g_object_set (wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", NULL); + + return wsec; +error: + if (wsec) + g_object_unref (wsec); + return NULL; +} + +static gboolean +add_one_wep_key (const char *ssid, + const char *key, + int key_idx, + NMSettingWirelessSecurity *s_wsec, + GError **error) +{ + const char *value; + char *converted = NULL; + gboolean success = FALSE; + + g_return_val_if_fail (ssid != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (key_idx >= 0 && key_idx <= 3, FALSE); + g_return_val_if_fail (s_wsec != NULL, FALSE); + + value = wpa_get_value (ssid, key); + if (!value) + return TRUE; + + /* Validate keys */ + if (strlen (value) == 10 || strlen (value) == 26) { + /* Hexadecimal WEP key */ + if (!is_hex (value)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid hexadecimal WEP key."); + goto out; + } + converted = g_strdup (value); + } else if (value[0] == '"' + && (strlen (value) == 7 || strlen (value) == 15)) { + /* ASCII passphrase */ + char *tmp = g_strdup (value); + char *p = strip_string (tmp, '"'); + + if (!is_ascii (p)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid ASCII WEP passphrase."); + g_free (tmp); + goto out; + + } + + converted = nm_utils_bin2hexstr (tmp, strlen (tmp), -1); + g_free (tmp); + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid WEP key length. Key: %s", value); + goto out; + } + + if (converted) { + nm_setting_wireless_security_set_wep_key (s_wsec, key_idx, converted); + g_free (converted); + success = TRUE; + } + +out: + return success; +} + +static gboolean +add_wep_keys (const char *ssid, + NMSettingWirelessSecurity *s_wsec, + GError **error) +{ + if (!add_one_wep_key (ssid, "wep_key0", 0, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ssid, "wep_key1", 1, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ssid, "wep_key2", 2, s_wsec, error)) + return FALSE; + if (!add_one_wep_key (ssid, "wep_key3", 3, s_wsec, error)) + return FALSE; + return TRUE; + +} + +static NMSettingWirelessSecurity * +make_wep_setting (const char *ssid, GError **error) +{ + const char *auth_alg, *value; + int default_key_idx = 0; + NMSettingWirelessSecurity *s_wireless_sec; + + s_wireless_sec = + NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); + g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "none", NULL); + + /* default key index */ + value = wpa_get_value (ssid, "wep_tx_keyidx"); + if (value) { + default_key_idx = atoi (value); + if (default_key_idx >= 0 && default_key_idx <= 3) { + g_object_set (s_wireless_sec, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, + default_key_idx, NULL); + nm_log_info (LOGD_SETTINGS, "Default key index: %d", default_key_idx); + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid default WEP key '%s'", value); + goto error; + } + } + + if (!add_wep_keys (ssid, s_wireless_sec, error)) + goto error; + + /* If there's a default key, ensure that key exists */ + if ((default_key_idx == 1) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Default WEP key index was 2, but no valid KEY2 exists."); + goto error; + } else if ((default_key_idx == 2) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, + 2)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Default WEP key index was 3, but no valid KEY3 exists."); + goto error; + } else if ((default_key_idx == 3) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, + 3)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Default WEP key index was 4, but no valid KEY4 exists."); + goto error; + } + + /* authentication algorithms */ + auth_alg = wpa_get_value (ssid, "auth_alg"); + if (auth_alg) { + if (strcmp (auth_alg, "OPEN") == 0) { + g_object_set (s_wireless_sec, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", NULL); + nm_log_info (LOGD_SETTINGS, "WEP: Use open system authentication"); + } else if (strcmp (auth_alg, "SHARED") == 0) { + g_object_set (s_wireless_sec, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "shared", NULL); + nm_log_info (LOGD_SETTINGS, "WEP: Use shared system authentication"); + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid WEP authentication algorithm '%s'", + auth_alg); + goto error; + } + + } + + if (!nm_setting_wireless_security_get_wep_key (s_wireless_sec, 0) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 2) + && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 3) + && !nm_setting_wireless_security_get_wep_tx_keyidx (s_wireless_sec)) { + 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."); + goto error; + } + /* Unencrypted */ + g_object_unref (s_wireless_sec); + s_wireless_sec = NULL; + } + return s_wireless_sec; + +error: + if (s_wireless_sec) + g_object_unref (s_wireless_sec); + return NULL; +} + +static char * +parse_wpa_psk (const char *psk, GError **error) +{ + char *hashed = NULL; + gboolean quoted = FALSE; + + if (!psk) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing WPA_PSK for WPA-PSK key management"); + return NULL; + } + + /* 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. + */ + + if (psk[0] == '"' && psk[strlen (psk) - 1] == '"') + quoted = TRUE; + if (!quoted && (strlen (psk) == 64)) { + /* Verify the hex PSK; 64 digits */ + if (!is_hex (psk)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid WPA_PSK (contains non-hexadecimal characters)"); + goto out; + } + hashed = g_strdup (psk); + } else { + char *stripped = g_strdup (psk); + + strip_string (stripped, '"'); + + /* Length check */ + if (strlen (stripped) < 8 || strlen (stripped) > 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))"); + g_free (stripped); + goto out; + } + + hashed = g_strdup (stripped); + g_free (stripped); + } + + if (!hashed) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid WPA_PSK (doesn't look like a passphrase or hex key)"); + goto out; + } + +out: + return hashed; +} + +static gboolean +fill_wpa_ciphers (const char *ssid, + NMSettingWirelessSecurity *wsec, + gboolean group, + gboolean adhoc) +{ + const char *value; + char **list = NULL, **iter; + int i = 0; + + value = wpa_get_value (ssid, group ? "group" : "pairwise"); + if (!value) + return TRUE; + + list = g_strsplit_set (value, " ", 0); + for (iter = list; iter && *iter; iter++, i++) { + /* Ad-Hoc configurations cannot have pairwise ciphers, and can only + * have one group cipher. Ignore any additional group ciphers and + * any pairwise ciphers specified. + */ + if (adhoc) { + if (group && (i > 0)) { + nm_log_warn (LOGD_SETTINGS, " ignoring group cipher '%s' (only one group cipher allowed in Ad-Hoc mode)", + *iter); + continue; + } else if (!group) { + nm_log_warn (LOGD_SETTINGS, " ignoring pairwise cipher '%s' (pairwise not used in Ad-Hoc mode)", + *iter); + continue; + } + } + + 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 { + nm_log_warn (LOGD_SETTINGS, " ignoring invalid %s cipher '%s'", + group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE", + *iter); + } + } + + if (list) + g_strfreev (list); + return TRUE; +} + +static NMSetting8021x * +fill_8021x (const char *ssid, + const char *key_mgmt, + gboolean wifi, + const char *basepath, + GError **error) +{ + NMSetting8021x *s_8021x; + const char *value; + char **list, **iter; + + value = wpa_get_value (ssid, "eap"); + if (!value) { + 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 = g_strsplit (value, " ", 0); + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + /* Validate and handle each EAP method */ + for (iter = list; iter && *iter; iter++) { + EAPReader *eap = &eap_readers[0]; + gboolean found = FALSE; + 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 WiFi unless they are an inner method + * used with TTLS or PEAP or whatever. + */ + if (wifi && eap->wifi_phase2_only) { + nm_log_warn (LOGD_SETTINGS, " ignored invalid IEEE_8021X_EAP_METHOD '%s'; not allowed for wifi.", + lower); + goto next; + } + + /* Parse EAP method specific options */ + if (!(*eap->reader) (lower, ssid, s_8021x, FALSE, basepath, error)) { + g_free (lower); + goto error; + } + nm_setting_802_1x_add_eap_method (s_8021x, lower); + found = TRUE; + break; + + next: + eap++; + } + + if (!found) { + nm_log_warn (LOGD_SETTINGS, " ignored unknown IEEE_8021X_EAP_METHOD '%s'.", lower); + } + g_free (lower); + } + g_strfreev (list); + + 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."); + goto error; + } + + return s_8021x; + +error: + g_object_unref (s_8021x); + return NULL; +} + +static NMSettingWirelessSecurity * +make_wpa_setting (const char *ssid, + const char *basepath, + NMSetting8021x **s_8021x, + GError **error) +{ + NMSettingWirelessSecurity *wsec; + const char *value; + char *lower; + gboolean adhoc = FALSE; + + if (!exist_ssid (ssid)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "No security info found for ssid: %s", ssid); + return NULL; + } + + wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); + + /* mode=1: adhoc + * mode=0: infrastructure */ + value = wpa_get_value (ssid, "mode"); + if (value) + adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE; + + /* Pairwise and Group ciphers */ + fill_wpa_ciphers (ssid, wsec, FALSE, adhoc); + fill_wpa_ciphers (ssid, wsec, TRUE, adhoc); + + /* WPA and/or RSN */ + if (adhoc) { + /* Ad-Hoc mode only supports WPA proto for now */ + nm_setting_wireless_security_add_proto (wsec, "wpa"); + } else { + nm_setting_wireless_security_add_proto (wsec, "wpa"); + nm_setting_wireless_security_add_proto (wsec, "rsn"); + + } + + value = wpa_get_value (ssid, "key_mgmt"); + if (!strcmp (value, "WPA-PSK")) { + char *psk = parse_wpa_psk (wpa_get_value (ssid, "psk"), error); + + if (!psk) + goto error; + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, + NULL); + g_free (psk); + + if (adhoc) + g_object_set (wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-none", NULL); + else + g_object_set (wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-psk", NULL); + } else if (!strcmp (value, "WPA-EAP") || !strcmp (value, "IEEE8021X")) { + 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'", + value); + goto error; + } + *s_8021x = fill_8021x (ssid, value, TRUE, basepath, error); + if (!*s_8021x) + goto error; + + lower = g_ascii_strdown (value, -1); + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + lower, NULL); + g_free (lower); + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Unknown wireless KEY_MGMT type '%s'", value); + goto error; + } + return wsec; +error: + if (wsec) + g_object_unref (wsec); + return NULL; +} + +static NMSettingWirelessSecurity * +make_wireless_security_setting (const char *conn_name, + const char *basepath, + NMSetting8021x **s_8021x, + GError ** error) +{ + NMSettingWirelessSecurity *wsec = NULL; + const char *ssid; + gboolean adhoc = FALSE; + const char *value; + + g_return_val_if_fail (conn_name != NULL + && strcmp (ifnet_get_data (conn_name, "type"), + "ppp") != 0, NULL); + nm_log_info (LOGD_SETTINGS, "updating wireless security settings (%s).", conn_name); + + ssid = conn_name; + value = wpa_get_value (ssid, "mode"); + if (value) + adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE; + + value = wpa_get_value (ssid, "key_mgmt"); + if (!adhoc && g_strcmp0 (value, "IEEE8021X") == 0) { + value = wpa_get_value (ssid, "eap"); + if (value && strcasecmp (value, "LEAP") == 0) { + wsec = make_leap_setting (ssid, error); + if (wsec == NULL) + goto error; + } + } else if (g_strcmp0 (value, "WPA-PSK") == 0 || g_strcmp0 (value, "WPA-EAP") == 0) { + wsec = make_wpa_setting (ssid, basepath, s_8021x, error); + if (wsec == NULL) + goto error; + } + if (!wsec) { + wsec = make_wep_setting (ssid, error); + if (wsec == NULL) + goto error; + } + return wsec; + +error: + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Can't handle security information for ssid: %s", + conn_name); + return NULL; +} + +/* Currently only support username and password */ +static gboolean +make_pppoe_connection_setting (NMConnection *connection, + const char *conn_name, + GError **error) +{ + NMSettingPppoe *s_pppoe; + NMSettingPpp *s_ppp; + const char *value; + + s_pppoe = NM_SETTING_PPPOE (nm_setting_pppoe_new ()); + + /* username */ + value = ifnet_get_data (conn_name, "username"); + if (!value) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "ppp requires at lease a username"); + return FALSE; + } + g_object_set (s_pppoe, NM_SETTING_PPPOE_USERNAME, value, NULL); + + /* password */ + value = ifnet_get_data (conn_name, "password"); + if (!value) { + value = ""; + } + + g_object_set (s_pppoe, NM_SETTING_PPPOE_PASSWORD, value, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_pppoe)); + + /* PPP setting */ + s_ppp = (NMSettingPpp *) nm_setting_ppp_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ppp)); + + return TRUE; +} + +NMConnection * +ifnet_update_connection_from_config_block (const char *conn_name, + const char *basepath, + GError **error) +{ + const gchar *type = NULL; + NMConnection *connection = NULL; + NMSettingConnection *setting = NULL; + NMSetting8021x *s_8021x = NULL; + NMSettingWirelessSecurity *wsec = NULL; + gboolean auto_conn = TRUE; + const char *value = NULL; + gchar *id, *uuid; + gboolean success = FALSE; + + connection = nm_simple_connection_new (); + setting = nm_connection_get_setting_connection (connection); + if (!setting) { + setting = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + g_assert (setting); + nm_connection_add_setting (connection, NM_SETTING (setting)); + } + + type = guess_connection_type (conn_name); + value = ifnet_get_data (conn_name, "auto"); + if (value && !strcmp (value, "false")) + auto_conn = FALSE; + + /* Try to read UUID from the ifnet block, otherwise generate UUID from + * the connection ID. + */ + id = connection_id_from_ifnet_name (conn_name); + uuid = g_strdup (ifnet_get_data (conn_name, "uuid")); + if (!uuid) + uuid = nm_utils_uuid_generate_from_string (id, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); + + g_object_set (setting, + NM_SETTING_CONNECTION_TYPE, type, + NM_SETTING_CONNECTION_ID, id, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_INTERFACE_NAME, conn_name, + NM_SETTING_CONNECTION_READ_ONLY, FALSE, + NM_SETTING_CONNECTION_AUTOCONNECT, auto_conn, + NULL); + nm_log_info (LOGD_SETTINGS, "name:%s, id:%s, uuid: %s", conn_name, id, uuid); + g_free (id); + g_free (uuid); + + if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type) + || !strcmp (NM_SETTING_PPPOE_SETTING_NAME, type)) { + /* wired setting */ + if (!make_wired_connection_setting (connection, conn_name, error)) + goto error; + + /* pppoe setting */ + if (!strcmp (NM_SETTING_PPPOE_SETTING_NAME, type)) { + if (!make_pppoe_connection_setting (connection, conn_name, error)) + goto error; + } + } else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) { + /* wireless setting */ + NMSetting *wireless_setting; + + wireless_setting = make_wireless_connection_setting (conn_name, &s_8021x, error); + if (!wireless_setting) + goto error; + nm_connection_add_setting (connection, wireless_setting); + + /* wireless security setting */ + if (wpa_get_value (conn_name, "ssid")) { + wsec = make_wireless_security_setting (conn_name, basepath, &s_8021x, error); + if (!wsec) + goto error; + nm_connection_add_setting (connection, NM_SETTING (wsec)); + if (s_8021x) + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + } + } else + goto error; + + /* IPv4 setting */ + if (!make_ip4_setting (connection, conn_name, error)) + goto error; + + /* IPv6 setting */ + if (!make_ip6_setting (connection, conn_name, error)) + goto error; + + if (nm_connection_verify (connection, error)) { + nm_log_info (LOGD_SETTINGS, "Connection verified %s:%d", conn_name, success); + } else { + goto error; + } + + return connection; +error: + g_object_unref (connection); + return NULL; +} + +typedef struct Setting8021xSchemeVtable { + const NMSetting8021xSchemeVtable *vtable; + const char *ifnet_key; +} Setting8021xSchemeVtable; + +static const Setting8021xSchemeVtable setting_8021x_scheme_vtable[] = { + [NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT] = { + .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT], + .ifnet_key = "ca_cert", + }, + [NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT] = { + .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT], + .ifnet_key = "ca_cert2", + }, + [NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT] = { + .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT], + .ifnet_key = "client_cert", + }, + [NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT] = { + .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT], + .ifnet_key = "client_cert2", + }, + [NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY] = { + .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY], + .ifnet_key = "private_key", + }, + [NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY] = { + .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY], + .ifnet_key = "private_key2", + }, +}; + +static gboolean +write_object (NMSetting8021x *s_8021x, + const char *conn_name, + GBytes *override_data, + const Setting8021xSchemeVtable *objtype, + GError **error) +{ + NMSetting8021xCKScheme scheme; + const char *path = NULL; + GBytes *blob = NULL; + + g_return_val_if_fail (conn_name != NULL, FALSE); + g_return_val_if_fail (objtype != NULL, FALSE); + if (override_data) + /* if given explicit data to save, always use that instead of asking + * the setting what to do. + */ + blob = override_data; + else { + scheme = (*(objtype->vtable->scheme_func)) (s_8021x); + switch (scheme) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + blob = (*(objtype->vtable->blob_func)) (s_8021x); + break; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = (*(objtype->vtable->path_func)) (s_8021x); + break; + default: + break; + } + } + + /* If the object path was specified, prefer that over any raw cert data that + * may have been sent. + */ + if (path) { + wpa_set_data (conn_name, (gchar *) objtype->ifnet_key, + (gchar *) path); + return TRUE; + } + + /* does not support writing encryption data now */ + if (blob) + nm_log_warn (LOGD_SETTINGS, " Currently we do not support cert writing."); + + return TRUE; +} + +static gboolean +write_8021x_certs (NMSetting8021x *s_8021x, + gboolean phase2, + const char *conn_name, + GError **error) +{ + char *password = NULL; + const Setting8021xSchemeVtable *otype = NULL; + gboolean is_pkcs12 = FALSE, success = FALSE; + GBytes *blob = NULL; + GBytes *enc_key = NULL; + gchar *generated_pw = NULL; + + /* CA certificate */ + otype = 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]; + + if (!write_object (s_8021x, conn_name, NULL, otype, error)) + return FALSE; + + /* Private key */ + if (phase2) { + if (nm_setting_802_1x_get_phase2_private_key_scheme (s_8021x) != + NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { + if (nm_setting_802_1x_get_phase2_private_key_format + (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) + is_pkcs12 = TRUE; + } + password = (char *) + nm_setting_802_1x_get_phase2_private_key_password (s_8021x); + } else { + if (nm_setting_802_1x_get_private_key_scheme (s_8021x) != + NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { + if (nm_setting_802_1x_get_private_key_format (s_8021x) + == NM_SETTING_802_1X_CK_FORMAT_PKCS12) + is_pkcs12 = TRUE; + } + password = (char *) + nm_setting_802_1x_get_private_key_password (s_8021x); + } + + otype = phase2 + ? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY] + : &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY]; + + if ((*(otype->vtable->scheme_func)) (s_8021x) == + NM_SETTING_802_1X_CK_SCHEME_BLOB) + blob = (*(otype->vtable->blob_func)) (s_8021x); + + /* Only do the private key re-encrypt dance if we got the raw key data, which + * by definition will be unencrypted. If we're given a direct path to the + * private key file, it'll be encrypted, so we don't need to re-encrypt. + */ + if (blob && !is_pkcs12) { + GByteArray *tmp_enc_key; + + /* Encrypt the unencrypted private key with the fake password */ + tmp_enc_key = + nm_utils_rsa_key_encrypt (g_bytes_get_data (blob, NULL), g_bytes_get_size (blob), + password, &generated_pw, error); + if (!tmp_enc_key) + goto out; + + enc_key = g_byte_array_free_to_bytes (tmp_enc_key); + + if (generated_pw) + password = generated_pw; + } + + /* Save the private key */ + if (!write_object + (s_8021x, conn_name, enc_key ? enc_key : blob, otype, error)) + goto out; + + if (phase2) + wpa_set_data (conn_name, "private_key2_passwd", password); + else + wpa_set_data (conn_name, "private_key_passwd", password); + + /* Client certificate */ + if (is_pkcs12) { + wpa_set_data (conn_name, + phase2 ? "client_cert2" : "client_cert", NULL); + } else { + otype = 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]; + + /* Save the client certificate */ + if (!write_object (s_8021x, conn_name, NULL, otype, error)) + goto out; + } + + success = TRUE; +out: + if (generated_pw) { + memset (generated_pw, 0, strlen (generated_pw)); + g_free (generated_pw); + } + if (enc_key) { + memset ((gpointer) g_bytes_get_data (enc_key, NULL), 0, g_bytes_get_size (enc_key)); + g_bytes_unref (enc_key); + } + return success; +} + +static gboolean +write_8021x_setting (NMConnection *connection, + const char *conn_name, + gboolean wired, + GError **error) +{ + NMSetting8021x *s_8021x; + const char *value; + char *tmp = NULL; + gboolean success = FALSE; + GString *phase2_auth; + GString *phase1; + + s_8021x = nm_connection_get_setting_802_1x (connection); + if (!s_8021x) { + return TRUE; + } + + nm_log_info (LOGD_SETTINGS, "Adding 8021x setting for %s", conn_name); + + /* If wired, write KEY_MGMT */ + if (wired) + wpa_set_data (conn_name, "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); + } + wpa_set_data (conn_name, "eap", tmp ? tmp : NULL); + g_free (tmp); + + wpa_set_data (conn_name, "identity", + (gchar *) nm_setting_802_1x_get_identity (s_8021x)); + + wpa_set_data (conn_name, "anonymous_identity", (gchar *) + nm_setting_802_1x_get_anonymous_identity (s_8021x)); + + wpa_set_data (conn_name, "password", + (gchar *) nm_setting_802_1x_get_password (s_8021x)); + + phase1 = g_string_new (NULL); + + /* PEAP version */ + wpa_set_data (conn_name, "phase1", NULL); + value = nm_setting_802_1x_get_phase1_peapver (s_8021x); + if (value && (!strcmp (value, "0") || !strcmp (value, "1"))) + g_string_append_printf (phase1, "peapver=%s ", value); + + /* PEAP label */ + value = nm_setting_802_1x_get_phase1_peaplabel (s_8021x); + if (value && !strcmp (value, "1")) + g_string_append_printf (phase1, "peaplabel=%s ", value); + if (phase1->len) { + tmp = g_strstrip (g_strdup (phase1->str)); + wpa_set_data (conn_name, "phase1", tmp); + g_free (tmp); + } + + /* Phase2 auth methods */ + wpa_set_data (conn_name, "phase2", NULL); + 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_printf (phase2_auth, "auth=%s ", tmp); + g_free (tmp); + } + + /* Phase2 auth heap */ + value = nm_setting_802_1x_get_phase2_autheap (s_8021x); + if (value) { + tmp = g_ascii_strup (value, -1); + g_string_append_printf (phase2_auth, "autheap=%s ", tmp); + g_free (tmp); + } + tmp = g_strstrip (g_strdup (phase2_auth->str)); + wpa_set_data (conn_name, "phase2", phase2_auth->len ? tmp : NULL); + g_free (tmp); + + g_string_free (phase2_auth, TRUE); + g_string_free (phase1, TRUE); + + success = write_8021x_certs (s_8021x, FALSE, conn_name, error); + if (success) { + /* phase2/inner certs */ + success = write_8021x_certs (s_8021x, TRUE, conn_name, error); + } + + return success; +} + +static gboolean +write_wireless_security_setting (NMConnection * connection, + gchar * conn_name, + gboolean adhoc, + gboolean * no_8021x, GError ** error) +{ + NMSettingWirelessSecurity *s_wsec; + const char *key_mgmt, *auth_alg, *key, *cipher, *psk; + gboolean wep = FALSE, wpa = FALSE; + 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_INVALID_CONNECTION, + "Missing '%s' setting", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + return FALSE; + } + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + g_assert (key_mgmt); + + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); + + if (!strcmp (key_mgmt, "none")) { + wpa_set_data (conn_name, "key_mgmt", "NONE"); + wep = TRUE; + *no_8021x = TRUE; + } else if (!strcmp (key_mgmt, "wpa-none") + || !strcmp (key_mgmt, "wpa-psk")) { + wpa_set_data (conn_name, "key_mgmt", "WPA-PSK"); + wpa = TRUE; + *no_8021x = TRUE; + } else if (!strcmp (key_mgmt, "ieee8021x")) { + wpa_set_data (conn_name, "key_mgmt", "IEEE8021X"); + } else if (!strcmp (key_mgmt, "wpa-eap")) { + wpa_set_data (conn_name, "key_mgmt", "WPA-EAP"); + wpa = TRUE; + } else + nm_log_warn (LOGD_SETTINGS, "Unknown key_mgmt: %s", key_mgmt); + + if (auth_alg) { + if (!strcmp (auth_alg, "shared")) + wpa_set_data (conn_name, "auth_alg", "SHARED"); + else if (!strcmp (auth_alg, "open")) + wpa_set_data (conn_name, "auth_alg", "OPEN"); + else if (!strcmp (auth_alg, "leap")) { + wpa_set_data (conn_name, "auth_alg", "LEAP"); + wpa_set_data (conn_name, "eap", "LEAP"); + wpa_set_data (conn_name, "identity", (gchar *) + nm_setting_wireless_security_get_leap_username + (s_wsec)); + wpa_set_data (conn_name, "password", (gchar *) + nm_setting_wireless_security_get_leap_password + (s_wsec)); + *no_8021x = TRUE; + } + } else + wpa_set_data (conn_name, "auth_alg", NULL); + + /* Default WEP TX key index */ + if (wep) { + tmp = + g_strdup_printf ("%d", + nm_setting_wireless_security_get_wep_tx_keyidx + (s_wsec)); + wpa_set_data (conn_name, "wep_tx_keyidx", tmp); + g_free (tmp); + } else + wpa_set_data (conn_name, "wep_tx_keyidx", NULL); + + /* WEP keys */ + for (i = 0; i < 4; i++) { + int length; + + key = nm_setting_wireless_security_get_wep_key (s_wsec, i); + if (!key) + continue; + tmp = g_strdup_printf ("wep_key%d", i); + length = strlen (key); + if (length == 10 || length == 26 || length == 58) + wpa_set_data (conn_name, tmp, (gchar *) key); + else { + gchar *tmp_key = g_strdup_printf ("\"%s\"", key); + + wpa_set_data (conn_name, tmp, tmp_key); + g_free (tmp_key); + } + g_free (tmp); + } + + /* WPA Pairwise ciphers */ + wpa_set_data (conn_name, "pairwise", NULL); + 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); + tmp = g_ascii_strup (cipher, -1); + g_string_append (str, tmp); + g_free (tmp); + } + if (strlen (str->str)) + wpa_set_data (conn_name, "pairwise", str->str); + g_string_free (str, TRUE); + + /* WPA Group ciphers */ + wpa_set_data (conn_name, "group", NULL); + 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)) + wpa_set_data (conn_name, "group", str->str); + g_string_free (str, TRUE); + + /* WPA Passphrase */ + if (wpa) { + GString *quoted = NULL; + + psk = nm_setting_wireless_security_get_psk (s_wsec); + if (psk && (strlen (psk) != 64)) { + quoted = g_string_sized_new (strlen (psk) + 2); + g_string_append_c (quoted, '"'); + g_string_append (quoted, psk); + g_string_append_c (quoted, '"'); + } + /* psk will be lost here if we don't check it for NULL */ + if (psk) + wpa_set_data (conn_name, "psk", + quoted ? quoted->str : (gchar *) psk); + if (quoted) + g_string_free (quoted, TRUE); + } else + wpa_set_data (conn_name, "psk", NULL); + + return TRUE; +} + +/* remove old ssid and add new one*/ +static void +update_wireless_ssid (NMConnection *connection, + const char *conn_name, + const char *ssid, + gboolean hex) +{ + if(strcmp (conn_name, ssid)){ + ifnet_delete_network (conn_name); + wpa_delete_security (conn_name); + } + + ifnet_add_network (ssid, "wireless"); + wpa_add_security (ssid); +} + +static gboolean +write_wireless_setting (NMConnection *connection, + const char *conn_name, + gboolean *no_8021x, + const char **out_new_name, + GError **error) +{ + NMSettingWireless *s_wireless; + GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; + const char *mac, *bssid, *mode; + char buf[33]; + guint32 mtu, i; + gboolean adhoc = FALSE, hex_ssid = FALSE; + gchar *ssid_str, *tmp; + + s_wireless = nm_connection_get_setting_wireless (connection); + if (!s_wireless) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing '%s' setting", + NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + ssid = nm_setting_wireless_get_ssid (s_wireless); + if (!ssid) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "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_INVALID_CONNECTION, + "Invalid SSID in '%s' setting", + NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + /* If the SSID contains any non-alnum characters, we need to use + * the hex notation of the SSID instead. (Because openrc doesn't + * support these characters, see bug #356337) + */ + for (i = 0; i < ssid_len; i++) { + if (!g_ascii_isalnum (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]); + update_wireless_ssid (connection, conn_name, str->str, hex_ssid); + ssid_str = g_string_free (str, FALSE); + } else { + /* Printable SSIDs get quoted */ + memset (buf, 0, sizeof (buf)); + memcpy (buf, ssid_data, ssid_len); + g_strstrip (buf); + update_wireless_ssid (connection, conn_name, buf, hex_ssid); + ssid_str = g_strdup (buf); + } + + ifnet_set_data (ssid_str, "mac", NULL); + mac = nm_setting_wireless_get_mac_address (s_wireless); + if (mac) + ifnet_set_data (ssid_str, "mac", mac); + + ifnet_set_data (ssid_str, "mtu", NULL); + mtu = nm_setting_wireless_get_mtu (s_wireless); + if (mtu) { + tmp = g_strdup_printf ("%u", mtu); + ifnet_set_data (ssid_str, "mtu", tmp); + g_free (tmp); + } + + ifnet_set_data (ssid_str, "mode", NULL); + mode = nm_setting_wireless_get_mode (s_wireless); + if (!mode || !strcmp (mode, "infrastructure")) { + wpa_set_data (ssid_str, "mode", "0"); + } else if (!strcmp (mode, "adhoc")) { + wpa_set_data (ssid_str, "mode", "1"); + adhoc = TRUE; + } else { + nm_log_warn (LOGD_SETTINGS, "Invalid mode '%s' in '%s' setting", + mode, NM_SETTING_WIRELESS_SETTING_NAME); + return FALSE; + } + + wpa_set_data (ssid_str, "bssid", NULL); + bssid = nm_setting_wireless_get_bssid (s_wireless); + if (bssid) + wpa_set_data (ssid_str, "bssid", bssid); + + if (nm_connection_get_setting_wireless_security (connection)) { + if (!write_wireless_security_setting + (connection, ssid_str, adhoc, no_8021x, error)) + return FALSE; + } else + wpa_delete_security (ssid_str); + + if (out_new_name) + *out_new_name = ifnet_get_data (ssid_str, "name"); + g_free (ssid_str); + return TRUE; +} + +static gboolean +write_wired_setting (NMConnection *connection, + const char *conn_name, + GError **error) +{ + NMSettingWired *s_wired; + const char *mac; + char *tmp; + guint32 mtu; + + s_wired = nm_connection_get_setting_wired (connection); + if (!s_wired) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing '%s' setting", + NM_SETTING_WIRED_SETTING_NAME); + return FALSE; + } + + ifnet_set_data (conn_name, "mac", NULL); + mac = nm_setting_wired_get_mac_address (s_wired); + if (mac) + ifnet_set_data (conn_name, "mac", mac); + + ifnet_set_data (conn_name, "mtu", NULL); + mtu = nm_setting_wired_get_mtu (s_wired); + if (mtu) { + tmp = g_strdup_printf ("%u", mtu); + ifnet_set_data (conn_name, "mtu", tmp); + g_free (tmp); + } + //FIXME may add connection type in future + //ifnet_set_data (conn_name, "TYPE", TYPE_ETHERNET); + + return TRUE; +} + +static gboolean +write_ip4_setting (NMConnection *connection, const char *conn_name, GError **error) +{ + NMSettingIPConfig *s_ip4; + const char *value; + guint32 i, num; + GString *searches; + GString *ips; + GString *routes; + GString *dns; + gboolean success = FALSE; + + s_ip4 = nm_connection_get_setting_ip4_config (connection); + if (!s_ip4) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing '%s' setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + return FALSE; + } + routes = g_string_new (NULL); + + value = nm_setting_ip_config_get_method (s_ip4); + g_assert (value); + if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + + num = nm_setting_ip_config_get_num_addresses (s_ip4); + ips = g_string_new (NULL); + /* IPv4 addresses */ + for (i = 0; i < num; i++) { + NMIPAddress *addr; + + addr = nm_setting_ip_config_get_address (s_ip4, i); + + g_string_append_printf (ips, "\"%s/%u", + nm_ip_address_get_address (addr), + nm_ip_address_get_prefix (addr)); + + /* only the first gateway will be written */ + if (i == 0 && nm_setting_ip_config_get_gateway (s_ip4)) { + g_string_append_printf (routes, + "\"default via %s\" ", + nm_setting_ip_config_get_gateway (s_ip4)); + } + } + ifnet_set_data (conn_name, "config", ips->str); + g_string_free (ips, TRUE); + } else if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) + ifnet_set_data (conn_name, "config", "shared"); + else if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) + ifnet_set_data (conn_name, "config", "autoip"); + else + ifnet_set_data (conn_name, "config", "dhcp"); + + /* DNS Servers */ + num = nm_setting_ip_config_get_num_dns (s_ip4); + if (num > 0) { + dns = g_string_new (NULL); + for (i = 0; i < num; i++) { + const char *ip; + + ip = nm_setting_ip_config_get_dns (s_ip4, i); + g_string_append_printf (dns, " %s", ip); + } + ifnet_set_data (conn_name, "dns_servers", dns->str); + g_string_free (dns, TRUE); + } else + ifnet_set_data (conn_name, "dns_servers", NULL); + + /* DNS Searches */ + 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)); + } + ifnet_set_data (conn_name, "dns_search", searches->str); + g_string_free (searches, TRUE); + } else + ifnet_set_data (conn_name, "dns_search", NULL); + /* FIXME Will be implemented when configuration supports it + if (!strcmp(value, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + value = nm_setting_ip_config_get_dhcp_hostname(s_ip4); + if (value) + ifnet_set_data(conn_name, "DHCP_HOSTNAME", value, + FALSE); + + value = nm_setting_ip_config_get_dhcp_client_id(s_ip4); + if (value) + ifnet_set_data(conn_name, "DHCP_CLIENT_ID", value, + FALSE); + } + */ + + /* Static routes */ + num = nm_setting_ip_config_get_num_routes (s_ip4); + if (num > 0) { + for (i = 0; i < num; i++) { + NMIPRoute *route; + const char *next_hop; + + route = nm_setting_ip_config_get_route (s_ip4, i); + + next_hop = nm_ip_route_get_next_hop (route); + if (!next_hop) + next_hop = "0.0.0.0"; + + g_string_append_printf (routes, "\"%s/%u via %s\" ", + nm_ip_route_get_dest (route), + nm_ip_route_get_prefix (route), + next_hop); + } + } + if (routes->len > 0) + ifnet_set_data (conn_name, "routes", routes->str); + else + ifnet_set_data (conn_name, "routes", NULL); + g_string_free (routes, TRUE); + + success = TRUE; + + return success; +} + +static void +write_route6_file (NMSettingIPConfig *s_ip6, const char *conn_name) +{ + NMIPRoute *route; + const char *next_hop; + guint32 i, num; + GString *routes_string; + const char *old_routes; + + g_return_if_fail (s_ip6 != NULL); + num = nm_setting_ip_config_get_num_routes (s_ip6); + if (num == 0) + return; + + old_routes = ifnet_get_data (conn_name, "routes"); + routes_string = g_string_new (old_routes); + if (old_routes) + g_string_append (routes_string, "\" "); + for (i = 0; i < num; i++) { + route = nm_setting_ip_config_get_route (s_ip6, i); + + next_hop = nm_ip_route_get_next_hop (route); + if (!next_hop) + next_hop = "::"; + + g_string_append_printf (routes_string, "\"%s/%u via %s\" ", + nm_ip_route_get_dest (route), + nm_ip_route_get_prefix (route), + next_hop); + } + if (num > 0) + ifnet_set_data (conn_name, "routes", routes_string->str); + g_string_free (routes_string, TRUE); +} + +static gboolean +write_ip6_setting (NMConnection *connection, const char *conn_name, GError **error) +{ + NMSettingIPConfig *s_ip6; + const char *value; + guint32 i, num; + GString *searches; + NMIPAddress *addr; + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (!s_ip6) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing '%s' setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + return FALSE; + } + + value = nm_setting_ip_config_get_method (s_ip6); + g_assert (value); + if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { + ifnet_set_data (conn_name, "enable_ipv6", "false"); + return TRUE; + } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + /* nothing to do now */ + } else { + // if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { + const char *config = ifnet_get_data (conn_name, "config"); + gchar *tmp; + + if (!config) + tmp = g_strdup_printf ("dhcp6"); + else + tmp = g_strdup_printf ("%s\" \"dhcp6\"", config); + ifnet_set_data (conn_name, "config", tmp); + g_free (tmp); + } + /* else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) { + } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { + } */ + + /* Remember to set IPv6 enabled */ + ifnet_set_data (conn_name, "enable_ipv6", "true"); + + if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + const char *config = ifnet_get_data (conn_name, "config"); + gchar *tmp; + GString *ip_str; + + if (!config) + config = ""; + num = nm_setting_ip_config_get_num_addresses (s_ip6); + + /* IPv6 addresses */ + ip_str = g_string_new (NULL); + for (i = 0; i < num; i++) { + addr = nm_setting_ip_config_get_address (s_ip6, i); + + g_string_append_printf (ip_str, "\"%s/%u\"", + nm_ip_address_get_address (addr), + nm_ip_address_get_prefix (addr)); + } + tmp = g_strdup_printf ("%s\" %s", config, ip_str->str); + ifnet_set_data (conn_name, "config", tmp); + g_free (tmp); + g_string_free (ip_str, TRUE); + } + + /* DNS Servers */ + num = nm_setting_ip_config_get_num_dns (s_ip6); + if (num > 0) { + const char *dns_servers = ifnet_get_data (conn_name, "dns_servers"); + gchar *tmp; + GString *dns_string = g_string_new (NULL); + const char *dns; + + if (!dns_servers) + dns_servers = ""; + for (i = 0; i < num; i++) { + dns = nm_setting_ip_config_get_dns (s_ip6, i); + + if (!strstr (dns_servers, dns)) + g_string_append_printf (dns_string, "%s ", dns); + } + tmp = g_strdup_printf ("%s %s", dns_servers, dns_string->str); + ifnet_set_data (conn_name, "dns_servers", tmp); + g_free (tmp); + g_string_free (dns_string, TRUE); + + } else + /* DNS Searches */ + num = nm_setting_ip_config_get_num_dns_searches (s_ip6); + if (num > 0) { + const char *ip4_domains; + + ip4_domains = ifnet_get_data (conn_name, "dns_search"); + if (!ip4_domains) + ip4_domains = ""; + searches = g_string_new (ip4_domains); + for (i = 0; i < num; i++) { + const gchar *search = NULL; + + search = + nm_setting_ip_config_get_dns_search (s_ip6, i); + if (search && !strstr (searches->str, search)) { + if (searches->len > 0) + g_string_append_c (searches, ' '); + g_string_append (searches, search); + } + } + ifnet_set_data (conn_name, "dns_search", searches->str); + g_string_free (searches, TRUE); + } + + write_route6_file (s_ip6, conn_name); + return TRUE; +} + +static gboolean +write_pppoe_setting (const char *conn_name, NMSettingPppoe * s_pppoe) +{ + const gchar *value; + + value = nm_setting_pppoe_get_username (s_pppoe); + if (!value) { + return FALSE; + } + ifnet_set_data (conn_name, "username", (gchar *) value); + + value = nm_setting_pppoe_get_password (s_pppoe); + /* password could be NULL here */ + if (value) { + ifnet_set_data (conn_name, "password", (gchar *) value); + } + return TRUE; +} + +gboolean +ifnet_update_parsers_by_connection (NMConnection *connection, + const char *conn_name, + const char *config_file, + const char *wpa_file, + gchar **out_new_name, + gchar **out_backup, + GError **error) +{ + NMSettingConnection *s_con; + NMSettingIPConfig *s_ip6; + gboolean success = FALSE; + const char *type; + gboolean no_8021x = FALSE; + gboolean wired = FALSE, pppoe = TRUE; + const char *new_name = NULL; + + if (!ifnet_can_write_connection (connection, error)) + return FALSE; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + type = nm_setting_connection_get_connection_type (s_con); + if (!type) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing connection type!"); + goto out; + } + + if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) { + /* Writing wired setting */ + if (!write_wired_setting (connection, conn_name, error)) + goto out; + wired = TRUE; + no_8021x = TRUE; + } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) { + /* Writing wireless setting */ + if (!write_wireless_setting (connection, conn_name, &no_8021x, &new_name, error)) + goto out; + } else if (!strcmp (type, NM_SETTING_PPPOE_SETTING_NAME)) { + NMSettingPppoe *s_pppoe; + + /* Writing pppoe setting */ + s_pppoe = nm_connection_get_setting_pppoe (connection); + if (!write_pppoe_setting (conn_name, s_pppoe)) + goto out; + pppoe = TRUE; + wired = TRUE; + no_8021x = TRUE; + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, + "Can't write connection type '%s'", type); + goto out; + } + + /* connection name may have been updated; use it when writing out + * the rest of the settings. + */ + if (new_name) + conn_name = new_name; + + //FIXME wired connection doesn't support 8021x now + if (!no_8021x) { + if (!write_8021x_setting (connection, conn_name, wired, error)) + goto out; + } + + /* IPv4 Setting */ + if (!write_ip4_setting (connection, conn_name, error)) + goto out; + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (s_ip6) { + /* IPv6 Setting */ + if (!write_ip6_setting (connection, conn_name, error)) + goto out; + } + + /* Connection Setting */ + ifnet_set_data (conn_name, "auto", + nm_setting_connection_get_autoconnect (s_con) ? "true" : "false"); + ifnet_set_data (conn_name, "uuid", nm_connection_get_uuid (connection)); + + /* Write changes to disk */ + success = ifnet_flush_to_file (config_file, out_backup); + if (success) + wpa_flush_to_file (wpa_file); + + if (out_new_name) + *out_new_name = g_strdup (conn_name); + +out: + return success; +} + +gboolean +ifnet_delete_connection_in_parsers (const char *conn_name, + const char *config_file, + const char *wpa_file, + gchar **out_backup) +{ + gboolean result = FALSE; + + ifnet_delete_network (conn_name); + result = ifnet_flush_to_file (config_file, out_backup); + if (result) { + /* connection may not have security information + * so simply ignore the return value*/ + wpa_delete_security (conn_name); + wpa_flush_to_file (wpa_file); + } + + return result; +} + +static void +check_unsupported_secrets (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + gboolean *unsupported_secret = user_data; + + if (flags & NM_SETTING_PARAM_SECRET) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) + g_return_if_reached (); + if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) + *unsupported_secret = TRUE; + } +} + +gboolean +ifnet_can_write_connection (NMConnection *connection, GError **error) +{ + NMSettingConnection *s_con; + gboolean has_unsupported_secrets = FALSE; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + /* If the connection is not available for all users, ignore + * it as this plugin only deals with System Connections */ + if (nm_setting_connection_get_num_permissions (s_con)) { + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, + "The ifnet plugin does not support non-system-wide connections."); + return FALSE; + } + + /* Only support wired, wifi, and PPPoE */ + if ( !nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME) + && !nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME) + && !nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, + "The ifnet plugin cannot write the connection '%s' (type '%s')", + nm_connection_get_id (connection), + nm_setting_connection_get_connection_type (s_con)); + return FALSE; + } + + /* If the connection has flagged secrets, ignore + * it as this plugin does not deal with user agent service */ + nm_connection_for_each_setting_value (connection, + check_unsupported_secrets, + &has_unsupported_secrets); + if (has_unsupported_secrets) { + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, + "The ifnet plugin only supports persistent system secrets."); + return FALSE; + } + + return TRUE; +} + +/* get the available wired name(eth*). */ +static gchar * +get_wired_name (void) +{ + int i = 0; + + for (; i < 256; i++) { + gchar *conn_name = g_strdup_printf ("eth%d", i); + + if (!ifnet_has_network (conn_name)) { + return conn_name; + } else + g_free (conn_name); + } + return NULL; +} + +/* get the available pppoe name(ppp*). */ +static gchar * +get_ppp_name (void) +{ + int i = 0; + + for (; i < 256; i++) { + gchar *conn_name = g_strdup_printf ("ppp%d", i); + + if (!ifnet_has_network (conn_name)) { + return conn_name; + } else + g_free (conn_name); + } + return NULL; +} + +/* get wireless ssid */ +static gchar * +get_wireless_name (NMConnection * connection) +{ + NMSettingWireless *s_wireless; + GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; + gboolean hex_ssid = FALSE; + gchar *result = NULL; + char buf[33]; + int i = 0; + + s_wireless = nm_connection_get_setting_wireless (connection); + if (!s_wireless) + return NULL; + + ssid = nm_setting_wireless_get_ssid (s_wireless); + ssid_data = g_bytes_get_data (ssid, &ssid_len); + if (!ssid_len || ssid_len > 32) { + return NULL; + } + + for (i = 0; i < ssid_len; i++) { + if (!g_ascii_isprint (ssid_data[i])) { + hex_ssid = TRUE; + break; + } + } + + if (hex_ssid) { + GString *str; + + 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]); + result = g_strdup (str->str); + g_string_free (str, TRUE); + } else { + memset (buf, 0, sizeof (buf)); + memcpy (buf, ssid_data, ssid_len); + result = g_strdup_printf ("%s", buf); + g_strstrip (result); + } + + return result; +} + +gboolean +ifnet_add_new_connection (NMConnection *connection, + const char *config_file, + const char *wpa_file, + gchar **out_new_name, + gchar **out_backup, + GError **error) +{ + NMSettingConnection *s_con; + gboolean success = FALSE; + const char *type; + gchar *new_type, *new_name = NULL; + + if (!ifnet_can_write_connection (connection, error)) + return FALSE; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + type = nm_setting_connection_get_connection_type (s_con); + g_assert (type); + + nm_log_info (LOGD_SETTINGS, "Adding %s connection", type); + + /* get name and type + * Wireless type: wireless + * Wired type: wired + * PPPoE type: ppp*/ + if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) { + new_name = get_wired_name (); + if (!new_name) + goto out; + new_type = "wired"; + } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) { + new_name = get_wireless_name (connection); + new_type = "wireless"; + } else if (!strcmp (type, NM_SETTING_PPPOE_SETTING_NAME)) { + new_name = get_ppp_name (); + if (!new_name) + goto out; + new_type = "ppp"; + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, + "Can't write connection type '%s'", type); + goto out; + } + + if (ifnet_add_network (new_name, new_type)) { + success = ifnet_update_parsers_by_connection (connection, + new_name, + config_file, + wpa_file, + NULL, + out_backup, + error); + } + + nm_log_info (LOGD_SETTINGS, "Added new connection: %s, result: %s", + new_name, success ? "success" : "fail"); + +out: + if (!success || !out_new_name) + g_free (new_name); + else if (out_new_name) + *out_new_name = new_name; + return success; +} + diff --git a/src/settings/plugins/ifnet/nms-ifnet-connection-parser.h b/src/settings/plugins/ifnet/nms-ifnet-connection-parser.h new file mode 100644 index 00000000..51bc34b9 --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-connection-parser.h @@ -0,0 +1,55 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef _CONNECTION_PARSER_H +#define _CONNECTION_PARSER_H + +#include "nm-connection.h" + +#include "nms-ifnet-net-parser.h" + +gboolean ifnet_can_write_connection (NMConnection *connection, GError **error); + +NMConnection *ifnet_update_connection_from_config_block (const char *conn_name, + const char *basepath, + GError **error); + +/* nm_conn_name is used to update nm_ifnet_connection's priv data */ +gboolean ifnet_update_parsers_by_connection (NMConnection *connection, + const char *conn_name, + const char *config_file, + const char *wpa_file, + gchar **out_new_name, + gchar **out_backup, + GError **error); + +gboolean ifnet_delete_connection_in_parsers (const char *conn_name, + const char *config_file, + const char *wpa_file, + gchar **out_backup); + +gboolean ifnet_add_new_connection (NMConnection *connection, + const char *config_file, + const char *wpa_file, + gchar **out_new_name, + gchar **out_backup, + GError ** error); +#endif diff --git a/src/settings/plugins/ifnet/nms-ifnet-connection.c b/src/settings/plugins/ifnet/nms-ifnet-connection.c new file mode 100644 index 00000000..ce0b3f2b --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-connection.c @@ -0,0 +1,233 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include "nm-default.h" + +#include "nms-ifnet-connection.h" + +#include +#include + +#include "nm-dbus-interface.h" +#include "nm-utils.h" +#include "nm-setting-wireless-security.h" +#include "settings/nm-settings-connection.h" +#include "settings/nm-settings-plugin.h" + +#include "nms-ifnet-connection-parser.h" +#include "nms-ifnet-net-parser.h" +#include "nms-ifnet-net-utils.h" +#include "nms-ifnet-wpa-parser.h" +#include "nms-ifnet-plugin.h" + +/*****************************************************************************/ + +enum { + IFNET_SETUP_MONITORS, + IFNET_CANCEL_MONITORS, + IFNET_LAST_SIGNAL +}; + +static guint signals[IFNET_LAST_SIGNAL] = { 0 }; + +typedef struct { + gchar *conn_name; + NMSettingsPlugin *config; +} NMIfnetConnectionPrivate; + +struct _NMIfnetConnection { + NMSettingsConnection parent; + NMIfnetConnectionPrivate _priv; +}; + +struct _NMIfnetConnectionClass { + NMSettingsConnectionClass parent; +}; + +G_DEFINE_TYPE (NMIfnetConnection, nm_ifnet_connection, NM_TYPE_SETTINGS_CONNECTION) + +#define NM_IFNET_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMIfnetConnection, NM_IS_IFNET_CONNECTION) + +/*****************************************************************************/ + +const char * +nm_ifnet_connection_get_conn_name (NMIfnetConnection *connection) +{ + return NM_IFNET_CONNECTION_GET_PRIVATE (connection)->conn_name; +} + +static gboolean +commit_changes (NMSettingsConnection *connection, + NMConnection *new_connection, + NMSettingsConnectionCommitReason commit_reason, + NMConnection **out_reread_connection, + char **out_logmsg_change, + GError **error) +{ + NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) connection); + char *new_name = NULL; + gboolean success = FALSE; + gboolean added = FALSE; + + nm_assert (out_reread_connection && !*out_reread_connection); + nm_assert (!out_logmsg_change || !*out_logmsg_change); + + g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0); + + if (priv->conn_name) { + success = ifnet_update_parsers_by_connection (new_connection, + priv->conn_name, + CONF_NET_FILE, + WPA_SUPPLICANT_CONF, + &new_name, + NULL, + error); + } else { + added = TRUE; + success = ifnet_add_new_connection (new_connection, + CONF_NET_FILE, + WPA_SUPPLICANT_CONF, + &new_name, + NULL, + error); + } + + g_assert (!!success == (new_name != NULL)); + if (success) { + g_free (priv->conn_name); + priv->conn_name = new_name; + } + + reload_parsers (); + + g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); + + if (success) { + NM_SET_OUT (out_logmsg_change, + g_strdup_printf ("ifcfg-rh: %s %s", + added ? "persist" : "updated", + new_name)); + } + return success; +} + +static gboolean +delete (NMSettingsConnection *connection, + GError **error) +{ + NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) connection); + + /* Only connections which exist in /etc/conf.d/net will have a conn_name */ + if (priv->conn_name) { + g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0); + + if (!ifnet_delete_connection_in_parsers (priv->conn_name, CONF_NET_FILE, WPA_SUPPLICANT_CONF, NULL)) { + nm_log_warn (LOGD_SETTINGS, "Failed to delete %s", priv->conn_name); + reload_parsers (); + /* let's not return an error. */ + } + + g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +nm_ifnet_connection_init (NMIfnetConnection * connection) +{ +} + +NMIfnetConnection * +nm_ifnet_connection_new (NMConnection *source, const char *conn_name) +{ + NMConnection *tmp; + GObject *object; + GError *error = NULL; + gboolean update_unsaved = TRUE; + + g_return_val_if_fail (source || conn_name, NULL); + + if (source) + tmp = g_object_ref (source); + else { + tmp = ifnet_update_connection_from_config_block (conn_name, NULL, &error); + if (!tmp) { + nm_log_warn (LOGD_SETTINGS, "Could not read connection '%s': %s", + conn_name, error->message); + g_error_free (error); + return NULL; + } + + /* If we just read the connection from disk, it's clearly not Unsaved */ + update_unsaved = FALSE; + } + + object = (GObject *) g_object_new (NM_TYPE_IFNET_CONNECTION, NULL); + + NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) object)->conn_name = g_strdup (conn_name); + if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (object), + tmp, + update_unsaved + ? NM_SETTINGS_CONNECTION_PERSIST_MODE_UNSAVED + : NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP_SAVED, + NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, + NULL, + NULL)) { + g_object_unref (object); + return NULL; + } + g_object_unref (tmp); + + return NM_IFNET_CONNECTION (object); +} + +static void +finalize (GObject * object) +{ + g_free (NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) object)->conn_name); + G_OBJECT_CLASS (nm_ifnet_connection_parent_class)->finalize (object); +} + +static void +nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (ifnet_connection_class); + NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (ifnet_connection_class); + + object_class->finalize = finalize; + + settings_class->delete = delete; + settings_class->commit_changes = commit_changes; + + signals[IFNET_SETUP_MONITORS] = + g_signal_new ("ifnet_setup_monitors", + G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, + 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + signals[IFNET_CANCEL_MONITORS] = + g_signal_new ("ifnet_cancel_monitors", + G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, + 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} diff --git a/src/settings/plugins/ifnet/nms-ifnet-connection.h b/src/settings/plugins/ifnet/nms-ifnet-connection.h new file mode 100644 index 00000000..1bc06644 --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-connection.h @@ -0,0 +1,46 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef __NETWORKMANAGER_IFNET_CONNECTION_H__ +#define __NETWORKMANAGER_IFNET_CONNECTION_H__ + +#include "settings/nm-settings-connection.h" + +#include "nms-ifnet-net-parser.h" + +#define NM_TYPE_IFNET_CONNECTION (nm_ifnet_connection_get_type ()) +#define NM_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnection)) +#define NM_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass)) +#define NM_IS_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFNET_CONNECTION)) +#define NM_IS_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IFNET_CONNECTION)) +#define NM_IFNET_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass)) + +typedef struct _NMIfnetConnection NMIfnetConnection; +typedef struct _NMIfnetConnectionClass NMIfnetConnectionClass; + +GType nm_ifnet_connection_get_type (void); + +NMIfnetConnection *nm_ifnet_connection_new (NMConnection *source, + const char *conn_name); + +const char *nm_ifnet_connection_get_conn_name (NMIfnetConnection *connection); + +#endif /* __NETWORKMANAGER_IFNET_CONNECTION_H__ */ diff --git a/src/settings/plugins/ifnet/nms-ifnet-net-parser.c b/src/settings/plugins/ifnet/nms-ifnet-net-parser.c new file mode 100644 index 00000000..d3e47219 --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-net-parser.c @@ -0,0 +1,734 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include "nm-default.h" + +#include "nms-ifnet-net-parser.h" + +#include +#include +#include +#include + +#include "settings/nm-settings-plugin.h" +#include "platform/nm-platform.h" + +#include "nms-ifnet-plugin.h" +#include "nms-ifnet-net-utils.h" + +/* Save all the connection information */ +static GHashTable *conn_table; + +/* Save global settings which are used for writing*/ +static GHashTable *global_settings_table; + +/* Save functions */ +static GList *functions_list; + +/* Used to decide whether to write changes to file*/ +static gboolean net_parser_data_changed = FALSE; + +static GHashTable * +add_new_connection_config (const gchar * type, const gchar * name) +{ + GHashTable *new_conn; + gchar *new_name; + + if (!name) + return NULL; + + /* Return existing connection */ + if ((new_conn = g_hash_table_lookup (conn_table, name)) != NULL) + return new_conn; + new_conn = g_hash_table_new (nm_str_hash, g_str_equal); + new_name = g_strdup (name); + g_hash_table_insert (new_conn, g_strdup ("name"), new_name); + g_hash_table_insert (new_conn, g_strdup ("type"), g_strdup (type)); + g_hash_table_insert (conn_table, new_name, new_conn); + return new_conn; +} + +gboolean +ifnet_add_network (const char *name, const char *type) +{ + if (ifnet_has_network (name)) + return TRUE; + if (add_new_connection_config (type, name)) { + nm_log_info (LOGD_SETTINGS, "Adding network for %s", name); + net_parser_data_changed = TRUE; + return TRUE; + } + return FALSE; +} + +gboolean +ifnet_has_network (const char *conn_name) +{ + return g_hash_table_lookup (conn_table, conn_name) != NULL; +} + +static GHashTable * +get_connection_config (const char *name) +{ + return g_hash_table_lookup (conn_table, name); +} + +/* Ignored name won't be treated as wireless ssid */ +static gchar *ignore_name[] = { + "vlan", "bond", "atm", "ath", "ippp", "vpn", "tap", "tun", "1", + "br", "nas", "6to4", "timeout", "kvm", "force", NULL +}; + +static gboolean +ignore_connection_name (const char *name) +{ + gboolean result = FALSE; + guint i = 0; + + /* check ignore_name list */ + while (ignore_name[i] != NULL) { + if (g_ascii_strncasecmp + (name, ignore_name[i], strlen (ignore_name[i])) == 0) { + return TRUE; + } + i++; + } + /* Ignore mac address based configuration */ + if (strlen (name) == 12 && is_hex (name)) + result = TRUE; + return result; +} + +static gboolean +is_global_setting (char *key) +{ + static gchar *global_settings[] = { "wpa_supplicant_", NULL }; + int i; + + for (i = 0; global_settings[i] != NULL; i++) { + if (strstr (key, global_settings[i])) + return 1; + } + return 0; +} + +/* Parse a complete line */ +/* Connection type is determined here */ +static void +init_block_by_line (gchar * buf) +{ + gchar **key_value; + gchar *pos; + gchar *data; + gchar *tmp; + GHashTable *conn; + + key_value = g_strsplit (buf, "=", 2); + if (g_strv_length (key_value) != 2) { + nm_log_warn (LOGD_SETTINGS, "Can't handle this line: %s\n", buf); + g_strfreev (key_value); + return; + } + pos = g_strrstr (key_value[0], "_"); + if (pos == NULL || is_global_setting (key_value[0])) { + /* global data */ + data = g_strdup (key_value[1]); + tmp = strip_string (data, '"'); + strip_string (tmp, '\''); + nm_log_info (LOGD_SETTINGS, "global:%s-%s\n", key_value[0], tmp); + g_hash_table_insert (global_settings_table, g_strdup (key_value[0]), g_strdup (tmp)); + g_strfreev (key_value); + g_free (data); + return; + } + *pos++ = '\0'; + if ((conn = get_connection_config (pos)) == NULL) { + if (g_ascii_strncasecmp (pos, "eth", 3) == 0 + && strlen (pos) == 4) + /* wired connection */ + conn = add_new_connection_config ("wired", pos); + else if (g_ascii_strncasecmp (pos, "ppp", 3) == 0 + && strlen (pos) == 4) + /* pppoe connection */ + conn = add_new_connection_config ("ppp", pos); + else if (ignore_connection_name (pos)) { + /* ignored connection */ + conn = add_new_connection_config ("ignore", pos); + } else { + int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, pos); + + if (ifindex && nm_platform_link_get_type (NM_PLATFORM_GET, ifindex) != NM_LINK_TYPE_WIFI) + /* wired connection */ + conn = add_new_connection_config ("wired", pos); + else + /* wireless connection */ + conn = add_new_connection_config ("wireless", pos); + } + } + data = g_strdup (key_value[1]); + tmp = strip_string (data, '"'); + strip_string (tmp, '\''); + if (conn) + g_hash_table_insert (conn, strip_string (g_strdup (key_value[0]), ' '), + g_strdup (tmp)); + g_free (data); + g_strfreev (key_value); +} + +static void +destroy_connection_config (GHashTable * conn) +{ + gpointer key, value; + GHashTableIter iter; + + g_hash_table_iter_init (&iter, conn); + while (g_hash_table_iter_next (&iter, &key, &value)) { + g_free (key); + g_free (value); + } + + g_hash_table_destroy (conn); +} + +static void +strip_function (GIOChannel * channel, gchar * line) +{ + + int counter = 0; + gchar *p, *tmp; + gboolean begin = FALSE; + GString *function_str = g_string_new (line); + + g_string_append (function_str, "\n"); + while (1) { + p = line; + while (*p != '\0') { + if (*p == '{') { + counter++; + begin = TRUE; + } else if (*p == '}') + counter--; + p++; + } + if (begin && counter == 0) { + g_free (line); + goto done; + } + while (1) { + g_free (line); + if (g_io_channel_read_line + (channel, &line, NULL, NULL, + NULL) == G_IO_STATUS_EOF) + goto done; + g_string_append (function_str, line); + tmp = g_strdup (line); + g_strstrip (tmp); + if (tmp[0] != '#' && tmp[0] != '\0') { + g_free (tmp); + break; + } else + g_free (tmp); + } + } +done: + functions_list = + g_list_append (functions_list, g_strdup (function_str->str)); + g_string_free (function_str, TRUE); +} + +static gboolean +is_function (gchar * line) +{ + static gchar *func_names[] = + { "preup", "predown", "postup", "postdown", "failup", "faildown", + NULL, + }; + int i; + + for (i = 0; func_names[i]; i++) { + if (g_str_has_prefix (line, func_names[i])) { + nm_log_info (LOGD_SETTINGS, "Ignoring function: %s", func_names[i]); + return TRUE; + } + } + return FALSE; +} + +static void +append_line (GString *buf, gchar* line) +{ + gchar *pos = NULL; + + if ((pos = strchr (line, '#')) != NULL) + *pos = '\0'; + g_strstrip (line); + + if (line[0] != '\0') + g_string_append_printf (buf, " %s", line); + g_free (line); +} + +gboolean +ifnet_init (gchar * config_file) +{ + GIOChannel *channel = NULL; + gchar *line; + + /* Handle multiple lines with brackets */ + gboolean complete = TRUE; + + gboolean openrc_style = TRUE; + + /* line buffer */ + GString *buf; + + net_parser_data_changed = FALSE; + + conn_table = g_hash_table_new (nm_str_hash, g_str_equal); + global_settings_table = g_hash_table_new (nm_str_hash, g_str_equal); + functions_list = NULL; + + if (g_file_test (config_file, G_FILE_TEST_IS_REGULAR)) + channel = g_io_channel_new_file (config_file, "r", NULL); + if (channel == NULL) { + nm_log_warn (LOGD_SETTINGS, "Can't open %s", config_file); + return FALSE; + } + + buf = g_string_new (NULL); + while (g_io_channel_read_line + (channel, &line, NULL, NULL, NULL) != G_IO_STATUS_EOF) { + g_strstrip (line); + /* convert multiple lines to a complete line and + * pass it to init_block_by_line() */ + if (is_function (line)) { + strip_function (channel, line); + continue; + } + + // New openrc style, bash arrays are not allowed. We only care about '"' + if (openrc_style && line[0] != '#' && line[0] != '\0' + && !strchr (line, '(') && !strchr (line, ')')) { + gchar *tmp = line; + + while ((tmp = strchr (tmp, '"')) != NULL) { + complete = !complete; + ++tmp; + } + + append_line (buf, line); + // Add "(separator) for routes. It will be easier for later parsing + if (strstr (buf->str, "via")) + g_string_append_printf (buf, "\""); + + if (!complete) + continue; + + strip_string (buf->str, '"'); + + init_block_by_line (buf->str); + g_string_free (buf, TRUE); + buf = g_string_new (NULL); + } + // Old bash arrays for baselayout-1, to be deleted + else if (line[0] != '#' && line[0] != '\0') { + if (!complete) { + complete = + g_strrstr (line, + ")") == NULL ? FALSE : TRUE; + + append_line (buf, line); + if (!complete) { + openrc_style = FALSE; + continue; + } + else { + openrc_style = TRUE; + } + } else { + complete = + (g_strrstr (line, "(") != NULL + && g_strrstr (line, ")") != NULL) + || g_strrstr (line, "(") == NULL; + + append_line (buf, line); + if (!complete) + { + openrc_style = FALSE; + continue; + } else { + openrc_style = TRUE; + } + } + init_block_by_line (buf->str); + g_string_free (buf, TRUE); + buf = g_string_new (NULL); + } else + /* Blank line or comment line */ + g_free (line); + } + + g_string_free (buf, TRUE); + g_io_channel_shutdown (channel, FALSE, NULL); + g_io_channel_unref (channel); + return TRUE; +} + +const char * +ifnet_get_data (const char *conn_name, const char *key) +{ + GHashTable *conn; + + g_return_val_if_fail (conn_name && key, NULL); + + conn = g_hash_table_lookup (conn_table, conn_name); + + if (conn) + return g_hash_table_lookup (conn, key); + return NULL; +} + +/* format ip values for comparison */ +static gchar* +format_ip_for_comparison (const gchar * value) +{ + gchar **ipset; + guint length, i; + GString *formated_string = g_string_new (NULL); + gchar *formatted = NULL; + + ipset = g_strsplit (value, "\"", 0); + length = g_strv_length (ipset); + + for (i = 0; i < length; i++) + { + strip_string (ipset[i], ' '); + if (ipset[i][0] != '\0') + g_string_append_printf (formated_string, + "%s ", ipset[i]); + } + formatted = g_strdup (formated_string->str); + formatted[formated_string->len - 1] = '\0'; + + g_string_free (formated_string, TRUE); + g_strfreev (ipset); + + return formatted; +} + +void +ifnet_set_data (const char *conn_name, const char *key, const char *value) +{ + gpointer old_key = NULL, old_value = NULL; + GHashTable *conn = g_hash_table_lookup (conn_table, conn_name); + gchar * stripped = NULL; + + if (!conn) { + nm_log_warn (LOGD_SETTINGS, "%s does not exist!", conn_name); + return; + } + if (value){ + stripped = g_strdup (value); + strip_string (stripped, '"'); + } + /* Remove existing key value pair */ + if (g_hash_table_lookup_extended (conn, key, &old_key, &old_value)) { + + /* This ugly hack is due to baselayout compatibility. We have to + * deal with different ip format. So sometimes we have the same ips + * but different strings. + */ + if (stripped && + (!strcmp (key, "config") + || !strcmp (key, "routes") + || !strcmp (key, "pppd") + || !strcmp (key, "chat"))) + { + gchar *old_ips = format_ip_for_comparison (old_value); + gchar *new_ips = format_ip_for_comparison (value); + if(!strcmp (old_ips, new_ips)) + { + g_free (stripped); + g_free (old_ips); + g_free (new_ips); + return; + } + g_free (old_ips); + g_free (new_ips); + } + + if (stripped && !strcmp (old_value, stripped)) { + g_free (stripped); + return; + } + g_hash_table_remove (conn, old_key); + g_free (old_key); + g_free (old_value); + } else if (!value) + return; + if (stripped) + g_hash_table_insert (conn, g_strdup (key), stripped); + net_parser_data_changed = TRUE; +} + +// Remember to free return value +const char * +ifnet_get_global_data (const gchar * key) +{ + return g_hash_table_lookup (global_settings_table, key); +} + +// Return names of legal connections +GList * +ifnet_get_connection_names (void) +{ + GList *names = g_hash_table_get_keys (conn_table); + GList *iter, *result = NULL; + + for (iter = names; iter; iter = iter->next) { + if (!ignore_connection_name (iter->data)) + result = g_list_prepend (result, iter->data); + } + + g_list_free (names); + return g_list_reverse (result); +} + +/* format IP and route for writing */ +static void +format_ips (gchar * value, gchar ** out_line, gchar * key, gchar * name) +{ + gchar **ipset; + guint length, i; + GString *formated_string = g_string_new (NULL); + + strip_string (value, '('); + strip_string (value, ')'); + strip_string (value, '"'); + ipset = g_strsplit (value, "\"", 0); + length = g_strv_length (ipset); + + //only one line + if (length < 2) { + *out_line = + g_strdup_printf ("%s_%s=\"%s\"\n", key, name, value); + goto done; + } + // Multiple lines + g_string_append_printf (formated_string, "%s_%s=\"\n", key, name); + for (i = 0; i < length; i++) + { + strip_string (ipset[i], ' '); + if (ipset[i][0] != '\0') + g_string_append_printf (formated_string, + "%s\n", ipset[i]); + } + g_string_append (formated_string, "\"\n"); + *out_line = g_strdup (formated_string->str); +done: + g_string_free (formated_string, TRUE); + g_strfreev (ipset); +} + +gboolean +ifnet_flush_to_file (const char *config_file, gchar **out_backup) +{ + GIOChannel *channel; + GError *error = NULL; + gpointer key, value, name, network; + GHashTableIter iter, iter_network; + GList *list_iter; + gchar *out_line = NULL; + gsize bytes_written; + gboolean result = FALSE; + gchar *backup; + + if (!net_parser_data_changed) + return TRUE; + if (!conn_table || !global_settings_table) + return FALSE; + + backup = backup_file (config_file); + + channel = g_io_channel_new_file (config_file, "w", NULL); + if (!channel) { + nm_log_warn (LOGD_SETTINGS, "Can't open file %s for writing", config_file); + g_free (backup); + return FALSE; + } + g_hash_table_iter_init (&iter, global_settings_table); + nm_log_info (LOGD_SETTINGS, "Writing to %s", config_file); + g_io_channel_write_chars (channel, + "#Generated by NetworkManager\n" + "###### Global Configuration ######\n", + -1, &bytes_written, &error); + if (error) + goto done; + + /* Writing global data */ + while (g_hash_table_iter_next (&iter, &key, &value)) { + out_line = + g_strdup_printf ("%s=\"%s\"\n", (gchar *) key, (gchar *) value); + g_io_channel_write_chars (channel, out_line, -1, + &bytes_written, &error); + if (bytes_written == 0 || error) + goto done; + g_free (out_line); + } + + /* Writing connection data */ + g_io_channel_write_chars (channel, + "\n###### Connection Configuration ######\n", + -1, &bytes_written, &error); + if (error) + goto done; + + g_hash_table_iter_init (&iter, conn_table); + while (g_hash_table_iter_next (&iter, &name, &network)) { + g_hash_table_iter_init (&iter_network, (GHashTable *) network); + g_io_channel_write_chars (channel, + "#----------------------------------\n", + -1, &bytes_written, &error); + if (error) + goto done; + + while (g_hash_table_iter_next (&iter_network, &key, &value)) { + if (!g_str_has_prefix ((gchar *) key, "name") + && !g_str_has_prefix ((gchar *) key, "type")) { + /* These keys contain brackets */ + if (strcmp + ((gchar *) key, + "config") == 0 + || strcmp ((gchar *) key, + "routes") == 0 + || strcmp ((gchar *) key, + "pppd") == 0 + || strcmp ((gchar *) key, "chat") == 0) + format_ips (value, &out_line, (gchar *) + key, (gchar *) + name); + else + out_line = + g_strdup_printf + ("%s_%s=\"%s\"\n", + (gchar *) key, + (gchar *) name, (gchar *) value); + g_io_channel_write_chars (channel, out_line, -1, &bytes_written, &error); + if (bytes_written == 0 || error) + goto done; + g_free (out_line); + } + } + } + + /* Writing reserved functions */ + if (functions_list) { + g_io_channel_write_chars (channel, + "\n###### Reserved Functions ######\n", + -1, &bytes_written, &error); + if (error) + goto done; + + /* Writing functions */ + for (list_iter = functions_list; list_iter; + list_iter = g_list_next (list_iter)) { + out_line = + g_strdup_printf ("%s\n", (gchar *) list_iter->data); + g_io_channel_write_chars (channel, out_line, -1, + &bytes_written, &error); + if (bytes_written == 0 || error) + goto done; + g_free (out_line); + } + } + + g_io_channel_flush (channel, &error); + if (error) + goto done; + result = TRUE; + net_parser_data_changed = FALSE; + +done: + if (error) { + nm_log_warn (LOGD_SETTINGS, "Error writing the configuration file: %s", error->message); + g_error_free (error); + } + + if (result && out_backup) + *out_backup = backup; + else + g_free (backup); + + g_io_channel_shutdown (channel, FALSE, NULL); + g_io_channel_unref (channel); + return result; +} + +gboolean +ifnet_delete_network (const char *conn_name) +{ + GHashTable *network = NULL; + + g_return_val_if_fail (conn_table != NULL && conn_name != NULL, FALSE); + nm_log_info (LOGD_SETTINGS, "Deleting network for %s", conn_name); + network = g_hash_table_lookup (conn_table, conn_name); + if (!network) + return FALSE; + g_hash_table_remove (conn_table, conn_name); + destroy_connection_config (network); + net_parser_data_changed = TRUE; + return TRUE; +} + +void +ifnet_destroy (void) +{ + GHashTableIter iter; + gpointer key; + gpointer value; + GList *list_iter; + + /* Destroy connection setting */ + if (conn_table) { + g_hash_table_iter_init (&iter, conn_table); + while (g_hash_table_iter_next (&iter, &key, &value)) { + destroy_connection_config ((GHashTable *) + value); + } + g_hash_table_destroy (conn_table); + conn_table = NULL; + } + + /* Destroy global data */ + if (global_settings_table) { + g_hash_table_iter_init (&iter, global_settings_table); + while (g_hash_table_iter_next (&iter, &key, &value)) { + g_free (key); + g_free (value); + } + g_hash_table_destroy (global_settings_table); + global_settings_table = NULL; + } + for (list_iter = functions_list; list_iter; + list_iter = g_list_next (list_iter)) + g_free (list_iter->data); + g_list_free (functions_list); +} diff --git a/src/settings/plugins/ifnet/nms-ifnet-net-parser.h b/src/settings/plugins/ifnet/nms-ifnet-net-parser.h new file mode 100644 index 00000000..31fc9ead --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-net-parser.h @@ -0,0 +1,42 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef _NET_PARSER_H +#define _NET_PARSER_H + +#define CONF_NET_FILE SYSCONFDIR "/conf.d/net" + +gboolean ifnet_init (gchar * config_file); +void ifnet_destroy (void); + +/* Reader functions */ +GList *ifnet_get_connection_names (void); +const char *ifnet_get_data (const char *conn_name, const char *key); +const char *ifnet_get_global_data (const char *key); +gboolean ifnet_has_network (const char *conn_name); + +/* Writer functions */ +gboolean ifnet_flush_to_file (const char *config_file, gchar **out_backup); +void ifnet_set_data (const char *conn_name, const char *key, const char *value); +gboolean ifnet_add_network (const char *name, const char *type); +gboolean ifnet_delete_network (const char *conn_name); + +#endif diff --git a/src/settings/plugins/ifnet/nms-ifnet-net-utils.c b/src/settings/plugins/ifnet/nms-ifnet-net-utils.c new file mode 100644 index 00000000..6531a238 --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-net-utils.c @@ -0,0 +1,830 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include "nm-default.h" + +#include "nms-ifnet-net-utils.h" + +#include +#include +#include +#include + +#include "nm-utils.h" +#include "NetworkManagerUtils.h" +#include "settings/nm-settings-plugin.h" +#include "nm-config.h" +#include "dhcp/nm-dhcp-manager.h" + +#include "nms-ifnet-wpa-parser.h" +#include "nms-ifnet-net-parser.h" + +/* emit heading and tailing blank space, tab, character t */ +gchar * +strip_string (gchar * str, gchar t) +{ + gchar *ret = str; + gint length = 0; + guint i = 0; + + while (ret[i] != '\0' + && (ret[i] == '\t' || ret[i] == ' ' || ret[i] == t)) { + length++; + i++; + } + i = 0; + while (ret[i + length] != '\0') { + ret[i] = ret[i + length]; + i++; + } + ret[i] = '\0'; + length = strlen (ret); + while ((length - 1) >= 0 + && (ret[length - 1] == ' ' || ret[length - 1] == '\n' + || ret[length - 1] == '\t' || ret[length - 1] == t)) + length--; + ret[length] = '\0'; + return ret; +} + +gboolean +is_hex (const char *value) +{ + const char *p = value; + + if (!p) + return FALSE; + while (*p) { + if (!g_ascii_isxdigit (*p++)) + return FALSE; + } + return TRUE; +} + +gboolean +is_ascii (const char *value) +{ + const char *p = value; + + while (*p) { + if (!g_ascii_isprint (*p++)) + return FALSE; + } + return TRUE; + +} + +gboolean +is_true (const char *str) +{ + if (!g_ascii_strcasecmp (str, "yes") + || !g_ascii_strcasecmp (str, "true")) + return TRUE; + return FALSE; +} + +static char * +find_default_gateway_str (char *str) +{ + char *tmp; + + if ((tmp = strstr (str, "default via ")) != NULL) { + return tmp + strlen ("default via "); + } else if ((tmp = strstr (str, "default gw ")) != NULL) { + return tmp + strlen ("default gw "); + } + return NULL; +} + +static char * +find_gateway_str (char *str) +{ + char *tmp; + + if ((tmp = strstr (str, "via ")) != NULL) { + return tmp + strlen ("via "); + } else if ((tmp = strstr (str, "gw ")) != NULL) { + return tmp + strlen ("gw "); + } + return NULL; +} + +gboolean +reload_parsers (void) +{ + ifnet_destroy (); + wpa_parser_destroy (); + if (!ifnet_init (CONF_NET_FILE)) + return FALSE; + wpa_parser_init (WPA_SUPPLICANT_CONF); + return TRUE; +} + +gboolean +is_static_ip4 (const char *conn_name) +{ + const char *data = ifnet_get_data (conn_name, "config"); + const char *dhcp6; + + if (!data) + return FALSE; + if (!strcmp (data, "shared")) + return FALSE; + if (!strcmp (data, "autoip")) + return FALSE; + dhcp6 = strstr (data, "dhcp6"); + if (dhcp6) { + gchar *dhcp4; + + if (strstr (data, "dhcp ")) + return FALSE; + dhcp4 = strstr (data, "dhcp"); + if (!dhcp4) + return TRUE; + if (dhcp4[4] == '\0') + return FALSE; + return TRUE; + } + return strstr (data, "dhcp") == NULL ? TRUE : FALSE; +} + +gboolean +is_static_ip6 (const char *conn_name) +{ + const char *data = ifnet_get_data (conn_name, "config"); + + if (!data) + return TRUE; + return strstr (data, "dhcp6") == NULL ? TRUE : FALSE; +} + +gboolean +is_ip4_address (const char *in_address) +{ + const char *pattern = + "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.((\\{\\d{1,3}\\.\\.\\d{1,3}\\})|\\d{1,3})$"; + gchar *address = g_strdup (in_address); + gboolean result = FALSE; + gchar *tmp; + GRegex *regex = g_regex_new (pattern, 0, 0, NULL); + GMatchInfo *match_info = NULL; + + if (!address) + goto done; + g_strstrip (address); + if ((tmp = strstr (address, "/")) != NULL) + *tmp = '\0'; + if ((tmp = strstr (address, " ")) != NULL) + *tmp = '\0'; + g_regex_match (regex, address, 0, &match_info); + result = g_match_info_matches (match_info); +done: + if (match_info) + g_match_info_free (match_info); + g_regex_unref (regex); + g_free (address); + return result; +} + +gboolean +is_ip6_address (const char *in_address) +{ + struct in6_addr tmp_ip6_addr; + gchar *tmp, *address; + gboolean result = FALSE; + + if (!in_address) + return FALSE; + address = g_strdup (in_address); + g_strstrip (address); + if ((tmp = strchr (address, '/')) != NULL) + *tmp = '\0'; + if (inet_pton (AF_INET6, address, &tmp_ip6_addr)) + result = TRUE; + g_free (address); + return result; + +} + +// 'c' is only used for openrc style +static gchar ** +split_addresses_by_char (const gchar *addresses, const gchar *c) +{ + gchar **ipset; + + if (addresses == NULL) + return NULL; + + if (strchr (addresses, '(') != NULL) { // old baselayout style + gchar *tmp = g_strdup (addresses); + strip_string (tmp, '('); + strip_string (tmp, ')'); + strip_string (tmp, '"'); + strip_string (tmp, '\''); + ipset = g_strsplit (tmp, "\" \"", 0); + g_free(tmp); + } else { // openrc style + if (strstr (addresses, "netmask")) + // There is only one ip address if "netmask" is specified. + // '\n' is not used in config so there will be only one split. + ipset = g_strsplit (addresses, "\n", 0); + else + ipset = g_strsplit (addresses, c, 0); + } + + return ipset; +} + +static gchar ** +split_addresses (const gchar* addresses) +{ + // " " is only used by openrc style + return split_addresses_by_char (addresses, " "); +} + +static gchar ** +split_routes (const gchar* routes) +{ + // "\"" is only used by openrc style + return split_addresses_by_char (routes, "\""); +} + +gboolean +has_ip6_address (const char *conn_name) +{ + gchar **ipset; + guint length; + guint i; + + g_return_val_if_fail (conn_name != NULL, FALSE); + ipset = split_addresses (ifnet_get_data (conn_name, "config")); + length = ipset ? g_strv_length (ipset) : 0; + for (i = 0; i < length; i++) { + if (!is_ip6_address (ipset[i])) + continue; + else { + g_strfreev (ipset); + return TRUE; + } + + } + g_strfreev (ipset); + return FALSE; +} + +gboolean +has_default_route (const char *conn_name, gboolean (*check_fn) (const char *)) +{ + char *routes = NULL, *end, *tmp; + gboolean success = FALSE; + + g_return_val_if_fail (conn_name != NULL, FALSE); + + routes = g_strdup (ifnet_get_data (conn_name, "routes")); + if (!routes) + return FALSE; + tmp = find_default_gateway_str (routes); + if (tmp) { + g_strstrip (tmp); + if ((end = strstr (tmp, "\"")) != NULL) + *end = '\0'; + if (check_fn (tmp)) + success = TRUE; + } + + g_free (routes); + return success; +} + +static ip_block * +create_ip4_block (gchar * ip) +{ + ip_block *iblock = g_slice_new0 (ip_block); + guint32 tmp_ip4_addr; + int i; + guint length; + gchar **ip_mask; + + /* prefix format */ + if (strstr (ip, "/")) { + gchar *prefix; + + ip_mask = g_strsplit (ip, "/", 0); + length = g_strv_length (ip_mask); + if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0])) + goto error; + iblock->ip = g_strdup (ip_mask[0]); + prefix = ip_mask[1]; + i = 0; + while (i < length && g_ascii_isdigit (prefix[i])) + i++; + prefix[i] = '\0'; + iblock->prefix = (guint32) atoi (ip_mask[1]); + } else if (strstr (ip, "netmask")) { + ip_mask = g_strsplit (ip, " ", 0); + length = g_strv_length (ip_mask); + if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0])) + goto error; + iblock->ip = g_strdup (ip_mask[0]); + i = 0; + while (i < length && !strstr (ip_mask[++i], "netmask")) ; + while (i < length && ip_mask[++i][0] == '\0') ; + if (i >= length) + goto error; + if (!inet_pton (AF_INET, ip_mask[i], &tmp_ip4_addr)) + goto error; + iblock->prefix = nm_utils_ip4_netmask_to_prefix (tmp_ip4_addr); + } else { + g_slice_free (ip_block, iblock); + if (!is_ip6_address (ip) && !strstr (ip, "dhcp")) + nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, missing netmask or prefix", ip); + return NULL; + } + if (iblock->prefix == 0 || iblock->prefix > 32) { + nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, invalid prefix", ip); + goto error; + } + g_strfreev (ip_mask); + return iblock; +error: + if (!is_ip6_address (ip)) + nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 address: %s", ip); + g_strfreev (ip_mask); + g_free (iblock->ip); + g_slice_free (ip_block, iblock); + return NULL; +} + +static ip_block * +create_ip_block (gchar * ip) +{ + ip_block *iblock = g_slice_new0 (ip_block); + gchar *dup_ip = g_strdup (ip); + gchar *prefix = NULL; + + if ((prefix = strstr (dup_ip, "/")) != NULL) { + *prefix = '\0'; + prefix++; + } + if (!nm_utils_ipaddr_valid (AF_INET6, dup_ip)) + goto error; + iblock->ip = dup_ip; + if (prefix) { + errno = 0; + iblock->prefix = strtol (prefix, NULL, 10); + if (errno || iblock->prefix <= 0 || iblock->prefix > 128) { + goto error; + } + } else + iblock->prefix = 64; + return iblock; +error: + if (!is_ip4_address (ip)) + nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 address: %s", ip); + g_slice_free (ip_block, iblock); + g_free (dup_ip); + return NULL; +} + +static char * +get_ip4_gateway (gchar * gateway) +{ + gchar *tmp, *split; + + if (!gateway) + return NULL; + tmp = find_gateway_str (gateway); + if (!tmp) { + nm_log_warn (LOGD_SETTINGS, "Couldn't obtain gateway in \"%s\"", gateway); + return NULL; + } + tmp = g_strdup (tmp); + strip_string (tmp, ' '); + strip_string (tmp, '"'); + + // Only one gateway is selected + if ((split = strstr (tmp, "\"")) != NULL) + *split = '\0'; + + if (!nm_utils_ipaddr_valid (AF_INET, tmp)) + goto error; + return tmp; +error: + if (!is_ip6_address (tmp)) + nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 gateway: %s", tmp); + g_free (tmp); + return NULL; +} + +static char * +get_ip6_next_hop (gchar * next_hop) +{ + gchar *tmp; + + if (!next_hop) + return NULL; + tmp = find_gateway_str (next_hop); + if (!tmp) { + nm_log_warn (LOGD_SETTINGS, "Couldn't obtain next_hop in \"%s\"", next_hop); + return NULL; + } + tmp = g_strdup (tmp); + strip_string (tmp, ' '); + strip_string (tmp, '"'); + g_strstrip (tmp); + if (!nm_utils_ipaddr_valid (AF_INET6, tmp)) + goto error; + return tmp; +error: + if (!is_ip4_address (tmp)) + nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 next_hop: %s", tmp); + g_free (tmp); + + return NULL; +} + +ip_block * +convert_ip4_config_block (const char *conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip; + char *def_gateway = NULL; + const char *routes; + ip_block *start = NULL, *current = NULL, *iblock = NULL; + + g_return_val_if_fail (conn_name != NULL, NULL); + + ipset = split_addresses (ifnet_get_data (conn_name, "config")); + length = ipset ? g_strv_length (ipset) : 0; + + routes = ifnet_get_data (conn_name, "routes"); + if (routes) + def_gateway = get_ip4_gateway (strstr (routes, "default")); + + for (i = 0; i < length; i++) { + ip = ipset[i]; + ip = strip_string (ip, '"'); + iblock = create_ip4_block (ip); + if (iblock == NULL) + continue; + if (!iblock->next_hop && def_gateway != NULL) + iblock->next_hop = g_strdup (def_gateway); + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + } + g_strfreev (ipset); + g_free (def_gateway); + return start; +} + +ip_block * +convert_ip6_config_block (const char *conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip; + ip_block *start = NULL, *current = NULL, *iblock = NULL; + + g_return_val_if_fail (conn_name != NULL, NULL); + ipset = split_addresses (ifnet_get_data (conn_name, "config")); + length = ipset ? g_strv_length (ipset) : 0; + for (i = 0; i < length; i++) { + ip = ipset[i]; + ip = strip_string (ip, '"'); + iblock = create_ip_block (ip); + if (iblock == NULL) + continue; + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + } + g_strfreev (ipset); + return start; +} + +ip_block * +convert_ip4_routes_block (const char *conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip; + ip_block *start = NULL, *current = NULL, *iblock = NULL; + + g_return_val_if_fail (conn_name != NULL, NULL); + + ipset = split_routes (ifnet_get_data (conn_name, "routes")); + length = ipset ? g_strv_length (ipset) : 0; + for (i = 0; i < length; i++) { + ip = ipset[i]; + if (find_default_gateway_str (ip) || strstr (ip, "::") + || !find_gateway_str (ip)) + continue; + ip = strip_string (ip, '"'); + iblock = create_ip4_block (ip); + if (iblock == NULL) + continue; + iblock->next_hop = get_ip4_gateway (ip); + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + } + g_strfreev (ipset); + return start; +} + +ip_block * +convert_ip6_routes_block (const char *conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip, *tmp_addr; + ip_block *start = NULL, *current = NULL, *iblock = NULL; + + g_return_val_if_fail (conn_name != NULL, NULL); + ipset = split_routes (ifnet_get_data (conn_name, "routes")); + length = ipset ? g_strv_length (ipset) : 0; + for (i = 0; i < length; i++) { + ip = ipset[i]; + ip = strip_string (ip, '"'); + if (ip[0] == '\0') + continue; + if ((tmp_addr = find_default_gateway_str (ip)) != NULL) { + if (!is_ip6_address (tmp_addr)) + continue; + else { + iblock = g_slice_new0 (ip_block); + iblock->ip = g_strdup ("::"); + iblock->prefix = 128; + } + } else + iblock = create_ip_block (ip); + if (iblock == NULL) + continue; + iblock->next_hop = get_ip6_next_hop (ip); + if (iblock->next_hop == NULL) { + destroy_ip_block (iblock); + continue; + } + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + } + g_strfreev (ipset); + return start; +} + +void +destroy_ip_block (ip_block * iblock) +{ + g_free (iblock->ip); + g_free (iblock->next_hop); + g_slice_free (ip_block, iblock); +} + +void +set_ip4_dns_servers (NMSettingIPConfig *s_ip4, const char *conn_name) +{ + const char *dns_servers; + gchar **server_list, *stripped; + guint length, i; + guint32 tmp_ip4_addr; + + dns_servers = ifnet_get_data (conn_name, "dns_servers"); + if (!dns_servers) + return; + stripped = g_strdup (dns_servers); + strip_string (stripped, '"'); + server_list = g_strsplit (stripped, " ", 0); + g_free (stripped); + + length = g_strv_length (server_list); + if (length) + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, + TRUE, NULL); + for (i = 0; i < length; i++) { + g_strstrip (server_list[i]); + if (server_list[i][0] == '\0') + continue; + if (!inet_pton (AF_INET, server_list[i], &tmp_ip4_addr)) { + if (!is_ip6_address (server_list[i])) + nm_log_warn (LOGD_SETTINGS, "ignored dns: %s\n", server_list[i]); + continue; + } + if (!nm_setting_ip_config_add_dns (s_ip4, server_list[i])) + nm_log_warn (LOGD_SETTINGS, "warning: duplicate DNS server %s", server_list[i]); + } + g_strfreev (server_list); +} + +void +set_ip6_dns_servers (NMSettingIPConfig *s_ip6, const char *conn_name) +{ + const char *dns_servers; + gchar **server_list, *stripped; + guint length, i; + struct in6_addr tmp_ip6_addr; + + dns_servers = ifnet_get_data (conn_name, "dns_servers"); + if (!dns_servers) + return; + + stripped = g_strdup (dns_servers); + strip_string (stripped, '"'); + server_list = g_strsplit (stripped, " ", 0); + g_free (stripped); + + length = g_strv_length (server_list); + if (length) + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, + TRUE, NULL); + for (i = 0; i < length; i++) { + g_strstrip (server_list[i]); + if (server_list[i][0] == '\0') + continue; + if (!inet_pton (AF_INET6, server_list[i], &tmp_ip6_addr)) { + if (is_ip6_address (server_list[i])) + nm_log_warn (LOGD_SETTINGS, "ignored dns: %s\n", server_list[i]); + continue; + } + if (!nm_setting_ip_config_add_dns (s_ip6, server_list[i])) + nm_log_warn (LOGD_SETTINGS, "warning: duplicate DNS server %s", server_list[i]); + } + g_strfreev (server_list); +} + +gboolean +is_managed (const char *conn_name) +{ + gchar *config; + + g_return_val_if_fail (conn_name != NULL, FALSE); + config = (gchar *) ifnet_get_data (conn_name, "managed"); + if (!config) + return TRUE; + if (strcmp (config, "false") == 0) + return FALSE; + return TRUE; +} + +static char * +_has_prefix_impl (char *str, const char *prefix, gsize prefix_len) +{ + if (!g_str_has_prefix (str, prefix)) + return NULL; + str += prefix_len; + if (!g_ascii_isspace (str[0])) + return NULL; + do { + str++; + } while (g_ascii_isspace (str[0])); + return str; +} +#define _has_prefix(STR, PREFIX) _has_prefix_impl (STR, PREFIX, NM_STRLEN (PREFIX)) + +void +get_dhcp_hostname_and_client_id (char **hostname, char **client_id) +{ + const char *dhcp_client; + const gchar *dhcpcd_conf = SYSCONFDIR "/dhcpcd.conf"; + const gchar *dhclient_conf = SYSCONFDIR "/dhcp/dhclient.conf"; + gchar *line = NULL, *tmp = NULL, *contents = NULL, *tmp1; + gchar **all_lines; + guint line_num, i; + gboolean use_dhclient = FALSE; + + *hostname = NULL; + *client_id = NULL; + dhcp_client = nm_dhcp_manager_get_config (nm_dhcp_manager_get ()); + if (dhcp_client) { + if (!strcmp (dhcp_client, "dhclient")) { + g_file_get_contents (dhclient_conf, &contents, NULL, + NULL); + use_dhclient = TRUE; + } else if (!strcmp (dhcp_client, "dhcpcd")) { + g_file_get_contents (dhcpcd_conf, &contents, NULL, + NULL); + } + } else { + if (g_file_test (dhclient_conf, G_FILE_TEST_IS_REGULAR)) { + g_file_get_contents (dhclient_conf, &contents, NULL, + NULL); + use_dhclient = TRUE; + } else if (g_file_test (dhcpcd_conf, G_FILE_TEST_IS_REGULAR)) { + g_file_get_contents (dhcpcd_conf, &contents, NULL, + NULL); + } + } + if (!contents) + return; + all_lines = g_strsplit (contents, "\n", 0); + line_num = g_strv_length (all_lines); + for (i = 0; i < line_num; i++) { + line = all_lines[i]; + g_strstrip (line); + if (line[0] == '#' || line[0] == '\0') + continue; + if (!use_dhclient) { + // dhcpcd.conf + if ((tmp = _has_prefix (line, "hostname"))) { + if (tmp[0] != '\0') { + g_free (*hostname); + *hostname = g_strdup (tmp); + } else + nm_log_info (LOGD_SETTINGS, "dhcpcd hostname not defined, ignoring"); + } else if ((tmp = _has_prefix (line, "clientid"))) { + if (tmp[0] != '\0') { + g_free (*client_id); + *client_id = g_strdup (tmp); + } else + nm_log_info (LOGD_SETTINGS, "dhcpcd clientid not defined, ignoring"); + } + } else { + // dhclient.conf + if ((tmp1 = _has_prefix (line, "send"))) { + if ((tmp = _has_prefix (tmp1, "host-name"))) { + strip_string (tmp, ';'); + strip_string (tmp, '"'); + if (tmp[0] != '\0') { + g_free (*hostname); + *hostname = g_strdup (tmp); + } else + nm_log_info (LOGD_SETTINGS, "dhclient hostname not defined, ignoring"); + } else if ((tmp = _has_prefix (tmp1, "dhcp-client-identifier"))) { + strip_string (tmp, ';'); + if (tmp[0] != '\0') { + g_free (*client_id); + *client_id = g_strdup (tmp); + } else + nm_log_info (LOGD_SETTINGS, "dhclient clientid not defined, ignoring"); + } + } + } + } + g_strfreev (all_lines); + g_free (contents); +} + +gchar *backup_file (const gchar* target) +{ + GFile *source, *backup; + gchar* backup_path; + GError *error = NULL; + + source = g_file_new_for_path (target); + + if (!g_file_query_exists (source, NULL)) { + g_object_unref (source); + return NULL; + } + + backup_path = g_strdup_printf ("%s.bak", target); + backup = g_file_new_for_path (backup_path); + + if (!g_file_copy (source, backup, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error)) { + nm_log_warn (LOGD_SETTINGS, "Backup failed: %s", error->message); + g_free (backup_path); + backup_path = NULL; + g_error_free (error); + } + + g_object_unref (source); + g_object_unref (backup); + + return backup_path; +} diff --git a/src/settings/plugins/ifnet/nms-ifnet-net-utils.h b/src/settings/plugins/ifnet/nms-ifnet-net-utils.h new file mode 100644 index 00000000..cc273aa7 --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-net-utils.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef _IFNET_UTILS_H +#define _IFNET_UTILS_H + +#define IFNET_PLUGIN_NAME "SettingsPlugin-Ifnet" + +#include + +#include "nm-setting-ip6-config.h" +#include "nm-setting-ip4-config.h" + +#include "nms-ifnet-net-parser.h" + +#define has_default_ip4_route(conn_name) has_default_route((conn_name), &is_ip4_address) +#define has_default_ip6_route(conn_name) has_default_route((conn_name), &is_ip6_address) + +typedef struct _ip_block { + char *ip; + guint32 prefix; + char *next_hop; + struct _ip_block *next; +} ip_block; + +gboolean is_static_ip4 (const char *conn_name); +gboolean is_static_ip6 (const char *conn_name); +gboolean is_ip4_address (const char *in_address); +gboolean is_ip6_address (const char *in_address); +gboolean has_ip6_address (const char *conn_name); +gboolean has_default_route (const char *conn_name, gboolean (*check_fn) (const char *)); +gboolean reload_parsers (void); + +ip_block *convert_ip4_config_block (const char *conn_name); +ip_block *convert_ip6_config_block (const char *conn_name); +ip_block *convert_ip4_routes_block (const char *conn_name); +ip_block *convert_ip6_routes_block (const char *conn_name); +void destroy_ip_block (ip_block * iblock); + +void set_ip4_dns_servers (NMSettingIPConfig * s_ip4, const char *conn_name); +void set_ip6_dns_servers (NMSettingIPConfig * s_ip6, const char *conn_name); + +gchar *strip_string (gchar *str, gchar t); +gboolean is_managed (const char *conn_name); + +gboolean is_hex (const char *value); +gboolean is_ascii (const char *value); +gboolean is_true (const char *str); + +void get_dhcp_hostname_and_client_id (char **hostname, char **client_id); + +gchar *backup_file (const gchar* target); +#endif diff --git a/src/settings/plugins/ifnet/nms-ifnet-plugin.c b/src/settings/plugins/ifnet/nms-ifnet-plugin.c new file mode 100644 index 00000000..8332358f --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-plugin.c @@ -0,0 +1,524 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service (ifnet) + * + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include "nm-default.h" + +#include "nms-ifnet-plugin.h" + +#include +#include + +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-dbus-interface.h" +#include "settings/nm-settings-plugin.h" +#include "nm-config.h" +#include "NetworkManagerUtils.h" + +#include "nms-ifnet-connection.h" +#include "nms-ifnet-net-utils.h" +#include "nms-ifnet-net-parser.h" +#include "nms-ifnet-wpa-parser.h" +#include "nms-ifnet-connection-parser.h" + +#define IFNET_PLUGIN_NAME_PRINT "ifnet" +#define IFNET_PLUGIN_INFO "(C) 1999-2010 Gentoo Foundation, Inc. To report bugs please use bugs.gentoo.org with [networkmanager] or [qiaomuf] prefix." +#define IFNET_MANAGE_WELL_KNOWN_DEFAULT TRUE + +/*****************************************************************************/ + +typedef void (*FileChangedFn) (gpointer user_data); + +typedef struct { + FileChangedFn callback; + gpointer user_data; +} FileMonitorInfo; + +/*****************************************************************************/ + +typedef struct { + GHashTable *connections; /* uuid::connection */ + gboolean unmanaged_well_known; + + GFileMonitor *net_monitor; + GFileMonitor *wpa_monitor; +} SettingsPluginIfnetPrivate; + +struct _SettingsPluginIfnet { + GObject parent; + SettingsPluginIfnetPrivate _priv; +}; + +struct _SettingsPluginIfnetClass { + GObjectClass parent; +}; + +static void settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface); + +G_DEFINE_TYPE_EXTENDED (SettingsPluginIfnet, settings_plugin_ifnet, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_PLUGIN, + settings_plugin_interface_init)) + +#define SETTINGS_PLUGIN_IFNET_GET_PRIVATE(self) _NM_GET_PRIVATE (self, SettingsPluginIfnet, SETTINGS_IS_PLUGIN_IFNET) + +/*****************************************************************************/ + +static SettingsPluginIfnet *settings_plugin_ifnet_get (void); + +NM_DEFINE_SINGLETON_GETTER (SettingsPluginIfnet, settings_plugin_ifnet_get, SETTINGS_TYPE_PLUGIN_IFNET); + +/*****************************************************************************/ + +static void reload_connections (NMSettingsPlugin *config); + +/*****************************************************************************/ + +static gboolean +is_managed_plugin (void) +{ + return nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG, + NM_CONFIG_KEYFILE_GROUP_IFNET, NM_CONFIG_KEYFILE_KEY_IFNET_MANAGED, + IFNET_MANAGE_WELL_KNOWN_DEFAULT); +} + +static void +file_changed (GFileMonitor * monitor, + GFile * file, + GFile * other_file, + GFileMonitorEvent event_type, gpointer user_data) +{ + FileMonitorInfo *info; + + switch (event_type) { + case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: + info = (FileMonitorInfo *) user_data; + info->callback (info->user_data); + break; + default: + break; + } +} + +static GFileMonitor * +monitor_file_changes (const char *filename, + FileChangedFn callback, gpointer user_data) +{ + GFile *file; + GFileMonitor *monitor; + FileMonitorInfo *info; + GError **error = NULL; + + if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) + return NULL; + file = g_file_new_for_path (filename); + monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, error); + g_object_unref (file); + + if (monitor) { + info = g_new0 (FileMonitorInfo, 1); + info->callback = callback; + info->user_data = user_data; + g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free, + info); + g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), + info); + } else { + nm_log_warn (LOGD_SETTINGS, "Monitoring %s failed, error: %s", filename, + error == NULL ? "nothing" : (*error)->message); + } + + return monitor; +} + +static void +setup_monitors (NMIfnetConnection *connection, gpointer user_data) +{ + SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (user_data); + SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self); + + if (!nm_config_get_monitor_connection_files (nm_config_get ())) + return; + + if (priv->net_monitor || priv->wpa_monitor) + return; + + priv->net_monitor = monitor_file_changes (CONF_NET_FILE, + (FileChangedFn) reload_connections, + user_data); + priv->wpa_monitor = monitor_file_changes (WPA_SUPPLICANT_CONF, + (FileChangedFn) reload_connections, + user_data); +} + +static void +cancel_monitors (NMIfnetConnection *connection, gpointer user_data) +{ + SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (user_data); + SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self); + + if (priv->net_monitor) { + g_file_monitor_cancel (priv->net_monitor); + g_clear_object (&priv->net_monitor); + } + if (priv->wpa_monitor) { + g_file_monitor_cancel (priv->wpa_monitor); + g_clear_object (&priv->wpa_monitor); + } +} + +static void +connection_removed_cb (NMSettingsConnection *obj, gpointer user_data) +{ + g_hash_table_remove (SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) user_data)->connections, + nm_connection_get_uuid (NM_CONNECTION (obj))); +} + +static void +track_new_connection (SettingsPluginIfnet *self, NMIfnetConnection *connection) +{ + g_hash_table_insert (SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self)->connections, + g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection))), + g_object_ref (connection)); + g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (connection_removed_cb), + self); +} + +static void +reload_connections (NMSettingsPlugin *config) +{ + SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (config); + SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self); + GList *conn_names = NULL, *n_iter = NULL; + gboolean auto_refresh; + GError *error = NULL; + + /* save names for removing unused connections */ + GHashTable *new_connections = NULL; + GHashTableIter iter; + const char *uuid; + NMSettingsConnection *candidate; + + if (priv->unmanaged_well_known) + return; + + if (!reload_parsers ()) + return; + + nm_log_info (LOGD_SETTINGS, "Loading connections"); + + auto_refresh = nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG, + NM_CONFIG_KEYFILE_GROUP_IFNET, NM_CONFIG_KEYFILE_KEY_IFNET_AUTO_REFRESH, + FALSE); + + new_connections = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref); + + /* Reread on-disk data and refresh in-memory connections from it */ + conn_names = ifnet_get_connection_names (); + for (n_iter = conn_names; n_iter; n_iter = g_list_next (n_iter)) { + NMIfnetConnection *new; + NMIfnetConnection *old; + const char *conn_name = n_iter->data; + + /* read the new connection */ + new = nm_ifnet_connection_new (NULL, conn_name); + if (!new) + continue; + + g_signal_connect (G_OBJECT (new), "ifnet_setup_monitors", + G_CALLBACK (setup_monitors), config); + g_signal_connect (G_OBJECT (new), "ifnet_cancel_monitors", + G_CALLBACK (cancel_monitors), config); + + old = g_hash_table_lookup (priv->connections, + nm_connection_get_uuid (NM_CONNECTION (new))); + if (old && new) { + if (auto_refresh) { + /* If connection has changed, remove the old one and add the + * new one to force a disconnect/reconnect with new settings + */ + if (!nm_connection_compare (NM_CONNECTION (old), + NM_CONNECTION (new), + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | + NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) { + nm_log_info (LOGD_SETTINGS, "Auto refreshing %s", conn_name); + + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (old)); + track_new_connection (self, new); + if (is_managed_plugin () && is_managed (conn_name)) + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, new); + } + } else { + /* Update existing connection with new settings */ + if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (old), + NM_CONNECTION (new), + NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP_SAVED, + NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, + "ifnet-update", + &error)) { + /* Shouldn't ever get here as 'new' was verified by the reader already + * and the UUID did not change. */ + g_assert_not_reached (); + } + g_assert_no_error (error); + nm_log_info (LOGD_SETTINGS, "Connection %s updated", + nm_connection_get_id (NM_CONNECTION (new))); + } + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED); + } else if (new) { + track_new_connection (self, new); + if (is_managed_plugin () && is_managed (conn_name)) + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, new); + } + + /* Track all valid connections so we can remove deleted ones later */ + g_hash_table_insert (new_connections, + (gpointer) nm_connection_get_uuid (NM_CONNECTION (new)), + new); + } + + /* remove deleted/unused connections */ + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, (gpointer) &uuid, (gpointer) &candidate)) { + /* only saved connections (which have a conn_name) get removed; unsaved + * ones obviously don't exist in /etc/conf.d/net yet and shouldn't get + * blown away by net file changes. + */ + if ( nm_ifnet_connection_get_conn_name (NM_IFNET_CONNECTION (candidate)) + && !g_hash_table_lookup (new_connections, uuid)) { + nm_settings_connection_signal_remove (candidate); + g_hash_table_iter_remove (&iter); + } + } + g_hash_table_destroy (new_connections); + g_list_free (conn_names); +} + +static NMSettingsConnection * +add_connection (NMSettingsPlugin *config, + NMConnection *source, + gboolean save_to_disk, + GError **error) +{ + SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) config); + NMIfnetConnection *new = NULL; + + /* Ensure we reject attempts to add the connection long before we're + * asked to write it to disk. + */ + if (!ifnet_can_write_connection (source, error)) + goto out; + + if (save_to_disk) { + if (!ifnet_add_new_connection (source, CONF_NET_FILE, WPA_SUPPLICANT_CONF, NULL, NULL, error)) + goto out; + reload_connections (config); + new = g_hash_table_lookup (priv->connections, nm_connection_get_uuid (source)); + } else { + new = nm_ifnet_connection_new (source, NULL); + if (new) { + track_new_connection (SETTINGS_PLUGIN_IFNET (config), new); + /* track_new_connection refs 'new' */ + g_object_unref (new); + } + } + +out: + if (!new && error && !*error) { + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "The ifnet plugin cannot add the connection (unknown error)."); + } + return (NMSettingsConnection *) new; +} + +static void +check_unmanaged (gpointer key, gpointer data, gpointer user_data) +{ + NMIfnetConnection *connection = NM_IFNET_CONNECTION (data); + GSList **list = (GSList **) user_data; + const char *mac, *conn_name; + char *unmanaged_spec; + GSList *iter; + + conn_name = nm_ifnet_connection_get_conn_name (connection); + + if (!conn_name || is_managed (conn_name)) + return; + + nm_log_info (LOGD_SETTINGS, "Checking unmanaged: %s", conn_name); + mac = ifnet_get_data (conn_name, "mac"); + if (mac) + unmanaged_spec = g_strdup_printf ("mac:%s", mac); + else + unmanaged_spec = g_strdup_printf ("interface-name:%s", conn_name); + + /* Just return if the unmanaged spec is already in the list */ + for (iter = *list; iter; iter = g_slist_next (iter)) { + if (g_str_equal (iter->data, unmanaged_spec)) { + g_free (unmanaged_spec); + return; + } + } + + nm_log_info (LOGD_SETTINGS, "Add unmanaged: %s", unmanaged_spec); + *list = g_slist_prepend (*list, unmanaged_spec); +} + +static GSList * +get_unmanaged_specs (NMSettingsPlugin * config) +{ + SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) config); + GSList *list = NULL; + + nm_log_info (LOGD_SETTINGS, "getting unmanaged specs..."); + g_hash_table_foreach (priv->connections, check_unmanaged, &list); + return list; +} + +static GSList * +get_connections (NMSettingsPlugin *config) +{ + SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) config); + GSList *connections = NULL; + GHashTableIter iter; + NMIfnetConnection *connection; + + nm_log_info (LOGD_SETTINGS, "(%p) ... get_connections.", config); + + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) { + const char *conn_name = nm_ifnet_connection_get_conn_name (connection); + + if (!conn_name || (!priv->unmanaged_well_known && is_managed (conn_name))) + connections = g_slist_prepend (connections, connection); + } + nm_log_info (LOGD_SETTINGS, "(%p) connections count: %d", + config, g_slist_length (connections)); + return connections; +} + +/*****************************************************************************/ + +static void +get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + switch (prop_id) { + case NM_SETTINGS_PLUGIN_PROP_NAME: + g_value_set_string (value, IFNET_PLUGIN_NAME_PRINT); + break; + case NM_SETTINGS_PLUGIN_PROP_INFO: + g_value_set_string (value, IFNET_PLUGIN_INFO); + break; + case NM_SETTINGS_PLUGIN_PROP_CAPABILITIES: + g_value_set_uint (value, + NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +init (NMSettingsPlugin *config) +{ + SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (config); + SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self); + + nm_log_info (LOGD_SETTINGS, "Initializing!"); + + priv->connections = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); + priv->unmanaged_well_known = !is_managed_plugin (); + nm_log_info (LOGD_SETTINGS, "management mode: %s", + priv->unmanaged_well_known ? "unmanaged" : "managed"); + + setup_monitors (NULL, config); + reload_connections (config); + + nm_log_info (LOGD_SETTINGS, "Initialzation complete!"); +} + +/*****************************************************************************/ + +static void +settings_plugin_ifnet_init (SettingsPluginIfnet * plugin) +{ +} + +static void +dispose (GObject * object) +{ + SettingsPluginIfnet *plugin = SETTINGS_PLUGIN_IFNET (object); + SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) plugin); + + cancel_monitors (NULL, object); + if (priv->connections) { + g_hash_table_destroy (priv->connections); + priv->connections = NULL; + } + + ifnet_destroy (); + wpa_parser_destroy (); + G_OBJECT_CLASS (settings_plugin_ifnet_parent_class)->dispose (object); +} + +static void +settings_plugin_ifnet_class_init (SettingsPluginIfnetClass * req_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (req_class); + + object_class->dispose = dispose; + object_class->get_property = get_property; + + g_object_class_override_property (object_class, + NM_SETTINGS_PLUGIN_PROP_NAME, + NM_SETTINGS_PLUGIN_NAME); + + g_object_class_override_property (object_class, + NM_SETTINGS_PLUGIN_PROP_INFO, + NM_SETTINGS_PLUGIN_INFO); + + g_object_class_override_property (object_class, + NM_SETTINGS_PLUGIN_PROP_CAPABILITIES, + NM_SETTINGS_PLUGIN_CAPABILITIES); +} + +static void +settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface) +{ + plugin_iface->init = init; + plugin_iface->get_connections = get_connections; + plugin_iface->get_unmanaged_specs = get_unmanaged_specs; + plugin_iface->add_connection = add_connection; + plugin_iface->reload_connections = reload_connections; +} + +/*****************************************************************************/ + +G_MODULE_EXPORT GObject * +nm_settings_plugin_factory (void) +{ + return G_OBJECT (g_object_ref (settings_plugin_ifnet_get ())); +} diff --git a/src/settings/plugins/ifnet/nms-ifnet-plugin.h b/src/settings/plugins/ifnet/nms-ifnet-plugin.h new file mode 100644 index 00000000..f006e7e4 --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-plugin.h @@ -0,0 +1,38 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service (ifnet) + * + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ + +#define SETTINGS_TYPE_PLUGIN_IFNET (settings_plugin_ifnet_get_type ()) +#define SETTINGS_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SETTINGS_TYPE_PLUGIN_IFNET, SettingsPluginIfnet)) +#define SETTINGS_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SETTINGS_TYPE_PLUGIN_IFNET, SettingsPluginIfnetClass)) +#define SETTINGS_IS_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SETTINGS_TYPE_PLUGIN_IFNET)) +#define SETTINGS_IS_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SETTINGS_TYPE_PLUGIN_IFNET)) +#define SETTINGS_PLUGIN_IFNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SETTINGS_TYPE_PLUGIN_IFNET, SettingsPluginIfnetClass)) + +typedef struct _SettingsPluginIfnet SettingsPluginIfnet; +typedef struct _SettingsPluginIfnetClass SettingsPluginIfnetClass; + +GType settings_plugin_ifnet_get_type (void); + +#endif diff --git a/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c b/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c new file mode 100644 index 00000000..2b62e886 --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c @@ -0,0 +1,584 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include "nm-default.h" + +#include "nms-ifnet-wpa-parser.h" + +#include +#include + +#include "nm-utils/nm-hash-utils.h" +#include "settings/nm-settings-plugin.h" + +#include "nms-ifnet-net-parser.h" +#include "nms-ifnet-net-utils.h" + +/* Security information */ +static GHashTable *wsec_table = NULL; + +/* Global information used for writing */ +static GHashTable *wsec_global_table = NULL; + +static gboolean wpa_parser_data_changed = FALSE; + +static long +wpa_get_long (GHashTable *table, const char *key) +{ + return atol (g_hash_table_lookup (table, key)); +} + +static void +destroy_security (GHashTable * network) +{ + gpointer key, value; + GHashTableIter iter; + + g_return_if_fail (network); + g_hash_table_iter_init (&iter, network); + while (g_hash_table_iter_next (&iter, &key, &value)) { + g_free (key); + g_free (value); + } + + g_hash_table_destroy (network); +} + +static GHashTable * +add_security (GHashTable *security) +{ + GHashTable *oldsecurity; + const char *ssid, *value; + char *ssid_key; + gboolean is_hex_ssid; + + /* Every security information should have a ssid */ + ssid = g_hash_table_lookup (security, "ssid"); + if (!ssid) { + destroy_security (security); + return NULL; + } + + /* Hex format begins with " */ + is_hex_ssid = (ssid[0] != '"'); + if ((value = g_hash_table_lookup (security, "disabled")) != NULL) { + if (strcmp (value, "1") == 0) { + destroy_security (security); + return NULL; + } + } + + /* Default priority is 1 */ + if (g_hash_table_lookup (security, "priority") == NULL) + g_hash_table_insert (security, g_strdup ("priority"), + g_strdup ("1")); + + oldsecurity = g_hash_table_lookup (wsec_table, ssid); + /* Security with lower priority will be ignored */ + if (oldsecurity != NULL) { + if (wpa_get_long (oldsecurity, "priority") >= + wpa_get_long (security, "priority")) { + destroy_security (security); + return NULL; + } else { + g_hash_table_remove (wsec_table, ssid); + destroy_security (oldsecurity); + } + } + + /* format ssid */ + ssid_key = + is_hex_ssid ? g_strdup_printf ("0x%s", + ssid) : + strip_string (g_strdup (ssid), '"'); + g_hash_table_insert (wsec_table, ssid_key, security); + return security; +} + +static void +add_key_value (GHashTable * network, gchar * line) +{ + gpointer orig_key, orig_value; + gchar **key_value; + + if (g_str_has_prefix (line, "network={")) + line += 9; + strip_string (line, '{'); + strip_string (line, '}'); + if (line[0] == '\0') + return; + key_value = g_strsplit (line, "=", 2); + if (g_strv_length (key_value) != 2) { + g_strfreev (key_value); + return; + } + g_strstrip (key_value[0]); + g_strstrip (key_value[1]); + + /* Reserve quotes for psk, wep_key, ssid + * Quotes will determine whether they are hex format */ + if (strcmp (key_value[0], "psk") != 0 + && !g_str_has_prefix (key_value[0], "wep_key") + && strcmp (key_value[0], "ssid") != 0) + strip_string (key_value[1], '"'); + + /* This sucks */ + if (g_hash_table_lookup_extended (network, key_value[0], &orig_key, &orig_value)) { + g_hash_table_remove (network, orig_key); + g_free (orig_key); + g_free (orig_value); + } + + g_hash_table_insert (network, g_strdup (key_value[0]), + g_strdup (key_value[1])); + g_strfreev (key_value); +} + +static void +add_one_wep_key (GHashTable * table, int key_num, gchar * one_wep_key) +{ + if (one_wep_key[0] == 's') { + //asc key + g_hash_table_insert (table, + g_strdup_printf ("wep_key%d", key_num - 1), + g_strdup_printf ("\"%s\"", + one_wep_key + 2)); + } else { + gchar buf[30]; + int i = 0, j = 0; + + //hex key + while (one_wep_key[i] != '\0') { + if (one_wep_key[i] != '-') + buf[j++] = one_wep_key[i]; + i++; + } + buf[j] = '\0'; + g_hash_table_insert (table, + g_strdup_printf ("wep_key%d", key_num - 1), + g_strdup (buf)); + + } +} + +/* Reading wep security information from /etc/conf.d/net. + * This should not be used in future, use wpa_supplicant instead. */ +static void +add_keys_from_net (void) +{ + GList *names = ifnet_get_connection_names (); + GList *iter = names; + gchar *wep_keys = "(\\[([1-4])\\]\\s+(s:\\w{5}|s:\\w{13}|" + "([\\da-fA-F]{4}\\-){2}[\\da-fA-F]{2}|" + "([\\da-fA-F]{4}\\-){6}[\\da-fA-F]{2})\\s+)"; + gchar *key_method = + "\\s+key\\s+\\[([1-4])\\]\\s+enc\\s+(open|restricted)"; + GRegex *regex_keys = g_regex_new (wep_keys, 0, 0, NULL); + GRegex *regex_method = g_regex_new (key_method, 0, 0, NULL); + GMatchInfo *keys_info; + GMatchInfo *method_info; + + while (iter) { + gchar *conn_name = iter->data; + GHashTable *table; + const char *key_str; + + if ((key_str = ifnet_get_data (conn_name, "key")) == NULL) { + iter = g_list_next (iter); + continue; + } + + wpa_add_security (conn_name); + table = _get_hash_table (conn_name); + /* Give lowest priority */ + wpa_set_data (conn_name, "priority", "0"); + g_regex_match (regex_keys, key_str, 0, &keys_info); + /* add wep keys */ + while (g_match_info_matches (keys_info)) { + gchar *key_num = g_match_info_fetch (keys_info, 2); + gchar *one_wep_key = g_match_info_fetch (keys_info, 3); + + add_one_wep_key (table, atoi (key_num), one_wep_key); + g_free (key_num); + g_free (one_wep_key); + g_match_info_next (keys_info, NULL); + } + g_match_info_free (keys_info); + + g_regex_match (regex_method, key_str, 0, &method_info); + /* set default key index and auth alg */ + if (g_match_info_matches (method_info)) { + gchar *default_idx = + g_match_info_fetch (method_info, 1); + gchar *method = g_match_info_fetch (method_info, 2); + + default_idx[0]--; + g_hash_table_insert (table, g_strdup ("wep_tx_keyidx"), + default_idx); + g_hash_table_insert (table, g_strdup ("auth_alg"), + g_ascii_strup (method, -1)); + } + g_match_info_free (method_info); + add_security (table); + iter = g_list_next (iter); + } + g_list_free (names); + g_regex_unref (regex_keys); + g_regex_unref (regex_method); +} + +static void +add_global_data (gchar * line) +{ + gchar **key_value; + + g_strstrip (line); + key_value = g_strsplit (line, "=", 2); + if (g_strv_length (key_value) != 2) { + nm_log_warn (LOGD_SETTINGS, "Can't handle this line: %s\n", line); + g_strfreev (key_value); + return; + } + g_hash_table_insert (wsec_global_table, + g_strdup (g_strstrip (key_value[0])), + g_strdup (g_strstrip (key_value[1]))); + g_strfreev (key_value); +} + +void +wpa_parser_init (const char *wpa_supplicant_conf) +{ + GIOChannel *channel = NULL; + gchar *line; + gboolean complete = FALSE; + + wpa_parser_data_changed = FALSE; + wsec_table = g_hash_table_new (nm_str_hash, g_str_equal); + wsec_global_table = g_hash_table_new (nm_str_hash, g_str_equal); + + if (g_file_test (wpa_supplicant_conf, G_FILE_TEST_IS_REGULAR)) + channel = + g_io_channel_new_file (wpa_supplicant_conf, "r", NULL); + if (channel == NULL) { + nm_log_warn (LOGD_SETTINGS, "Can't open %s for wireless security", + wpa_supplicant_conf); + return; + } + + while (g_io_channel_read_line (channel, &line, NULL, NULL, NULL) + != G_IO_STATUS_EOF) { + g_strstrip (line); + if (line[0] != '#' && line[0] != '\0') { + if (strstr (line, "network={") == NULL) { + add_global_data (line); + g_free (line); + continue; + } else { + GHashTable *network = + g_hash_table_new (nm_str_hash, g_str_equal); + + do { + gchar *quote_start, *quote_end = NULL, *comment; + + if (line[0] == '#' || line[0] == '\0') { + g_free (line); + continue; + } + /* ignore inline comments unless inside + a double-quoted string */ + if ((quote_start = strchr (line, '"')) != NULL) + quote_end = strrchr (quote_start + 1, '"'); + if ((comment = strchr ((quote_end != NULL) ? + quote_end : line, '#')) != NULL) + *comment = '\0'; + if (strstr (line, "}") != NULL) + complete = TRUE; + add_key_value (network, line); + g_free (line); + } while (complete == FALSE + && + g_io_channel_read_line + (channel, &line, NULL, + NULL, NULL) != G_IO_STATUS_EOF); + add_security (network); + //EOF in inner loop + if (complete == FALSE) { + g_free (line); + break; + } + complete = FALSE; + } + } else + g_free (line); + } + + g_io_channel_shutdown (channel, FALSE, NULL); + g_io_channel_unref (channel); + + add_keys_from_net (); +} + +const char * +wpa_get_value (const char *ssid, const char *key) +{ + GHashTable *target = g_hash_table_lookup (wsec_table, ssid); + + if (target) + return g_hash_table_lookup (target, key); + return NULL; +} + +gboolean +exist_ssid (const char *ssid) +{ + return g_hash_table_lookup (wsec_table, ssid) != NULL; +} + +GHashTable * +_get_hash_table (const char *ssid) +{ + return g_hash_table_lookup (wsec_table, ssid); +} + +static gchar *quoted_keys[] = + { "identity", "cert", "private", "phase", "password", NULL }; + +/* tell whether the key needs quotes when writing is performed */ +static gboolean +need_quote (gchar * key) +{ + int i = 0; + + while (quoted_keys[i] != NULL) { + if (strstr (key, quoted_keys[i])) + return TRUE; + i++; + } + return FALSE; +} + +gboolean +wpa_flush_to_file (const char *config_file) +{ + GIOChannel *channel; + GError *error = NULL; + gpointer key, value, ssid, security; + GHashTableIter iter, iter_security; + gchar *out_line; + gsize bytes_written; + gboolean result = FALSE; + + if (!wpa_parser_data_changed) + return TRUE; + if (!wsec_table || !wsec_global_table) + return FALSE; + + backup_file (config_file); + + channel = g_io_channel_new_file (config_file, "w", NULL); + if (!channel) { + nm_log_warn (LOGD_SETTINGS, "Can't open file %s for writing", config_file); + return FALSE; + } + g_hash_table_iter_init (&iter, wsec_global_table); + nm_log_info (LOGD_SETTINGS, "Writing to %s", config_file); + g_io_channel_write_chars (channel, + "#Generated by NetworkManager\n" + "###### Global Configuration ######\n", + -1, &bytes_written, &error); + if (error) + goto done; + + /* Writing global information */ + while (g_hash_table_iter_next (&iter, &key, &value)) { + out_line = + g_strdup_printf ("%s=%s\n", (gchar *) key, (gchar *) value); + g_io_channel_write_chars (channel, out_line, -1, &bytes_written, + &error); + if (bytes_written == 0 || error) + break; + g_free (out_line); + } + if (error) + goto done; + g_io_channel_write_chars (channel, + "\n###### Security Configuration ######\n", + -1, &bytes_written, &error); + if (error) + goto done; + + g_hash_table_iter_init (&iter, wsec_table); + /* Writing security */ + while (g_hash_table_iter_next (&iter, &ssid, &security)) { + g_hash_table_iter_init (&iter_security, + (GHashTable *) security); + g_io_channel_write_chars (channel, "network={\n", -1, + &bytes_written, &error); + if (error) + goto done; + while (g_hash_table_iter_next (&iter_security, &key, &value)) { + out_line = + g_strdup_printf (need_quote ((gchar *) key) ? + "\t%s=\"%s\"\n" : "\t%s=%s\n", + (gchar *) key, (gchar *) value); + g_io_channel_write_chars (channel, out_line, -1, + &bytes_written, &error); + if (bytes_written == 0 || error) + goto done; + g_free (out_line); + } + g_io_channel_write_chars (channel, "}\n\n", -1, &bytes_written, &error); + + } + g_io_channel_flush (channel, &error); + if (error) + goto done; + + wpa_parser_data_changed = FALSE; + result = TRUE; +done: + if (error) { + nm_log_warn (LOGD_SETTINGS, "Error writing WPA configuration: %s", error->message); + g_error_free (error); + } + g_io_channel_shutdown (channel, FALSE, NULL); + g_io_channel_unref (channel); + return result; +} + +/* If value is NULL, this method will delete old key value pair */ +void +wpa_set_data (const char *ssid, const char *key, const char *value) +{ + gpointer old_key = NULL, old_value = NULL; + GHashTable *security = g_hash_table_lookup (wsec_table, ssid); + gchar * stripped = NULL; + + g_return_if_fail (security != NULL); + + if (value){ + stripped = g_strdup(value); + if (strcmp (key, "ssid") != 0 && strcmp (key, "psk") != 0 + && !g_str_has_prefix (key, "wep_key")) + strip_string (stripped, '"'); + } + + /* Remove old key value pairs */ + if (g_hash_table_lookup_extended + (security, key, &old_key, &old_value)) { + if (stripped && !strcmp(old_value, stripped)){ + g_free (stripped); + return; + } + g_hash_table_remove (security, old_key); + g_free (old_key); + g_free (old_value); + } else if (!value) + return; + + /* Add new key value */ + if (stripped) + g_hash_table_insert (security, g_strdup (key), stripped); + wpa_parser_data_changed = TRUE; +} + +gboolean +wpa_has_security (const char *ssid) +{ + return g_hash_table_lookup (wsec_table, ssid) != NULL; +} + +gboolean +wpa_add_security (const char *ssid) +{ + if (wpa_has_security (ssid)) + return TRUE; + else { + GHashTable *security = + g_hash_table_new (nm_str_hash, g_str_equal); + gchar *ssid_i; + + nm_log_info (LOGD_SETTINGS, "Adding security for %s", ssid); + if (g_str_has_prefix (ssid, "0x")) { + /* hex ssid */ + ssid_i = g_strdup (ssid + 2); + } else { + /* ascii ssid requires quotes */ + ssid_i = g_strdup_printf ("\"%s\"", ssid); + } + g_hash_table_insert (security, strdup ("ssid"), ssid_i); + g_hash_table_insert (security, strdup ("priority"), + strdup ("1")); + g_hash_table_insert (wsec_table, g_strdup (ssid), security); + wpa_parser_data_changed = TRUE; + return TRUE; + } +} + +gboolean +wpa_delete_security (const char *ssid) +{ + gpointer old_key, old_value; + + g_return_val_if_fail (wsec_table != NULL && ssid != NULL, FALSE); + nm_log_info (LOGD_SETTINGS, "Deleting security for %s", ssid); + if (!g_hash_table_lookup_extended + (wsec_table, ssid, &old_key, &old_value)) + return FALSE; + g_hash_table_remove (wsec_table, old_key); + g_free (old_key); + destroy_security ((GHashTable *) old_value); + wpa_parser_data_changed = TRUE; + return TRUE; + +} + +void +wpa_parser_destroy (void) +{ + GHashTableIter iter; + gpointer key; + gpointer value; + + /* Destroy security */ + if (wsec_table) { + g_hash_table_iter_init (&iter, wsec_table); + while (g_hash_table_iter_next (&iter, &key, &value)) { + destroy_security ((GHashTable *) value); + g_free (key); + } + + g_hash_table_destroy (wsec_table); + wsec_table = NULL; + } + + /* Destroy global data */ + if (wsec_global_table) { + g_hash_table_iter_init (&iter, wsec_global_table); + while (g_hash_table_iter_next (&iter, &key, &value)) { + g_free (key); + g_free (value); + } + + g_hash_table_destroy (wsec_global_table); + wsec_global_table = NULL; + } +} diff --git a/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.h b/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.h new file mode 100644 index 00000000..d096f468 --- /dev/null +++ b/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.h @@ -0,0 +1,41 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#ifndef _WPA_PARSER_H +#define _WPA_PARSER_H + +#define WPA_SUPPLICANT_CONF SYSCONFDIR "/wpa_supplicant/wpa_supplicant.conf" + +void wpa_parser_init (const char *wpa_supplicant_conf); +void wpa_parser_destroy (void); + +/* reader functions */ +const char *wpa_get_value (const char *ssid, const char *key); +gboolean exist_ssid (const char *ssid); +GHashTable *_get_hash_table (const char *ssid); +gboolean wpa_has_security (const char *ssid); + +/* writer functions */ +gboolean wpa_flush_to_file (const char *config_file); +void wpa_set_data (const char *ssid, const char *key, const char *value); +gboolean wpa_add_security (const char *ssid); +gboolean wpa_delete_security (const char *ssid); +#endif diff --git a/src/settings/plugins/ifnet/tests/net b/src/settings/plugins/ifnet/tests/net new file mode 100644 index 00000000..a5ac9ca2 --- /dev/null +++ b/src/settings/plugins/ifnet/tests/net @@ -0,0 +1,158 @@ +# This blank configuration will automatically use DHCP for any net.* +# scripts in /etc/init.d. To create a more complete configuration, +# please review /etc/conf.d/net.example and save your configuration +# in /etc/conf.d/net (this file :]!). + +modules="!wpa_supplicant" + +config_eth0=( +"202.117.16.121 netmask 255.255.255.0 brd 202.117.16.255" +"192.168.4.121/24" +"dhcp6" +) +routes_eth0=( "default via 202.117.16.1" + "192.168.4.0/24 via 192.168.4.1") +dns_servers_eth0="202.117.0.20 202.117.0.21" +dns_search_eth0="p12.edu.cn p13.edu.cn" + +config_eth1=( + "dhcp" +) +enable_ipv6_eth1="true" +routes_eth1=( "default via 202.117.16.1" ) +dns_servers_eth1="202.117.0.20 202.117.0.21" +config_eth2=( +"202.117.16.1211 netmask 255.255.255.0 brd 202.117.16.255" +"192.168.4.121/24" +"4321:0:1:2:3:4:567:89ab/64" +) +routes_eth2=("default via 4321:0:1:2:3:4:567:89ab") +enable_ipv6_eth2="true" +config_eth3=("nufjlsjlll") +managed_eth4="false" +routes_eth4=("default via 4321:0:1:2:3:4:567:89ab") +config_eth5=("dhcp") + +config_eth7=( "dhcp" ) +auto_eth7="true" + +# missing config_eth8 +auto_eth8="true" + +#new openrc style +config_eth9="202.117.16.10/24 202.117.17.10/24" +routes_eth9="default via 202.117.16.1 +10.0.0.0/8 via 192.168.0.1 +" +config_eth10="202.117.16.2 netmask 255.255.255.0" +routes_eth10="10.0.0.0/8 via 192.168.0.1" + +config_myxjtu2=("202.117.16.121/24 brd 202.117.16.255") +routes_myxjtu2=("default via 202.117.16.1") +dns_servers_myxjtu2="202.117.0.20 202.117.0.21" +#key_myxjtu2="[1] s:xjtud key [1] enc restricted" +#key_eth6="[1] aaaa-4444-3d [2] s:xjtudlc key [1] enc open" + + +username_ppp0='user' +password_ppp0='password' + +config_qiaomuf=("dhcp") + +config_1xtest=("dhcp") + +config_0xab3ace=("dhcp") + +modules=( "iproute2" ) + config_kvm0=( "null" ) + config_kvm1=( "null" ) + + tuntap_kvm0="tap" + tuntap_kvm1="tap" + tunctl_kvm0="-u user" + tunctl_kvm1="-u user" + +bridge_br0="eth0 kvm0 kvm1" +config_br0=( "192.168.1.10/24" ) + brctl_br0=( "setfd 0") + dhcp_eth1="nosendhost nontp -I" + +predown() { + # The default in the script is to test for NFS root and disallow + # downing interfaces in that case. Note that if you specify a + # predown() function you will override that logic. Here it is, in + # case you still want it... + if is_net_fs /; then + eerror "root filesystem is network mounted -- can't stop ${IFACE}" + return 1 + fi + + # Remember to return 0 on success + return 0 +} + +postup() { + # This function could be used, for example, to register with a + # dynamic DNS service. Another possibility would be to + # send/receive mail once the interface is brought up. + + # Here is an example that allows the use of iproute rules + # which have been configured using the rules_eth0 variable. + #rules_eth0=" \ + # 'from 24.80.102.112/32 to 192.168.1.0/24 table localnet priority 100' \ + # 'from 216.113.223.51/32 to 192.168.1.0/24 table localnet priority 100' \ + #" + eval set -- \$rules_${IFVAR} + if [ $# != 0 ]; then + einfo "Adding IP policy routing rules" + eindent + # Ensure that the kernel supports policy routing + if ! ip rule list | grep -q "^"; then + eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)" + eerror "in your kernel to use ip rules" + else + for x; do + ebegin "${x}" + ip rule add ${x} + eend $? + done + fi + eoutdent + # Flush the cache + ip route flush cache dev "${IFACE}" + fi + +} + +postdown() { + # Enable Wake-On-LAN for every interface except for lo + # Probably a good idea to set ifdown="no" in /etc/conf.d/net + # as well ;) + [ "${IFACE}" != "lo" ] && ethtool -s "${IFACE}" wol g + + Automatically erase any ip rules created in the example postup above + if interface_exists "${IFACE}"; then + # Remove any rules for this interface + local rule + ip rule list | grep " iif ${IFACE}[ ]*" | { + while read rule; do + rule="${rule#*:}" + ip rule del ${rule} + done + } + # Flush the route cache + ip route flush cache dev "${IFACE}" + fi + + # Return 0 always + return 0 +} + +failup() { + # This function is mostly here for completeness... I haven't + # thought of anything nifty to do with it yet ;-) +} + +faildown() +{} + diff --git a/src/settings/plugins/ifnet/tests/net.all b/src/settings/plugins/ifnet/tests/net.all new file mode 100644 index 00000000..285a4cdf --- /dev/null +++ b/src/settings/plugins/ifnet/tests/net.all @@ -0,0 +1,864 @@ +############################################################################## +# QUICK-START +# +# The quickest start is if you want to use DHCP. +# In that case, everything should work out of the box, no configuration +# necessary, though the startup script will warn you that you haven't +# specified anything. + +# WARNING :- some examples have a mixture of IPv4 (ie 192.168.0.1) and IPv6 +# (ie 4321:0:1:2:3:4:567:89ab) internet addresses. They only work if you have +# the relevant kernel option enabled. So if you don't have an IPv6 enabled +# kernel then remove the IPv6 address from your config. + +# If you want to use a static address or use DHCP explicitly, jump +# down to the section labelled INTERFACE HANDLERS. +# +# If you want to do anything more fancy, you should take the time to +# read through the rest of this file. + +############################################################################## +# MODULES +# +# We now support modular networking scripts which means we can easily +# add support for new interface types and modules while keeping +# compatability with existing ones. +# +# Modules load by default if the package they need is installed. If +# you specify a module here that doesn't have it's package installed +# then you get an error stating which package you need to install. +# Ideally, you only use the modules setting when you have two or more +# packages installed that supply the same service. +# +# In other words, you probably should DO NOTHING HERE... + +# Prefer ifconfig over iproute2 +modules=( "ifconfig" ) + +# You can also specify other modules for an interface +# In this case we prefer udhcpc over dhcpcd +modules_eth0=( "udhcpc" ) + +# You can also specify which modules not to use - for example you may be +# using a supplicant or linux-wlan-ng to control wireless configuration but +# you still want to configure network settings per ESSID associated with. +modules=( "!iwconfig" "!wpa_supplicant" ) +# IMPORTANT: If you need the above, please disable modules in that order + + +############################################################################## +# INTERFACE HANDLERS +# +# We provide two interface handlers presently: ifconfig and iproute2. +# You need one of these to do any kind of network configuration. +# For ifconfig support, emerge sys-apps/net-tools +# For iproute2 support, emerge sys-apps/iproute2 + +# If you don't specify an interface then we prefer iproute2 if it's installed +# To prefer ifconfig over iproute2 +modules=( "ifconfig" ) + +# For a static configuration, use something like this +# (They all do exactly the same thing btw) +config_eth0=( "192.168.0.2/24" ) +config_eth0=( "192.168.0.2 netmask 255.255.255.0" ) + +# We can also specify a broadcast +config_eth0=( "192.168.0.2/24 brd 192.168.0.255" ) +config_eth0=( "192.168.0.2 netmask 255.255.255.0 broadcast 192.168.0.255" ) + +# If you need more than one address, you can use something like this +# NOTE: ifconfig creates an aliased device for each extra IPv4 address +# (eth0:1, eth0:2, etc) +# iproute2 does not do this as there is no need to +config_eth0=( + "192.168.0.2/24" + "192.168.0.3/24" + "192.168.0.4/24" +) +# Or you can use sequence expressions +config_eth0=( "192.168.0.{2..4}/24" ) +# which does the same as above. Be careful though as if you use this and +# fallbacks, you have to ensure that both end up with the same number of +# values otherwise your fallback won't work correctly. + +# You can also use IPv6 addresses +# (you should always specify a prefix length with IPv6 here) +config_eth0=( + "192.168.0.2/24" + "4321:0:1:2:3:4:567:89ab/64" + "4321:0:1:2:3:4:567:89ac/64" +) + +# If you wish to keep existing addresses + routing and the interface is up, +# you can specify a noop (no operation). If the interface is down or there +# are no addresses assigned, then we move onto the next step (default dhcp) +# This is useful when configuring your interface with a kernel command line +# or similar +config_eth0=( "noop" "192.168.0.2/24" ) + +# If you don't want ANY address (only useful when calling for advanced stuff) +config_eth0=( "null" ) + +# Here's how to do routing if you need it +routes_eth0=( + "default via 192.168.0.1" # IPv4 default route + "10.0.0.0/8 via 192.168.0.1" # IPv4 subnet route + "::/0" # IPv6 unicast +) + +# If a specified module fails (like dhcp - see below), you can specify a +# fallback like so +fallback_eth0=( "192.168.0.2 netmask 255.255.255.0" ) +fallback_route_eth0=( "default via 192.168.0.1" ) + +# NOTE: fallback entry must match the entry location in config_eth0 +# As such you can only have one fallback route. + +# Some users may need to alter the MTU - here's how +mtu_eth0="1500" + +# Each module described below can set a default base metric, lower is +# preferred over higher. This is so we can prefer a wired route over a +# wireless route automaticaly. You can override this by setting +metric_eth0="100" +# or on a global basis +metric="100" +# The only downside of the global setting is that you have to ensure that +# there are no conflicting routes yourself. For users with large routing +# tables you may have to set a global metric as the due to a simple read of +# the routing table taking over a minute at a time. + +############################################################################## +# OPTIONAL MODULES + +# INTERFACE RENAMING +# There is no consistent device renaming scheme for Linux. +# The preferred way of naming devices is via the kernel module directly or +# by using udev (http://www.reactivated.net/udevrules.php) + +# If you are unable to write udev rules, then we do provide a way of renaming +# the interface based on it's MAC address, but it is not optimal. +# Here is how to rename an interface whose MAC address is 00:11:22:33:44:55 +# to foo1 +rename_001122334455="foo1" + +# You can also do this based on current device name - although this is not +# recommended. Here we rename eth1 to foo2. +rename_eth1="foo2" + +#----------------------------------------------------------------------------- +# WIRELESS (802.11 support) +# Wireless can be provided by iwconfig or wpa_supplicant + +# iwconfig +# emerge net-wireless/wireless-tools +# Wireless options are held in /etc/conf.d/wireless - but could be here too +# Consult the sample file /etc/conf.d/wireless.example for instructions +# iwconfig is the default + +# wpa_supplicant +# emerge net-wireless/wpa-supplicant +# Wireless options are held in /etc/wpa_supplicant.conf +# Consult the sample file /etc/wpa_supplicant.conf.example for instructions +# To choose wpa_supplicant over iwconfig +modules=( "wpa_supplicant" ) +# To configure wpa_supplicant +wpa_supplicant_eth0="-Dwext" # For generic wireless +wpa_supplicant_ath0="-Dmadwifi" # For Atheros based cards +# Consult wpa_supplicant for more drivers +# By default don't wait for wpa_suppliant to associate and authenticate. +# If you would like to, so can specify how long in seconds +associate_timeout_eth0=60 +# A value of 0 means wait forever. + +# GENERIC WIRELESS OPTIONS +# PLEASE READ THE INSTRUCTIONS IN /etc/conf.d/wireless.example FOR +# HOW TO USE THIS ESSID VARIABLE +# You can also override any settings found here per ESSID - which is very +# handy if you use different networks a lot +config_ESSID=( "dhcp" ) +dhcpcd_ESSID="-t 5" + +# Setting name/domain server causes /etc/resolv.conf to be overwritten +# Note that if DHCP is used, and you want this to take precedence then + set dhcp_ESSID="nodns" +dns_servers_ESSID=( "192.168.0.1" "192.168.0.2" ) +dns_domain_ESSID="some.domain" +dns_search_ESSID="search.this.domain search.that.domain" +# Please check the man page for resolv.conf for more information +# as domain and search are mutually exclusive. + +# You can also override any settings found here per MAC address of the AP +# in case you use Access Points with the same ESSID but need different +# networking configs. Below is an example - of course you use the same +# method with other variables +mac_config_001122334455=( "dhcp" ) +mac_dhcpcd_001122334455="-t 10" +mac_dns_servers_001122334455=( "192.168.0.1" "192.168.0.2" ) + +# When an interface has been associated with an Access Point, a global +# variable called ESSID is set to the Access Point's ESSID for use in the +# pre/post user functions below (although it's not available in preup as you +# won't have associated then) + +# If you're using anything else to configure wireless on your interface AND +# you have installed any of the above packages, you need to disable them +modules=( "!iwconfig" "!wpa_supplicant" ) + +#----------------------------------------------------------------------------- +# DHCP +# DHCP can be provided by dhclient, dhcpcd, pump or udhcpc. +# +# dhclient: emerge net-misc/dhcp +# dhcpcd: emerge net-misc/dhcpcd +# pump: emerge net-misc/pump +# udhcpc: emerge net-misc/udhcp + +# If you have more than one DHCP client installed, you need to specify which +# one to use - otherwise we default to dhcpcd if available. +modules=( "dhclient" ) # to select dhclient over dhcpcd +# +# Notes: +# - All clients send the current hostname to the DHCP server by default +# - dhcpcd does not daemonize when the lease time is infinite +# - udhcp-0.9.3-r3 and earlier do not support getting NTP servers +# - pump does not support getting NIS servers +# - DHCP tends to erase any existing device information - so add +# static addresses after dhcp if you need them +# - dhclient and udhcpc can set other resolv.conf options such as "option" +# and "sortlist"- see the System module for more details + +# Regardless of which DHCP client you prefer, you configure them the +# same way using one of following depending on which interface modules +# you're using. +config_eth0=( "dhcp" ) + +# For passing custom options to dhcpcd use something like the following. This +# example reduces the timeout for retrieving an address from 60 seconds (the +# default) to 10 seconds. +dhcpcd_eth0="-t 10" + +# dhclient, udhcpc and pump don't have many runtime options +# You can pass options to them in a similar manner to dhcpcd though +dhclient_eth0="..." +udhcpc_eth0="..." +pump_eth0="..." + +# GENERIC DHCP OPTIONS +# Set generic DHCP options like so +dhcp_eth0="release nodns nontp nonis nogateway nosendhost" + +# This tells the dhcp client to release it's lease when it stops, not to +# overwrite dns, ntp and nis settings, not to set a default route and not to +# send the current hostname to the dhcp server and when it starts. +# You can use any combination of the above options - the default is not to +# use any of them. + +#----------------------------------------------------------------------------- +# For APIPA support, emerge net-misc/iputils or net-analyzer/arping + +# APIPA is a module that tries to find a free address in the range +# 169.254.0.0-169.254.255.255 by arping a random address in that range on the +# interface. If no reply is found then we assign that address to the interface + +# This is only useful for LANs where there is no DHCP server and you don't +# connect directly to the internet. +config_eth0=( "dhcp" ) +fallback_eth0=( "apipa" ) + +#----------------------------------------------------------------------------- +# ARPING Gateway configuration +# and +# Automatic Private IP Addressing (APIPA) +# For arpingnet / apipa support, emerge net-misc/iputils or net-analyzer/arping +# +# This is a module that tries to find a gateway IP. If it exists then we use +# that gateways configuration for our own. For the configuration variables +# simply ensure that each octet is zero padded and the dots are removed. +# Below is an example. +# +gateways_eth0="192.168.0.1 10.0.0.1" +config_192168000001=( "192.168.0.2/24" ) +routes_192168000001=( "default via 192.168.0.1" ) +dns_servers_192168000001=( "192.168.0.1" ) +config_010000000001=( "10.0.0.254/8" ) +routes_010000000001=( "default via 10.0.0.1" ) +dns_servers_010000000001=( "10.0.0.1" ) + +# We can also specify a specific MAC address for each gateway if different +# networks have the same gateway. +gateways_eth0="192.168.0.1,00:11:22:AA:BB:CC 10.0.0.1,33:44:55:DD:EE:FF" +config_192168000001_001122AABBCC=( "192.168.0.2/24" ) +routes_192168000001_001122AABBCC=( "default via 192.168.0.1" ) +dns_servers_192168000001_001122AABBCC=( "192.168.0.1" ) +config_010000000001_334455DDEEFF=( "10.0.0.254/8" ) +routes_010000000001_334455DDEEFF=( "default via 10.0.0.1" ) +dns_servers_010000000001_334455DDEEFF=( "10.0.0.1" ) + +# If we don't find any gateways (or there are none configured) then we try and +# use APIPA to find a free address in the range 169.254.0.0-169.254.255.255 +# by arping a random address in that range on the interface. If no reply is +# found then we assign that address to the interface. + +# This is only useful for LANs where there is no DHCP server. +config_eth0=( "arping" ) + +# or if no DHCP server can be found +config_eth0=( "dhcp" ) +fallback_eth0=( "arping" ) + +# NOTE: We default to sleeping for 1 second the first time we attempt an +# arping to give the interface time to settle on the LAN. This appears to +# be a good default for most instances, but if not you can alter it here. +arping_sleep=5 +arping_sleep_lan=7 + +# NOTE: We default to waiting 3 seconds to get an arping response. You can +# change the default wait like so. +arping_wait=3 +arping_wait_lan=2 + +#----------------------------------------------------------------------------- +# VLAN (802.1q support) +# For VLAN support, emerge net-misc/vconfig + +# Specify the VLAN numbers for the interface like so +# Please ensure your VLAN IDs are NOT zero-padded +vlans_eth0="1 2" + +# You may not want to assign an IP to the physical interface, but we still +# need it up. +config_eth0=( "null" ) + +# You can also configure the VLAN - see for vconfig man page for more details +vconfig_eth0=( "set_name_type VLAN_PLUS_VID_NO_PAD" ) +vconfig_vlan1=( "set_flag 1" "set_egress_map 2 6" ) +config_vlan1=( "172.16.3.1 netmask 255.255.254.0" ) +config_vlan2=( "172.16.2.1 netmask 255.255.254.0" ) + +# NOTE: Vlans can be configured with a . in their interface names +# When configuring vlans with this name type, you need to replace . with a _ +config_eth0.1=( "dhcp" ) - does not work +config_eth0_1=( "dhcp" ) - does work + +# NOTE: Vlans are controlled by their physical interface and not per vlan +# This means you do not need to create init scripts in /etc/init.d for each +# vlan, you must need to create one for the physical interface. +# If you wish to control the configuration of each vlan through a separate +# script, or wish to rename the vlan interface to something that vconfig +# cannot then you need to do this. +vlan_start_eth0="no" + +# If you do the above then you may want to depend on eth0 like so + RC_NEED_vlan1="net.eth0" +# NOTE: depend functions only work in /etc/conf.d/net +# and not in profile configs such as /etc/conf.d/net.foo + +#----------------------------------------------------------------------------- +# Bonding +# For link bonding/trunking emerge net-misc/ifenslave + +# To bond interfaces together +slaves_bond0="eth0 eth1 eth2" +config_bond0=( "null" ) # You may not want to assign an IP to the bond + +# If any of the slaves require extra configuration - for example wireless or +# ppp devices - we need to depend function on the bonded interfaces +RC_NEED_bond0="net.eth0 net.eth1" + + +#----------------------------------------------------------------------------- +# Classical IP over ATM +# For CLIP support emerge net-dialup/linux-atm + +# Ensure that you have /etc/atmsigd.conf setup correctly +# Now setup each clip interface like so +clip_atm0=( "peer_ip [if.]vpi.vci [opts]" ... ) +# where "peer_ip" is the IP address of a PVC peer (in case of an ATM connection +# with your ISP, your only peer is usually the ISP gateway closest to you), +# "if" is the number of the ATM interface which will carry the PVC, "vpi.vci" +# is the ATM VC address, and "opts" may optionally specify VC parameters like +# qos, pcr, and the like (see "atmarp -s" for further reference). Please also +# note quoting: it is meant to distinguish the VCs you want to create. You may, +# in example, create an atm0 interface to more peers, like this: +clip_atm0=( "1.1.1.254 0.8.35" "1.1.1.253 1.8.35" ) + +# By default, the PVC will use the LLC/SNAP encapsulation. If you rather need a +# null encapsulation (aka "VC mode"), please add the keyword "null" to opts. + + +#----------------------------------------------------------------------------- +# PPP +# For PPP support, emerge net-dialup/ppp +# PPP is used for most dialup connections, including ADSL. +# The older ADSL module is documented below, but you are encouraged to try +# this module first. +# +# You need to create the PPP net script yourself. Make it like so +#ln -s net.lo /etc/init.d/net.ppp0 +# +# We have to instruct ppp0 to actually use ppp +config_ppp0=( "ppp" ) +# +# Each PPP interface requires an interface to use as a "Link" +link_ppp0="/dev/ttyS0" # Most PPP links will use a serial port +link_ppp0="eth0" # PPPoE requires an ethernet interface +link_ppp0="[itf.]vpi.vci" # PPPoA requires the ATM VC's address +link_ppp0="/dev/null" # ISDN links should have this +link_ppp0="pty 'your_link_command'" # PPP links over ssh, rsh, etc +# +# Here you should specify what pppd plugins you want to use +# Available plugins are: pppoe, pppoa, capi, dhcpc, minconn, radius, +# radattr, radrealms and winbind +plugins_ppp0=( + "pppoe" # Required plugin for PPPoE + "pppoa vc-encaps" # Required plugin for PPPoA with an option + "capi" # Required plugin for ISDN +) +# +# PPP requires at least a username. You can optionally set a password here too +# If you don't, then it will use the password specified in /etc/ppp/*-secrets +# against the specified username +username_ppp0='user' +password_ppp0='password' +# NOTE: You can set a blank password like so +password_ppp0= +# +# The PPP daemon has many options you can specify - although there are many +# and may seem daunting, it is recommended that you read the pppd man page +# before enabling any of them +pppd_ppp0=( + "maxfail 0" # WARNING: It's not recommended you use this + # if you don't specify maxfail then we assume 0 + "updetach" # If not set, "/etc/init.d/net.ppp0 start" will return + # immediately, without waiting the link to come up + # for the first time. + # Do not use it for dial-on-demand links! + "debug" # Enables syslog debugging + "noauth" # Do not require the peer to authenticate itself + "defaultroute" # Make this PPP interface the default route + "usepeerdns" # Use the DNS settings provided by PPP + +# On demand options + "demand" # Enable dial on demand + "idle 30" # Link goes down after 30 seconds of inactivity + "10.112.112.112:10.112.112.113" # Phony IP addresses + "ipcp-accept-remote" # Accept the peers idea of remote address + "ipcp-accept-local" # Accept the peers idea of local address + "holdoff 3" # Wait 3 seconds after link dies before re-starting + +# Dead peer detection + "lcp-echo-interval 15" # Send a LCP echo every 15 seconds + "lcp-echo-failure 3" # Make peer dead after 3 consective + # echo-requests + +# Compression options - use these to completely disable compression +# noaccomp noccp nobsdcomp nodeflate nopcomp novj novjccomp + +# Dial-up settings + "lock" # Lock serial port + "115200" # Set the serial port baud rate + "modem crtscts" # Enable hardware flow control + "192.168.0.1:192.168.0.2" # Local and remote IP addresses +) +# +# Dial-up PPP users need to specify at least one telephone number +phone_number_ppp0=( "12345689" ) # Maximum 2 phone numbers are supported +# They will also need a chat script - here's a good one +chat_ppp0=( +# 'ABORT' 'BUSY' +# 'ABORT' 'ERROR' +# 'ABORT' 'NO ANSWER' +# 'ABORT' 'NO CARRIER' +# 'ABORT' 'NO DIALTONE' +# 'ABORT' 'Invalid Login' +# 'ABORT' 'Login incorrect' +# 'TIMEOUT' '5' +# '' 'ATZ' +# 'OK' 'AT' # Put your modem initialization string here +# 'OK' 'ATDT\T' +# 'TIMEOUT' '60' +# 'CONNECT' '' +# 'TIMEOUT' '5' +# '~--' '' +) + +# If the link require extra configuration - for example wireless or +# RFC 268 bridge - we need to depend on the bridge so they get +# configured correctly. +RC_NEED_ppp0="net.nas0" + +#WARNING: if MTU of the PPP interface is less than 1500 and you use this +#machine as a router, you should add the following rule to your firewall +# +#iptables -I FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu + +#----------------------------------------------------------------------------- +# ADSL +# For ADSL support, emerge net-dialup/rp-pppoe +# WARNING: This ADSL module is being deprecated in favour of the PPP module +# above. +# You should make the following settings and also put your +# username/password information in /etc/ppp/pap-secrets + +# Configure the interface to use ADSL +config_eth0=( "adsl" ) + +# You probably won't need to edit /etc/ppp/pppoe.conf if you set this +adsl_user_eth0="my-adsl-username" + +#----------------------------------------------------------------------------- +# ISDN +# For ISDN support, emerge net-dialup/isdn4k-utils +# You should make the following settings and also put your +# username/password information in /etc/ppp/pap-secrets + +# Configure the interface to use ISDN +config_ippp0=( "dhcp" ) +# It's important to specify dhcp if you need it! +config_ippp0=( "192.168.0.1/24" ) +# Otherwise, you can use a static IP + +# NOTE: The interface name must be either ippp or isdn followed by a number + +# You may need this option to set the default route +ipppd_eth0="defaultroute" + +#----------------------------------------------------------------------------- +# MAC changer +# To set a specific MAC address +mac_eth0="00:11:22:33:44:55" + +# For changing MAC addresses using the below, emerge net-analyzer/macchanger +# - to randomize the last 3 bytes only +mac_eth0="random-ending" +# - to randomize between the same physical type of connection (e.g. fibre, +# copper, wireless) , all vendors +mac_eth0="random-samekind" +# - to randomize between any physical type of connection (e.g. fibre, copper, +# wireless) , all vendors +mac_eth0="random-anykind" +# - full randomization - WARNING: some MAC addresses generated by this may NOT +# act as expected +mac_eth0="random-full" +# custom - passes all parameters directly to net-analyzer/macchanger +mac_eth0="some custom set of parameters" + +# You can also set other options based on the MAC address of your network card +# Handy if you use different docking stations with laptops +config_001122334455=( "dhcp" ) + +#----------------------------------------------------------------------------- +# TUN/TAP +# For TUN/TAP support emerge net-misc/openvpn or sys-apps/usermode-utilities +# +# You must specify if we're a tun or tap device. Then you can give it any +# name you like - such as vpn +tuntap_vpn="tun" +config_vpn=( "192.168.0.1/24") + +# Or stick wit the generic names - like tap0 +tuntap_tap0="tap" +config_tap0=( "192.168.0.1/24") + +# For passing custom options to tunctl use something like the following. This +# example sets the owner to adm +tunctl_tun1="-u adm" +# When using openvpn, there are no options + +#----------------------------------------------------------------------------- +# Bridging (802.1d) +# For bridging support emerge net-misc/bridge-utils + +# To add ports to bridge br0 +bridge_br0="eth0 eth1" +# or dynamically add them when the interface comes up +bridge_add_eth0="br0" +bridge_add_eth1="br0" + +# You need to configure the ports to null values so dhcp does not get started +config_eth0=( "null" ) +config_eth1=( "null" ) + +# Finally give the bridge an address - dhcp or a static IP +config_br0=( "dhcp" ) # may not work when adding ports dynamically +config_br0=( "192.168.0.1/24" ) + +# If any of the ports require extra configuration - for example wireless or +# ppp devices - we need to depend on them like so. +RC_NEED_br0="net.eth0 net.eth1" + +# Below is an example of configuring the bridge +# Consult "man brctl" for more details +brctl_br0=( "setfd 0" "sethello 0" "stp off" ) + +#----------------------------------------------------------------------------- +# RFC 2684 Bridge Support +# For RFC 2684 bridge support emerge net-misc/br2684ctl + +# Interface names have to be of the form nas0, nas1, nas2, etc. +# You have to specify a VPI and VCI for the interface like so +br2684ctl_nas0="-a 0.38" # UK VPI and VCI + +# You may want to configure the encapsulation method as well by adding the -e +# option to the command above (may need to be before the -a command) +# -e 0 # LLC (default) +# -e 1 # VC mux + +# Then you can configure the interface as normal +config_nas0=( "192.168.0.1/24" ) + +#----------------------------------------------------------------------------- +# Tunnelling +# WARNING: For tunnelling it is highly recommended that you +# emerge sys-apps/iproute2 +# +# For GRE tunnels +iptunnel_vpn0="mode gre remote 207.170.82.1 key 0xffffffff ttl 255" + +# For IPIP tunnels +iptunnel_vpn0="mode ipip remote 207.170.82.2 ttl 255" + +# To configure the interface +config_vpn0=( "192.168.0.2 pointopoint 192.168.1.2" ) # ifconfig style +config_vpn0=( "192.168.0.2 peer 192.168.1.1" ) # iproute2 style + +# 6to4 Tunnels allow IPv6 to work over IPv4 addresses, provided you +# have a non-private address configured on an interface. + link_6to4="eth0" # Interface to base it's addresses on + config_6to4=( "ip6to4" ) +# You may want to depend on eth0 like so +RC_NEED_6to4="net.eth0" +# To ensure that eth0 is configured before 6to4. Of course, the tunnel could be +# any name and this also works for any configured interface. +# NOTE: If you're not using iproute2 then your 6to4 tunnel has to be called +# sit0 - otherwise use a different name like 6to4 in the example above. + + +#----------------------------------------------------------------------------- +# System +# For configuring system specifics such as domain, dns, ntp and nis servers +# It's rare that you would need todo this, but you can anyway. +# This is most benefit to wireless users who don't use DHCP so they can change +# their configs based on ESSID. See wireless.example for more details + +# To use dns settings such as these, dns_servers_eth0 must be set! +# If you omit the _eth0 suffix, then it applies to all interfaces unless +# overridden by the interface suffix. +dns_domain_eth0="your.domain" +dns_servers_eth0="192.168.0.2 192.168.0.3" +dns_search_eth0="this.domain that.domain" +dns_options_eth0=( "timeout 1" "rotate" ) +dns_sortlist_eth0="130.155.160.0/255.255.240.0 130.155.0.0" +# See the man page for resolv.conf for details about the options and sortlist +# directives + +ntp_servers_eth0="192.168.0.2 192.168.0.3" + +nis_domain_eth0="domain" +nis_servers_eth0="192.168.0.2 192.168.0.3" + +# NOTE: Setting any of these will stamp on the files in question. So if you +# don't specify dns_servers but you do specify dns_domain then no nameservers +# will be listed in /etc/resolv.conf even if there were any there to start +# with. +# If this is an issue for you then maybe you should look into a resolv.conf +# manager like resolvconf-gentoo to manage this file for you. All packages +# that baselayout supports use resolvconf-gentoo if installed. + +#----------------------------------------------------------------------------- +# Cable in/out detection +# Sometimes the cable is in, others it's out. Obviously you don't want to +# restart net.eth0 every time when you plug it in either. +# +# netplug is a package that detects this and requires no extra configuration +# on your part. +# emerge sys-apps/netplug +# or +# emerge sys-apps/ifplugd +# and you're done :) + +# By default we don't wait for netplug/ifplugd to configure the interface. +# If you would like it to wait so that other services now that network is up +# then you can specify a timeout here. +plug_timeout="10" +# A value of 0 means wait forever. + +# If you don't want to use netplug on a specific interface but you have it +# installed, you can disable it for that interface via the modules statement +modules_eth0=( "!netplug" ) +# You can do the same for ifplugd +# +# You can disable them both with the generic plug +modules_eth0=( "!plug" ) + +# To use specific ifplugd options, fex specifying wireless mode +ifplugd_eth0="--api-mode=wlan" +# man ifplugd for more options + +############################################################################## +# ADVANCED CONFIGURATION +# +# Four functions can be defined which will be called surrounding the +# start/stop operations. The functions are called with the interface +# name first so that one function can control multiple adapters. An extra two +# functions can be defined when an interface fails to start or stop. +# +# The return values for the preup and predown functions should be 0 +# (success) to indicate that configuration or deconfiguration of the +# interface can continue. If preup returns a non-zero value, then +# interface configuration will be aborted. If predown returns a +# non-zero value, then the interface will not be allowed to continue +# deconfiguration. +# +# The return values for the postup, postdown, failup and faildown functions are +# ignored since there's nothing to do if they indicate failure. +# +# ${IFACE} is set to the interface being brought up/down +# ${IFVAR} is ${IFACE} converted to variable name bash allows + +#preup() { +# # Test for link on the interface prior to bringing it up. This +# # only works on some network adapters and requires the mii-diag +# # package to be installed. +# if mii-tool "${IFACE}" 2> /dev/null | grep -q 'no link'; then +# ewarn "No link on ${IFACE}, aborting configuration" +# return 1 +# fi +# +# # Test for link on the interface prior to bringing it up. This +# # only works on some network adapters and requires the ethtool +# # package to be installed. +# if ethtool "${IFACE}" | grep -q 'Link detected: no'; then +# ewarn "No link on ${IFACE}, aborting configuration" +# return 1 +# fi +# +# +# # Remember to return 0 on success +# return 0 +#} + +#predown() { +# # The default in the script is to test for NFS root and disallow +# # downing interfaces in that case. Note that if you specify a +# # predown() function you will override that logic. Here it is, in +# # case you still want it... +# if is_net_fs /; then +# eerror "root filesystem is network mounted -- can't stop ${IFACE}" +# return 1 +# fi +# +# # Remember to return 0 on success +# return 0 +#} + +#postup() { +# # This function could be used, for example, to register with a +# # dynamic DNS service. Another possibility would be to +# # send/receive mail once the interface is brought up. + +# # Here is an example that allows the use of iproute rules +# # which have been configured using the rules_eth0 variable. +# #rules_eth0=( +# # "from 24.80.102.112/32 to 192.168.1.0/24 table localnet priority 100" +# # "from 216.113.223.51/32 to 192.168.1.0/24 table localnet priority 100" +# #) +# local x="rules_${IFVAR}[@]" +# local -a rules=( "${!x}" ) +# if [[ -n ${rules} ]] ; then +# einfo "Adding IP policy routing rules" +# eindent +# # Ensure that the kernel supports policy routing +# if ! ip rule list | grep -q "^" ; then +# eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)" +# eerror "in your kernel to use ip rules" +# else +# for x in "${rules[@]}" ; do +# ebegin "${x}" +# ip rule add ${x} dev "${IFACE}" +# eend $? +# done +# fi +# eoutdent +# # Flush the cache +# ip route flush cache dev "${IFACE}" +# fi + +#} + +#postdown() { +# # Enable Wake-On-LAN for every interface except for lo +# # Probably a good idea to set RC_DOWN_INTERFACE="no" in /etc/conf.d/rc +# # as well ;) +# [[ ${IFACE} != "lo" ]] && ethtool -s "${IFACE}" wol g + +# Automatically erase any ip rules created in the example postup above +# if interface_exists "${IFACE}" ; then +# # Remove any rules for this interface +# local rule +# ip rule list | grep " iif ${IFACE}[ ]*" | { +# while read rule ; do +# rule="${rule#*:}" +# ip rule del ${rule} +# done +# } +# # Flush the route cache +# ip route flush cache dev "${IFACE}" +# fi + +# # Return 0 always +# return 0 +#} + +#failup() { +# # This function is mostly here for completeness... I haven't +# # thought of anything nifty to do with it yet ;-) +#} + +#faildown() { +# # This function is mostly here for completeness... I haven't +# # thought of anything nifty to do with it yet ;-) +#} + +############################################################################## +# FORCING MODULES +# The Big Fat Warning :- If you use module forcing do not complain to us or +# file bugs about it not working! +# +# Loading modules is a slow affair - we have to check each one for the following +# 1) Code sanity +# 2) Has the required package been emerged? +# 3) Has it modified anything? +# 4) Have all the dependant modules been loaded? + +# Then we have to strip out the conflicting modules based on user preference +# and default configuration and sort them into the correct order. +# Finally we check the end result for dependencies. + +# This, of course, takes valuable CPU time so we provide module forcing as a +# means to speed things up. We still do *some* checking but not much. + +# It is essential that you force modules in the correct order and supply all +# the modules you need. You must always supply an interface module - we +# supply ifconfig or iproute2. + +# The Big Fat Warning :- If you use module forcing do not complain to us or +# file bugs about it not working! + +# Now that we've warned you twice, here's how to do it +modules_force=( "ifconfig" ) +modules_force=( "iproute2" "dhcpcd" ) + +# We can also apply this to a specific interface +modules_force_eth1=( "iproute2" ) + +# The below will not work +modules_force=( "dhcpcd" ) +# No interface (ifconfig/iproute2) +modules_force=( "ifconfig" "essidnet" "iwconfig" ) +# Although it will not crash, essidnet will not work as it has to come after +# iwconfig +modules_force=( "iproute2" "ifconfig" ) +# The interface will be setup twice which will cause problems diff --git a/src/settings/plugins/ifnet/tests/nm-system-settings.conf b/src/settings/plugins/ifnet/tests/nm-system-settings.conf new file mode 100644 index 00000000..39bc87b8 --- /dev/null +++ b/src/settings/plugins/ifnet/tests/nm-system-settings.conf @@ -0,0 +1,5 @@ +[main] +plugins=ifnet,keyfile + +[ifnet] +managed=false diff --git a/src/settings/plugins/ifnet/tests/test-ifnet.c b/src/settings/plugins/ifnet/tests/test-ifnet.c new file mode 100644 index 00000000..68f2b928 --- /dev/null +++ b/src/settings/plugins/ifnet/tests/test-ifnet.c @@ -0,0 +1,396 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service (ifnet) + * + * Mu Qiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include "nm-default.h" + +#include +#include +#include +#include +#include + +#include "nm-utils.h" + +#include "platform/nm-linux-platform.h" +#include "dhcp/nm-dhcp-manager.h" + +#include "settings/plugins/ifnet/nms-ifnet-net-parser.h" +#include "settings/plugins/ifnet/nms-ifnet-net-utils.h" +#include "settings/plugins/ifnet/nms-ifnet-wpa-parser.h" +#include "settings/plugins/ifnet/nms-ifnet-connection-parser.h" + +#include "nm-test-utils-core.h" + +/* Fake config handling; the values it returns don't matter, so this + * is easier than forcing it to read our own config file, etc. + */ +NMDhcpManager * +nm_dhcp_manager_get (void) +{ + return NULL; +} + +const char * +nm_dhcp_manager_get_config (NMDhcpManager *dhcp_manager) +{ + return "dhclient"; +} + +static void +test_getdata (void) +{ + g_assert (ifnet_get_data ("eth1", "config") && + strcmp (ifnet_get_data ("eth1", "config"), "( \"dhcp\" )") == 0); + g_assert (ifnet_get_data ("ppp0", "username") && + strcmp (ifnet_get_data ("ppp0", "username"), "user") == 0); + g_assert (ifnet_get_data ("ppp0", "password") && + strcmp (ifnet_get_data ("ppp0", "password"), "password") == 0); + g_assert (ifnet_get_global_data ("modules") && + strcmp ("!wpa_supplicant", ifnet_get_global_data ("modules")) == 0); +} + +static void +test_is_static (void) +{ + g_assert (!is_static_ip4 ("eth1")); + g_assert (is_static_ip4 ("eth0")); + g_assert (!is_static_ip6 ("eth0")); +} + +static void +test_has_default_route (void) +{ + g_assert (has_default_ip4_route ("eth0")); + g_assert (has_default_ip6_route ("eth4")); + g_assert (!has_default_ip4_route ("eth5") && + !has_default_ip6_route ("eth5")); +} + +static void +test_has_ip6_address (void) +{ + g_assert (has_ip6_address ("eth2")); + g_assert (!has_ip6_address ("eth0")); +} + +static void +test_is_ip4_address (void) +{ + gchar *address1 = "192.168.4.232/24"; + gchar *address2 = "192.168.100.{1..254}/24"; + gchar *address3 = "192.168.4.2555/24"; + + g_assert (is_ip4_address (address1)); + g_assert (is_ip4_address (address2)); + g_assert (!is_ip4_address (address3)); +} + +static void +test_is_ip6_address (void) +{ + gchar *address1 = "4321:0:1:2:3:4:567:89ac/24"; + + g_assert (is_ip6_address (address1)); +} + +static void +check_ip_block (ip_block * iblock, gchar * ip, guint32 prefix, gchar * gateway) +{ + g_assert_cmpstr (ip, ==, iblock->ip); + g_assert (prefix == iblock->prefix); + g_assert_cmpstr (gateway, ==, iblock->next_hop); +} + +static void +test_convert_ipv4_config_block (void) +{ + ip_block *iblock = convert_ip4_config_block ("eth0"); + ip_block *tmp = iblock; + + g_assert (iblock != NULL); + check_ip_block (iblock, "202.117.16.121", 24, "202.117.16.1"); + iblock = iblock->next; + destroy_ip_block (tmp); + g_assert (iblock != NULL); + check_ip_block (iblock, "192.168.4.121", 24, "202.117.16.1"); + destroy_ip_block (iblock); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*Can't handle IPv4 address*202.117.16.1211*"); + iblock = convert_ip4_config_block ("eth2"); + g_test_assert_expected_messages (); + g_assert (iblock != NULL && iblock->next == NULL); + check_ip_block (iblock, "192.168.4.121", 24, NULL); + destroy_ip_block (iblock); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*missing netmask or prefix*"); + iblock = convert_ip4_config_block ("eth3"); + g_assert (iblock == NULL); +} + +static void +test_convert_ipv4_routes_block (void) +{ + ip_block *iblock = convert_ip4_routes_block ("eth0"); + ip_block *tmp = iblock; + + g_assert (iblock != NULL); + check_ip_block (iblock, "192.168.4.0", 24, "192.168.4.1"); + iblock = iblock->next; + destroy_ip_block (tmp); + g_assert (iblock == NULL); + + iblock = convert_ip4_routes_block ("eth9"); + tmp = iblock; + + g_assert (iblock != NULL); + check_ip_block (iblock, "10.0.0.0", 8, "192.168.0.1"); + iblock = iblock->next; + destroy_ip_block (tmp); + g_assert (iblock == NULL); +} + +static void +test_wpa_parser (void) +{ + const char *value; + + g_assert (exist_ssid ("example")); + + g_assert (exist_ssid ("static-wep-test")); + value = wpa_get_value ("static-wep-test", "key_mgmt"); + g_assert_cmpstr (value, ==, "NONE"); + value = wpa_get_value ("static-wep-test", "wep_key0"); + g_assert_cmpstr (value, ==, "\"abcde\""); + + g_assert (exist_ssid ("leap-example")); + + value = wpa_get_value ("test-with-hash-in-psk", "psk"); + g_assert_cmpstr (value, ==, "\"xjtudlc3731###asdfasdfasdf\""); +} + +static void +test_strip_string (void) +{ + gchar *str = "( \"default via 202.117.16.1\" )"; + gchar *result = g_strdup (str); + gchar *result_b = result; + + result = strip_string (result, '('); + result = strip_string (result, ')'); + result = strip_string (result, '"'); + g_assert_cmpstr (result, ==, "default via 202.117.16.1"); + g_free (result_b); +} + +static void +test_is_unmanaged (void) +{ + g_assert (is_managed ("eth0")); + g_assert (!is_managed ("eth4")); +} + +static void +test_new_connection (void) +{ + GError *error = NULL; + NMConnection *connection; + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*Can't handle IPv4 address*202.117.16.1211*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*Can't handle IPv6 address*202.117.16.1211*"); + connection = ifnet_update_connection_from_config_block ("eth2", NULL, &error); + g_test_assert_expected_messages (); + g_assert (connection != NULL); + g_object_unref (connection); + + connection = ifnet_update_connection_from_config_block ("qiaomuf", NULL, &error); + g_assert (connection != NULL); + g_object_unref (connection); + + connection = ifnet_update_connection_from_config_block ("myxjtu2", NULL, &error); + g_assert (connection != NULL); + g_object_unref (connection); + + connection = ifnet_update_connection_from_config_block ("eth9", NULL, &error); + g_assert (connection != NULL); + g_object_unref (connection); + + connection = ifnet_update_connection_from_config_block ("eth10", NULL, &error); + g_assert (connection != NULL); + g_object_unref (connection); +} + +static void +kill_backup (char **path) +{ + if (*path) { + unlink (*path); + g_free (*path); + *path = NULL; + } +} + +#define NET_GEN_NAME "net.generate" +#define SUP_GEN_NAME "wpa_supplicant.conf.generate" + +static void +test_update_connection (void) +{ + GError *error = NULL; + NMConnection *connection; + gboolean success; + char *backup = NULL; + char *basepath = TEST_IFNET_DIR; + + connection = ifnet_update_connection_from_config_block ("eth0", basepath, &error); + g_assert (connection != NULL); + + success = ifnet_update_parsers_by_connection (connection, "eth0", + NET_GEN_NAME, + SUP_GEN_NAME, + NULL, + &backup, + &error); + kill_backup (&backup); + g_assert (success); + g_object_unref (connection); + + connection = ifnet_update_connection_from_config_block ("0xab3ace", basepath, &error); + g_assert (connection != NULL); + + success = ifnet_update_parsers_by_connection (connection, "0xab3ace", + NET_GEN_NAME, + SUP_GEN_NAME, + NULL, + &backup, + &error); + kill_backup (&backup); + g_assert (success); + g_object_unref (connection); + + unlink (NET_GEN_NAME); + unlink (SUP_GEN_NAME); +} + +static void +test_add_connection (void) +{ + NMConnection *connection; + char *backup = NULL; + const char *basepath = TEST_IFNET_DIR; + + connection = ifnet_update_connection_from_config_block ("eth0", basepath, NULL); + g_assert (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL, &backup, NULL)); + kill_backup (&backup); + g_object_unref (connection); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*Can't handle ipv4 address: brd, missing netmask or prefix*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*Can't handle ipv4 address: 202.117.16.255, missing netmask or prefix*"); + connection = ifnet_update_connection_from_config_block ("myxjtu2", basepath, NULL); + g_test_assert_expected_messages (); + g_assert (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL, &backup, NULL)); + kill_backup (&backup); + g_object_unref (connection); + + unlink (NET_GEN_NAME); + unlink (SUP_GEN_NAME); +} + +static void +test_delete_connection (void) +{ + GError *error = NULL; + NMConnection *connection; + char *backup = NULL; + + connection = ifnet_update_connection_from_config_block ("eth7", NULL, &error); + g_assert (connection != NULL); + g_assert (ifnet_delete_connection_in_parsers ("eth7", NET_GEN_NAME, SUP_GEN_NAME, &backup)); + kill_backup (&backup); + g_object_unref (connection); + + connection = ifnet_update_connection_from_config_block ("qiaomuf", NULL, &error); + g_assert (connection != NULL); + g_assert (ifnet_delete_connection_in_parsers ("qiaomuf", NET_GEN_NAME, SUP_GEN_NAME, &backup)); + kill_backup (&backup); + g_object_unref (connection); + + unlink (NET_GEN_NAME); + unlink (SUP_GEN_NAME); +} + +static void +test_missing_config (void) +{ + gs_free_error GError *error = NULL; + NMConnection *connection; + + connection = ifnet_update_connection_from_config_block ("eth8", NULL, &error); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_assert (connection == NULL && error != NULL); +} + +NMTST_DEFINE (); + +#define TPATH "/settings/plugins/ifnet/" + +int +main (int argc, char **argv) +{ + int ret; + + nm_linux_platform_setup (); + + nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT"); + + ifnet_init (TEST_IFNET_DIR "/net"); + wpa_parser_init (TEST_IFNET_DIR "/wpa_supplicant.conf"); + + g_test_add_func (TPATH "strip-string", test_strip_string); + g_test_add_func (TPATH "is-static", test_is_static); + g_test_add_func (TPATH "has-ip6-address", test_has_ip6_address); + g_test_add_func (TPATH "has-default-route", test_has_default_route); + g_test_add_func (TPATH "get-data", test_getdata); + g_test_add_func (TPATH "is-ip4-address", test_is_ip4_address); + g_test_add_func (TPATH "is-ip6-address", test_is_ip6_address); + g_test_add_func (TPATH "convert-ip4-config", test_convert_ipv4_config_block); + g_test_add_func (TPATH "convert-ip4-routes", test_convert_ipv4_routes_block); + g_test_add_func (TPATH "is-unmanaged", test_is_unmanaged); + g_test_add_func (TPATH "wpa-parser", test_wpa_parser); + g_test_add_func (TPATH "new-connection", test_new_connection); + g_test_add_func (TPATH "update-connection", test_update_connection); + g_test_add_func (TPATH "add-connection", test_add_connection); + g_test_add_func (TPATH "delete-connection", test_delete_connection); + g_test_add_func (TPATH "missing-config", test_missing_config); + + ret = g_test_run (); + + ifnet_destroy (); + wpa_parser_destroy (); + + return ret; +} diff --git a/src/settings/plugins/ifnet/tests/test_ca_cert.pem b/src/settings/plugins/ifnet/tests/test_ca_cert.pem new file mode 100644 index 00000000..ef1be20d --- /dev/null +++ b/src/settings/plugins/ifnet/tests/test_ca_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEjzCCA3egAwIBAgIJAOvnZPt59yIZMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD +VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw +FQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UE +AxMEdGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAzMTAx +NTEyMTRaFw0xOTAzMDgxNTEyMTRaMIGLMQswCQYDVQQGEwJVUzESMBAGA1UECBMJ +QmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55 +IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3 +DQEJARYNdGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAKot9j+/+CX1/gZLgJHIXCRgCItKLGnf7qGbgqB9T2ACBqR0jllKWwDKrcWU +xjXNIc+GF9Wnv+lX6G0Okn4Zt3/uRNobL+2b/yOF7M3Td3/9W873zdkQQX930YZc +Rr8uxdRPP5bxiCgtcw632y21sSEbG9mjccAUnV/0jdvfmMNj0i8gN6E0fMBiJ9S3 +FkxX/KFvt9JWE9CtoyL7ki7UIDq+6vj7Gd5N0B3dOa1y+rRHZzKlJPcSXQSEYUS4 +HmKDwiKSVahft8c4tDn7KPi0vex91hlgZVd3usL2E/Vq7o5D9FAZ5kZY0AdFXwdm +J4lO4Mj7ac7GE4vNERNcXVIX59sCAwEAAaOB8zCB8DAdBgNVHQ4EFgQUuDU3Mr7P +T3n1e3Sy8hBauoDFahAwgcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDF +ahChgZGkgY4wgYsxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO +BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQL +EwdUZXN0aW5nMQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRl +c3QuY29tggkA6+dk+3n3IhkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC +AQEAVRG4aALIvCXCiKfe7K+iJxjBVRDFPEf7JWA9LGgbFOn6pNvbxonrR+0BETdc +JV1ET4ct2xsE7QNFIkp9GKRC+6J32zCo8qtLCD5+v436r8TUG2/t2JRMkb9I2XVT +p7RJoot6M0Ltf8KNQUPYh756xmKZ4USfQUwc58MOSDGY8VWEXJOYij9Pf0e0c52t +qiCEjXH7uXiS8Pgq9TYm7AkWSOrglYhSa83x0f8mtT8Q15nBESIHZ6o8FAS2bBgn +B0BkrKRjtBUkuJG3vTox+bYINh2Gxi1JZHWSV1tN5z3hd4VFcKqanW5OgQwToBqp +3nniskIjbH0xjgZf/nVMyLnjxg== +-----END CERTIFICATE----- diff --git a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf new file mode 100644 index 00000000..917d495d --- /dev/null +++ b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf @@ -0,0 +1,70 @@ +# Only WPA-PSK is used. Any valid cipher combination is accepted. +network={ + ssid="example" + proto=WPA + key_mgmt=WPA-PSK + pairwise=CCMP TKIP + group=CCMP TKIP WEP104 WEP40 + psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb + priority=2 +} + +# LEAP with dynamic WEP keys +network={ + ssid="leap-example" + key_mgmt=IEEE8021X + eap=LEAP + identity="user" + password="foobar" +} + +# Shared WEP key connection (no WPA, no IEEE 802.1X) +network={ + ssid="static-wep-test" + key_mgmt=NONE + wep_key0="abcde" + wep_key1=0102030405 + wep_key2="1234567890123" + wep_tx_keyidx=0 + priority=5 +} + +# Wildcard match for SSID (plaintext APs only). This example select any +# open AP regardless of its SSID. +network={ + key_mgmt=NONE +} + +network={ + ssid="myxjtu2" + scan_ssid=1 + key_mgmt=WPA-PSK + psk="xjtudlc3731" + disabled=0 + key_mgmt=NONE + wep_key0="12345" + wep_key1=1234567890 + wep_key2="zxcvb" + wep_tx_keyidx=1 + auth_alg=OPEN + mode=1 +} + +network={ + ssid=ab3ace + key_mgmt=WPA-EAP + eap=TTLS + identity="user@example.com" + anonymous_identity="anonymous@example.com" + password="foobar" + ca_cert="test_ca_cert.pem" + phase2="auth=CHAP" + priority=20 +} + +network={ + ssid="test-with-hash-in-psk" + key_mgmt=WPA-PSK + psk="xjtudlc3731###asdfasdfasdf" +} + diff --git a/src/settings/plugins/ifupdown/meson.build b/src/settings/plugins/ifupdown/meson.build deleted file mode 100644 index 87b5bea2..00000000 --- a/src/settings/plugins/ifupdown/meson.build +++ /dev/null @@ -1,53 +0,0 @@ -sources = files( - 'nms-ifupdown-interface-parser.c', - 'nms-ifupdown-parser.c' -) - -deps = [ - libudev_dep, - nm_dep -] - -cflags = '-DSYSCONFDIR="@0@"'.format(nm_sysconfdir) - -libnms_ifupdown_core = static_library( - 'nms-ifupdown-core', - sources: sources, - dependencies: deps, - c_args: cflags -) - -sources = files( - 'nms-ifupdown-connection.c', - 'nms-ifupdown-plugin.c' -) - -libnm_settings_plugin_ifupdown = shared_module( - 'nm-settings-plugin-ifupdown', - sources: sources, - dependencies: deps, - c_args: cflags, - link_with: libnms_ifupdown_core, - link_args: ldflags_linker_script_settings, - link_depends: linker_script_settings, - install: true, - install_dir: nm_pkglibdir -) - -core_plugins += libnm_settings_plugin_ifupdown - -# FIXME: check_so_symbols replacement -''' -run_target( - 'check-local-symbols-settings-ifupdown', - command: [check_so_symbols, libnm_settings_plugin_ifupdown.full_path()], - depends: libnm_settings_plugin_ifupdown -) - -check-local-symbols-settings-ifupdown: src/settings/plugins/ifupdown/libnm-settings-plugin-ifupdown.la - $(call check_so_symbols,$(builddir)/src/settings/plugins/ifupdown/.libs/libnm-settings-plugin-ifupdown.so) -''' - -if enable_tests - subdir('tests') -endif diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c index 014998a6..8421afc2 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c @@ -129,8 +129,8 @@ _recursive_ifparser (const char *eni_file, int quiet) 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 *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; @@ -169,7 +169,7 @@ _recursive_ifparser (const char *eni_file, int quiet) continue; } -#define SPACES " \t" +#define SPACES " \t" /* tokenize input; */ for (toknum = 0, token[toknum] = strtok_r(line, SPACES, &safeptr); token[toknum] != NULL; diff --git a/src/settings/plugins/ifupdown/tests/meson.build b/src/settings/plugins/ifupdown/tests/meson.build deleted file mode 100644 index 7f210034..00000000 --- a/src/settings/plugins/ifupdown/tests/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -test_unit = 'test-ifupdown' - -cflags = '-DTEST_ENI_DIR="@0@"'.format(meson.current_source_dir()) - -exe = executable( - test_unit, - test_unit + '.c', - dependencies: test_nm_dep, - c_args: cflags, - link_with: libnms_ifupdown_core -) - -test( - 'ifupdown/' + test_unit, - test_script, - args: test_args + [exe.full_path()] -) diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c index 56515438..d037b8a6 100644 --- a/src/settings/plugins/ifupdown/tests/test-ifupdown.c +++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c @@ -168,7 +168,7 @@ dump_blocks (void) for (n = ifparser_getfirst (); n != NULL; n = n->next) { if_data *m; - // each block start with its type & 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); diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.c b/src/settings/plugins/keyfile/nms-keyfile-plugin.c index df2c05b7..e6299d1e 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-plugin.c +++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.c @@ -436,7 +436,7 @@ read_connections (NMSettingsPlugin *config) return; } - alive_connections = g_hash_table_new (nm_direct_hash, NULL); + alive_connections = g_hash_table_new (NULL, NULL); filenames = g_ptr_array_new_with_free_func (g_free); while ((item = g_dir_read_name (dir))) { diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection index 1e62f4b3..5cb4d726 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection @@ -15,7 +15,7 @@ mtu=1400 [ipv4] method=manual -dns=4.2.2.1;bogus;4.2.2.2; +dns=4.2.2.1;4.2.2.2; addresses1=192.168.0.5;24;192.168.0.1; addresses2=1.2.3.4;16;1.2.1.1; address=2.3.4.5/24,2.3.4.6 @@ -26,21 +26,15 @@ routes1=1.2.3.0/24,2.3.4.8,99 route=5.6.7.8/32 routes2=1.1.1.2/12, routes3=1.1.1.3/13,, -routes7=1.1.1.7/17,0.0.0.0 routes4=1.1.1.4/14,2.2.2.4 -address30=1.2.3.130/24 routes5=1.1.1.5/15,2.2.2.5, routes6=1.1.1.6/16,2.2.2.6,0 +routes7=1.1.1.7/17,0.0.0.0 routes8=1.1.1.8/18,0.0.0.0, routes9=1.1.1.9/19,0.0.0.0,0 -route10=1.1.1.10/21,,0 routes10=1.1.1.10/20,,0 routes11=1.1.1.11/21,,21 routes11_options=cwnd=10,lock-cwnd=true,mtu=1430,src=7.7.7.7 -address30=1.2.3.30/24 -addresses30=1.2.3.30/25 -addresses31=1.2.3.31/25 -address31=1.2.3.31/24 ignore-auto-routes=false ignore-auto-dns=false diff --git a/src/settings/plugins/keyfile/tests/meson.build b/src/settings/plugins/keyfile/tests/meson.build deleted file mode 100644 index 54b4ee0d..00000000 --- a/src/settings/plugins/keyfile/tests/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -test_unit = 'test-keyfile' - -test_keyfiles_dir = join_paths(meson.current_source_dir(), 'keyfiles') - -cflags = [ - '-DTEST_KEYFILES_DIR="@0@"'.format(test_keyfiles_dir), - '-DTEST_SCRATCH_DIR="@0@"'.format(test_keyfiles_dir) -] - -exe = executable( - test_unit, - test_unit + '.c', - dependencies: test_nm_dep, - c_args: cflags -) - -test( - 'keyfile/' + test_unit, - test_script, - args: test_args + [exe.full_path()] -) diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c index b46475e8..f27efddd 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile.c @@ -231,21 +231,34 @@ test_read_valid_wired_connection (void) char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; gboolean success; - 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*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv4.addresses:*semicolon at the end*addresses1*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv4.addresses:*semicolon at the end*addresses2*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*missing prefix length*address4*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*missing prefix length*address5*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv4.routes*semicolon at the end*routes2*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv4.routes*semicolon at the end*routes3*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv4.routes*semicolon at the end*routes5*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv4.routes*semicolon at the end*routes8*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*missing prefix length*address4*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv6.address*semicolon at the end*address5*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*missing prefix length*address5*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv6.address*semicolon at the end*address7*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv6.routes*semicolon at the end*routes1*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv6.route*semicolon at the end*route6*"); connection = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Wired_Connection", &error); g_assert_no_error (error); g_test_assert_expected_messages (); @@ -281,23 +294,19 @@ test_read_valid_wired_connection (void) 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); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 6); 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), ==, 13); + g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 12); 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); @@ -308,12 +317,11 @@ test_read_valid_wired_connection (void) 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, 10, "1.1.1.10", 20, NULL, 0); + check_ip_route (s_ip4, 11, "1.1.1.11", 21, NULL, 21); /* Route attributes */ - route = nm_setting_ip_config_get_route (s_ip4, 12); + route = nm_setting_ip_config_get_route (s_ip4, 11); g_assert (route); nmtst_assert_route_attribute_uint32 (route, NM_IP_ROUTE_ATTRIBUTE_CWND, 10); @@ -641,9 +649,12 @@ test_read_wired_mac_case (void) char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55 }; gboolean success; - 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*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv4.addresses*semicolon at the end*addresses1*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv4.addresses*semicolon at the end*addresses2*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*ipv6.routes*semicolon at the end*routes1*"); connection = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Wired_Connection_MAC_Case", NULL); g_test_assert_expected_messages (); g_assert (connection); @@ -1404,8 +1415,10 @@ test_read_wired_8021x_tls_blob_connection (void) gboolean success; 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*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "* * keyfile: 802-1x.client-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "* * keyfile: 802-1x.private-key: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); connection = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Wired_TLS_Blob", &error); g_assert_no_error (error); g_assert (connection); @@ -1434,7 +1447,8 @@ test_read_wired_8021x_tls_blob_connection (void) g_assert_cmpint (nm_setting_802_1x_get_ca_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_BLOB); /* Make sure it's not a path, since it's a blob */ - NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)); + g_test_expect_message ("libnm", G_LOG_LEVEL_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); @@ -1462,7 +1476,8 @@ test_read_wired_8021x_tls_bad_path_connection (void) char *tmp2; gboolean success; - NMTST_EXPECT_NM_WARN ("*does not exist*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*does not exist*"); connection = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Wired_TLS_Path_Missing", &error); g_test_assert_expected_messages (); g_assert_no_error (error); @@ -1515,9 +1530,12 @@ test_read_wired_8021x_tls_old_connection (void) const char *tmp; gboolean success; - 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*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "* * keyfile: 802-1x.ca-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem' does not exist*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "* * keyfile: 802-1x.client-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "* * keyfile: 802-1x.private-key: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); connection = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Wired_TLS_Old", &error); g_assert_no_error (error); g_assert (connection); diff --git a/src/settings/plugins/meson.build b/src/settings/plugins/meson.build deleted file mode 100644 index a1aa7823..00000000 --- a/src/settings/plugins/meson.build +++ /dev/null @@ -1,15 +0,0 @@ -if enable_ibft - subdir('ibft') -endif - -if enable_ifcfg_rh - subdir('ifcfg-rh') -endif - -if enable_ifupdown - subdir('ifupdown') -endif - -if enable_tests - subdir('keyfile/tests') -endif -- cgit 1.3.0-6-gf8a5 From 04bc9e1cd3544445d883ad29ea108c1645c8e7b7 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Mon, 4 Jun 2018 00:07:45 +0200 Subject: New upstream version 1.11.4 --- src/settings/nm-agent-manager.c | 160 +- src/settings/nm-agent-manager.h | 2 +- src/settings/nm-secret-agent.c | 140 +- src/settings/nm-settings-connection.c | 673 +++-- src/settings/nm-settings-connection.h | 62 +- src/settings/nm-settings-plugin.c | 24 - src/settings/nm-settings-plugin.h | 23 - src/settings/nm-settings.c | 1013 ++++--- src/settings/nm-settings.h | 11 +- src/settings/plugins/ibft/meson.build | 48 + src/settings/plugins/ibft/nms-ibft-plugin.c | 35 - src/settings/plugins/ibft/nms-ibft-reader.c | 8 +- src/settings/plugins/ibft/tests/meson.build | 17 + src/settings/plugins/ibft/tests/test-ibft.c | 22 +- src/settings/plugins/ifcfg-rh/meson.build | 77 + src/settings/plugins/ifcfg-rh/nm-inotify-helper.c | 2 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-common.h | 3 - .../plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c | 172 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 176 +- .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 68 +- src/settings/plugins/ifcfg-rh/shvar.c | 4 +- src/settings/plugins/ifcfg-rh/tests/meson.build | 17 + .../ifcfg-Test_Write_WiFi_Hidden.cexpected | 1 - .../ifcfg-Test_Write_Wired_Static_Routes.cexpected | 2 + .../ifcfg-rh/tests/network-scripts/ifcfg-test-tc | 16 + .../network-scripts/ifcfg-test-tc-write.cexpected | 16 + .../network-scripts/ifcfg-test-wired-ipv4-manual-1 | 2 + .../network-scripts/ifcfg-test-wired-ipv4-manual-2 | 2 + .../network-scripts/ifcfg-test-wired-ipv4-manual-3 | 2 + .../network-scripts/ifcfg-test-wired-ipv4-manual-4 | 2 + .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 683 +++-- .../plugins/ifnet/nms-ifnet-connection-parser.c | 2912 -------------------- .../plugins/ifnet/nms-ifnet-connection-parser.h | 55 - src/settings/plugins/ifnet/nms-ifnet-connection.c | 233 -- src/settings/plugins/ifnet/nms-ifnet-connection.h | 46 - src/settings/plugins/ifnet/nms-ifnet-net-parser.c | 734 ----- src/settings/plugins/ifnet/nms-ifnet-net-parser.h | 42 - src/settings/plugins/ifnet/nms-ifnet-net-utils.c | 830 ------ src/settings/plugins/ifnet/nms-ifnet-net-utils.h | 71 - src/settings/plugins/ifnet/nms-ifnet-plugin.c | 524 ---- src/settings/plugins/ifnet/nms-ifnet-plugin.h | 38 - src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c | 584 ---- src/settings/plugins/ifnet/nms-ifnet-wpa-parser.h | 41 - src/settings/plugins/ifnet/tests/net | 158 -- src/settings/plugins/ifnet/tests/net.all | 864 ------ .../plugins/ifnet/tests/nm-system-settings.conf | 5 - src/settings/plugins/ifnet/tests/test-ifnet.c | 396 --- src/settings/plugins/ifnet/tests/test_ca_cert.pem | 27 - .../plugins/ifnet/tests/wpa_supplicant.conf | 70 - src/settings/plugins/ifupdown/meson.build | 53 + .../ifupdown/nms-ifupdown-interface-parser.c | 7 +- .../ifupdown/nms-ifupdown-interface-parser.h | 1 - .../plugins/ifupdown/nms-ifupdown-parser.c | 7 +- .../plugins/ifupdown/nms-ifupdown-plugin.c | 38 - src/settings/plugins/ifupdown/tests/meson.build | 15 + .../plugins/ifupdown/tests/test-ifupdown.c | 46 +- src/settings/plugins/keyfile/nms-keyfile-plugin.c | 37 +- src/settings/plugins/keyfile/nms-keyfile-utils.h | 3 - .../keyfile/tests/keyfiles/Test_Wired_Connection | 10 +- src/settings/plugins/keyfile/tests/meson.build | 16 + src/settings/plugins/keyfile/tests/test-keyfile.c | 96 +- src/settings/plugins/meson.build | 15 + 62 files changed, 2222 insertions(+), 9235 deletions(-) create mode 100644 src/settings/plugins/ibft/meson.build create mode 100644 src/settings/plugins/ibft/tests/meson.build create mode 100644 src/settings/plugins/ifcfg-rh/meson.build create mode 100644 src/settings/plugins/ifcfg-rh/tests/meson.build create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc-write.cexpected delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-connection-parser.c delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-connection-parser.h delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-connection.c delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-connection.h delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-net-parser.c delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-net-parser.h delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-net-utils.c delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-net-utils.h delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-plugin.c delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-plugin.h delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c delete mode 100644 src/settings/plugins/ifnet/nms-ifnet-wpa-parser.h delete mode 100644 src/settings/plugins/ifnet/tests/net delete mode 100644 src/settings/plugins/ifnet/tests/net.all delete mode 100644 src/settings/plugins/ifnet/tests/nm-system-settings.conf delete mode 100644 src/settings/plugins/ifnet/tests/test-ifnet.c delete mode 100644 src/settings/plugins/ifnet/tests/test_ca_cert.pem delete mode 100644 src/settings/plugins/ifnet/tests/wpa_supplicant.conf create mode 100644 src/settings/plugins/ifupdown/meson.build create mode 100644 src/settings/plugins/ifupdown/tests/meson.build create mode 100644 src/settings/plugins/keyfile/tests/meson.build create mode 100644 src/settings/plugins/meson.build (limited to 'src/settings') diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index a68db47e..453136e4 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -31,14 +31,12 @@ #include "nm-auth-utils.h" #include "nm-setting-vpn.h" #include "nm-auth-manager.h" -#include "nm-bus-manager.h" +#include "nm-dbus-manager.h" #include "nm-session-monitor.h" #include "nm-simple-connection.h" #include "NetworkManagerUtils.h" #include "nm-core-internal.h" -#include "nm-utils/c-list.h" - -#include "introspection/org.freedesktop.NetworkManager.AgentManager.h" +#include "c-list/src/c-list.h" /*****************************************************************************/ @@ -67,15 +65,15 @@ typedef struct { } NMAgentManagerPrivate; struct _NMAgentManager { - NMExportedObject parent; + NMDBusObject parent; NMAgentManagerPrivate _priv; }; struct _NMAgentManagerClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, NM_TYPE_EXPORTED_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) @@ -362,7 +360,7 @@ agent_register_permissions_done (NMAuthChain *chain, request_add_agent (c_list_entry (iter, Request, lst_request), agent); } - nm_auth_chain_unref (chain); + nm_auth_chain_destroy (chain); } static NMSecretAgent * @@ -392,10 +390,10 @@ agent_disconnected_cb (NMSecretAgent *agent, gpointer user_data) } static void -impl_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); NMAuthSubject *subject; @@ -460,45 +458,56 @@ done: } static void -impl_agent_manager_register (NMAgentManager *self, - GDBusMethodInvocation *context, - const char *identifier) +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_with_capabilities (self, context, identifier, 0); + const char *identifier; + + g_variant_get (parameters, "(&s)", &identifier); + agent_manager_register_with_capabilities (NM_AGENT_MANAGER (obj), invocation, identifier, 0); } static void -impl_agent_manager_unregister (NMAgentManager *self, - GDBusMethodInvocation *context) +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) { - GError *error = NULL; - char *sender = NULL; + const char *identifier; + guint32 capabilities; - if (!nm_bus_manager_get_caller_info (nm_bus_manager_get (), - context, - &sender, - NULL, - NULL)) { - error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, - "Unable to determine request sender."); - goto done; - } + 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) +{ + NMAgentManager *self = NM_AGENT_MANAGER (obj); - /* Found the agent, unregister and remove it */ if (!remove_agent (self, sender)) { - error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, - "Caller is not registered as an Agent"); - goto done; + 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; } - g_dbus_method_invocation_return_value (context, NULL); - -done: - if (error) - g_dbus_method_invocation_take_error (context, error); - g_free (sender); + g_dbus_method_invocation_return_value (invocation, NULL); } /*****************************************************************************/ @@ -530,7 +539,7 @@ request_free (Request *req) g_object_unref (req->con.connection); g_free (req->con.path); if (req->con.chain) - nm_auth_chain_unref (req->con.chain); + nm_auth_chain_destroy (req->con.chain); if (req->request_type == REQUEST_TYPE_CON_GET) { g_free (req->con.get.setting_name); g_strfreev (req->con.get.hints); @@ -801,7 +810,7 @@ request_remove_agent (Request *req, NMSecretAgent *agent) case REQUEST_TYPE_CON_DEL: if (req->con.chain) { /* This cancels the pending authorization requests. */ - nm_auth_chain_unref (req->con.chain); + nm_auth_chain_destroy (req->con.chain); req->con.chain = NULL; } break; @@ -1038,7 +1047,7 @@ _con_get_request_start_validated (NMAuthChain *chain, _con_get_request_start_proceed (req, req->con.current_has_modify); } - nm_auth_chain_unref (chain); + nm_auth_chain_destroy (chain); } static void @@ -1532,7 +1541,7 @@ agent_permissions_changed_done (NMAuthChain *chain, nm_secret_agent_add_permission (agent, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, share_protected); nm_secret_agent_add_permission (agent, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, share_open); - nm_auth_chain_unref (chain); + nm_auth_chain_destroy (chain); } static void @@ -1586,7 +1595,7 @@ constructed (GObject *object) priv->auth_mgr = g_object_ref (nm_auth_manager_get ()); priv->session_monitor = g_object_ref (nm_session_monitor_get ()); - nm_exported_object_export (NM_EXPORTED_OBJECT (object)); + nm_dbus_object_export (NM_DBUS_OBJECT (object)); g_signal_connect (priv->auth_mgr, NM_AUTH_MANAGER_SIGNAL_CHANGED, @@ -1607,7 +1616,7 @@ cancel_more: goto cancel_more; } - g_slist_free_full (priv->chains, (GDestroyNotify) nm_auth_chain_unref); + g_slist_free_full (priv->chains, (GDestroyNotify) nm_auth_chain_destroy); priv->chains = NULL; if (priv->agents) { @@ -1622,20 +1631,64 @@ cancel_more: g_clear_object (&priv->auth_mgr); } - nm_exported_object_unexport (NM_EXPORTED_OBJECT (object)); + nm_dbus_object_unexport (NM_DBUS_OBJECT (object)); g_clear_object (&priv->session_monitor); 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 ( + "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) { GObjectClass *object_class = G_OBJECT_CLASS (agent_manager_class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (agent_manager_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (agent_manager_class); - exported_object_class->export_path = NM_DBUS_PATH_AGENT_MANAGER; + 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; @@ -1649,11 +1702,4 @@ nm_agent_manager_class_init (NMAgentManagerClass *agent_manager_class) g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (agent_manager_class), - NMDBUS_TYPE_AGENT_MANAGER_SKELETON, - "Register", impl_agent_manager_register, - "RegisterWithCapabilities", impl_agent_manager_register_with_capabilities, - "Unregister", impl_agent_manager_unregister, - NULL); } diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h index f6845818..8c27f26b 100644 --- a/src/settings/nm-agent-manager.h +++ b/src/settings/nm-agent-manager.h @@ -23,7 +23,7 @@ #include "nm-connection.h" -#include "nm-exported-object.h" +#include "nm-dbus-object.h" #include "nm-secret-agent.h" #define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ()) diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index 192e9877..af6d7017 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -26,13 +26,12 @@ #include #include "nm-dbus-interface.h" -#include "nm-bus-manager.h" +#include "nm-dbus-manager.h" +#include "nm-core-internal.h" #include "nm-auth-subject.h" #include "nm-simple-connection.h" #include "NetworkManagerUtils.h" -#include "nm-utils/c-list.h" - -#include "introspection/org.freedesktop.NetworkManager.SecretAgent.h" +#include "c-list/src/c-list.h" /*****************************************************************************/ @@ -51,8 +50,8 @@ typedef struct { char *dbus_owner; NMSecretAgentCapabilities capabilities; GSList *permissions; - NMDBusSecretAgent *proxy; - NMBusManager *bus_mgr; + GDBusProxy *proxy; + NMDBusManager *bus_mgr; GDBusConnection *connection; CList requests; gulong on_disconnected_id; @@ -300,7 +299,7 @@ nm_secret_agent_add_permission (NMSecretAgent *agent, * @permission: The name of the permission to check for * * Returns whether or not the agent has the given permission. - * + * * Returns: %TRUE if the agent has the given permission, %FALSE if it does not * or if the permission was not previous recorded with * nm_secret_agent_add_permission(). @@ -336,11 +335,17 @@ get_callback (GObject *proxy, if (request_check_return (r)) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); gs_free_error GError *error = NULL; + gs_unref_variant GVariant *ret = NULL; gs_unref_variant GVariant *secrets = NULL; - nmdbus_secret_agent_call_get_secrets_finish (priv->proxy, &secrets, result, &error); - if (error) + ret = _nm_dbus_proxy_call_finish (priv->proxy, result, G_VARIANT_TYPE ("(a{sa{sv}})"), &error); + if (!ret) g_dbus_error_strip_remote_error (error); + else { + g_variant_get (ret, + "(@a{sa{sv}})", + &secrets); + } r->callback (r->agent, r, secrets, error, r->callback_data); } @@ -358,7 +363,6 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, gpointer callback_data) { NMSecretAgentPrivate *priv; - static const char *no_hints[] = { NULL }; GVariant *dict; NMSecretAgentCallId *r; @@ -379,16 +383,20 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, r = request_new (self, "GetSecrets", path, setting_name, callback, callback_data); r->is_get_secrets = TRUE; - /* Increase the timeout only for this call */ - g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (priv->proxy), 120000); - nmdbus_secret_agent_call_get_secrets (priv->proxy, - dict, - path, - setting_name, - hints ? hints : no_hints, - flags, - r->cancellable, - get_callback, r); + g_dbus_proxy_call (priv->proxy, + "GetSecrets", + g_variant_new ("(@a{sa{sv}}os^asu)", + dict, + path, + setting_name, + hints ?: NM_PTRARRAY_EMPTY (const char *), + (guint32) flags), + G_DBUS_CALL_FLAGS_NONE, + 120000, + r->cancellable, + get_callback, + r); + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (priv->proxy), -1); return r; @@ -399,17 +407,16 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, static void cancel_done (GObject *proxy, GAsyncResult *result, gpointer user_data) { - char *description = user_data; - GError *error = NULL; + gs_free char *description = user_data; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *ret = NULL; - if (!nmdbus_secret_agent_call_cancel_get_secrets_finish (NMDBUS_SECRET_AGENT (proxy), result, &error)) { + ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, G_VARIANT_TYPE ("()"), &error); + if (!ret) { nm_log_dbg (LOGD_AGENTS, "%s%s%s: agent failed to cancel secrets: %s", NM_PRINT_FMT_QUOTED (description, "(", description, ")", "???"), error->message); - g_clear_error (&error); } - - g_free (description); } static void @@ -426,11 +433,16 @@ do_cancel_secrets (NMSecretAgent *self, NMSecretAgentCallId *r, gboolean disposi if ( r->is_get_secrets && priv->proxy) { /* for GetSecrets call, we must cancel the request. */ - nmdbus_secret_agent_call_cancel_get_secrets (priv->proxy, - r->path, r->setting_name, - NULL, - cancel_done, - g_strdup (nm_secret_agent_get_description (self))); + g_dbus_proxy_call (G_DBUS_PROXY (priv->proxy), + "CancelGetSecrets", + g_variant_new ("(os)", + r->path, + r->setting_name), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + cancel_done, + g_strdup (nm_secret_agent_get_description (self))); } cancellable = r->cancellable; @@ -494,11 +506,11 @@ agent_save_cb (GObject *proxy, NMSecretAgentCallId *r = user_data; if (request_check_return (r)) { - NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); gs_free_error GError *error = NULL; + gs_unref_variant GVariant *ret = NULL; - nmdbus_secret_agent_call_save_secrets_finish (priv->proxy, result, &error); - if (error) + ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, G_VARIANT_TYPE ("()"), &error); + if (!ret) g_dbus_error_strip_remote_error (error); r->callback (r->agent, r, NULL, error, r->callback_data); } @@ -527,11 +539,16 @@ nm_secret_agent_save_secrets (NMSecretAgent *self, dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); r = request_new (self, "SaveSecrets", path, NULL, callback, callback_data); - nmdbus_secret_agent_call_save_secrets (priv->proxy, - dict, - path, - NULL, /* cancelling the request does *not* cancel the D-Bus call. */ - agent_save_cb, r); + g_dbus_proxy_call (priv->proxy, + "SaveSecrets", + g_variant_new ("(@a{sa{sv}}o)", + dict, + path), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* cancelling the request does *not* cancel the D-Bus call. */ + agent_save_cb, + r); return r; } @@ -546,11 +563,11 @@ agent_delete_cb (GObject *proxy, NMSecretAgentCallId *r = user_data; if (request_check_return (r)) { - NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); gs_free_error GError *error = NULL; + gs_unref_variant GVariant *ret = NULL; - nmdbus_secret_agent_call_delete_secrets_finish (priv->proxy, result, &error); - if (error) + ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, G_VARIANT_TYPE ("()"), &error); + if (!ret) g_dbus_error_strip_remote_error (error); r->callback (r->agent, r, NULL, error, r->callback_data); } @@ -579,12 +596,16 @@ nm_secret_agent_delete_secrets (NMSecretAgent *self, dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); r = request_new (self, "DeleteSecrets", path, NULL, callback, callback_data); - nmdbus_secret_agent_call_delete_secrets (priv->proxy, - dict, - path, - NULL, /* cancelling the request does *not* cancel the D-Bus call. */ - agent_delete_cb, r); - + g_dbus_proxy_call (priv->proxy, + "DeleteSecrets", + g_variant_new ("(@a{sa{sv}}o)", + dict, + path), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* cancelling the request does *not* cancel the D-Bus call. */ + agent_delete_cb, + r); return r; } @@ -610,7 +631,7 @@ _on_disconnected_cleanup (NMSecretAgentPrivate *priv) } static void -_on_disconnected_private_connection (NMBusManager *mgr, +_on_disconnected_private_connection (NMDBusManager *mgr, GDBusConnection *connection, NMSecretAgent *self) { @@ -666,7 +687,6 @@ nm_secret_agent_new (GDBusMethodInvocation *context, NMSecretAgentPrivate *priv; const char *dbus_owner; struct passwd *pw; - GDBusProxy *proxy; char *owner_username = NULL; char *description = NULL; char buf_subject[64]; @@ -695,9 +715,9 @@ nm_secret_agent_new (GDBusMethodInvocation *context, priv = NM_SECRET_AGENT_GET_PRIVATE (self); - priv->bus_mgr = g_object_ref (nm_bus_manager_get ()); + priv->bus_mgr = g_object_ref (nm_dbus_manager_get ()); priv->connection = g_object_ref (connection); - priv->connection_is_private = !!nm_bus_manager_connection_get_private_name (priv->bus_mgr, connection); + priv->connection_is_private = !!nm_dbus_manager_connection_get_private_name (priv->bus_mgr, connection); _LOGt ("constructed: %s, owner=%s%s%s (%s), private-connection=%d, unique-name=%s%s%s, capabilities=%s", (description = _create_description (dbus_owner, identifier, uid)), @@ -714,20 +734,18 @@ nm_secret_agent_new (GDBusMethodInvocation *context, priv->capabilities = capabilities; priv->subject = g_object_ref (subject); - proxy = nm_bus_manager_new_proxy (priv->bus_mgr, - priv->connection, - NMDBUS_TYPE_SECRET_AGENT_PROXY, - priv->dbus_owner, - NM_DBUS_PATH_SECRET_AGENT, - NM_DBUS_INTERFACE_SECRET_AGENT); - g_assert (proxy); - priv->proxy = NMDBUS_SECRET_AGENT (proxy); + priv->proxy = nm_dbus_manager_new_proxy (priv->bus_mgr, + priv->connection, + G_TYPE_DBUS_PROXY, + priv->dbus_owner, + NM_DBUS_PATH_SECRET_AGENT, + NM_DBUS_INTERFACE_SECRET_AGENT); /* we cannot subscribe to notify::g-name-owner because that doesn't work * for unique names and it doesn't work for private connections. */ if (priv->connection_is_private) { priv->on_disconnected_id = g_signal_connect (priv->bus_mgr, - NM_BUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED, + NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED, G_CALLBACK (_on_disconnected_private_connection), self); } else { diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 58626372..6526abc7 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -25,13 +25,14 @@ #include -#include "nm-utils/c-list.h" +#include "c-list/src/c-list.h" #include "nm-common-macros.h" #include "nm-config.h" #include "nm-config-data.h" #include "nm-dbus-interface.h" #include "nm-session-monitor.h" +#include "nm-auth-manager.h" #include "nm-auth-utils.h" #include "nm-auth-subject.h" #include "nm-agent-manager.h" @@ -39,8 +40,6 @@ #include "nm-core-internal.h" #include "nm-audit-manager.h" -#include "introspection/org.freedesktop.NetworkManager.Settings.Connection.h" - #define SETTINGS_TIMESTAMPS_FILE NMSTATEDIR "/timestamps" #define SETTINGS_SEEN_BSSIDS_FILE NMSTATEDIR "/seen-bssids" @@ -60,9 +59,9 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSettingsConnection, ); enum { - UPDATED, REMOVED, UPDATED_INTERNAL, + FLAGS_CHANGED, LAST_SIGNAL }; @@ -74,7 +73,7 @@ typedef struct _NMSettingsConnectionPrivate { NMSessionMonitor *session_monitor; gulong session_changed_id; - NMSettingsConnectionFlags flags:5; + NMSettingsConnectionIntFlags flags:5; bool removed:1; bool ready:1; @@ -83,7 +82,8 @@ typedef struct _NMSettingsConnectionPrivate { NMSettingsAutoconnectBlockedReason autoconnect_blocked_reason:4; - GSList *pending_auths; /* List of pending authentication requests */ + /* List of pending authentication requests */ + CList auth_lst_head; CList call_ids_lst_head; /* in-progress secrets requests */ @@ -115,7 +115,7 @@ typedef struct _NMSettingsConnectionPrivate { } NMSettingsConnectionPrivate; -G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_EXPORTED_OBJECT, +G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_DBUS_OBJECT, G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION, nm_settings_connection_connection_interface_init) ) @@ -135,7 +135,7 @@ G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_E const char *__uuid = (self) ? nm_settings_connection_get_uuid (self) : NULL; \ \ if (self) { \ - g_snprintf (__prefix, sizeof (__prefix), "%s[%p%s%s]", _NMLOG_PREFIX_NAME, self, __uuid ? "," : "", __uuid ? __uuid : ""); \ + g_snprintf (__prefix, sizeof (__prefix), "%s[%p%s%s]", _NMLOG_PREFIX_NAME, self, __uuid ? "," : "", __uuid ?: ""); \ __p_prefix = __prefix; \ } \ _nm_log (__level, _NMLOG_DOMAIN, 0, NULL, __uuid, \ @@ -146,12 +146,9 @@ G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_E /*****************************************************************************/ -static void -_emit_updated (NMSettingsConnection *self, gboolean by_user) -{ - g_signal_emit (self, signals[UPDATED], 0); - g_signal_emit (self, signals[UPDATED_INTERNAL], 0, by_user); -} +static const GDBusSignalInfo signal_info_updated; +static const GDBusSignalInfo signal_info_removed; +static const NMDBusInterfaceInfoExtended interface_info_settings_connection; /*****************************************************************************/ @@ -320,7 +317,7 @@ static void set_visible (NMSettingsConnection *self, gboolean new_visible) { nm_settings_connection_set_flags (self, - NM_SETTINGS_CONNECTION_FLAGS_VISIBLE, + NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE, new_visible); } @@ -390,7 +387,7 @@ nm_settings_connection_check_permission (NMSettingsConnection *self, priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); if (!NM_FLAGS_HAS (nm_settings_connection_get_flags (self), - NM_SETTINGS_CONNECTION_FLAGS_VISIBLE)) + NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) return FALSE; s_con = nm_connection_get_setting_connection (NM_CONNECTION (self)); @@ -466,7 +463,7 @@ update_agent_secrets_cache (NMSettingsConnection *self, NMConnection *new) if (priv->agent_secrets) g_object_unref (priv->agent_secrets); - priv->agent_secrets = nm_simple_connection_new_clone (new ? new : NM_CONNECTION (self)); + priv->agent_secrets = nm_simple_connection_new_clone (new ?: NM_CONNECTION(self)); /* Clear out non-system-owned secrets */ nm_connection_clear_secrets_with_flags (priv->agent_secrets, @@ -490,30 +487,30 @@ secrets_cleared_cb (NMSettingsConnection *self) static void set_persist_mode (NMSettingsConnection *self, NMSettingsConnectionPersistMode persist_mode) { - NMSettingsConnectionFlags flags = NM_SETTINGS_CONNECTION_FLAGS_NONE; - const NMSettingsConnectionFlags ALL = NM_SETTINGS_CONNECTION_FLAGS_UNSAVED - | NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED - | NM_SETTINGS_CONNECTION_FLAGS_VOLATILE; + NMSettingsConnectionIntFlags flags = NM_SETTINGS_CONNECTION_INT_FLAGS_NONE; + const NMSettingsConnectionIntFlags ALL = NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED + | NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED + | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE; switch (persist_mode) { case NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK: - flags = NM_SETTINGS_CONNECTION_FLAGS_NONE; + flags = NM_SETTINGS_CONNECTION_INT_FLAGS_NONE; break; case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY: case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED: case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY: - flags = NM_SETTINGS_CONNECTION_FLAGS_UNSAVED; + flags = NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED; break; case NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_DETACHED: case NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_ONLY: - flags = NM_SETTINGS_CONNECTION_FLAGS_UNSAVED | - NM_SETTINGS_CONNECTION_FLAGS_VOLATILE; + flags = NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED | + NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE; break; case NM_SETTINGS_CONNECTION_PERSIST_MODE_UNSAVED: /* only set the connection as unsaved, but preserve the nm-generated * and volatile flag. */ nm_settings_connection_set_flags (self, - NM_SETTINGS_CONNECTION_FLAGS_UNSAVED, + NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED, TRUE); return; case NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP: @@ -525,6 +522,16 @@ set_persist_mode (NMSettingsConnection *self, NMSettingsConnectionPersistMode pe nm_settings_connection_set_flags_full (self, ALL, flags); } +static void +_emit_updated (NMSettingsConnection *self, gboolean by_user) +{ + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_settings_connection, + &signal_info_updated, + "()"); + g_signal_emit (self, signals[UPDATED_INTERNAL], 0, by_user); +} + static void connection_changed_cb (NMSettingsConnection *self, gpointer unused) { @@ -571,17 +578,13 @@ _update_prepare (NMSettingsConnection *self, NMConnection *new_connection, GError **error) { - NMSettingsConnectionPrivate *priv; - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (new_connection), FALSE); - priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - if (!nm_connection_normalize (new_connection, NULL, NULL, error)) return FALSE; - if ( nm_connection_get_path (NM_CONNECTION (self)) + if ( nm_dbus_object_get_path (NM_DBUS_OBJECT (self)) && g_strcmp0 (nm_settings_connection_get_uuid (self), nm_connection_get_uuid (new_connection)) != 0) { /* Updating the UUID is not allowed once the path is exported. */ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, @@ -661,8 +664,10 @@ nm_settings_connection_update (NMSettingsConnection *self, NM_SETTING_COMPARE_FLAG_EXACT)) { gs_unref_object NMConnection *simple = NULL; - if (log_diff_name) - nm_utils_log_connection_diff (replace_connection, NM_CONNECTION (self), LOGL_DEBUG, LOGD_CORE, log_diff_name, "++ "); + if (log_diff_name) { + nm_utils_log_connection_diff (replace_connection, NM_CONNECTION (self), LOGL_DEBUG, LOGD_CORE, log_diff_name, "++ ", + nm_dbus_object_get_path (NM_DBUS_OBJECT (self))); + } /* Make a copy of agent-owned secrets because they won't be present in * the connection returned by plugins, as plugins return only what was @@ -679,7 +684,7 @@ nm_settings_connection_update (NMSettingsConnection *self, } nm_settings_connection_set_flags (self, - NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_FLAGS_VOLATILE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE, FALSE); if (replaced) { @@ -798,7 +803,7 @@ nm_settings_connection_delete (NMSettingsConnection *self, for_agents = nm_simple_connection_new_clone (NM_CONNECTION (self)); nm_connection_clear_secrets (for_agents); nm_agent_manager_delete_secrets (priv->agent_mgr, - nm_connection_get_path (NM_CONNECTION (self)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), for_agents); g_object_unref (for_agents); @@ -812,10 +817,8 @@ nm_settings_connection_delete (NMSettingsConnection *self, return TRUE; } - /*****************************************************************************/ - typedef enum { CALL_ID_TYPE_REQ, CALL_ID_TYPE_IDLE, @@ -1295,7 +1298,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, priv->last_secret_agent_version_id = nm_agent_manager_get_agent_version_id (priv->agent_mgr); call_id_a = nm_agent_manager_get_secrets (priv->agent_mgr, - nm_connection_get_path (NM_CONNECTION (self)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), NM_CONNECTION (self), subject, existing_secrets, @@ -1359,7 +1362,7 @@ nm_settings_connection_cancel_secrets (NMSettingsConnection *self, _get_secrets_cancel (self, call_id, FALSE); } -/**** User authorization **************************************/ +/*****************************************************************************/ typedef void (*AuthCallback) (NMSettingsConnection *self, GDBusMethodInvocation *context, @@ -1367,46 +1370,61 @@ typedef void (*AuthCallback) (NMSettingsConnection *self, GError *error, gpointer data); -static void -pk_auth_cb (NMAuthChain *chain, - GError *chain_error, - GDBusMethodInvocation *context, - gpointer user_data) -{ - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data); - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - GError *error = NULL; - NMAuthCallResult result; - const char *perm; +typedef struct { + CList auth_lst; + NMAuthManagerCallId *call_id; + NMSettingsConnection *self; AuthCallback callback; gpointer callback_data; + GDBusMethodInvocation *invocation; NMAuthSubject *subject; +} AuthData; - priv->pending_auths = g_slist_remove (priv->pending_auths, chain); +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; - perm = nm_auth_chain_get_data (chain, "perm"); - g_assert (perm); - result = nm_auth_chain_get_result (chain, perm); + auth_data->call_id = NULL; - /* If our NMSettingsConnection is already gone, do nothing */ - if (chain_error) { + 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", - chain_error->message ? chain_error->message : "(unknown)"); - } else if (result != NM_AUTH_CALL_RESULT_YES) { + 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, - "Insufficient privileges."); + "Insufficient privileges"); } - 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, context, subject, error, callback_data); + auth_data->callback (self, + auth_data->invocation, + auth_data->subject, + error, + auth_data->callback_data); - g_clear_error (&error); - nm_auth_chain_unref (chain); + g_object_unref (auth_data->invocation); + g_object_unref (auth_data->subject); + g_slice_free (AuthData, auth_data); } /** @@ -1434,59 +1452,52 @@ _new_auth_subject (GDBusMethodInvocation *context, GError **error) return subject; } +/* may either invoke callback synchronously or asynchronously. */ static void auth_start (NMSettingsConnection *self, - GDBusMethodInvocation *context, + GDBusMethodInvocation *invocation, NMAuthSubject *subject, const char *check_permission, AuthCallback callback, gpointer callback_data) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - NMAuthChain *chain; + AuthData *auth_data; GError *error = NULL; - char *error_desc = NULL; - g_return_if_fail (context != NULL); - g_return_if_fail (NM_IS_AUTH_SUBJECT (subject)); + 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)); - /* Ensure the caller can view this connection */ - if (!nm_auth_is_subject_in_acl (NM_CONNECTION (self), - subject, - &error_desc)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - error_desc); - g_free (error_desc); - - callback (self, context, subject, error, callback_data); + if (!nm_auth_is_subject_in_acl_set_error (NM_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, context, subject, NULL, callback_data); + callback (self, invocation, subject, NULL, callback_data); return; } - chain = nm_auth_chain_new_subject (subject, context, pk_auth_cb, self); - if (!chain) { - g_set_error_literal (&error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Unable to authenticate the request."); - callback (self, context, subject, error, callback_data); - g_clear_error (&error); - return; - } - - priv->pending_auths = g_slist_append (priv->pending_auths, chain); - nm_auth_chain_set_data (chain, "perm", (gpointer) check_permission, NULL); - nm_auth_chain_set_data (chain, "callback", callback, NULL); - nm_auth_chain_set_data (chain, "callback-data", callback_data, NULL); - nm_auth_chain_set_data (chain, "subject", g_object_ref (subject), g_object_unref); - nm_auth_chain_add_call (chain, check_permission, TRUE); + 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 ************************************/ @@ -1523,7 +1534,7 @@ check_writable (NMConnection *self, GError **error) } static void -get_settings_auth_cb (NMSettingsConnection *self, +get_settings_auth_cb (NMSettingsConnection *self, GDBusMethodInvocation *context, NMAuthSubject *subject, GError *error, @@ -1577,18 +1588,25 @@ get_settings_auth_cb (NMSettingsConnection *self, } static void -impl_settings_connection_get_settings (NMSettingsConnection *self, - GDBusMethodInvocation *context) -{ - NMAuthSubject *subject; +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; - subject = _new_auth_subject (context, &error); - if (subject) { - auth_start (self, context, subject, NULL, get_settings_auth_cb, NULL); - g_object_unref (subject); - } else - g_dbus_method_invocation_take_error (context, error); + 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); } typedef struct { @@ -1782,7 +1800,7 @@ update_auth_cb (NMSettingsConnection *self, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); nm_agent_manager_save_secrets (info->agent_mgr, - nm_connection_get_path (NM_CONNECTION (self)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), for_agent, info->subject); } @@ -1790,7 +1808,6 @@ update_auth_cb (NMSettingsConnection *self, update_complete (self, info, local); } - static const char * get_update_modify_permission (NMConnection *old, NMConnection *new) { @@ -1830,7 +1847,6 @@ settings_connection_update (NMSettingsConnection *self, GError *error = NULL; UpdateInfo *info; const char *permission; - char *error_desc = NULL; /* If the connection is read-only, that has to be changed at the source of * the problem (ex a system settings plugin that can't write connections out) @@ -1867,15 +1883,12 @@ settings_connection_update (NMSettingsConnection *self, * that's sending the update request. You can't make a connection * invisible to yourself. */ - if (!nm_auth_is_subject_in_acl (tmp ? tmp : NM_CONNECTION (self), - subject, - &error_desc)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - error_desc); - g_free (error_desc); + if (!nm_auth_is_subject_in_acl_set_error (tmp ?: NM_CONNECTION(self), + subject, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + &error)) goto error; - } info = g_slice_new0 (UpdateInfo); info->is_update2 = is_update2; @@ -1886,7 +1899,7 @@ settings_connection_update (NMSettingsConnection *self, info->new_settings = tmp; permission = get_update_modify_permission (NM_CONNECTION (self), - tmp ? tmp : NM_CONNECTION (self)); + tmp ?: NM_CONNECTION(self)); auth_start (self, context, subject, permission, update_auth_cb, info); return; @@ -1901,54 +1914,87 @@ error: } static void -impl_settings_connection_update (NMSettingsConnection *self, - GDBusMethodInvocation *context, - GVariant *new_settings) +impl_settings_connection_update (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - settings_connection_update (self, FALSE, context, new_settings, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); + 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); } static void -impl_settings_connection_update_unsaved (NMSettingsConnection *self, - GDBusMethodInvocation *context, - GVariant *new_settings) +impl_settings_connection_update_unsaved (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - settings_connection_update (self, FALSE, context, new_settings, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY); + 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); } static void -impl_settings_connection_save (NMSettingsConnection *self, - GDBusMethodInvocation *context) +impl_settings_connection_save (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - settings_connection_update (self, FALSE, context, NULL, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); + + settings_connection_update (self, FALSE, invocation, NULL, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); } static void -impl_settings_connection_update2 (NMSettingsConnection *self, - GDBusMethodInvocation *context, - GVariant *settings, - guint32 flags_u, - GVariant *args) -{ +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; - const NMSettingsUpdate2Flags flags = (NMSettingsUpdate2Flags) flags_u; + NMSettingsUpdate2Flags flags; const NMSettingsUpdate2Flags ALL_PERSIST_MODES = 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; + g_variant_get (parameters, "(@a{sa{sv}}u@a{sv})", &settings, &flags_u, &args); + if (NM_FLAGS_ANY (flags_u, ~((guint32) (ALL_PERSIST_MODES | NM_SETTINGS_UPDATE2_FLAG_VOLATILE | NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT)))) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "Unknown flags"); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); return; } + flags = (NMSettingsUpdate2Flags) flags_u; + if ( ( NM_FLAGS_ANY (flags, ALL_PERSIST_MODES) && !nm_utils_is_power_of_two (flags & ALL_PERSIST_MODES)) || ( NM_FLAGS_HAS (flags, NM_SETTINGS_UPDATE2_FLAG_VOLATILE) @@ -1957,7 +2003,7 @@ impl_settings_connection_update2 (NMSettingsConnection *self, error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "Conflicting flags"); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); return; } @@ -1965,7 +2011,7 @@ impl_settings_connection_update2 (NMSettingsConnection *self, error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "args is of invalid type"); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); return; } @@ -1974,13 +2020,13 @@ impl_settings_connection_update2 (NMSettingsConnection *self, error = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "Unsupported argument '%s'", args_name); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); return; } settings_connection_update (self, TRUE, - context, + invocation, settings, flags); } @@ -2025,7 +2071,7 @@ get_modify_permission_basic (NMSettingsConnection *self) * request affects more than just the caller, require 'modify.system'. */ s_con = nm_connection_get_setting_connection (NM_CONNECTION (self)); - g_assert (s_con); + nm_assert (s_con); if (nm_setting_connection_get_num_permissions (s_con) == 1) return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; @@ -2033,26 +2079,30 @@ get_modify_permission_basic (NMSettingsConnection *self) } static void -impl_settings_connection_delete (NMSettingsConnection *self, - GDBusMethodInvocation *context) -{ - NMAuthSubject *subject = NULL; +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; if (!check_writable (NM_CONNECTION (self), &error)) - goto out_err; + goto err; - subject = _new_auth_subject (context, &error); - if (subject) { - auth_start (self, context, subject, get_modify_permission_basic (self), delete_auth_cb, NULL); - g_object_unref (subject); - } else - goto out_err; + 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; -out_err: +err: nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, NULL, subject, error->message); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); } /*****************************************************************************/ @@ -2111,24 +2161,33 @@ dbus_get_secrets_auth_cb (NMSettingsConnection *self, } static void -impl_settings_connection_get_secrets (NMSettingsConnection *self, - GDBusMethodInvocation *context, - const gchar *setting_name) -{ - NMAuthSubject *subject; +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 (context, &error); - if (subject) { - auth_start (self, - context, - subject, - get_modify_permission_basic (self), - dbus_get_secrets_auth_cb, - g_strdup (setting_name)); - g_object_unref (subject); - } else - g_dbus_method_invocation_take_error (context, error); + 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 @@ -2157,7 +2216,7 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self, /* Tell agents to remove secrets for this connection */ nm_agent_manager_delete_secrets (priv->agent_mgr, - nm_connection_get_path (NM_CONNECTION (self)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), NM_CONNECTION (self)); nm_settings_connection_update (self, @@ -2177,26 +2236,31 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self, } static void -impl_settings_connection_clear_secrets (NMSettingsConnection *self, - GDBusMethodInvocation *context) -{ - NMAuthSubject *subject; +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 (context, &error); - if (subject) { - auth_start (self, - context, - subject, - get_modify_permission_basic (self), - dbus_clear_secrets_auth_cb, - NULL); - g_object_unref (subject); - } else { + 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 (context, error); + 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); } /*****************************************************************************/ @@ -2216,55 +2280,64 @@ void nm_settings_connection_signal_remove (NMSettingsConnection *self) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + AuthData *auth_data; if (priv->removed) return; priv->removed = TRUE; - g_signal_emit_by_name (self, NM_SETTINGS_CONNECTION_REMOVED); + + while ((auth_data = c_list_first_entry (&priv->auth_lst_head, AuthData, auth_lst))) + nm_auth_manager_check_authorization_cancel (auth_data->call_id); + + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_settings_connection, + &signal_info_removed, + "()"); + g_signal_emit (self, signals[REMOVED], 0); } gboolean nm_settings_connection_get_unsaved (NMSettingsConnection *self) { - return NM_FLAGS_HAS (nm_settings_connection_get_flags (self), NM_SETTINGS_CONNECTION_FLAGS_UNSAVED); + return NM_FLAGS_HAS (nm_settings_connection_get_flags (self), NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED); } /*****************************************************************************/ -NM_UTILS_FLAGS2STR_DEFINE_STATIC (_settings_connection_flags_to_string, NMSettingsConnectionFlags, - NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_NONE, "none"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_UNSAVED, "unsaved"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED, "nm-generated"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_VOLATILE, "volatile"), - NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_VISIBLE, "visible"), +NM_UTILS_FLAGS2STR_DEFINE_STATIC (_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"), ); -NMSettingsConnectionFlags +NMSettingsConnectionIntFlags nm_settings_connection_get_flags (NMSettingsConnection *self) { - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_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; } -NMSettingsConnectionFlags -nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionFlags flags, gboolean set) +NMSettingsConnectionIntFlags +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_FLAGS_NONE); + set ? flags : NM_SETTINGS_CONNECTION_INT_FLAGS_NONE); } -NMSettingsConnectionFlags +NMSettingsConnectionIntFlags nm_settings_connection_set_flags_full (NMSettingsConnection *self, - NMSettingsConnectionFlags mask, - NMSettingsConnectionFlags value) + NMSettingsConnectionIntFlags mask, + NMSettingsConnectionIntFlags value) { NMSettingsConnectionPrivate *priv; - NMSettingsConnectionFlags old_flags; + NMSettingsConnectionIntFlags old_flags; - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_FLAGS_NONE); - nm_assert (mask && !NM_FLAGS_ANY (mask, ~NM_SETTINGS_CONNECTION_FLAGS_ALL)); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_INT_FLAGS_NONE); + nm_assert (mask && !NM_FLAGS_ANY (mask, ~NM_SETTINGS_CONNECTION_INT_FLAGS_ALL)); nm_assert (!NM_FLAGS_ANY (value, ~mask)); priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); @@ -2273,6 +2346,7 @@ nm_settings_connection_set_flags_full (NMSettingsConnection *self, 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)", @@ -2280,9 +2354,17 @@ nm_settings_connection_set_flags_full (NMSettingsConnection *self, _settings_connection_flags_to_string (priv->flags, buf2, sizeof (buf2))); priv->flags = value; nm_assert (priv->flags == value); - _notify (self, PROP_FLAGS); - if (NM_FLAGS_HAS (old_flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED) != NM_FLAGS_HAS (value, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED)) + + 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; } @@ -2703,7 +2785,7 @@ _autoconnect_retries_set (NMSettingsConnection *self, if (retries) priv->autoconnect_retries_blocked_until = 0; else { - /* XXX: the blocked time must be identical for all connections, otherwise + /* 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 everytime a connection gets blocked). */ @@ -2798,7 +2880,7 @@ gboolean nm_settings_connection_autoconnect_is_blocked (NMSettingsConnection *self) { NMSettingsConnectionPrivate *priv; - NMSettingsConnectionFlags flags; + NMSettingsConnectionIntFlags flags; g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), TRUE); @@ -2810,9 +2892,9 @@ nm_settings_connection_autoconnect_is_blocked (NMSettingsConnection *self) return TRUE; flags = priv->flags; - if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_VOLATILE)) + if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)) return TRUE; - if (!NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_VISIBLE)) + if (!NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) return TRUE; return FALSE; @@ -2900,8 +2982,11 @@ nm_settings_connection_init (NMSettingsConnection *self) priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionPrivate); self->_priv = priv; + c_list_init (&self->_connections_lst); + priv->ready = TRUE; c_list_init (&priv->call_ids_lst_head); + c_list_init (&priv->auth_lst_head); priv->session_monitor = g_object_ref (nm_session_monitor_get ()); priv->session_changed_id = g_signal_connect (priv->session_monitor, @@ -2937,6 +3022,9 @@ dispose (GObject *object) _LOGD ("disposing"); + 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) @@ -2954,11 +3042,7 @@ dispose (GObject *object) g_clear_object (&priv->system_secrets); g_clear_object (&priv->agent_secrets); - /* Cancel PolicyKit requests */ - g_slist_free_full (priv->pending_auths, (GDestroyNotify) nm_auth_chain_unref); - priv->pending_auths = NULL; - - g_clear_pointer (&priv->seen_bssids, (GDestroyNotify) g_hash_table_destroy); + g_clear_pointer (&priv->seen_bssids, g_hash_table_destroy); set_visible (self, FALSE); @@ -2986,7 +3070,8 @@ get_property (GObject *object, guint prop_id, g_value_set_boolean (value, nm_settings_connection_get_ready (self)); break; case PROP_FLAGS: - g_value_set_uint (value, nm_settings_connection_get_flags (self)); + 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)); @@ -3014,22 +3099,120 @@ set_property (GObject *object, guint prop_id, } } +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 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), + ), + ), + .legacy_property_changed = TRUE, +}; + static void -nm_settings_connection_class_init (NMSettingsConnectionClass *class) +nm_settings_connection_class_init (NMSettingsConnectionClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - g_type_class_add_private (class, sizeof (NMSettingsConnectionPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingsConnectionPrivate)); - exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH_SETTINGS); + 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->constructed = constructed; object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; - class->supports_secrets = supports_secrets; + klass->supports_secrets = supports_secrets; obj_properties[PROP_UNSAVED] = g_param_spec_boolean (NM_SETTINGS_CONNECTION_UNSAVED, "", "", @@ -3045,9 +3228,7 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) obj_properties[PROP_FLAGS] = g_param_spec_uint (NM_SETTINGS_CONNECTION_FLAGS, "", "", - NM_SETTINGS_CONNECTION_FLAGS_NONE, - NM_SETTINGS_CONNECTION_FLAGS_ALL, - NM_SETTINGS_CONNECTION_FLAGS_NONE, + 0, G_MAXUINT32, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); @@ -3060,20 +3241,10 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - signals[UPDATED] = - g_signal_new (NM_SETTINGS_CONNECTION_UPDATED, - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - /* internal signal, with an argument (gboolean by_user). */ signals[UPDATED_INTERNAL] = g_signal_new (NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, - G_TYPE_FROM_CLASS (class), + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, @@ -3081,24 +3252,20 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) signals[REMOVED] = g_signal_new (NM_SETTINGS_CONNECTION_REMOVED, - G_TYPE_FROM_CLASS (class), + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class), - NMDBUS_TYPE_SETTINGS_CONNECTION_SKELETON, - "Update", impl_settings_connection_update, - "UpdateUnsaved", impl_settings_connection_update_unsaved, - "Delete", impl_settings_connection_delete, - "GetSettings", impl_settings_connection_get_settings, - "GetSecrets", impl_settings_connection_get_secrets, - "ClearSecrets", impl_settings_connection_clear_secrets, - "Save", impl_settings_connection_save, - "Update2", impl_settings_connection_update2, - NULL); + 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); } static void diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index 29ec05dd..70518687 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -24,7 +24,7 @@ #include -#include "nm-exported-object.h" +#include "nm-dbus-object.h" #include "nm-connection.h" #define NM_TYPE_SETTINGS_CONNECTION (nm_settings_connection_get_type ()) @@ -34,14 +34,11 @@ #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)) -/* Signals */ -#define NM_SETTINGS_CONNECTION_UPDATED "updated" #define NM_SETTINGS_CONNECTION_REMOVED "removed" #define NM_SETTINGS_CONNECTION_GET_SECRETS "get-secrets" #define NM_SETTINGS_CONNECTION_CANCEL_SECRETS "cancel-secrets" - -/* Internal signals */ #define NM_SETTINGS_CONNECTION_UPDATED_INTERNAL "updated-internal" +#define NM_SETTINGS_CONNECTION_FLAGS_CHANGED "flags-changed" /* Properties */ #define NM_SETTINGS_CONNECTION_UNSAVED "unsaved" @@ -51,34 +48,46 @@ #define NM_SETTINGS_CONNECTION_FLAGS "flags" #define NM_SETTINGS_CONNECTION_FILENAME "filename" - /** - * NMSettingsConnectionFlags: - * @NM_SETTINGS_CONNECTION_FLAGS_NONE: no flag set - * @NM_SETTINGS_CONNECTION_FLAGS_UNSAVED: the connection is not saved to disk - * @NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED: A connection is "nm-generated" if + * NMSettingsConnectionIntFlags: + * @NM_SETTINGS_CONNECTION_INT_FLAGS_NONE: no flag set + * @NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED: the connection is not saved to disk. + * See also #NM_SETTINGS_CONNECTION_FLAG_UNSAVED. + * @NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED: A connection is "nm-generated" if * it was generated by NetworkManger. If the connection gets modified or saved * by the user, the flag gets cleared. A nm-generated is implicitly unsaved. - * @NM_SETTINGS_CONNECTION_FLAGS_VOLATILE: The connection will be deleted + * See also #NM_SETTINGS_CONNECTION_FLAG_NM_GENERATED. + * @NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE: The connection will be deleted * when it disconnects. That is for in-memory connections (unsaved), which are * currently active but cleanup on disconnect. - * @NM_SETTINGS_CONNECTION_FLAGS_VISIBLE: The connection is visible - * @NM_SETTINGS_CONNECTION_FLAGS_ALL: special mask, for all known flags + * See also #NM_SETTINGS_CONNECTION_FLAG_VOLATILE. + * @NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE: The connection is visible + * @NM_SETTINGS_CONNECTION_INT_FLAGS_EXPORTED_MASK: the entire enum is + * internal, however, parts of it is public API as #NMSettingsConnectionFlags. + * This mask, are the public flags. + * @NM_SETTINGS_CONNECTION_INT_FLAGS_ALL: special mask, for all known flags * * #NMSettingsConnection flags. **/ typedef enum { - NM_SETTINGS_CONNECTION_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_VISIBLE = (1LL << 3), - NM_SETTINGS_CONNECTION_FLAGS_UNSAVED = (1LL << 0), - NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED = (1LL << 1), - NM_SETTINGS_CONNECTION_FLAGS_VOLATILE = (1LL << 2), + __NM_SETTINGS_CONNECTION_INT_FLAGS_LAST, - NM_SETTINGS_CONNECTION_FLAGS_VISIBLE = (1LL << 3), + 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 + | 0, - __NM_SETTINGS_CONNECTION_FLAGS_LAST, - NM_SETTINGS_CONNECTION_FLAGS_ALL = ((__NM_SETTINGS_CONNECTION_FLAGS_LAST - 1) << 1) - 1, -} NMSettingsConnectionFlags; + NM_SETTINGS_CONNECTION_INT_FLAGS_ALL = ((__NM_SETTINGS_CONNECTION_INT_FLAGS_LAST - 1) << 1) - 1, +} NMSettingsConnectionIntFlags; typedef enum { NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE = 0, @@ -106,12 +115,13 @@ typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass; struct _NMSettingsConnectionPrivate; struct _NMSettingsConnection { - NMExportedObject parent; + NMDBusObject parent; struct _NMSettingsConnectionPrivate *_priv; + CList _connections_lst; }; struct _NMSettingsConnectionClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; gboolean (*commit_changes) (NMSettingsConnection *self, NMConnection *new_connection, @@ -199,9 +209,9 @@ void nm_settings_connection_signal_remove (NMSettingsConnection *self); gboolean nm_settings_connection_get_unsaved (NMSettingsConnection *self); -NMSettingsConnectionFlags nm_settings_connection_get_flags (NMSettingsConnection *self); -NMSettingsConnectionFlags nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionFlags flags, gboolean set); -NMSettingsConnectionFlags nm_settings_connection_set_flags_full (NMSettingsConnection *self, NMSettingsConnectionFlags mask, NMSettingsConnectionFlags value); +NMSettingsConnectionIntFlags nm_settings_connection_get_flags (NMSettingsConnection *self); +NMSettingsConnectionIntFlags nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionIntFlags flags, gboolean set); +NMSettingsConnectionIntFlags nm_settings_connection_set_flags_full (NMSettingsConnection *self, NMSettingsConnectionIntFlags mask, NMSettingsConnectionIntFlags value); 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); diff --git a/src/settings/nm-settings-plugin.c b/src/settings/nm-settings-plugin.c index 234e345f..f6dd2cfb 100644 --- a/src/settings/nm-settings-plugin.c +++ b/src/settings/nm-settings-plugin.c @@ -35,30 +35,6 @@ nm_settings_plugin_default_init (NMSettingsPluginInterface *g_iface) if (initialized) return; - /* Properties */ - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_SETTINGS_PLUGIN_NAME, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_SETTINGS_PLUGIN_INFO, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property - (g_iface, - g_param_spec_uint (NM_SETTINGS_PLUGIN_CAPABILITIES, "", "", - NM_SETTINGS_PLUGIN_CAP_NONE, - NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS, - NM_SETTINGS_PLUGIN_CAP_NONE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - /* Signals */ g_signal_new (NM_SETTINGS_PLUGIN_CONNECTION_ADDED, iface_type, diff --git a/src/settings/nm-settings-plugin.h b/src/settings/nm-settings-plugin.h index 97bb7b65..6fba25e7 100644 --- a/src/settings/nm-settings-plugin.h +++ b/src/settings/nm-settings-plugin.h @@ -34,33 +34,10 @@ GObject * nm_settings_plugin_factory (void); #define NM_IS_SETTINGS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_PLUGIN)) #define NM_SETTINGS_PLUGIN_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPluginInterface)) - -#define NM_SETTINGS_PLUGIN_NAME "name" -#define NM_SETTINGS_PLUGIN_INFO "info" -#define NM_SETTINGS_PLUGIN_CAPABILITIES "capabilities" - #define NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED "unmanaged-specs-changed" #define NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED "unrecognized-specs-changed" #define NM_SETTINGS_PLUGIN_CONNECTION_ADDED "connection-added" -typedef enum { - NM_SETTINGS_PLUGIN_CAP_NONE = 0x00000000, - NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS = 0x00000001, - - /* When adding more capabilities, be sure to update the "Capabilities" - * property max value in nm-settings-plugin.c. - */ -} NMSettingsPluginCapabilities; - -typedef enum { - NM_SETTINGS_PLUGIN_PROP_FIRST = 0x1000, - - NM_SETTINGS_PLUGIN_PROP_NAME = NM_SETTINGS_PLUGIN_PROP_FIRST, - NM_SETTINGS_PLUGIN_PROP_INFO, - NM_SETTINGS_PLUGIN_PROP_CAPABILITIES, -} NMSettingsPluginProp; - - typedef struct _NMSettingsPlugin NMSettingsPlugin; typedef struct { diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 8e3fc582..94018734 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -62,10 +62,12 @@ #include "nm-utils.h" #include "nm-core-internal.h" +#include "nm-utils/nm-c-list.h" +#include "nm-dbus-object.h" #include "devices/nm-device-ethernet.h" #include "nm-settings-connection.h" #include "nm-settings-plugin.h" -#include "nm-bus-manager.h" +#include "nm-dbus-manager.h" #include "nm-auth-utils.h" #include "nm-auth-subject.h" #include "nm-session-monitor.h" @@ -77,8 +79,6 @@ #include "nm-dispatcher.h" #include "nm-hostname-manager.h" -#include "introspection/org.freedesktop.NetworkManager.Settings.h" - /*****************************************************************************/ #define EXPORT(sym) void * __export_##sym = &sym; @@ -107,7 +107,6 @@ enum { CONNECTION_UPDATED, CONNECTION_REMOVED, CONNECTION_FLAGS_CHANGED, - NEW_CONNECTION, /* exported, not used internally */ LAST_SIGNAL }; @@ -121,29 +120,33 @@ typedef struct { GSList *auths; GSList *plugins; - gboolean connections_loaded; - GHashTable *connections; + + CList connections_lst_head; + NMSettingsConnection **connections_cached_list; GSList *unmanaged_specs; GSList *unrecognized_specs; - gboolean started; - gboolean startup_complete; - NMHostnameManager *hostname_manager; + guint connections_len; + + bool started:1; + bool startup_complete:1; + bool connections_loaded:1; + } NMSettingsPrivate; struct _NMSettings { - NMExportedObject parent; + NMDBusObject parent; NMSettingsPrivate _priv; }; struct _NMSettingsClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_EXPORTED_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) @@ -154,6 +157,10 @@ G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT); /*****************************************************************************/ +static const NMDBusInterfaceInfoExtended interface_info_settings; +static const GDBusSignalInfo signal_info_new_connection; +static const GDBusSignalInfo signal_info_connection_removed; + static void claim_connection (NMSettings *self, NMSettingsConnection *connection); @@ -164,27 +171,29 @@ static void connection_ready_changed (NMSettingsConnection *conn, GParamSpec *pspec, gpointer user_data); +static void default_wired_clear_tag (NMSettings *self, + NMDevice *device, + NMSettingsConnection *connection, + gboolean add_to_no_auto_default); + /*****************************************************************************/ static void check_startup_complete (NMSettings *self) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GHashTableIter iter; NMSettingsConnection *conn; if (priv->startup_complete) return; - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn)) { + c_list_for_each_entry (conn, &priv->connections_lst_head, _connections_lst) { if (!nm_settings_connection_get_ready (conn)) return; } /* the connection_ready_changed signal handler is no longer needed. */ - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn)) + c_list_for_each_entry (conn, &priv->connections_lst_head, _connections_lst) g_signal_handlers_disconnect_by_func (conn, G_CALLBACK (connection_ready_changed), self); priv->startup_complete = TRUE; @@ -247,43 +256,25 @@ load_connections (NMSettings *self) unrecognized_specs_changed (NULL, self); } -void -nm_settings_for_each_connection (NMSettings *self, - NMSettingsForEachFunc for_each_func, - gpointer user_data) -{ - NMSettingsPrivate *priv; - GHashTableIter iter; - gpointer data; - - g_return_if_fail (NM_IS_SETTINGS (self)); - g_return_if_fail (for_each_func != NULL); - - priv = NM_SETTINGS_GET_PRIVATE (self); - - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) - for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data); -} - static void -impl_settings_list_connections (NMSettings *self, - GDBusMethodInvocation *context) +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); - GPtrArray *connections; - GHashTableIter iter; - gpointer key; - - connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1); - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, &key, NULL)) - g_ptr_array_add (connections, key); - g_ptr_array_add (connections, NULL); - - g_dbus_method_invocation_return_value (context, - g_variant_new ("(^ao)", connections->pdata)); - g_ptr_array_unref (connections); + 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 * @@ -291,16 +282,14 @@ nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid) { NMSettingsPrivate *priv; NMSettingsConnection *candidate; - GHashTableIter iter; g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); g_return_val_if_fail (uuid != NULL, NULL); priv = NM_SETTINGS_GET_PRIVATE (self); - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) { - if (g_strcmp0 (uuid, nm_settings_connection_get_uuid (candidate)) == 0) + c_list_for_each_entry (candidate, &priv->connections_lst_head, _connections_lst) { + if (nm_streq (uuid, nm_settings_connection_get_uuid (candidate))) return candidate; } @@ -308,14 +297,21 @@ nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid) } static void -impl_settings_get_connection_by_uuid (NMSettings *self, - GDBusMethodInvocation *context, - const char *uuid) +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 *connection = NULL; - NMAuthSubject *subject = NULL; + gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; - char *error_desc = NULL; + const char *uuid; + + g_variant_get (parameters, "(&s)", &uuid); connection = nm_settings_get_connection_by_uuid (self, uuid); if (!connection) { @@ -325,7 +321,7 @@ impl_settings_get_connection_by_uuid (NMSettings *self, goto error; } - subject = nm_auth_subject_new_unix_process_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (invocation); if (!subject) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, @@ -333,26 +329,40 @@ impl_settings_get_connection_by_uuid (NMSettings *self, goto error; } - if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection), - subject, - &error_desc)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - error_desc); - g_free (error_desc); + if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (connection), + subject, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + &error)) goto error; - } - g_clear_object (&subject); - g_dbus_method_invocation_return_value ( - context, - g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection)))); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(o)", + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)))); return; error: - g_assert (error); - g_dbus_method_invocation_take_error (context, error); - g_clear_object (&subject); + g_dbus_method_invocation_take_error (invocation, error); +} + +static void +_clear_connections_cached_list (NMSettingsPrivate *priv) +{ + if (!priv->connections_cached_list) + return; + + 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, + 0xdeaddead, + sizeof (NMSettingsConnection *) * (priv->connections_len + 1)); +#endif + nm_clear_g_free (&priv->connections_cached_list); } /** @@ -370,37 +380,33 @@ error: NMSettingsConnection *const* nm_settings_get_connections (NMSettings *self, guint *out_len) { - GHashTableIter iter; NMSettingsPrivate *priv; - guint l, i; NMSettingsConnection **v; NMSettingsConnection *con; + guint i; g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); priv = NM_SETTINGS_GET_PRIVATE (self); - if (G_LIKELY (priv->connections_cached_list)) { - NM_SET_OUT (out_len, g_hash_table_size (priv->connections)); - return priv->connections_cached_list; - } + nm_assert (priv->connections_len == c_list_length (&priv->connections_lst_head)); - l = g_hash_table_size (priv->connections); + if (G_UNLIKELY (!priv->connections_cached_list)) { + v = g_new (NMSettingsConnection *, priv->connections_len + 1); - v = g_new (NMSettingsConnection *, (gsize) l + 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; - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &con)) { - nm_assert (i < l); - v[i++] = con; + priv->connections_cached_list = v; } - nm_assert (i == l); - v[i] = NULL; - NM_SET_OUT (out_len, l); - priv->connections_cached_list = v; - return v; + NM_SET_OUT (out_len, priv->connections_len); + return priv->connections_cached_list; } /** @@ -467,28 +473,48 @@ NMSettingsConnection * nm_settings_get_connection_by_path (NMSettings *self, const char *path) { NMSettingsPrivate *priv; + NMSettingsConnection *connection; g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); - g_return_val_if_fail (path != NULL, NULL); + g_return_val_if_fail (path, NULL); priv = NM_SETTINGS_GET_PRIVATE (self); - return (NMSettingsConnection *) g_hash_table_lookup (priv->connections, path); + connection = (NMSettingsConnection *) 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; } gboolean nm_settings_has_connection (NMSettings *self, NMSettingsConnection *connection) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GHashTableIter iter; - gpointer data; + gboolean has; - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) - if (data == connection) - return TRUE; + g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), FALSE); - return FALSE; + 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; + + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)); + if (path) + candidate = nm_settings_get_connection_by_path (self, path); + + (has == (connection == candidate)); + })); + + return has; } const GSList * @@ -500,7 +526,7 @@ nm_settings_get_unmanaged_specs (NMSettings *self) } static NMSettingsPlugin * -get_plugin (NMSettings *self, guint32 capability) +get_plugin (NMSettings *self, gboolean has_add_connection) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; @@ -509,11 +535,13 @@ get_plugin (NMSettings *self, guint32 capability) /* Do any of the plugins support the given capability? */ for (iter = priv->plugins; iter; iter = iter->next) { - NMSettingsPluginCapabilities caps = NM_SETTINGS_PLUGIN_CAP_NONE; + NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); + + if (!has_add_connection) + return plugin; - g_object_get (G_OBJECT (iter->data), NM_SETTINGS_PLUGIN_CAPABILITIES, &caps, NULL); - if (NM_FLAGS_ALL (caps, capability)) - return NM_SETTINGS_PLUGIN (iter->data); + if (NM_SETTINGS_PLUGIN_GET_INTERFACE (iter->data)->add_connection != NULL) + return plugin; } return NULL; @@ -583,8 +611,6 @@ static gboolean add_plugin (NMSettings *self, NMSettingsPlugin *plugin) { NMSettingsPrivate *priv; - char *pname = NULL; - char *pinfo = NULL; const char *path; g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); @@ -600,44 +626,102 @@ add_plugin (NMSettings *self, NMSettingsPlugin *plugin) priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin)); nm_settings_plugin_init (plugin); - g_object_get (G_OBJECT (plugin), - NM_SETTINGS_PLUGIN_NAME, &pname, - NM_SETTINGS_PLUGIN_INFO, &pinfo, - NULL); path = g_object_get_qdata (G_OBJECT (plugin), plugin_module_path_quark ()); - _LOGI ("loaded plugin %s: %s%s%s%s", pname, pinfo, - NM_PRINT_FMT_QUOTED (path, " (", path, ")", "")); - g_free (pname); - g_free (pinfo); + _LOGI ("Loaded settings plugin: %s (%s)", G_OBJECT_TYPE_NAME (plugin), path ?: "internal"); return TRUE; } -static GObject * -find_plugin (GSList *list, const char *pname) +static gboolean +plugin_loaded (GSList *list, const char *path) { GSList *iter; - GObject *obj = NULL; - g_return_val_if_fail (pname != NULL, NULL); + g_return_val_if_fail (path != NULL, TRUE); - for (iter = list; iter && !obj; iter = g_slist_next (iter)) { - NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); - char *list_pname = NULL; + for (iter = list; iter; iter = g_slist_next (iter)) { + const char *list_path = g_object_get_qdata (G_OBJECT (iter->data), + plugin_module_path_quark ()); + + if (g_strcmp0 (path, list_path) == 0) + return TRUE; + } + + return FALSE; +} + +static gboolean +load_plugin (NMSettings *self, GSList *list, const char *pname, GError **error) +{ + gs_free char *full_name = NULL; + gs_free char *path = NULL; + gs_unref_object GObject *obj = NULL; + GModule *plugin; + GObject * (*factory_func) (void); + struct stat st; + int errsv; + + full_name = g_strdup_printf ("nm-settings-plugin-%s", pname); + path = g_module_build_path (NMPLUGINDIR, full_name); + + if (plugin_loaded (list, path)) + return TRUE; + + if (stat (path, &st) != 0) { + errsv = errno; + _LOGW ("could not load plugin '%s' from file '%s': %s", pname, path, strerror (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; + } + + plugin = g_module_open (path, G_MODULE_BIND_LOCAL); + if (!plugin) { + _LOGW ("could not load plugin '%s' from file '%s': %s", + pname, path, g_module_error ()); + return TRUE; + } - g_object_get (G_OBJECT (plugin), - NM_SETTINGS_PLUGIN_NAME, - &list_pname, - NULL); - if (list_pname && !strcmp (pname, list_pname)) - obj = G_OBJECT (plugin); + /* errors after this point are fatal, because we loaded the shared library already. */ - g_free (list_pname); + if (!g_module_symbol (plugin, "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 (plugin); + return FALSE; } - return obj; + /* after accessing the plugin we cannot unload it anymore, because the glib + * types cannot be properly unregistered. */ + g_module_make_resident (plugin); + + obj = (*factory_func) (); + if (!obj || !NM_IS_SETTINGS_PLUGIN (obj)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Plugin '%s' returned invalid system config object.", + pname); + return FALSE; + } + + g_object_set_qdata_full (obj, plugin_module_path_quark (), path, g_free); + path = NULL; + if (add_plugin (self, NM_SETTINGS_PLUGIN (obj))) + list = g_slist_append (list, g_steal_pointer (&obj)); + + return TRUE; } static void @@ -670,15 +754,14 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) for (iter = plugins; iter && *iter; iter++) { const char *pname = *iter; - GObject *obj; if (!*pname || strchr (pname, '/')) { _LOGW ("ignore invalid plugin \"%s\"", pname); continue; } - if (!strcmp (pname, "ifcfg-suse")) { - _LOGW ("skipping deprecated plugin ifcfg-suse"); + if (NM_IN_STRSET (pname, "ifcfg-suse", "ifnet")) { + _LOGW ("skipping deprecated plugin %s", pname); continue; } @@ -704,84 +787,19 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) continue; } - if (find_plugin (list, pname)) - continue; - -load_plugin: - { - GModule *plugin; - gs_free char *full_name = NULL; - gs_free char *path = NULL; - GObject * (*factory_func) (void); - 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, strerror (errsv)); - goto next; - } - if (!S_ISREG (st.st_mode)) { - _LOGW ("could not load plugin '%s' from file '%s': not a file", pname, path); - goto next; - } - if (st.st_uid != 0) { - _LOGW ("could not load plugin '%s' from file '%s': file must be owned by root", pname, path); - goto next; - } - if (st.st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) { - _LOGW ("could not load plugin '%s' from file '%s': invalid file permissions", pname, path); - goto next; - } - - plugin = g_module_open (path, G_MODULE_BIND_LOCAL); - if (!plugin) { - _LOGW ("could not load plugin '%s' from file '%s': %s", - pname, path, g_module_error ()); - goto next; - } - - /* errors after this point are fatal, because we loaded the shared library already. */ + success = load_plugin (self, list, pname, error); + if (!success) + break; - if (!g_module_symbol (plugin, "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); - success = FALSE; - g_module_close (plugin); - break; - } - - /* after accessing the plugin we cannot unload it anymore, because the glib - * types cannot be properly unregistered. */ - g_module_make_resident (plugin); - - obj = (*factory_func) (); - if (!obj || !NM_IS_SETTINGS_PLUGIN (obj)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "Plugin '%s' returned invalid system config object.", - pname); - success = FALSE; - break; - } - - g_object_set_qdata_full (obj, plugin_module_path_quark (), path, g_free); - path = NULL; - if (add_plugin (self, NM_SETTINGS_PLUGIN (obj))) - list = g_slist_append (list, obj); - else - g_object_unref (obj); - } -next: if (add_ibft && !strcmp (pname, "ifcfg-rh")) { /* The plugin ibft is not explicitly mentioned but we just enabled "ifcfg-rh". * Enable "ibft" by default after "ifcfg-rh". */ pname = "ibft"; add_ibft = FALSE; - goto load_plugin; + + success = load_plugin (self, list, "ibft", error); + if (!success) + break; } } @@ -806,7 +824,6 @@ connection_updated (NMSettingsConnection *connection, gboolean by_user, gpointer static void connection_flags_changed (NMSettingsConnection *connection, - GParamSpec *pspec, gpointer user_data) { g_signal_emit (NM_SETTINGS (user_data), @@ -820,11 +837,20 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) { NMSettings *self = NM_SETTINGS (user_data); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - const char *cpath = nm_connection_get_path (NM_CONNECTION (connection)); + NMDevice *device; - if (!g_hash_table_lookup (priv->connections, cpath)) - g_return_if_reached (); - g_object_ref (connection); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); + g_return_if_fail (!c_list_is_empty (&connection->_connections_lst)); + nm_assert (c_list_contains (&priv->connections_lst_head, &connection->_connections_lst)); + + /* When the default wired connection is removed (either deleted or saved to + * a new persistent connection by a plugin), write the MAC address of the + * wired device to the config file and don't create a new default wired + * connection for that device again. + */ + device = g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ()); + if (device) + default_wired_clear_tag (self, device, connection, TRUE); /* Disconnect signal handlers, as plugins might still keep references * to the connection (and thus the signal handlers would still be live) @@ -836,23 +862,30 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_flags_changed), self); if (!priv->startup_complete) g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_ready_changed), self); - g_object_unref (self); /* Forget about the connection internally */ - g_hash_table_remove (priv->connections, (gpointer) cpath); - g_clear_pointer (&priv->connections_cached_list, g_free); + _clear_connections_cached_list (priv); + priv->connections_len--; + c_list_unlink (&connection->_connections_lst); + + if (priv->connections_loaded) { + _notify (self, PROP_CONNECTIONS); - /* Notify D-Bus */ - g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection); + 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 (connection))); + } - /* Re-emit for listeners like NMPolicy */ - _notify (self, PROP_CONNECTIONS); - if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (connection))) - nm_exported_object_unexport (NM_EXPORTED_OBJECT (connection)); + nm_dbus_object_unexport (NM_DBUS_OBJECT (connection)); - check_startup_complete (self); + if (priv->connections_loaded) + g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection); g_object_unref (connection); + + check_startup_complete (self); } #define NM_DBUS_SERVICE_OPENCONNECT "org.freedesktop.NetworkManager.openconnect" @@ -900,19 +933,16 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GError *error = NULL; - GHashTableIter iter; - gpointer data; const char *path; NMSettingsConnection *existing; g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); - g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); + g_return_if_fail (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (connection))); - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) { - /* prevent duplicates */ - if (data == connection) - return; + /* prevent duplicates */ + if (!c_list_is_empty (&connection->_connections_lst)) { + nm_assert (c_list_contains (&priv->connections_lst_head, &connection->_connections_lst)); + return; } if (!nm_connection_normalize (NM_CONNECTION (connection), NULL, NULL, &error)) { @@ -944,20 +974,19 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) /* Read seen-bssids from look-aside file and put it into the connection's data */ nm_settings_connection_read_and_fill_seen_bssids (connection); - /* Ensure it's initial visibility is up-to-date */ + /* Ensure its initial visibility is up-to-date */ nm_settings_connection_recheck_visibility (connection); /* Evil openconnect migration hack */ openconnect_migrate_hack (NM_CONNECTION (connection)); - g_object_ref (self); /* This one unexports the connection, it needs to run late to give the active * connection a chance to deal with its reference to this settings connection. */ g_signal_connect_after (connection, NM_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, G_CALLBACK (connection_updated), self); - g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_FLAGS, + g_signal_connect (connection, NM_SETTINGS_CONNECTION_FLAGS_CHANGED, G_CALLBACK (connection_flags_changed), self); if (!priv->startup_complete) { @@ -966,28 +995,29 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) self); } - /* Export the connection over D-Bus */ - g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); - path = nm_exported_object_export (NM_EXPORTED_OBJECT (connection)); - nm_connection_set_path (NM_CONNECTION (connection), path); + _clear_connections_cached_list (priv); + + g_object_ref (connection); + priv->connections_len++; + c_list_link_tail (&priv->connections_lst_head, &connection->_connections_lst); - g_hash_table_insert (priv->connections, - (gpointer) nm_connection_get_path (NM_CONNECTION (connection)), - g_object_ref (connection)); - g_clear_pointer (&priv->connections_cached_list, g_free); + path = nm_dbus_object_export (NM_DBUS_OBJECT (connection)); - nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ "); + nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ ", + path); /* Only emit the individual connection-added signal after connections * have been initially loaded. */ if (priv->connections_loaded) { - /* Internal added signal */ + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_settings, + &signal_info_new_connection, + "(o)", + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection))); + g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); _notify (self, PROP_CONNECTIONS); - - /* Exported D-Bus signal */ - g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); } nm_settings_connection_added (connection); @@ -1035,14 +1065,14 @@ nm_settings_add_connection (NMSettings *self, NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; NMSettingsConnection *added = NULL; - GHashTableIter citer; - NMConnection *candidate = NULL; + NMSettingsConnection *candidate = NULL; + const char *uuid; + + uuid = nm_connection_get_uuid (connection); /* Make sure a connection with this UUID doesn't already exist */ - g_hash_table_iter_init (&citer, priv->connections); - while (g_hash_table_iter_next (&citer, NULL, (gpointer *) &candidate)) { - if (g_strcmp0 (nm_connection_get_uuid (connection), - nm_connection_get_uuid (candidate)) == 0) { + c_list_for_each_entry (candidate, &priv->connections_lst_head, _connections_lst) { + if (nm_streq0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate)))) { g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_UUID_EXISTS, @@ -1099,7 +1129,7 @@ send_agent_owned_secrets (NMSettings *self, NMAuthSubject *subject) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - NMConnection *for_agent; + 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. @@ -1110,10 +1140,9 @@ send_agent_owned_secrets (NMSettings *self, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); nm_agent_manager_save_secrets (priv->agent_mgr, - nm_connection_get_path (NM_CONNECTION (connection)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)), for_agent, subject); - g_object_unref (for_agent); } static void @@ -1170,7 +1199,7 @@ pk_add_cb (NMAuthChain *chain, send_agent_owned_secrets (self, added, subject); g_clear_error (&error); - nm_auth_chain_unref (chain); + nm_auth_chain_destroy (chain); } /* FIXME: remove if/when kernel supports adhoc wpa */ @@ -1209,20 +1238,20 @@ void nm_settings_add_connection_dbus (NMSettings *self, NMConnection *connection, gboolean save_to_disk, + NMAuthSubject *subject, GDBusMethodInvocation *context, NMSettingsAddCallback callback, gpointer user_data) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMSettingConnection *s_con; - NMAuthSubject *subject = NULL; NMAuthChain *chain; GError *error = NULL, *tmp_error = NULL; - char *error_desc = NULL; const char *perm; - g_return_if_fail (connection != NULL); - g_return_if_fail (context != NULL); + 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)); /* Connection must be valid, of course */ if (!nm_connection_verify (connection, &tmp_error)) { @@ -1246,33 +1275,19 @@ nm_settings_add_connection_dbus (NMSettings *self, } /* Do any of the plugins support adding? */ - if (!get_plugin (self, NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS)) { + if (!get_plugin (self, TRUE)) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, "None of the registered plugins support add."); goto done; } - subject = nm_auth_subject_new_unix_process_from_context (context); - if (!subject) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Unable to determine UID of request."); + if (!nm_auth_is_subject_in_acl_set_error (connection, + subject, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + &error)) goto done; - } - - /* 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 (connection, - subject, - &error_desc)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - error_desc); - g_free (error_desc); - 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 @@ -1295,50 +1310,50 @@ nm_settings_add_connection_dbus (NMSettings *self, } priv->auths = g_slist_append (priv->auths, chain); - nm_auth_chain_add_call (chain, perm, TRUE); 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, "save-to-disk", GUINT_TO_POINTER (save_to_disk), NULL); + nm_auth_chain_add_call (chain, perm, TRUE); + return; done: - if (error) - callback (self, NULL, error, context, subject, user_data); - - g_clear_error (&error); - g_clear_object (&subject); + nm_assert (error); + callback (self, NULL, error, context, subject, user_data); + g_error_free (error); } static void -impl_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) { 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); } else { - g_dbus_method_invocation_return_value ( - context, - g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection)))); + 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 -impl_settings_add_connection_helper (NMSettings *self, - GDBusMethodInvocation *context, - GVariant *settings, - gboolean save_to_disk) +settings_add_connection_helper (NMSettings *self, + GDBusMethodInvocation *context, + GVariant *settings, + gboolean save_to_disk) { gs_unref_object NMConnection *connection = NULL; GError *error = NULL; + gs_unref_object NMAuthSubject *subject = NULL; connection = _nm_simple_connection_new_from_dbus (settings, NM_SETTING_PARSE_FLAGS_STRICT @@ -1351,81 +1366,125 @@ impl_settings_add_connection_helper (NMSettings *self, return; } + subject = nm_auth_subject_new_unix_process_from_context (context); + if (!subject) { + g_dbus_method_invocation_return_error_literal (context, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + "Unable to determine UID of request."); + return; + } + nm_settings_add_connection_dbus (self, connection, save_to_disk, + subject, context, - impl_settings_add_connection_add_cb, + settings_add_connection_add_cb, NULL); } static void -impl_settings_add_connection (NMSettings *self, - GDBusMethodInvocation *context, - GVariant *settings) +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_helper (self, context, settings, TRUE); + 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, settings, TRUE); } static void -impl_settings_add_connection_unsaved (NMSettings *self, - GDBusMethodInvocation *context, - GVariant *settings) +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_helper (self, context, settings, FALSE); + 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, settings, FALSE); } static void -impl_settings_load_connections (NMSettings *self, - GDBusMethodInvocation *context, - char **filenames) +impl_settings_load_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); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GPtrArray *failures; + gs_unref_ptrarray GPtrArray *failures = NULL; GSList *iter; - int i; + guint i; + gs_free const char **filenames = 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_bus_manager_ensure_uid (nm_bus_manager_get (), - context, - G_MAXULONG, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED)) + if (!nm_dbus_manager_ensure_uid (nm_dbus_object_get_manager (obj), + invocation, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) return; - failures = g_ptr_array_new (); + if (filenames) { + for (i = 0; filenames[i]; i++) { + for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { + NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); - for (i = 0; filenames[i]; i++) { - for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { - NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); - - if (nm_settings_plugin_load_connection (plugin, filenames[i])) - break; - } + if (nm_settings_plugin_load_connection (plugin, filenames[i])) + break; + } - if (!iter) { - if (!g_path_is_absolute (filenames[i])) - _LOGW ("connection filename '%s' is not an absolute path", filenames[i]); - g_ptr_array_add (failures, (char *) filenames[i]); + if (!iter) { + if (!g_path_is_absolute (filenames[i])) + _LOGW ("connection filename '%s' is not an absolute path", filenames[i]); + if (!failures) + failures = g_ptr_array_new (); + g_ptr_array_add (failures, (char *) filenames[i]); + } } } - g_ptr_array_add (failures, NULL); - g_dbus_method_invocation_return_value ( - context, - g_variant_new ("(b^as)", - failures->len == 1, - failures->pdata)); - g_ptr_array_unref (failures); + if (failures) + g_ptr_array_add (failures, 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 (NMSettings *self, - GDBusMethodInvocation *context) +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); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; @@ -1433,11 +1492,11 @@ impl_settings_reload_connections (NMSettings *self, * 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_bus_manager_ensure_uid (nm_bus_manager_get (), - context, - G_MAXULONG, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED)) + if (!nm_dbus_manager_ensure_uid (nm_dbus_object_get_manager (obj), + invocation, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) return; for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { @@ -1446,7 +1505,7 @@ impl_settings_reload_connections (NMSettings *self, nm_settings_plugin_reload_connections (plugin); } - g_dbus_method_invocation_return_value (context, g_variant_new ("(b)", TRUE)); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", TRUE)); } /*****************************************************************************/ @@ -1494,41 +1553,46 @@ pk_hostname_cb (NMAuthChain *chain, else g_dbus_method_invocation_return_value (context, NULL); - nm_auth_chain_unref (chain); + nm_auth_chain_destroy (chain); } static void -impl_settings_save_hostname (NMSettings *self, - GDBusMethodInvocation *context, - const char *hostname) +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; - GError *error = NULL; + const char *hostname; + + g_variant_get (parameters, "(&s)", &hostname); /* Minimal validation of the hostname */ if (!nm_hostname_manager_validate_hostname (hostname)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_HOSTNAME, - "The hostname was too long or contained invalid characters."); - goto done; + g_dbus_method_invocation_return_error_literal (invocation, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_HOSTNAME, + "The hostname was too long or contained invalid characters."); + return; } - chain = nm_auth_chain_new_context (context, pk_hostname_cb, self); + chain = nm_auth_chain_new_context (invocation, pk_hostname_cb, self); if (!chain) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Unable to authenticate the request."); - goto done; + g_dbus_method_invocation_return_error_literal (invocation, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + "Unable to authenticate the request."); + return; } priv->auths = g_slist_append (priv->auths, 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); - -done: - if (error) - g_dbus_method_invocation_take_error (context, error); } /*****************************************************************************/ @@ -1537,27 +1601,24 @@ static gboolean have_connection_for_device (NMSettings *self, NMDevice *device) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GHashTableIter iter; - gpointer data; NMSettingConnection *s_con; NMSettingWired *s_wired; const char *setting_hwaddr; const char *perm_hw_addr; + NMSettingsConnection *connection; g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); perm_hw_addr = nm_device_get_permanent_hw_address (device); /* Find a wired connection locked to the given MAC address, if any */ - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) { - NMConnection *connection = NM_CONNECTION (data); + c_list_for_each_entry (connection, &priv->connections_lst_head, _connections_lst) { const char *ctype, *iface; - if (!nm_device_check_connection_compatible (device, connection)) + if (!nm_device_check_connection_compatible (device, NM_CONNECTION (connection))) continue; - s_con = nm_connection_get_setting_connection (connection); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); iface = nm_setting_connection_get_interface_name (s_con); if (iface && strcmp (iface, nm_device_get_iface (device)) != 0) @@ -1568,7 +1629,7 @@ have_connection_for_device (NMSettings *self, NMDevice *device) && strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) continue; - s_wired = nm_connection_get_setting_wired (connection); + s_wired = nm_connection_get_setting_wired (NM_CONNECTION (connection)); if (!s_wired && !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) { /* No wired setting; therefore the PPPoE connection applies to any device */ @@ -1596,26 +1657,6 @@ have_connection_for_device (NMSettings *self, NMDevice *device) return FALSE; } -static void default_wired_clear_tag (NMSettings *self, - NMDevice *device, - NMSettingsConnection *connection, - gboolean add_to_no_auto_default); - -static void -default_wired_connection_removed_cb (NMSettingsConnection *connection, NMSettings *self) -{ - NMDevice *device; - - /* When the default wired connection is removed (either deleted or saved to - * a new persistent connection by a plugin), write the MAC address of the - * wired device to the config file and don't create a new default wired - * connection for that device again. - */ - device = g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ()); - if (device) - default_wired_clear_tag (self, device, connection, TRUE); -} - static void default_wired_connection_updated_by_user_cb (NMSettingsConnection *connection, gboolean by_user, NMSettings *self) { @@ -1648,7 +1689,6 @@ default_wired_clear_tag (NMSettings *self, g_object_set_qdata (G_OBJECT (connection), _default_wired_device_quark (), NULL); g_object_set_qdata (G_OBJECT (device), _default_wired_connection_quark (), NULL); - g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_removed_cb), self); g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_updated_by_user_cb), self); if (add_to_no_auto_default) @@ -1700,8 +1740,6 @@ device_realized (NMDevice *device, GParamSpec *pspec, NMSettings *self) g_signal_connect (added, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, G_CALLBACK (default_wired_connection_updated_by_user_cb), self); - g_signal_connect (added, NM_SETTINGS_CONNECTION_REMOVED, - G_CALLBACK (default_wired_connection_removed_cb), self); _LOGI ("(%s): created default wired connection '%s'", nm_device_get_iface (device), @@ -1774,10 +1812,8 @@ nm_settings_start (NMSettings *self, GError **error) /* 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 **) plugins, error)) { - g_object_unref (self); + if (!load_plugins (self, (const char **) plugins, error)) return FALSE; - } load_connections (self); check_startup_complete (self); @@ -1802,18 +1838,19 @@ get_property (GObject *object, guint prop_id, NMSettings *self = NM_SETTINGS (object); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); const GSList *specs, *iter; - GHashTableIter citer; - GPtrArray *array; - const char *path; + guint i; + char **strvs; + const char **strv; switch (prop_id) { case PROP_UNMANAGED_SPECS: - array = g_ptr_array_new (); specs = nm_settings_get_unmanaged_specs (self); - for (iter = specs; iter; iter = g_slist_next (iter)) - g_ptr_array_add (array, g_strdup (iter->data)); - g_ptr_array_add (array, NULL); - g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE)); + strvs = g_new (char *, g_slist_length ((GSList *) specs) + 1); + i = 0; + for (iter = specs; iter; iter = iter->next) + strvs[i++] = g_strdup (iter->data); + strvs[i] = NULL; + g_value_take_boxed (value, strvs); break; case PROP_HOSTNAME: g_value_set_string (value, @@ -1822,15 +1859,17 @@ get_property (GObject *object, guint prop_id, : NULL); break; case PROP_CAN_MODIFY: - g_value_set_boolean (value, !!get_plugin (self, NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS)); + g_value_set_boolean (value, !!get_plugin (self, TRUE)); break; case PROP_CONNECTIONS: - array = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1); - g_hash_table_iter_init (&citer, priv->connections); - while (g_hash_table_iter_next (&citer, (gpointer) &path, NULL)) - g_ptr_array_add (array, g_strdup (path)); - g_ptr_array_add (array, NULL); - g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE)); + if (priv->connections_loaded) { + 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)); + } else + g_value_set_boxed (value, NULL); break; case PROP_STARTUP_COMPLETE: g_value_set_boolean (value, nm_settings_get_startup_complete (self)); @@ -1848,7 +1887,7 @@ nm_settings_init (NMSettings *self) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - priv->connections = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref); + c_list_init (&priv->connections_lst_head); priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); priv->config = g_object_ref (nm_config_get ()); @@ -1866,11 +1905,9 @@ dispose (GObject *object) NMSettings *self = NM_SETTINGS (object); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - g_slist_free_full (priv->auths, (GDestroyNotify) nm_auth_chain_unref); + g_slist_free_full (priv->auths, (GDestroyNotify) nm_auth_chain_destroy); priv->auths = NULL; - g_object_unref (priv->agent_mgr); - if (priv->hostname_manager) { g_signal_handlers_disconnect_by_func (priv->hostname_manager, G_CALLBACK (_hostname_changed_cb), @@ -1887,26 +1924,139 @@ finalize (GObject *object) NMSettings *self = NM_SETTINGS (object); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - g_hash_table_destroy (priv->connections); - g_clear_pointer (&priv->connections_cached_list, g_free); + _clear_connections_cached_list (priv); + + nm_assert (c_list_is_empty (&priv->connections_lst_head)); g_slist_free_full (priv->unmanaged_specs, g_free); g_slist_free_full (priv->unrecognized_specs, g_free); g_slist_free_full (priv->plugins, g_object_unref); + g_clear_object (&priv->agent_mgr); + g_clear_object (&priv->config); G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object); } +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 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 ( + "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) { GObjectClass *object_class = G_OBJECT_CLASS (class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (class); - exported_object_class->export_path = NM_DBUS_PATH_SETTINGS; + 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->dispose = dispose; @@ -1975,23 +2125,4 @@ nm_settings_class_init (NMSettingsClass *class) 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION); - - signals[NEW_CONNECTION] = - g_signal_new ("new-connection", - 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); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class), - NMDBUS_TYPE_SETTINGS_SKELETON, - "ListConnections", impl_settings_list_connections, - "GetConnectionByUuid", impl_settings_get_connection_by_uuid, - "AddConnection", impl_settings_add_connection, - "AddConnectionUnsaved", impl_settings_add_connection_unsaved, - "LoadConnections", impl_settings_load_connections, - "ReloadConnections", impl_settings_reload_connections, - "SaveHostname", impl_settings_save_hostname, - NULL); } - diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 0ecffb70..021512fd 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -28,8 +28,6 @@ #include "nm-connection.h" -#include "nm-exported-object.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)) @@ -72,14 +70,6 @@ NMSettings *nm_settings_get (void); NMSettings *nm_settings_new (void); gboolean nm_settings_start (NMSettings *self, GError **error); -typedef void (*NMSettingsForEachFunc) (NMSettings *settings, - NMSettingsConnection *connection, - gpointer user_data); - -void nm_settings_for_each_connection (NMSettings *settings, - NMSettingsForEachFunc for_each_func, - gpointer user_data); - typedef void (*NMSettingsAddCallback) (NMSettings *settings, NMSettingsConnection *connection, GError *error, @@ -90,6 +80,7 @@ typedef void (*NMSettingsAddCallback) (NMSettings *settings, void nm_settings_add_connection_dbus (NMSettings *self, NMConnection *connection, gboolean save_to_disk, + NMAuthSubject *subject, GDBusMethodInvocation *context, NMSettingsAddCallback callback, gpointer user_data); diff --git a/src/settings/plugins/ibft/meson.build b/src/settings/plugins/ibft/meson.build new file mode 100644 index 00000000..1b6ff28a --- /dev/null +++ b/src/settings/plugins/ibft/meson.build @@ -0,0 +1,48 @@ +name = 'nm-settings-plugin-ibft' + +cflags = [ + '-DSBINDIR="@0@"'.format(nm_sbindir), + '-DSYSCONFDIR="@0@"'.format(nm_sysconfdir) +] + +libnms_ibft_core = static_library( + 'nms-ibft-core', + 'nms-ibft-reader.c', + dependencies: nm_dep, + c_args: cflags +) + +sources = files( + 'nms-ibft-connection.c', + 'nms-ibft-plugin.c' +) + +libnm_settings_plugin_ibft = shared_module( + name, + sources: sources, + dependencies: nm_dep, + c_args: cflags, + link_with: libnms_ibft_core, + link_args: ldflags_linker_script_settings, + link_depends: linker_script_settings, + install: true, + install_dir: nm_plugindir +) + +core_plugins += libnm_settings_plugin_ibft + +# FIXME: check_so_symbols replacement +''' +run_target( + 'check-local-symbols-settings-ibft', + command: [check_so_symbols, libnm_settings_plugin_ibft.full_path()], + depends: libnm_settings_plugin_ibft +) + +check-local-symbols-settings-ibft: src/settings/plugins/ibft/libnm-settings-plugin-ibft.la + $(call check_so_symbols,$(builddir)/src/settings/plugins/ibft/.libs/libnm-settings-plugin-ibft.so) +''' + +if enable_tests + subdir('tests') +endif diff --git a/src/settings/plugins/ibft/nms-ibft-plugin.c b/src/settings/plugins/ibft/nms-ibft-plugin.c index ea4d1524..77ce208f 100644 --- a/src/settings/plugins/ibft/nms-ibft-plugin.c +++ b/src/settings/plugins/ibft/nms-ibft-plugin.c @@ -120,28 +120,6 @@ get_connections (NMSettingsPlugin *config) /*****************************************************************************/ -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - switch (prop_id) { - case NM_SETTINGS_PLUGIN_PROP_NAME: - g_value_set_string (value, "iBFT"); - break; - case NM_SETTINGS_PLUGIN_PROP_INFO: - g_value_set_string (value, "(c) 2014 Red Hat, Inc. To report bugs please use the NetworkManager mailing list."); - break; - case NM_SETTINGS_PLUGIN_PROP_CAPABILITIES: - g_value_set_uint (value, NM_SETTINGS_PLUGIN_CAP_NONE); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/*****************************************************************************/ - static void init (NMSettingsPlugin *config) { @@ -175,19 +153,6 @@ nms_ibft_plugin_class_init (NMSIbftPluginClass *req_class) GObjectClass *object_class = G_OBJECT_CLASS (req_class); object_class->dispose = dispose; - object_class->get_property = get_property; - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_NAME, - NM_SETTINGS_PLUGIN_NAME); - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_INFO, - NM_SETTINGS_PLUGIN_INFO); - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_CAPABILITIES, - NM_SETTINGS_PLUGIN_CAPABILITIES); } static void diff --git a/src/settings/plugins/ibft/nms-ibft-reader.c b/src/settings/plugins/ibft/nms-ibft-reader.c index d26c8334..cf849e28 100644 --- a/src/settings/plugins/ibft/nms-ibft-reader.c +++ b/src/settings/plugins/ibft/nms-ibft-reader.c @@ -128,7 +128,7 @@ nms_ibft_reader_load_blocks (const char *iscsiadm_path, } g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "iBFT: %s exited with error %d. Message: '%s'", - iscsiadm_path, WEXITSTATUS (status), err ? err : "(none)"); + iscsiadm_path, WEXITSTATUS (status), err ?: "(none)"); goto done; } @@ -392,15 +392,15 @@ connection_setting_add (const GPtrArray *block, id = g_strdup_printf ("iBFT%s%s %s", prefix ? " " : "", - prefix ? prefix : "", + prefix ?: "", iface); uuid = _nm_utils_uuid_generate_from_strings ("ibft", s_hwaddr, s_vlanid ? "V" : "v", - s_vlanid ? s_vlanid : "", + s_vlanid ?: "", s_ip4addr ? "A" : "DHCP", - s_ip4addr ? s_ip4addr : "", + s_ip4addr ?: "", NULL); s_con = nm_setting_connection_new (); diff --git a/src/settings/plugins/ibft/tests/meson.build b/src/settings/plugins/ibft/tests/meson.build new file mode 100644 index 00000000..59f49c31 --- /dev/null +++ b/src/settings/plugins/ibft/tests/meson.build @@ -0,0 +1,17 @@ +test_unit = 'test-ibft' + +test_ibft_dir = meson.current_source_dir() + +exe = executable( + test_unit, + test_unit + '.c', + dependencies: test_nm_dep, + c_args: nm_build_cflags, + link_with: libnms_ibft_core +) + +test( + 'ibft/' + test_unit, + test_script, + args: test_args + [exe.full_path()] +) diff --git a/src/settings/plugins/ibft/tests/test-ibft.c b/src/settings/plugins/ibft/tests/test-ibft.c index 72d1a7db..5e46be2e 100644 --- a/src/settings/plugins/ibft/tests/test-ibft.c +++ b/src/settings/plugins/ibft/tests/test-ibft.c @@ -36,6 +36,8 @@ #include "nm-test-utils-core.h" +#define TEST_DIR NM_BUILD_SRCDIR"/src/settings/plugins/ibft/tests" + static GPtrArray * read_block (const char *iscsiadm_path, const char *expected_mac) { @@ -78,7 +80,7 @@ test_read_ibft_dhcp (void) const char *expected_mac_address = "00:33:21:98:b9:f1"; GPtrArray *block; - block = read_block (TEST_IBFT_DIR "/iscsiadm-test-dhcp", expected_mac_address); + block = read_block (TEST_DIR "/iscsiadm-test-dhcp", expected_mac_address); connection = nms_ibft_reader_get_connection_from_block (block, &error); g_assert_no_error (error); @@ -125,7 +127,7 @@ test_read_ibft_static (void) NMIPAddress *ip4_addr; GPtrArray *block; - block = read_block (TEST_IBFT_DIR "/iscsiadm-test-static", expected_mac_address); + block = read_block (TEST_DIR "/iscsiadm-test-static", expected_mac_address); connection = nms_ibft_reader_get_connection_from_block (block, &error); g_assert_no_error (error); @@ -181,7 +183,7 @@ test_read_ibft_malformed (gconstpointer user_data) g_assert (g_file_test (iscsiadm_path, G_FILE_TEST_EXISTS)); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*malformed iscsiadm record*"); + NMTST_EXPECT_NM_WARN ("*malformed iscsiadm record*"); success = nms_ibft_reader_load_blocks (iscsiadm_path, &blocks, &error); g_assert_no_error (error); @@ -227,7 +229,7 @@ test_read_ibft_vlan (void) GError *error = NULL; GPtrArray *block; - block = read_block (TEST_IBFT_DIR "/iscsiadm-test-vlan", expected_mac_address); + block = read_block (TEST_DIR "/iscsiadm-test-vlan", expected_mac_address); connection = nms_ibft_reader_get_connection_from_block (block, &error); g_assert_no_error (error); @@ -280,12 +282,12 @@ int main (int argc, char **argv) g_test_add_func (TPATH "ibft/dhcp", test_read_ibft_dhcp); g_test_add_func (TPATH "ibft/static", test_read_ibft_static); g_test_add_func (TPATH "ibft/vlan", test_read_ibft_vlan); - g_test_add_data_func (TPATH "ibft/bad-record-read", TEST_IBFT_DIR "/iscsiadm-test-bad-record", test_read_ibft_malformed); - g_test_add_data_func (TPATH "ibft/bad-entry-read", TEST_IBFT_DIR "/iscsiadm-test-bad-entry", test_read_ibft_malformed); - g_test_add_data_func (TPATH "ibft/bad-ipaddr-read", TEST_IBFT_DIR "/iscsiadm-test-bad-ipaddr", test_read_ibft_bad_address); - g_test_add_data_func (TPATH "ibft/bad-gateway-read", TEST_IBFT_DIR "/iscsiadm-test-bad-gateway", test_read_ibft_bad_address); - g_test_add_data_func (TPATH "ibft/bad-dns1-read", TEST_IBFT_DIR "/iscsiadm-test-bad-dns1", test_read_ibft_bad_address); - g_test_add_data_func (TPATH "ibft/bad-dns2-read", TEST_IBFT_DIR "/iscsiadm-test-bad-dns2", test_read_ibft_bad_address); + g_test_add_data_func (TPATH "ibft/bad-record-read", TEST_DIR "/iscsiadm-test-bad-record", test_read_ibft_malformed); + g_test_add_data_func (TPATH "ibft/bad-entry-read", TEST_DIR "/iscsiadm-test-bad-entry", test_read_ibft_malformed); + g_test_add_data_func (TPATH "ibft/bad-ipaddr-read", TEST_DIR "/iscsiadm-test-bad-ipaddr", test_read_ibft_bad_address); + g_test_add_data_func (TPATH "ibft/bad-gateway-read", TEST_DIR "/iscsiadm-test-bad-gateway", test_read_ibft_bad_address); + g_test_add_data_func (TPATH "ibft/bad-dns1-read", TEST_DIR "/iscsiadm-test-bad-dns1", test_read_ibft_bad_address); + g_test_add_data_func (TPATH "ibft/bad-dns2-read", TEST_DIR "/iscsiadm-test-bad-dns2", test_read_ibft_bad_address); return g_test_run (); } diff --git a/src/settings/plugins/ifcfg-rh/meson.build b/src/settings/plugins/ifcfg-rh/meson.build new file mode 100644 index 00000000..964ce22d --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/meson.build @@ -0,0 +1,77 @@ +install_data( + 'nm-ifcfg-rh.conf', + install_dir: dbus_conf_dir +) + +cflags = [ + '-DSBINDIR="@0@"'.format(nm_sbindir), + '-DSYSCONFDIR="@0@"'.format(nm_sysconfdir) +] + +name = 'nmdbus-ifcfg-rh' + +dbus_sources = gnome.gdbus_codegen( + name, + 'nm-ifcfg-rh.xml', + interface_prefix: 'com.redhat', + namespace: 'NMDBus' +) + +libnmdbus_ifcfg_rh = static_library( + name, + sources: dbus_sources, + dependencies: glib_dep, + c_args: cflags +) + +sources = files( + 'nm-inotify-helper.c', + 'nms-ifcfg-rh-reader.c', + 'nms-ifcfg-rh-utils.c', + 'nms-ifcfg-rh-writer.c', + 'shvar.c' +) + +deps = [ + crypto_dep, + nm_dep +] + +libnms_ifcfg_rh_core = static_library( + 'nms-ifcfg-rh-core', + sources: sources, + dependencies: deps, + c_args: cflags +) + +sources = [dbus_sources] + files('nms-ifcfg-rh-connection.c') + +libnm_settings_plugin_ifcfg_rh = shared_module( + 'nm-settings-plugin-ifcfg-rh', + sources: sources, + dependencies: deps, + c_args: cflags, + link_with: [libnms_ifcfg_rh_core], + link_args: ldflags_linker_script_settings, + link_depends: linker_script_settings, + install: true, + install_dir: nm_plugindir +) + +core_plugins += libnm_settings_plugin_ifcfg_rh + +# FIXME: check_so_symbols replacement +''' +run_target( + 'check-local-symbols-settings-ifcfg-rh', + command: [check_so_symbols, libnm_settings_plugin_ifcfg_rh.full_path()], + depends: libnm_settings_plugin_ifcfg_rh +) + +check-local-symbols-settings-ifcfg-rh: src/settings/plugins/ifcfg-rh/libnm-settings-plugin-ifcfg-rh.la + $(call check_so_symbols,$(builddir)/src/settings/plugins/ifcfg-rh/.libs/libnm-settings-plugin-ifcfg-rh.so) +''' + +if enable_tests + subdir('tests') +endif diff --git a/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c index 97417db9..2863df64 100644 --- a/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c +++ b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c @@ -172,7 +172,7 @@ nm_inotify_helper_init (NMInotifyHelper *self) { NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); - priv->wd_refs = g_hash_table_new (g_direct_hash, g_direct_equal); + priv->wd_refs = g_hash_table_new (nm_direct_hash, NULL); } static void 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 d850ac4e..eaff2db4 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h @@ -38,9 +38,6 @@ #define IFCFG_DIR SYSCONFDIR "/sysconfig/network-scripts" -#define IFCFG_PLUGIN_NAME "ifcfg-rh" -#define IFCFG_PLUGIN_INFO "(c) 2007 - 2015 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." - #define TYPE_ETHERNET "Ethernet" #define TYPE_WIRELESS "Wireless" #define TYPE_INFINIBAND "InfiniBand" 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 0743fc9f..0fb77b9d 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c @@ -37,7 +37,6 @@ #include "settings/nm-settings-plugin.h" #include "nm-config.h" #include "NetworkManagerUtils.h" -#include "nm-exported-object.h" #include "nms-ifcfg-rh-connection.h" #include "nms-ifcfg-rh-common.h" @@ -46,10 +45,10 @@ #include "nms-ifcfg-rh-utils.h" #include "shvar.h" -#include "settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.h" - -#define IFCFGRH1_DBUS_SERVICE_NAME "com.redhat.ifcfgrh1" -#define IFCFGRH1_DBUS_OBJECT_PATH "/com/redhat/ifcfgrh1" +#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" /*****************************************************************************/ @@ -58,9 +57,9 @@ typedef struct { struct { GDBusConnection *connection; - GDBusInterfaceSkeleton *interface; GCancellable *cancellable; gulong signal_id; + guint regist_id; } dbus; GHashTable *connections; /* uuid::connection */ @@ -126,7 +125,6 @@ connection_ifcfg_changed (NMIfcfgConnection *connection, gpointer user_data) path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection)); g_return_if_fail (path != NULL); - if (!priv->ifcfg_monitor) { _LOGD ("connection_ifcfg_changed("NM_IFCFG_CONNECTION_LOG_FMTD"): %s", NM_IFCFG_CONNECTION_LOG_ARGD (connection), "ignore event"); return; @@ -327,21 +325,21 @@ update_connection (SettingsPluginIfcfg *self, if (new_unmanaged || new_unrecognized) { if (!old_unmanaged && !old_unrecognized) { + /* ref connection first, because we put it into priv->connections below. + * Emitting signal-removed might otherwise delete it. */ g_object_ref (connection_by_uuid); + /* Unexport the connection by telling the settings service it's * been removed. */ nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection_by_uuid)); - /* Remove the path so that claim_connection() doesn't complain later when - * interface gets managed and connection is re-added. */ - nm_connection_set_path (NM_CONNECTION (connection_by_uuid), NULL); /* signal_remove() will end up removing the connection from our hash, * so add it back now. */ g_hash_table_insert (priv->connections, g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection_by_uuid))), - connection_by_uuid); + connection_by_uuid /* we took reference above and pass it on */); } } else { if (old_unmanaged /* && !new_unmanaged */) { @@ -373,7 +371,9 @@ update_connection (SettingsPluginIfcfg *self, _LOGI ("add connection "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); else _LOGI ("new connection "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); - g_hash_table_insert (priv->connections, g_strdup (uuid), connection_new); + g_hash_table_insert (priv->connections, + g_strdup (uuid), + connection_new /* take reference */); g_signal_connect (connection_new, NM_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed_cb), @@ -418,7 +418,7 @@ ifcfg_dir_changed (GFileMonitor *monitor, path = g_file_get_path (file); ifcfg_path = utils_detect_ifcfg_path (path, FALSE); - _LOGD ("ifcfg_dir_changed(%s) = %d // %s", path, event_type, ifcfg_path ? ifcfg_path : "(none)"); + _LOGD ("ifcfg_dir_changed(%s) = %d // %s", path, event_type, ifcfg_path ?: "(none)"); if (ifcfg_path) { connection = find_by_path (plugin, ifcfg_path); switch (event_type) { @@ -516,7 +516,7 @@ read_connections (SettingsPluginIfcfg *plugin) return; } - alive_connections = g_hash_table_new (NULL, NULL); + alive_connections = g_hash_table_new (nm_direct_hash, NULL); filenames = g_ptr_array_new_with_free_func (g_free); while ((item = g_dir_read_name (dir))) { @@ -749,7 +749,7 @@ impl_ifcfgrh_get_ifcfg_details (SettingsPluginIfcfg *plugin, return; } - path = nm_connection_get_path (NM_CONNECTION (connection)); + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)); if (!path) { g_dbus_method_invocation_return_error (context, NM_SETTINGS_ERROR, @@ -768,15 +768,15 @@ static void _dbus_clear (SettingsPluginIfcfg *self) { SettingsPluginIfcfgPrivate *priv = SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self); + guint id; nm_clear_g_signal_handler (priv->dbus.connection, &priv->dbus.signal_id); nm_clear_g_cancellable (&priv->dbus.cancellable); - if (priv->dbus.interface) { - g_dbus_interface_skeleton_unexport (priv->dbus.interface); - nm_exported_object_skeleton_release (priv->dbus.interface); - priv->dbus.interface = NULL; + 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); @@ -788,12 +788,55 @@ _dbus_connection_closed (GDBusConnection *connection, GError *error, gpointer user_data) { - _LOGW ("dbus: %s bus closed", IFCFGRH1_DBUS_SERVICE_NAME); + _LOGW ("dbus: %s bus closed", IFCFGRH1_BUS_NAME); _dbus_clear (SETTINGS_PLUGIN_IFCFG (user_data)); /* 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) +{ + SettingsPluginIfcfg *self = SETTINGS_PLUGIN_IFCFG (user_data); + const char *ifcfg; + + if ( !nm_streq (interface_name, IFCFGRH1_IFACE1_NAME) + || !nm_streq (method_name, IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS)) { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "Unknown method %s", + method_name); + return; + } + + g_variant_get (parameters, "(&s)", &ifcfg); + impl_ifcfgrh_get_ifcfg_details (self, invocation, ifcfg); +} + +static GDBusInterfaceInfo *const interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO ( + IFCFGRH1_BUS_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, @@ -830,36 +873,27 @@ _dbus_request_name_done (GObject *source_object, } { - GType skeleton_type = NMDBUS_TYPE_IFCFGRH1_SKELETON; - gs_free char *method_name_get_ifcfg_details = NULL; - NMExportedObjectDBusMethodImpl methods[] = { - { - .method_name = (method_name_get_ifcfg_details = nm_exported_object_skeletonify_method_name ("GetIfcfgDetails")), - .impl = G_CALLBACK (impl_ifcfgrh_get_ifcfg_details), - }, + static const GDBusInterfaceVTable interface_vtable = { + .method_call = _method_call, }; - priv->dbus.interface = nm_exported_object_skeleton_create (skeleton_type, - g_type_class_peek (SETTINGS_TYPE_PLUGIN_IFCFG), - methods, - G_N_ELEMENTS (methods), - (GObject *) self); - - if (!g_dbus_interface_skeleton_export (priv->dbus.interface, - priv->dbus.connection, - IFCFGRH1_DBUS_OBJECT_PATH, - &error)) { - nm_exported_object_skeleton_release (priv->dbus.interface); - priv->dbus.interface = NULL; - _LOGW ("dbus: failed exporting interface: %s", error->message); + 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: aquired D-Bus service %s and exported %s object", - IFCFGRH1_DBUS_SERVICE_NAME, - IFCFGRH1_DBUS_OBJECT_PATH); + _LOGD ("dbus: acquired D-Bus service %s and exported %s object", + IFCFGRH1_BUS_NAME, + IFCFGRH1_OBJECT_PATH); } static void @@ -900,7 +934,7 @@ _dbus_create_done (GObject *source_object, DBUS_INTERFACE_DBUS, "RequestName", g_variant_new ("(su)", - IFCFGRH1_DBUS_SERVICE_NAME, + IFCFGRH1_BUS_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE), G_VARIANT_TYPE ("(u)"), G_DBUS_CALL_FLAGS_NONE, @@ -917,7 +951,7 @@ _dbus_setup (SettingsPluginIfcfg *self) gs_free char *address = NULL; gs_free_error GError *error = NULL; - g_return_if_fail (!priv->dbus.connection); + _dbus_clear (self); address = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (address == NULL) { @@ -943,39 +977,22 @@ config_changed_cb (NMConfig *config, NMConfigData *old_data, SettingsPluginIfcfg *self) { + SettingsPluginIfcfgPrivate *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 conneciton 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)) { - if (!SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self)->dbus.connection) - _dbus_setup (self); - } -} - -/*****************************************************************************/ + if (!NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_CAUSE_SIGHUP + | NM_CONFIG_CHANGE_CAUSE_SIGUSR1)) + return; -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - switch (prop_id) { - case NM_SETTINGS_PLUGIN_PROP_NAME: - g_value_set_string (value, IFCFG_PLUGIN_NAME); - break; - case NM_SETTINGS_PLUGIN_PROP_INFO: - g_value_set_string (value, IFCFG_PLUGIN_INFO); - break; - case NM_SETTINGS_PLUGIN_PROP_CAPABILITIES: - g_value_set_uint (value, NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + priv = SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self); + if ( !priv->dbus.connection + && !priv->dbus.cancellable) + _dbus_setup (self); } /*****************************************************************************/ @@ -1048,19 +1065,6 @@ settings_plugin_ifcfg_class_init (SettingsPluginIfcfgClass *req_class) object_class->constructed = constructed; object_class->dispose = dispose; - object_class->get_property = get_property; - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_NAME, - NM_SETTINGS_PLUGIN_NAME); - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_INFO, - NM_SETTINGS_PLUGIN_INFO); - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_CAPABILITIES, - NM_SETTINGS_PLUGIN_CAPABILITIES); } static void 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 c91cd253..722d4e36 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -181,7 +181,7 @@ make_connection_setting (const char *file, const char *v; gs_free char *stable_id = NULL; const char *const *iter; - int vint64; + int vint64, i_val; ifcfg_name = utils_get_ifcfg_name (file, TRUE); if (!ifcfg_name) @@ -256,7 +256,6 @@ make_connection_setting (const char *file, } } - nm_clear_g_free (&value); v = svGetValueStr (ifcfg, "ZONE", &value); g_object_set (s_con, NM_SETTING_CONNECTION_ZONE, v, NULL); @@ -338,6 +337,13 @@ make_connection_setting (const char *file, vint64 = svGetValueInt64 (ifcfg, "AUTH_RETRIES", 10, -1, G_MAXINT32, -1); g_object_set (s_con, NM_SETTING_CONNECTION_AUTH_RETRIES, (gint) vint64, 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); + return NM_SETTING (s_con); } @@ -380,7 +386,7 @@ is_any_ip4_address_defined (shvarFile *ifcfg, int *idx) { int i, ignore, *ret_idx; - ret_idx = idx ? idx : &ignore; + ret_idx = idx ?: &ignore; for (i = -1; i <= 2; i++) { gs_free char *value = NULL; @@ -496,7 +502,7 @@ parse_route_line_is_comment (const char *line) * * initscripts compares: "$line" =~ '^[[:space:]]*(\#.*)?$' */ - while (NM_IN_SET (line[0], ' ', '\t')) + while (nm_utils_is_separator (line[0])) line++; if (NM_IN_SET (line[0], '\0', '#')) return TRUE; @@ -927,7 +933,7 @@ next: : "")); break; case PARSE_LINE_TYPE_FLAG: - /* XXX: the flag (for "onlink") only allows to explictly set "TRUE". + /* NOTE: the flag (for "onlink") only allows to explictly set "TRUE". * There is no way to express an explicit "FALSE" setting * of this attribute, hence, the file format cannot encode * that configuration. */ @@ -1338,29 +1344,7 @@ make_ip4_setting (shvarFile *ifcfg, } else if (!g_ascii_strcasecmp (v, "autoip")) { method = NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL; } else if (!g_ascii_strcasecmp (v, "shared")) { - int idx; - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED, - NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, - NULL); - /* 1 IP address is allowed for shared connections. Read it. */ - if (is_any_ip4_address_defined (ifcfg, &idx)) { - guint32 gw; - NMIPAddress *addr = NULL; - - if (!read_full_ip4_address (ifcfg, idx, NULL, &addr, NULL, error)) - return NULL; - if (!read_ip4_address (ifcfg, "GATEWAY", NULL, &gw, error)) - return NULL; - (void) nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - if (never_default) - PARSE_WARNING ("GATEWAY will be ignored when DEFROUTE is disabled"); - gateway = g_strdup (nm_utils_inet4_ntop (gw, inet_buf)); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL); - } - return g_steal_pointer (&s_ip4); + method = NM_SETTING_IP4_CONFIG_METHOD_SHARED; } else { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown BOOTPROTO '%s'", v); @@ -1387,7 +1371,7 @@ make_ip4_setting (shvarFile *ifcfg, NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) route_table, NULL); - if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) return g_steal_pointer (&s_ip4); /* Handle DHCP settings */ @@ -1464,39 +1448,47 @@ make_ip4_setting (shvarFile *ifcfg, if (gateway && never_default) PARSE_WARNING ("GATEWAY will be ignored when DEFROUTE is disabled"); - /* 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_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_valid (AF_INET6, v)) { - /* Ignore IPv6 addresses */ - } else { - PARSE_WARNING ("invalid DNS server address %s", v); - return NULL; + /* 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_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_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; + /* 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); + 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); + } } } } @@ -1545,7 +1537,8 @@ make_ip4_setting (shvarFile *ifcfg, } /* Legacy value NM used for a while but is incorrect (rh #459370) */ - if (!nm_setting_ip_config_get_num_dns_searches (s_ip4)) { + 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) { @@ -1561,10 +1554,14 @@ make_ip4_setting (shvarFile *ifcfg, } } - timeout = svGetValueInt64 (ifcfg, "ARPING_WAIT", 10, -1, - NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX / 1000, -1); - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DAD_TIMEOUT, - (gint) (timeout <= 0 ? timeout : timeout * 1000), NULL); + timeout = svGetValueInt64 (ifcfg, "ACD_TIMEOUT", 10, -1, NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, -2); + if (timeout == -2) { + timeout = svGetValueInt64 (ifcfg, "ARPING_WAIT", 10, -1, + NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX / 1000, -1); + if (timeout > 0) + timeout *= 1000; + } + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DAD_TIMEOUT, (gint) timeout, NULL); return g_steal_pointer (&s_ip4); } @@ -1642,7 +1639,7 @@ read_aliases (NMSettingIPConfig *s_ip4, gboolean read_defroute, const char *file read_defroute ? &gateway : NULL, &err); if (ok) { - nm_ip_address_set_attribute (addr, "label", g_variant_new_string (device)); + 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)) @@ -1850,8 +1847,8 @@ make_ip6_setting (shvarFile *ifcfg, ipv6addr_secondaries = svGetValueStr_cp (ifcfg, "IPV6ADDR_SECONDARIES"); value = g_strjoin (ipv6addr && ipv6addr_secondaries ? " " : NULL, - ipv6addr ? ipv6addr : "", - ipv6addr_secondaries ? ipv6addr_secondaries : "", + ipv6addr ?: "", + ipv6addr_secondaries ?: "", NULL); g_free (ipv6addr); g_free (ipv6addr_secondaries); @@ -2001,11 +1998,15 @@ make_tc_setting (shvarFile *ifcfg) break; qdisc = nm_utils_tc_qdisc_from_str (value, &local); - if (!qdisc) - PARSE_WARNING ("ignoring bad qdisc: '%s': %s", value, local->message); + 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 qdisc"); + PARSE_WARNING ("duplicate tc qdisc"); + + nm_tc_qdisc_unref (qdisc); } for (i = 1;; i++) { @@ -2019,11 +2020,15 @@ make_tc_setting (shvarFile *ifcfg) break; tfilter = nm_utils_tc_tfilter_from_str (value, &local); - if (!tfilter) - PARSE_WARNING ("ignoring bad tfilter: '%s': %s", value, local->message); + 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 filter"); + PARSE_WARNING ("duplicate tc filter"); + + nm_tc_tfilter_unref (tfilter); } if ( nm_setting_tc_config_get_num_qdiscs (s_tc) > 0 @@ -3552,6 +3557,13 @@ make_wpa_setting (shvarFile *ifcfg, 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")) @@ -4407,7 +4419,6 @@ parse_infiniband_p_key (shvarFile *ifcfg, return ret; } - static NMSetting * make_infiniband_setting (shvarFile *ifcfg, const char *file, @@ -4513,9 +4524,9 @@ handle_bond_option (NMSettingBond *s_bond, } } - if (!nm_setting_bond_add_option (s_bond, key, sanitized ? sanitized : value)) + if (!nm_setting_bond_add_option (s_bond, key, sanitized ?: value)) PARSE_WARNING ("invalid bonding option '%s' = %s", - key, sanitized ? sanitized : value); + key, sanitized ?: value); g_free (sanitized); } @@ -5321,6 +5332,8 @@ connection_from_file_full (const char *filename, 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"; @@ -5341,6 +5354,7 @@ connection_from_file_full (const char *filename, if (!svGetValueBoolean (parsed, "NM_CONTROLLED", TRUE)) { connection = create_unhandled_connection (filename, parsed, "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"); } @@ -5350,8 +5364,7 @@ connection_from_file_full (const char *filename, /* iBFT is handled by the iBFT settings plugin */ bootproto = svGetValueStr_cp (parsed, "BOOTPROTO"); if (bootproto && !g_ascii_strcasecmp (bootproto, "ibft")) { - if (out_ignore_error) - *out_ignore_error = TRUE; + 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); @@ -5397,8 +5410,7 @@ connection_from_file_full (const char *filename, char *device; if ((tmp = svGetValueStr_cp (parsed, "IPV6TUNNELIPV4"))) { - if (out_ignore_error) - *out_ignore_error = TRUE; + 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; @@ -5412,8 +5424,7 @@ connection_from_file_full (const char *filename, } if (!strcmp (device, "lo")) { - if (out_ignore_error) - *out_ignore_error = TRUE; + 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); @@ -5460,8 +5471,7 @@ connection_from_file_full (const char *filename, 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. */ - if (out_ignore_error) - *out_ignore_error = TRUE; + 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); 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 e9dd08b7..bdad7389 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -148,16 +148,7 @@ write_secrets (shvarFile *ifcfg, /* we purge all existing secrets. */ svUnsetAll (keyfile, SV_KEY_TYPE_ANY); - /* sort the keys. */ - secrets_keys = (const char **) g_hash_table_get_keys_as_array (secrets, &secrets_keys_n); - if (secrets_keys_n > 1) { - g_qsort_with_data (secrets_keys, - secrets_keys_n, - sizeof (const char *), - nm_strcmp_p_with_data, - NULL); - } - + 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); @@ -786,7 +777,6 @@ write_wireless_security_setting (NMConnection *connection, "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) svUnsetValue (ifcfg, "PMF"); else { @@ -794,6 +784,13 @@ write_wireless_security_setting (NMConnection *connection, nm_setting_wireless_security_get_pmf (s_wsec)); } + if (nm_setting_wireless_security_get_fils (s_wsec) == NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT) + svUnsetValue (ifcfg, "FILS"); + else { + svSetValueEnum (ifcfg, "FILS", nm_setting_wireless_security_fils_get_type (), + nm_setting_wireless_security_get_fils (s_wsec)); + } + return TRUE; } @@ -899,14 +896,16 @@ write_wireless_setting (NMConnection *connection, } mode = nm_setting_wireless_get_mode (s_wireless); - if (!mode || !strcmp (mode, "infrastructure")) { + if (!mode) + svUnsetValue(ifcfg, "MODE"); + else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_INFRA)) svSetValueStr (ifcfg, "MODE", "Managed"); - } else if (!strcmp (mode, "adhoc")) { + else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { svSetValueStr (ifcfg, "MODE", "Ad-Hoc"); adhoc = TRUE; - } else if (!strcmp (mode, "ap")) { + } else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_AP)) svSetValueStr (ifcfg, "MODE", "Ap"); - } else { + else { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Invalid mode '%s' in '%s' setting", mode, NM_SETTING_WIRELESS_SETTING_NAME); @@ -1728,6 +1727,7 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) GString *str; const char *master, *master_iface = NULL, *type; gint vint; + NMSettingConnectionMdns mdns; guint32 vuint32; const char *tmp; @@ -1749,9 +1749,7 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) /* Only save the value for master connections */ type = nm_setting_connection_get_connection_type (s_con); - if ( !g_strcmp0 (type, NM_SETTING_BOND_SETTING_NAME) - || !g_strcmp0 (type, NM_SETTING_TEAM_SETTING_NAME) - || !g_strcmp0 (type, NM_SETTING_BRIDGE_SETTING_NAME)) { + if (_nm_connection_type_is_master (type)) { NMSettingConnectionAutoconnectSlaves autoconnect_slaves; autoconnect_slaves = nm_setting_connection_get_autoconnect_slaves (s_con); svSetValueStr (ifcfg, "AUTOCONNECT_SLAVES", @@ -1888,6 +1886,13 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) vint = nm_setting_connection_get_auth_retries (s_con); svSetValueInt64_cond (ifcfg, "AUTH_RETRIES", vint >= 0, vint); + + 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); + } else + svUnsetValue (ifcfg, "MDNS"); } static char * @@ -2158,7 +2163,6 @@ write_tc_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) n++; } - num = nm_setting_tc_config_get_num_tfilters (s_tc); for (n = 1, i = 0; i < num; i++) { NMTCTfilter *tfilter; @@ -2281,7 +2285,7 @@ write_ip4_setting (NMConnection *connection, if (i > 0) { GVariant *label; - label = nm_ip_address_get_attribute (addr, "label"); + label = nm_ip_address_get_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL); if (label) continue; } @@ -2411,12 +2415,15 @@ write_ip4_setting (NMConnection *connection, NM_SET_OUT (out_route_content, write_route_file (s_ip4)); timeout = nm_setting_ip_config_get_dad_timeout (s_ip4); - if (timeout < 0) + if (timeout < 0) { + svUnsetValue (ifcfg, "ACD_TIMEOUT"); svUnsetValue (ifcfg, "ARPING_WAIT"); - else if (timeout == 0) + } else if (timeout == 0) { + svSetValueStr (ifcfg, "ACD_TIMEOUT", "0"); svSetValueStr (ifcfg, "ARPING_WAIT", "0"); - else { - /* Round the value up to next integer */ + } else { + svSetValueInt64 (ifcfg, "ACD_TIMEOUT", timeout); + /* Round the value up to next integer for initscripts */ svSetValueInt64 (ifcfg, "ARPING_WAIT", (timeout - 1) / 1000 + 1); } @@ -2484,7 +2491,7 @@ write_ip4_aliases (NMConnection *connection, const char *base_ifcfg_path) addr = nm_setting_ip_config_get_address (s_ip4, i); - label_var = nm_ip_address_get_attribute (addr, "label"); + 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); @@ -2987,7 +2994,7 @@ do_write_to_disk (NMConnection *connection, { /* 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-momory). */ + * new settings (in-memory). */ if (!svWriteFile (ifcfg, 0644, error)) return FALSE; @@ -3138,10 +3145,10 @@ nms_ifcfg_rh_writer_write_connection (NMConnection *connection, * does not yet allow to inject the configuration. */ if (out_reread || out_reread_same) { if (!do_write_reread (connection, - svFileGetName (ifcfg), - out_reread, - out_reread_same, - &local)) { + svFileGetName (ifcfg), + out_reread, + out_reread_same, + &local)) { _LOGW ("write: failure to re-read connection \"%s\": %s", svFileGetName (ifcfg), local->message); g_clear_error (&local); @@ -3188,4 +3195,3 @@ nms_ifcfg_rh_writer_can_write_connection (NMConnection *connection, GError **err NM_PRINT_FMT_QUOTE_STRING (type)); return FALSE; } - diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index 2b64f3fc..9120b870 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -39,7 +39,7 @@ #include "nm-core-internal.h" #include "nm-core-utils.h" #include "nm-utils/nm-enum-utils.h" -#include "nm-utils/c-list.h" +#include "c-list/src/c-list.h" /*****************************************************************************/ @@ -1278,7 +1278,7 @@ svSetValueEnum (shvarFile *s, const char *key, GType gtype, int value) { gs_free char *v = NULL; - v = _nm_utils_enum_to_str_full (gtype, value, " "); + v = _nm_utils_enum_to_str_full (gtype, value, " ", NULL); return svSetValueStr (s, key, v); } diff --git a/src/settings/plugins/ifcfg-rh/tests/meson.build b/src/settings/plugins/ifcfg-rh/tests/meson.build new file mode 100644 index 00000000..3d72d892 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/meson.build @@ -0,0 +1,17 @@ +test_unit = 'test-ifcfg-rh' + +test_ifcfg_dir = meson.current_source_dir() + +exe = executable( + test_unit, + test_unit + '.c', + dependencies: test_nm_dep, + c_args: nm_build_cflags, + link_with: libnms_ifcfg_rh_core +) + +test( + 'ifcfg-rh/' + test_unit, + test_script, + args: test_args + [exe.full_path()] +) diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected index 026993b8..cf325f35 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected @@ -1,5 +1,4 @@ ESSID="Test SSID" -MODE=Managed SSID_HIDDEN=yes MAC_ADDRESS_RANDOMIZATION=default TYPE=Wireless diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected index c0e47c48..cd8fc96f 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected @@ -14,6 +14,8 @@ DNS2=4.2.2.2 DOMAIN="foobar.com lab.foobar.com" DEFROUTE=yes IPV4_FAILURE_FATAL=no +ACD_TIMEOUT=400 +ARPING_WAIT=1 IPV6INIT=no NAME="Test Write Wired Static Routes" UUID=${UUID} diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc new file mode 100644 index 00000000..d0a3c254 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc @@ -0,0 +1,16 @@ +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:55 +BOOTPROTO=none +ONBOOT=yes +DNS1=4.2.2.1 +DNS2=4.2.2.2 +IPADDR=192.168.1.5 +PREFIX=24 +NETMASK=255.255.255.0 +GATEWAY=192.168.1.1 +IPV6INIT=no +QDISC1="root fq_codel" +FILTER1="parent 1234: matchall action simple sdata Hello" +NAME=ethernet-tc +UUID=a42c8d4e-11a2-4144-92d2-5cbce8c6b2c4 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc-write.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc-write.cexpected new file mode 100644 index 00000000..a67ca598 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc-write.cexpected @@ -0,0 +1,16 @@ +TYPE=Ethernet +PROXY_METHOD=none +BROWSER_ONLY=no +QDISC1="parent 2468:2 pfifo_fast" +FILTER1="parent 1234: matchall action simple sdata Hello" +BOOTPROTO=none +IPADDR=1.1.1.3 +PREFIX=24 +GATEWAY=1.1.1.1 +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=no +NAME="Test Write TC config" +UUID=${UUID} +DEVICE=eth0 +ONBOOT=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 index 1bc3d524..db09afdb 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 @@ -10,3 +10,5 @@ PREFIX1=16 IPADDR2=3.3.3.3 PREFIX2=8 GATEWAY=1.1.1.1 +ACD_TIMEOUT=2000 +ARPING_WAIT=1 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 index d7273e36..6972e279 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 @@ -9,3 +9,5 @@ IPADDR2=9.8.7.6 PREFIX2=16 IPADDR3=3.3.3.3 PREFIX3=8 +ACD_TIMEOUT=2000 +ARPING_WAIT=1 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-3 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-3 index f2457bd2..d9065994 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-3 +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-3 @@ -9,3 +9,5 @@ IPADDR3=9.8.7.6 PREFIX3=16 IPADDR4=3.3.3.3 PREFIX4=8 +ACD_TIMEOUT=2000 +ARPING_WAIT=1 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-4 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-4 index e6b77141..935267f7 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-4 +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-4 @@ -9,3 +9,5 @@ IPADDR1=9.8.7.6 PREFIX1=16 IPADDR2=3.3.3.3 PREFIX2=8 +ACD_TIMEOUT=2000 +ARPING_WAIT=1 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 6bf27556..1331391d 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -58,7 +59,11 @@ #include "nm-test-utils-core.h" -#define TEST_SCRATCH_DIR_TMP TEST_SCRATCH_DIR"/network-scripts/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" /*****************************************************************************/ @@ -410,7 +415,7 @@ test_read_netmask_1 (void) NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; NMIPAddress *ip4_addr; - const char *FILENAME = TEST_IFCFG_DIR "/network-scripts/ifcfg-netmask-1"; + const char *FILENAME = TEST_IFCFG_DIR"/ifcfg-netmask-1"; connection = _connection_from_file (FILENAME, NULL, TYPE_ETHERNET, NULL); @@ -430,14 +435,14 @@ test_read_netmask_1 (void) content = nmtst_file_get_contents (FILENAME); - testfile = g_strdup (TEST_SCRATCH_DIR "/network-scripts/ifcfg-netmask-1.copy"); + testfile = g_strdup (TEST_SCRATCH_DIR"/ifcfg-netmask-1.copy"); nmtst_file_set_contents (testfile, content); _writer_update_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, testfile, - TEST_IFCFG_DIR "/network-scripts/ifcfg-netmask-1.cexpected"); + TEST_IFCFG_DIR"/ifcfg-netmask-1.cexpected"); } /*****************************************************************************/ @@ -541,7 +546,6 @@ verify_cert_or_key (NMSetting8021x *s_compare, return TRUE; } - static void test_read_basic (void) { @@ -553,7 +557,7 @@ test_read_basic (void) const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-minimal", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-minimal", NULL, TYPE_ETHERNET, NULL); /* ===== CONNECTION SETTING ===== */ @@ -605,9 +609,8 @@ test_read_miscellaneous_variables (void) int mac_blacklist_num, i; guint64 expected_timestamp = 0; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*invalid MAC in HWADDR_BLACKLIST 'XX:aa:invalid'*"); - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-misc-variables", + 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 (); @@ -648,7 +651,7 @@ test_read_variables_corner_cases (void) const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-variables-corner-cases-1", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-variables-corner-cases-1", NULL, TYPE_ETHERNET, NULL); /* ===== CONNECTION SETTING ===== */ @@ -686,7 +689,7 @@ test_read_unmanaged (void) char *unhandled_spec = NULL; guint64 expected_timestamp = 0; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-nm-controlled", + 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"); @@ -710,7 +713,7 @@ test_read_unmanaged_unrecognized (void) gs_free char *unhandled_spec = NULL; guint64 expected_timestamp = 0; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-nm-controlled-unrecognized", + 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"); @@ -732,7 +735,7 @@ test_read_unrecognized (void) gs_free char *unhandled_spec = NULL; guint64 expected_timestamp = 0; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-unrecognized", + 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"); @@ -856,11 +859,10 @@ test_read_wired_static_no_prefix (gconstpointer user_data) NMIPAddress *ip4_addr; char *file, *expected_id; - file = g_strdup_printf (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wired-static-no-prefix-%u", expected_prefix); + 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); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*missing PREFIX, assuming*"); + NMTST_EXPECT_NM_WARN ("*missing PREFIX, assuming*"); connection = _connection_from_file (file, NULL, TYPE_ETHERNET, NULL); g_test_assert_expected_messages (); @@ -898,7 +900,7 @@ test_read_wired_dhcp (void) char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee }; const char *mac; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wired-dhcp", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-dhcp", NULL, TYPE_ETHERNET, &unmanaged); g_assert (unmanaged == NULL); @@ -941,7 +943,7 @@ test_read_wired_dhcp_plus_ip (void) NMIPAddress *ip4_addr; NMIPAddress *ip6_addr; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-plus-ip", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-dhcp-plus-ip", NULL, TYPE_ETHERNET, NULL); /* ===== IPv4 SETTING ===== */ @@ -1008,7 +1010,7 @@ test_read_wired_shared_plus_ip (void) NMSettingIPConfig *s_ip4; NMIPAddress *ip4_addr; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-shared-plus-ip", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-shared-plus-ip", NULL, TYPE_ETHERNET, NULL); /* ===== IPv4 SETTING ===== */ @@ -1040,8 +1042,8 @@ test_read_wired_global_gateway (void) NMIPAddress *ip4_addr; char *unmanaged = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-global-gateway", - TEST_IFCFG_DIR"/network-scripts/network-test-wired-global-gateway", + 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); @@ -1081,10 +1083,9 @@ test_read_wired_global_gateway_ignore (void) NMSettingIPConfig *s_ip4; char *unmanaged = NULL; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ignoring GATEWAY (/etc/sysconfig/network) for * because the connection has no static addresses"); - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-global-gateway-ignore", - TEST_IFCFG_DIR"/network-scripts/network-test-wired-global-gateway-ignore", + 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); @@ -1119,7 +1120,7 @@ test_read_wired_obsolete_gateway_n (void) NMSettingIPConfig *s_ip4; NMIPAddress *ip4_addr; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-obsolete-gateway-n", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-obsolete-gateway-n", NULL, TYPE_ETHERNET, NULL); /* ===== IPv4 SETTING ===== */ @@ -1187,8 +1188,8 @@ test_user_1 (void) nm_connection_add_setting (connection, NM_SETTING (s_user)); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_User_1.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_User_1.cexpected", &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -1203,8 +1204,8 @@ test_read_wired_never_default (void) NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-never-default", - TEST_IFCFG_DIR"/network-scripts/network-test-wired-never-default", + 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 ===== */ @@ -1235,7 +1236,7 @@ test_read_wired_defroute_no (void) NMSettingIPConfig *s_ip6; char *unmanaged = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-defroute-no", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-defroute-no", NULL, TYPE_ETHERNET, &unmanaged); g_assert (unmanaged == NULL); @@ -1267,8 +1268,8 @@ test_read_wired_defroute_no_gatewaydev_yes (void) NMSettingIPConfig *s_ip6; char *unmanaged = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-defroute-no-gatewaydev-yes", - TEST_IFCFG_DIR"/network-scripts/network-test-wired-defroute-no-gatewaydev-yes", + 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); @@ -1300,7 +1301,7 @@ test_read_wired_static_routes (void) NMSettingIPConfig *s_ip4; NMIPRoute *ip4_route; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-routes", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-static-routes", NULL, TYPE_ETHERNET, NULL); /* ===== CONNECTION SETTING ===== */ @@ -1373,7 +1374,7 @@ test_read_wired_static_routes_legacy (void) char *unmanaged = NULL; NMIPRoute *ip4_route; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-routes-legacy", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-static-routes-legacy", NULL, TYPE_ETHERNET, &unmanaged); g_assert (!unmanaged); @@ -1476,6 +1477,7 @@ test_read_wired_ipv4_manual (gconstpointer data) 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); @@ -1513,9 +1515,8 @@ test_read_wired_ipv6_manual (void) NMIPAddress *ip6_addr; NMIPRoute *ip6_route; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ignoring manual default route*"); - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ipv6-manual", + NMTST_EXPECT_NM_WARN ("*ignoring manual default route*"); + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-ipv6-manual", NULL, TYPE_ETHERNET, &unmanaged); g_test_assert_expected_messages (); g_assert (!unmanaged); @@ -1691,7 +1692,7 @@ test_read_wired_dhcp6_only (void) char *unmanaged = NULL; const char *method; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp6-only", NULL, TYPE_ETHERNET, &unmanaged); + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-dhcp6-only", NULL, TYPE_ETHERNET, &unmanaged); g_assert (!unmanaged); /* ===== CONNECTION SETTING ===== */ @@ -1729,7 +1730,7 @@ test_read_wired_autoip (void) NMSettingIPConfig *s_ip4; char *unmanaged = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wired-autoip", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-autoip", NULL, TYPE_ETHERNET, &unmanaged); g_assert (unmanaged == NULL); @@ -1748,7 +1749,7 @@ test_read_onboot_no (void) NMSettingConnection *s_con; char *unmanaged = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-onboot-no", NULL, TYPE_ETHERNET, &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); @@ -1766,7 +1767,7 @@ test_read_noip (void) NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/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); @@ -1781,7 +1782,7 @@ test_read_noip (void) g_object_unref (connection); } -#define TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT TEST_IFCFG_DIR "/network-scripts/test_ca_cert.pem" +#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) @@ -1797,7 +1798,7 @@ test_read_wired_8021x_peap_mschapv2 (void) const char *expected_ca_cert_path; const char *read_ca_cert_path; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wired-8021x-peap-mschapv2", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-8021x-peap-mschapv2", NULL, TYPE_ETHERNET, &unmanaged); g_assert (!unmanaged); @@ -1897,9 +1898,8 @@ test_read_write_802_1X_subj_matches (void) gs_unref_object NMConnection *reread = NULL; NMSetting8021x *s_8021x; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*missing IEEE_8021X_CA_CERT*peap*"); - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-802-1X-subj-matches", + NMTST_EXPECT_NM_WARN ("*missing IEEE_8021X_CA_CERT*peap*"); + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-802-1X-subj-matches", NULL, TYPE_ETHERNET, NULL); g_test_assert_expected_messages (); @@ -1919,16 +1919,14 @@ test_read_write_802_1X_subj_matches (void) 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_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*missing IEEE_8021X_CA_CERT for EAP method 'peap'; this is insecure!"); + NMTST_EXPECT_NM_WARN ("*missing IEEE_8021X_CA_CERT for EAP method 'peap'; this is insecure!"); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-System_test-wired-802-1X-subj-matches.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-System_test-wired-802-1X-subj-matches.cexpected", &testfile); g_test_assert_expected_messages (); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*missing IEEE_8021X_CA_CERT for EAP method 'peap'; this is insecure!"); + NMTST_EXPECT_NM_WARN ("*missing IEEE_8021X_CA_CERT for EAP method 'peap'; this is insecure!"); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); g_test_assert_expected_messages (); @@ -1961,7 +1959,7 @@ test_read_802_1x_ttls_eapgtc (void) * NMSetting8021x::autheap property. */ - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-802-1x-ttls-eapgtc", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-802-1x-ttls-eapgtc", NULL, TYPE_WIRELESS, NULL); /* ===== 802.1x SETTING ===== */ @@ -1993,7 +1991,7 @@ test_read_write_802_1x_password_raw (void) /* Test that the 802-1x.password-raw is correctly read and written. */ - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-802-1x-password-raw", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-802-1x-password-raw", NULL, TYPE_ETHERNET, NULL); /* ===== 802.1x SETTING ===== */ @@ -2010,7 +2008,7 @@ test_read_write_802_1x_password_raw (void) NM_SETTING_SECRET_FLAG_NONE); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); keyfile = utils_get_keys_path (testfile); @@ -2040,7 +2038,7 @@ test_read_wired_aliases_good (gconstpointer test_data) 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 "/network-scripts/ifcfg-aliasem%d", N); + nm_sprintf_buf (path, TEST_IFCFG_DIR"/ifcfg-aliasem%d", N); connection = _connection_from_file (path, NULL, TYPE_ETHERNET, NULL); @@ -2079,7 +2077,7 @@ test_read_wired_aliases_good (gconstpointer test_data) 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, "label"); + 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 @@ -2131,7 +2129,7 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id) 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, "label") == NULL); + 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"); @@ -2142,17 +2140,15 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id) static void test_read_wired_aliases_bad_1 (void) { - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*aliasem1:1*has no DEVICE*"); - test_read_wired_aliases_bad (TEST_IFCFG_DIR "/network-scripts/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) { - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*aliasem2:1*has invalid DEVICE*"); - test_read_wired_aliases_bad (TEST_IFCFG_DIR "/network-scripts/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 @@ -2166,7 +2162,7 @@ test_read_dns_options (void) const char *options6[] = { "inet6" }; guint32 i, num; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dns-options", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-dns-options", NULL, TYPE_ETHERNET, &unmanaged); g_assert_cmpstr (unmanaged, ==, NULL); @@ -2206,7 +2202,7 @@ test_clear_master (void) shvarFile *f; /* 1. load the bridge slave connection from disk */ - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-bridge-component", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bridge-component", NULL, TYPE_ETHERNET, &unmanaged); g_assert_cmpstr (unmanaged, ==, NULL); @@ -2218,8 +2214,8 @@ test_clear_master (void) /* 2. write the connection to a new file */ _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-System_test-bridge-component-a.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-System_test-bridge-component-a.cexpected", &testfile); /* 3. clear master and slave-type */ @@ -2235,9 +2231,9 @@ test_clear_master (void) /* 4. update the connection on disk */ _writer_update_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, testfile, - TEST_IFCFG_DIR "/network-scripts/ifcfg-System_test-bridge-component-b.cexpected"); + 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)); @@ -2322,7 +2318,7 @@ test_write_dns_options (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -2343,7 +2339,7 @@ test_read_wifi_open (void) char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; const char *expected_ssid = "blahblah"; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-open", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-open", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -2406,7 +2402,7 @@ test_read_wifi_open_auto (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-open-auto", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-open-auto", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -2431,7 +2427,7 @@ test_read_wifi_open_ssid_hex (void) GBytes *ssid; const char *expected_ssid = "blahblah"; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-open-ssid-hex", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-open-ssid-hex", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -2461,7 +2457,7 @@ test_read_wifi_open_ssid_hex_bad (void) GBytes *ssid; const char *expected_ssid = "0x626cxx"; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex", + 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); @@ -2491,7 +2487,7 @@ test_read_wifi_open_ssid_quoted (void) GBytes *ssid; const char *expected_ssid = "foo\"bar\\"; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-open-ssid-quoted", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-open-ssid-quoted", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -2526,7 +2522,7 @@ test_read_wifi_wep (void) const char *expected_ssid = "blahblah"; NMWepKeyType key_type; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wep", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -2600,7 +2596,7 @@ test_read_wifi_wep_adhoc (void) GBytes *ssid; const char *expected_ssid = "blahblah"; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wep-adhoc", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-adhoc", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -2667,7 +2663,7 @@ test_read_wifi_wep_passphrase (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wep-passphrase", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-passphrase", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -2704,7 +2700,7 @@ test_read_wifi_wep_40_ascii (void) NMSettingWirelessSecurity *s_wsec; NMWepKeyType key_type; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wep-40-ascii", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-40-ascii", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -2744,7 +2740,7 @@ test_read_wifi_wep_104_ascii (void) NMSettingWirelessSecurity *s_wsec; NMWepKeyType key_type; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wep-104-ascii", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-104-ascii", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -2783,7 +2779,7 @@ test_read_wifi_leap (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-leap", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-leap", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -2845,7 +2841,7 @@ test_ifcfg_no_trailing_newline (void) { shvarFile *sv; - sv = _svOpenFile (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wpa-psk"); + sv = _svOpenFile (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk"); _svGetValue_check (sv, "LAST_ENTRY", "no-newline"); svCloseFile (sv); } @@ -2872,7 +2868,7 @@ test_read_wifi_wpa_psk (void) gboolean found_proto_wpa = FALSE; gboolean found_proto_rsn = FALSE; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wpa-psk", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -2981,7 +2977,7 @@ test_read_wifi_wpa_psk_2 (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wpa-psk-2", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk-2", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -3012,7 +3008,7 @@ test_read_wifi_wpa_psk_unquoted (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk-unquoted", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -3040,7 +3036,7 @@ test_read_wifi_wpa_psk_unquoted2 (void) { gs_unref_object NMConnection *connection = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted2", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk-unquoted2", NULL, TYPE_WIRELESS, NULL); } @@ -3053,7 +3049,7 @@ test_read_wifi_wpa_psk_adhoc (void) NMSettingWirelessSecurity *s_wsec; NMSettingIPConfig *s_ip4; - connection = _connection_from_file(TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc", + connection = _connection_from_file(TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk-adhoc", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -3105,7 +3101,7 @@ test_read_wifi_wpa_psk_hex (void) GBytes *ssid; const char *expected_ssid = "blahblah"; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wpa-psk-hex", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-psk-hex", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -3140,9 +3136,9 @@ test_read_wifi_wpa_psk_hex (void) g_object_unref (connection); } -#define TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT TEST_IFCFG_DIR "/network-scripts/test_ca_cert.pem" -#define TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT TEST_IFCFG_DIR "/network-scripts/test1_key_and_cert.pem" -#define TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY TEST_IFCFG_DIR "/network-scripts/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) @@ -3154,7 +3150,7 @@ test_read_wifi_wpa_eap_tls (void) char *unmanaged = NULL; const char *expected_privkey_password = "test1"; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wpa-eap-tls", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-eap-tls", NULL, TYPE_ETHERNET, &unmanaged); g_assert (!unmanaged); @@ -3212,7 +3208,7 @@ test_read_wifi_wpa_eap_ttls_tls (void) char *unmanaged = NULL; const char *expected_privkey_password = "test1"; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wpa-eap-ttls-tls", NULL, TYPE_WIRELESS, &unmanaged); g_assert (!unmanaged); @@ -3236,7 +3232,7 @@ test_read_wifi_wpa_eap_ttls_tls (void) /* CA Cert */ verify_cert_or_key (s_8021x, - TEST_IFCFG_DIR "/network-scripts/test_ca_cert.pem", + TEST_IFCFG_DIR"/test_ca_cert.pem", NULL, NM_SETTING_802_1X_CA_CERT); @@ -3275,7 +3271,7 @@ test_read_wifi_dynamic_wep_leap (void) NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-dynamic-wep-leap", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-dynamic-wep-leap", NULL, TYPE_WIRELESS, NULL); /* ===== WIRELESS SETTING ===== */ @@ -3324,7 +3320,7 @@ test_read_wifi_wep_eap_ttls_chap (void) NMSetting8021x *s_8021x; char *unmanaged = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wep-eap-ttls-chap", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-eap-ttls-chap", NULL, TYPE_WIRELESS, &unmanaged); g_assert (!unmanaged); @@ -3354,7 +3350,7 @@ test_read_wifi_wep_eap_ttls_chap (void) /* CA Cert */ verify_cert_or_key (s_8021x, - TEST_IFCFG_DIR "/network-scripts/test_ca_cert.pem", + TEST_IFCFG_DIR"/test_ca_cert.pem", NULL, NM_SETTING_802_1X_CA_CERT); @@ -3372,7 +3368,7 @@ test_read_wired_wake_on_lan (void) NMSettingConnection *s_con; NMSettingWired *s_wired; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-wake-on-lan", + 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); @@ -3401,7 +3397,7 @@ test_read_wired_auto_negotiate_off (void) NMSettingConnection *s_con; NMSettingWired *s_wired; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-wake-on-lan", + 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); @@ -3423,7 +3419,7 @@ test_read_wired_auto_negotiate_on (void) NMSettingConnection *s_con; NMSettingWired *s_wired; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-auto-negotiate-on", + 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); @@ -3445,7 +3441,7 @@ test_read_wired_unknown_ethtool_opt (void) NMSettingConnection *s_con; NMSettingWired *s_wired; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-unknown-ethtool-opt", + 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); @@ -3476,7 +3472,7 @@ test_read_wifi_hidden (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-hidden", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-hidden", NULL, TYPE_WIRELESS, NULL); s_con = nm_connection_get_setting_connection (connection); @@ -3522,7 +3518,6 @@ test_write_wifi_hidden (void) g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); @@ -3531,8 +3526,8 @@ test_write_wifi_hidden (void) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_WiFi_Hidden.cexpected", &testfile); f = _svOpenFile (testfile); @@ -3557,7 +3552,7 @@ test_read_wifi_mac_random (gconstpointer user_data) nmtst_test_data_unpack (user_data, &name, &value_p); value = GPOINTER_TO_INT (value_p); - path = g_strdup_printf (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-mac-random-%s", name); + 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); @@ -3616,8 +3611,8 @@ test_write_wifi_mac_random (gconstpointer user_data) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - nm_sprintf_buf (cexpected, TEST_IFCFG_DIR"/network-scripts/ifcfg-Test_Write_WiFi_MAC_%s.cexpected", name), + TEST_SCRATCH_DIR, + nm_sprintf_buf (cexpected, TEST_IFCFG_DIR"/ifcfg-Test_Write_WiFi_MAC_%s.cexpected", name), &testfile); f = _svOpenFile (testfile); @@ -3669,8 +3664,8 @@ test_write_wired_wake_on_lan (void) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected", &testfile); f = _svOpenFile (testfile); @@ -3705,8 +3700,8 @@ test_write_wired_auto_negotiate_off (void) NULL); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected", &testfile); f = _svOpenFile (testfile); @@ -3740,7 +3735,7 @@ test_write_wired_auto_negotiate_on (void) NULL); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); f = _svOpenFile (testfile); @@ -3764,7 +3759,7 @@ test_read_wifi_band_a (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-a", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-band-a", NULL, TYPE_WIRELESS, NULL); s_con = nm_connection_get_setting_connection (connection); @@ -3819,8 +3814,8 @@ test_write_wifi_band_a (void) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_WiFi_Band_A.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_WiFi_Band_A.cexpected", &testfile); f = _svOpenFile (testfile); @@ -3837,7 +3832,7 @@ test_read_wifi_band_a_channel_mismatch (void) { gs_free_error GError *error = NULL; - _connection_from_file_fail (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-a-channel-mismatch", + _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); } @@ -3847,7 +3842,7 @@ test_read_wifi_band_bg_channel_mismatch (void) { gs_free_error GError *error = NULL; - _connection_from_file_fail (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-bg-channel-mismatch", + _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); } @@ -3862,7 +3857,7 @@ test_read_wired_qeth_static (void) char *unmanaged = NULL; const char * const *subchannels; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wired-qeth-static", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-qeth-static", NULL, TYPE_ETHERNET, &unmanaged); g_assert (!unmanaged); @@ -3911,7 +3906,7 @@ test_read_wired_ctc_static (void) char *unmanaged = NULL; const char * const *subchannels; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wired-ctc-static", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-ctc-static", NULL, TYPE_ETHERNET, &unmanaged); g_assert (unmanaged == NULL); @@ -3949,7 +3944,7 @@ test_read_wifi_wep_no_keys (void) NMSettingWirelessSecurity *s_wsec; NMWepKeyType key_type; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wep-no-keys", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-wep-no-keys", NULL, TYPE_WIRELESS, NULL); /* ===== CONNECTION SETTING ===== */ @@ -3998,7 +3993,7 @@ test_read_permissions (void) guint32 num; const char *tmp; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-permissions", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-permissions", NULL, TYPE_ETHERNET, NULL); /* ===== CONNECTION SETTING ===== */ @@ -4037,7 +4032,7 @@ test_read_wifi_wep_agent_keys (void) NMWepKeyType key_type; NMSettingSecretFlags flags; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wifi-wep-agent-keys", + 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 @@ -4188,7 +4183,7 @@ test_write_wired_static (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); route6file = utils_get_route6_path (testfile); @@ -4328,7 +4323,7 @@ test_write_wired_static_with_generic (void) nmtst_assert_connection_verifies (connection); _writer_new_connection_FIXME (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); route6file = utils_get_route6_path (testfile); @@ -4413,7 +4408,7 @@ test_write_wired_dhcp (void) NULL); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -4428,11 +4423,11 @@ test_write_wired_dhcp_plus_ip (void) gs_unref_object NMConnection *connection = NULL; gs_unref_object NMConnection *reread = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-plus-ip", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-dhcp-plus-ip", NULL, TYPE_ETHERNET, NULL); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -4450,7 +4445,7 @@ test_read_write_wired_dhcp_send_hostname (void) NMSettingIPConfig *s_ip6; const char * dhcp_hostname = "kamil-patka"; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-send-hostname", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-dhcp-send-hostname", NULL, TYPE_ETHERNET, NULL); /* Check dhcp-hostname and dhcp-send-hostname */ @@ -4468,7 +4463,7 @@ test_read_write_wired_dhcp_send_hostname (void) g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, dhcp_hostname, NULL); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -4491,7 +4486,7 @@ test_read_wired_dhcpv6_hostname_fallback (void) gs_unref_object NMConnection *connection = NULL; NMSettingIPConfig *s_ip6; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcpv6-hostname-fallback", + 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); @@ -4560,7 +4555,7 @@ test_write_wired_static_ip6_only (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -4599,7 +4594,7 @@ test_write_wired_static_ip6_only_gw (gconstpointer user_data) 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 ? gateway6 : "NULL"); + 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 (), @@ -4643,7 +4638,7 @@ test_write_wired_static_ip6_only_gw (gconstpointer user_data) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -4684,7 +4679,7 @@ test_read_write_static_routes_legacy (void) NMSettingIPConfig *s_ip4; const char *tmp; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-static-routes-legacy", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-static-routes-legacy", NULL, TYPE_ETHERNET, NULL); /* ===== CONNECTION SETTING ===== */ @@ -4718,7 +4713,7 @@ test_read_write_static_routes_legacy (void) */ _writer_new_connec_exp (connection, TEST_SCRATCH_DIR_TMP, - TEST_IFCFG_DIR "/network-scripts/ifcfg-test-static-routes-legacy.cexpected", + TEST_IFCFG_DIR"/ifcfg-test-static-routes-legacy.cexpected", &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -4774,6 +4769,7 @@ test_write_wired_static_routes (void) 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); @@ -4819,9 +4815,9 @@ test_write_wired_static_routes (void) nmtst_assert_connection_verifies (connection); _writer_new_connection_reread (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile, - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected", + 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. @@ -4914,7 +4910,7 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -4988,7 +4984,7 @@ test_write_wired_8021x_tls (gconstpointer test_data) /* CA cert */ success = nm_setting_802_1x_set_ca_cert (s_8021x, - TEST_IFCFG_DIR "/network-scripts/test_ca_cert.pem", + TEST_IFCFG_DIR"/test_ca_cert.pem", scheme, &format, &error); @@ -4999,7 +4995,7 @@ test_write_wired_8021x_tls (gconstpointer test_data) /* Client cert */ format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; success = nm_setting_802_1x_set_client_cert (s_8021x, - TEST_IFCFG_DIR "/network-scripts/test1_key_and_cert.pem", + TEST_IFCFG_DIR"/test1_key_and_cert.pem", scheme, &format, &error); @@ -5010,7 +5006,7 @@ test_write_wired_8021x_tls (gconstpointer test_data) /* Private key */ format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; success = nm_setting_802_1x_set_private_key (s_8021x, - TEST_IFCFG_DIR "/network-scripts/test1_key_and_cert.pem", + TEST_IFCFG_DIR"/test1_key_and_cert.pem", "test1", scheme, &format, @@ -5025,7 +5021,7 @@ test_write_wired_8021x_tls (gconstpointer test_data) nmtst_assert_connection_verifies (connection); _writer_new_connection_FIXME (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -5087,8 +5083,6 @@ test_write_wired_8021x_tls (gconstpointer test_data) g_free (tmp); } -#define TEST_SCRATCH_ALIAS_BASE TEST_SCRATCH_DIR "/network-scripts/ifcfg-alias0" - static void test_write_wired_aliases (void) { @@ -5141,7 +5135,7 @@ test_write_wired_aliases (void) 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, "label", g_variant_new_string (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); } @@ -5164,7 +5158,7 @@ test_write_wired_aliases (void) g_assert (g_file_test (TEST_SCRATCH_ALIAS_BASE ":5", G_FILE_TEST_EXISTS)); _writer_new_connection_FIXME (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); /* Re-check the alias files */ @@ -5200,9 +5194,9 @@ test_write_wired_aliases (void) 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, "label"), NULL), ==, 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, "label") == NULL); + g_assert (nm_ip_address_get_attribute (addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL) == NULL); ip[j] = NULL; } } @@ -5266,7 +5260,7 @@ test_write_gateway (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); f = _svOpenFile (testfile); @@ -5286,7 +5280,6 @@ test_write_gateway (void) nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); } - static void test_write_wifi_open (void) { @@ -5350,7 +5343,7 @@ test_write_wifi_open (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -5419,7 +5412,7 @@ test_write_wifi_open_hex_ssid (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -5501,7 +5494,7 @@ test_write_wifi_wep (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -5594,7 +5587,7 @@ test_write_wifi_wep_adhoc (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -5679,7 +5672,7 @@ test_write_wifi_wep_passphrase (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -5767,7 +5760,7 @@ test_write_wifi_wep_40_ascii (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -5855,8 +5848,8 @@ test_write_wifi_wep_104_ascii (void) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Wifi_WEP_104_ASCII.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_Wifi_WEP_104_ASCII.cexpected", &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -5940,8 +5933,8 @@ test_write_wifi_leap (void) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Wifi_LEAP.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_Wifi_LEAP.cexpected", &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -6023,7 +6016,7 @@ test_write_wifi_leap_secret_flags (gconstpointer data) nmtst_assert_connection_verifies (connection); _writer_new_connection_FIXME (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -6131,7 +6124,7 @@ test_write_wifi_wpa_psk (gconstpointer test_data) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -6227,7 +6220,7 @@ test_write_wifi_wpa_psk_adhoc (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -6285,7 +6278,9 @@ test_write_wifi_wpa_eap_tls (void) 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); + 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"); @@ -6343,7 +6338,7 @@ test_write_wifi_wpa_eap_tls (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -6470,7 +6465,7 @@ test_write_wifi_wpa_eap_ttls_tls (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -6574,7 +6569,7 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -6662,7 +6657,7 @@ test_write_wifi_wpa_then_open (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -6678,9 +6673,9 @@ test_write_wifi_wpa_then_open (void) /* Write it back out */ _writer_update_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, testfile, - TEST_IFCFG_DIR "/network-scripts/ifcfg-random_wifi_connection.cexpected"); + TEST_IFCFG_DIR"/ifcfg-random_wifi_connection.cexpected"); keyfile = utils_get_keys_path (testfile); g_assert (!g_file_test (keyfile, G_FILE_TEST_EXISTS)); @@ -6776,7 +6771,7 @@ test_write_wifi_wpa_then_wep_with_perms (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -6798,9 +6793,9 @@ test_write_wifi_wpa_then_wep_with_perms (void) /* Write it back out */ _writer_update_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, testfile, - TEST_IFCFG_DIR "/network-scripts/ifcfg-random_wifi_connection_2.cexpected"); + TEST_IFCFG_DIR"/ifcfg-random_wifi_connection_2.cexpected"); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -6888,7 +6883,7 @@ test_write_wifi_dynamic_wep_leap (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -6968,7 +6963,7 @@ test_write_wired_qeth_dhcp (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -7030,10 +7025,10 @@ test_write_wired_ctc_dhcp (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); - /* Ensure the CTCPROT item gets written out as it's own option */ + /* Ensure the CTCPROT item gets written out as its own option */ ifcfg = _svOpenFile (testfile); _svGetValue_check (ifcfg, "CTCPROT", "0"); @@ -7100,8 +7095,8 @@ test_write_permissions (void) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Permissions.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_Permissions.cexpected", &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -7175,7 +7170,7 @@ test_write_wifi_wep_agent_keys (void) nmtst_assert_connection_verifies (connection); _writer_new_connection_FIXME (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL); @@ -7246,7 +7241,7 @@ test_write_wired_pppoe (void) nmtst_assert_connection_verifies (connection); _writer_new_connection_fail (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, NULL); g_object_unref (connection); @@ -7298,7 +7293,7 @@ test_write_vpn (void) nmtst_assert_connection_verifies (connection); _writer_new_connection_fail (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, NULL); g_object_unref (connection); @@ -7371,7 +7366,7 @@ test_write_mobile_broadband (gconstpointer data) nmtst_assert_connection_verifies (connection); _writer_new_connection_fail (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, NULL); g_object_unref (connection); @@ -7387,7 +7382,7 @@ test_read_bridge_main (void) const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-bridge-main", + 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"); @@ -7485,7 +7480,7 @@ test_write_bridge_main (void) nmtst_assert_connection_verifies_without_normalization (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_BRIDGE, NULL); @@ -7500,7 +7495,7 @@ test_read_bridge_component (void) NMSettingConnection *s_con; NMSettingBridgePort *s_port; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-bridge-component", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bridge-component", NULL, TYPE_ETHERNET, NULL); s_con = nm_connection_get_setting_connection (connection); @@ -7565,8 +7560,8 @@ test_write_bridge_component (void) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Bridge_Component.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_Bridge_Component.cexpected", &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -7580,7 +7575,7 @@ test_read_bridge_missing_stp (void) NMConnection *connection; NMSettingBridge *s_bridge; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bridge-missing-stp", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bridge-missing-stp", NULL, TYPE_BRIDGE, NULL); g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "br0"); @@ -7594,7 +7589,7 @@ test_read_bridge_missing_stp (void) g_object_unref (connection); } -#define TEST_IFCFG_VLAN_INTERFACE TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-interface" +#define TEST_IFCFG_VLAN_INTERFACE TEST_IFCFG_DIR"/ifcfg-test-vlan-interface" static void test_read_vlan_interface (void) @@ -7645,7 +7640,7 @@ test_read_vlan_interface (void) g_object_unref (connection); } -#define TEST_IFCFG_VLAN_ONLY_VLANID TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-only-vlanid" +#define TEST_IFCFG_VLAN_ONLY_VLANID TEST_IFCFG_DIR"/ifcfg-test-vlan-only-vlanid" static void test_read_vlan_only_vlan_id (void) @@ -7673,7 +7668,7 @@ test_read_vlan_only_device (void) NMConnection *connection; NMSettingVlan *s_vlan; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-vlan-only-device", + 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"); @@ -7693,7 +7688,7 @@ test_read_vlan_physdev (void) NMConnection *connection; NMSettingVlan *s_vlan; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-physdev", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-vlan-physdev", NULL, TYPE_ETHERNET, NULL); g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "vlan0.3"); @@ -7713,9 +7708,8 @@ test_read_vlan_reorder_hdr_1 (void) NMConnection *connection; NMSettingVlan *s_vlan; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*REORDER_HDR key is deprecated, use VLAN_FLAGS*"); - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-reorder-hdr-1", + 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 (); @@ -7738,7 +7732,7 @@ test_read_vlan_reorder_hdr_2 (void) NMConnection *connection; NMSettingVlan *s_vlan; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-reorder-hdr-2", + 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"); @@ -7760,7 +7754,7 @@ test_read_vlan_flags_1 (void) NMConnection *connection; NMSettingVlan *s_vlan; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-flags-1", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-vlan-flags-1", NULL, TYPE_ETHERNET, NULL); g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "super-vlan"); @@ -7783,7 +7777,7 @@ test_read_vlan_flags_2 (void) NMConnection *connection; NMSettingVlan *s_vlan; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-flags-2", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-vlan-flags-2", NULL, TYPE_ETHERNET, NULL); g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "super-vlan"); @@ -7811,8 +7805,8 @@ test_write_vlan (void) NULL, TYPE_VLAN, NULL); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Vlan_test-vlan-interface.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Vlan_test-vlan-interface.cexpected", &testfile); } @@ -7823,11 +7817,11 @@ test_write_vlan_flags (void) gs_unref_object NMConnection *connection = NULL; gs_unref_object NMConnection *reread = NULL; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-flags-2", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-vlan-flags-2", NULL, TYPE_VLAN, NULL); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -7846,7 +7840,7 @@ test_write_vlan_only_vlanid (void) NULL, TYPE_VLAN, NULL); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -7892,8 +7886,8 @@ test_write_vlan_reorder_hdr (void) NULL); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_VLAN_reorder_hdr.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_VLAN_reorder_hdr.cexpected", &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -7948,7 +7942,7 @@ test_write_ethernet_missing_ipv6 (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -7961,7 +7955,7 @@ test_read_ibft_ignored (void) { gs_free_error GError *error = NULL; - _connection_from_file_fail (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-ibft", + _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); } @@ -7972,7 +7966,7 @@ test_read_bond_main (void) NMConnection *connection; NMSettingBond *s_bond; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-bond-main", + 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"); @@ -7993,7 +7987,7 @@ test_read_bond_eth_type (void) NMConnection *connection; NMSettingBond *s_bond; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-bond-eth-type", + 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"); @@ -8077,8 +8071,8 @@ test_write_bond_main (void) nmtst_assert_connection_verifies_without_normalization (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Bond_Main.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_Bond_Main.cexpected", &testfile); reread = _connection_from_file (testfile, NULL, TYPE_BOND, NULL); @@ -8092,7 +8086,7 @@ test_read_bond_slave (void) NMConnection *connection; NMSettingConnection *s_con; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-bond-slave", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bond-slave", NULL, TYPE_ETHERNET, NULL); g_test_assert_expected_messages (); @@ -8144,7 +8138,7 @@ test_write_bond_slave (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -8162,7 +8156,7 @@ test_read_infiniband (void) 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 "/network-scripts/ifcfg-test-infiniband", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-infiniband", NULL, TYPE_INFINIBAND, &unmanaged); g_assert (!unmanaged); @@ -8248,7 +8242,7 @@ test_write_infiniband (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, TYPE_INFINIBAND, NULL); @@ -8262,7 +8256,7 @@ test_read_bond_slave_ib (void) gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-bond-slave-ib", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-bond-slave-ib", NULL, NULL, NULL); s_con = nm_connection_get_setting_connection (connection); @@ -8310,7 +8304,7 @@ test_write_bond_slave_ib (void) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); reread = _connection_from_file (testfile, NULL, NULL, NULL); @@ -8325,7 +8319,7 @@ test_read_bond_opts_mode_numeric (void) NMSettingConnection *s_con; NMSettingBond *s_bond; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-bond-mode-numeric", + 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), ==, "bond0"); @@ -8358,7 +8352,7 @@ test_read_dcb_basic (void) 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 "/network-scripts/ifcfg-test-dcb", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-dcb", NULL, TYPE_ETHERNET, NULL); s_dcb = nm_connection_get_setting_dcb (connection); @@ -8472,8 +8466,8 @@ test_write_dcb_basic (void) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts//ifcfg-dcb-test.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"//ifcfg-dcb-test.cexpected", &testfile); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); @@ -8487,7 +8481,7 @@ test_read_dcb_default_app_priorities (void) gs_unref_object NMConnection *connection = NULL; NMSettingDcb *s_dcb; - connection = _connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-default-app-priorities", + 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); @@ -8508,9 +8502,8 @@ test_read_dcb_bad_booleans (void) { gs_free_error GError *error = NULL; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*invalid DCB_PG_STRICT value*not all 0s and 1s*"); - _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-booleans", + 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 (); @@ -8523,9 +8516,8 @@ test_read_dcb_short_booleans (void) { gs_free_error GError *error = NULL; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*DCB_PG_STRICT value*8 characters*"); - _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-booleans", + 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 (); @@ -8538,9 +8530,8 @@ test_read_dcb_bad_uints (void) { gs_free_error GError *error = NULL; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*invalid DCB_PG_UP2TC value*not 0 - 7*"); - _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-uints", + 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 (); @@ -8553,9 +8544,8 @@ test_read_dcb_short_uints (void) { gs_free_error GError *error = NULL; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*DCB_PG_UP2TC value*8 characters*"); - _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-uints", + 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 (); @@ -8568,9 +8558,8 @@ test_read_dcb_bad_percent (void) { gs_free_error GError *error = NULL; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*invalid DCB_PG_PCT percentage value*"); - _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-percent", + 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 (); @@ -8583,9 +8572,8 @@ test_read_dcb_short_percent (void) { gs_free_error GError *error = NULL; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*invalid DCB_PG_PCT percentage list value*"); - _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-percent", + 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 (); @@ -8598,9 +8586,8 @@ test_read_dcb_pgpct_not_100 (void) { gs_free_error GError *error = NULL; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*DCB_PG_PCT percentages do not equal 100*"); - _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-pgpct-not-100", + 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 (); @@ -8616,7 +8603,7 @@ test_read_fcoe_mode (gconstpointer user_data) const char *expected_mode = user_data; NMSettingDcb *s_dcb; - file = g_strdup_printf (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-fcoe-%s", expected_mode); + 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); @@ -8676,7 +8663,7 @@ test_write_fcoe_mode (gconstpointer user_data) nmtst_assert_connection_verifies (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); ifcfg = _svOpenFile (testfile); @@ -8720,7 +8707,7 @@ test_read_team_master_invalid (gconstpointer user_data) NMSettingConnection *s_con; NMSettingTeam *s_team; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*ignoring invalid team configuration*"); + NMTST_EXPECT_NM_WARN ("*ignoring invalid team configuration*"); connection = _connection_from_file (PATH_NAME, NULL, TYPE_ETHERNET, NULL); g_test_assert_expected_messages (); @@ -8797,7 +8784,7 @@ test_write_team_master (void) nmtst_assert_connection_verifies_without_normalization (connection); _writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile); f = _svOpenFile (testfile); @@ -8871,8 +8858,8 @@ test_write_team_port (void) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Team_Port.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_Team_Port.cexpected", &testfile); f = _svOpenFile (testfile); @@ -8928,8 +8915,8 @@ test_write_team_infiniband_port (void) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Team_Infiniband_Port.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_Team_Infiniband_Port.cexpected", &testfile); f = _svOpenFile (testfile); @@ -8951,7 +8938,7 @@ test_read_team_port_empty_config (void) NMConnection *connection; NMSettingConnection *s_con; - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port-empty-config", + 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); @@ -9016,9 +9003,9 @@ test_team_reread_slave (void) nmtst_assert_connection_equals (connection_1, FALSE, connection_2, FALSE); _writer_new_connection_reread ((nmtst_get_rand_int () % 2) ? connection_1 : connection_2, - TEST_SCRATCH_DIR "/network-scripts/", + TEST_SCRATCH_DIR, &testfile, - TEST_IFCFG_DIR "/network-scripts/ifcfg-team-slave-enp31s0f1-142.cexpected", + TEST_IFCFG_DIR"/ifcfg-team-slave-enp31s0f1-142.cexpected", &reread, &reread_same); _assert_reread_same ((nmtst_get_rand_int () % 2) ? connection_1 : connection_2, reread); @@ -9039,7 +9026,7 @@ test_read_proxy_basic (void) /* Test basic proxy configuration */ - connection = _connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-read-proxy-basic", + connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-read-proxy-basic", NULL, TYPE_ETHERNET, NULL); /* ===== Proxy setting ===== */ @@ -9091,8 +9078,8 @@ test_write_proxy_basic (void) nmtst_assert_connection_verifies (connection); _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR "/network-scripts/", - TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Proxy_Basic.cexpected", + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_Proxy_Basic.cexpected", &testfile); f = _svOpenFile (testfile); @@ -9487,7 +9474,7 @@ test_write_unknown (gconstpointer test_data) static void test_read_vlan_trailing_spaces (void) { - const char *testfile = TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-trailing-spaces"; + const char *testfile = TEST_IFCFG_DIR"/ifcfg-test-vlan-trailing-spaces"; NMConnection *connection; gboolean success; GError *error = NULL; @@ -9525,7 +9512,7 @@ test_sit_read_ignore (void) { gs_free_error GError *error = NULL; - _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-sit-ignore", + _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*"); } @@ -9645,12 +9632,131 @@ test_utils_ignore (void) do_test_utils_ignored ("ignored-augtmp", "ifcfg-FooBar" AUGTMP_TAG, TRUE); } +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); + + 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); +} + +static 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)); + + /* 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); + + /* TC setting */ + s_tc = (NMSettingTCConfig *) nm_setting_tc_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_tc)); + + 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); + + 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); +} + /*****************************************************************************/ #define TPATH "/settings/plugins/ifcfg-rh/" -#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_QUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-long-quoted" -#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_HEX TEST_IFCFG_DIR"/network-scripts/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" @@ -9665,10 +9771,10 @@ int main (int argc, char **argv) g_test_add_func (TPATH "svUnescape", test_svUnescape); - g_test_add_data_func (TPATH "write-unknown/1", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-write-unknown-1", test_write_unknown); - g_test_add_data_func (TPATH "write-unknown/2", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-write-unknown-2", test_write_unknown); - g_test_add_data_func (TPATH "write-unknown/3", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-write-unknown-3", test_write_unknown); - g_test_add_data_func (TPATH "write-unknown/4", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-write-unknown-4", test_write_unknown); + 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); @@ -9688,8 +9794,8 @@ int main (int argc, char **argv) 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"/network-scripts/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"/network-scripts/ifcfg-test-wired-static-bootproto", "System test-wired-static-bootproto", GINT_TO_POINTER (FALSE)); + 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); @@ -9707,17 +9813,17 @@ int main (int argc, char **argv) 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 "/network-scripts/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 "/network-scripts/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 "/network-scripts/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 "/network-scripts/ifcfg-test-wired-ipv4-manual-4", "System test-wired-ipv4-manual-4"); + 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"/network-scripts/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"/network-scripts/ifcfg-test-wired-ipv6-only-1", "System test-wired-ipv6-only-1"); + 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); @@ -9725,8 +9831,8 @@ int main (int argc, char **argv) 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"/network-scripts/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"/network-scripts/ifcfg-test-wired-8021x-tls-always", GINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED)); + 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); @@ -9749,8 +9855,8 @@ int main (int argc, char **argv) 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 "/network-scripts/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 "/network-scripts/ifcfg-test-wifi-leap-always-ask", GINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED)); + 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); @@ -9899,12 +10005,12 @@ int main (int argc, char **argv) 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"/network-scripts/ifcfg-test-team-master-1", test_read_team_master); - g_test_add_data_func (TPATH "team/read-master-2", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-master-2", test_read_team_master); - g_test_add_data_func (TPATH "team/read-master-invalid", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-master-invalid", test_read_team_master_invalid); + 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"/network-scripts/ifcfg-test-team-port-1", test_read_team_port); - g_test_add_data_func (TPATH "team/read-port-2", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port-2", test_read_team_port); + 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); @@ -9927,5 +10033,8 @@ int main (int argc, char **argv) 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 "tc/read", test_tc_read); + g_test_add_func (TPATH "tc/write", test_tc_write); + return g_test_run (); } diff --git a/src/settings/plugins/ifnet/nms-ifnet-connection-parser.c b/src/settings/plugins/ifnet/nms-ifnet-connection-parser.c deleted file mode 100644 index ed0a757f..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-connection-parser.c +++ /dev/null @@ -1,2912 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#include "nm-default.h" - -#include "nms-ifnet-connection-parser.h" - -#include -#include -#include -#include - -#include "settings/nm-settings-plugin.h" -#include "nm-core-internal.h" -#include "NetworkManagerUtils.h" -#include "nm-meta-setting.h" - -#include "nms-ifnet-net-utils.h" -#include "nms-ifnet-wpa-parser.h" -#include "nms-ifnet-connection.h" - -static char * -connection_id_from_ifnet_name (const char *conn_name) -{ - int name_len = strlen (conn_name); - - /* Convert a hex-encoded conn_name (only used for wifi SSIDs) to human-readable one */ - if ((name_len > 2) && (g_str_has_prefix (conn_name, "0x"))) { - GBytes *bytes = nm_utils_hexstr2bin (conn_name); - char *buf; - - if (bytes) { - buf = g_strndup (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes)); - g_bytes_unref (bytes); - return buf; - } - } - - return g_strdup (conn_name); -} - -static gboolean eap_simple_reader (const char *eap_method, - const char *ssid, - NMSetting8021x *s_8021x, - gboolean phase2, - const char *basepath, - GError **error); - -static gboolean eap_tls_reader (const char *eap_method, - const char *ssid, - NMSetting8021x *s_8021x, - gboolean phase2, - const char *basepath, - GError **error); - -static gboolean eap_peap_reader (const char *eap_method, - const char *ssid, - NMSetting8021x *s_8021x, - gboolean phase2, - const char *basepath, - GError **error); - -static gboolean eap_ttls_reader (const char *eap_method, - const char *ssid, - NMSetting8021x *s_8021x, - gboolean phase2, - const char *basepath, - GError **error); - -typedef struct { - const char *method; - gboolean (*reader) (const char *eap_method, - const char *ssid, - NMSetting8021x *s_8021x, - gboolean phase2, - const char *basepath, - GError **error); - gboolean wifi_phase2_only; -} EAPReader; - -static EAPReader eap_readers[] = { - {"md5", eap_simple_reader, TRUE}, - {"pwd", 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, TRUE}, - {"tls", eap_tls_reader, FALSE}, - {"peap", eap_peap_reader, FALSE}, - {"ttls", eap_ttls_reader, FALSE}, - {NULL, NULL} -}; - -/* reading identity and password */ -static gboolean -eap_simple_reader (const char *eap_method, - const char *ssid, - NMSetting8021x *s_8021x, - gboolean phase2, - const char *basepath, - GError **error) -{ - const char *value; - - /* identity */ - value = wpa_get_value (ssid, "identity"); - if (!value) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", - eap_method); - return FALSE; - } - g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); - - /* password */ - value = wpa_get_value (ssid, "password"); - if (!value) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing IEEE_8021X_PASSWORD for EAP method '%s'.", - eap_method); - return FALSE; - } - - g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL); - - return TRUE; -} - -static char * -get_cert (const char *ssid, const char *key, const char *basepath) -{ - const char *orig; - - /* If it's a relative path, convert to absolute using 'basepath' */ - orig = wpa_get_value (ssid, key); - if (g_path_is_absolute (orig)) - return g_strdup (orig); - return g_strdup_printf ("%s/%s", basepath, orig); -} - -static gboolean -eap_tls_reader (const char *eap_method, - const char *ssid, - NMSetting8021x *s_8021x, - gboolean phase2, - const char *basepath, - GError **error) -{ - const char *value; - char *ca_cert = NULL; - char *client_cert = NULL; - char *privkey = NULL; - const char *privkey_password = NULL; - gboolean success = FALSE; - NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - /* identity */ - value = wpa_get_value (ssid, "identity"); - if (!value) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", - eap_method); - return FALSE; - } - g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); - - /* ca cert */ - ca_cert = get_cert (ssid, phase2 ? "ca_cert2" : "ca_cert", basepath); - if (ca_cert) { - if (phase2) { - if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, - ca_cert, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, error)) - goto done; - } else { - if (!nm_setting_802_1x_set_ca_cert (s_8021x, - ca_cert, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, error)) - goto done; - } - } else { - nm_log_warn (LOGD_SETTINGS, " missing %s for EAP method '%s'; this is insecure!", - phase2 ? "IEEE_8021X_INNER_CA_CERT" : - "IEEE_8021X_CA_CERT", eap_method); - } - - /* Private key password */ - privkey_password = wpa_get_value (ssid, - phase2 ? "private_key2_passwd" : - "private_key_passwd"); - - if (!privkey_password) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing %s for EAP method '%s'.", - phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD" : - "IEEE_8021X_PRIVATE_KEY_PASSWORD", eap_method); - goto done; - } - - /* The private key itself */ - privkey = get_cert (ssid, phase2 ? "private_key2" : "private_key", basepath); - if (!privkey) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing %s for EAP method '%s'.", - phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : - "IEEE_8021X_PRIVATE_KEY", eap_method); - goto done; - } - - if (phase2) { - if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, - privkey, - privkey_password, - NM_SETTING_802_1X_CK_SCHEME_PATH, - &privkey_format, - error)) - goto done; - } else { - if (!nm_setting_802_1x_set_private_key (s_8021x, - privkey, - privkey_password, - NM_SETTING_802_1X_CK_SCHEME_PATH, - &privkey_format, error)) - goto done; - } - - /* Only set the client certificate if the private key is not PKCS#12 format, - * as NM (due to supplicant restrictions) requires. If the key was PKCS#12, - * then nm_setting_802_1x_set_private_key() already set the client certificate - * to the same value as the private key. - */ - if (privkey_format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY - || privkey_format == NM_SETTING_802_1X_CK_FORMAT_X509) { - client_cert = get_cert (ssid, phase2 ? "client_cert2" : "client_cert", basepath); - if (!client_cert) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing %s for EAP method '%s'.", - phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : - "IEEE_8021X_CLIENT_CERT", eap_method); - goto done; - } - - if (phase2) { - if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, - client_cert, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - error)) - goto done; - } else { - if (!nm_setting_802_1x_set_client_cert (s_8021x, - client_cert, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, error)) - goto done; - } - } - - success = TRUE; - -done: - g_free (ca_cert); - g_free (client_cert); - g_free (privkey); - return success; -} - -static gboolean -eap_peap_reader (const char *eap_method, - const char *ssid, - NMSetting8021x *s_8021x, - gboolean phase2, - const char *basepath, - GError **error) -{ - char *ca_cert = NULL; - const char *inner_auth = NULL; - const char *peapver = NULL; - char **list = NULL, **iter, *lower; - gboolean success = FALSE; - - ca_cert = get_cert (ssid, "ca_cert", basepath); - if (ca_cert) { - if (!nm_setting_802_1x_set_ca_cert (s_8021x, - ca_cert, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, error)) - goto done; - } else { - nm_log_warn (LOGD_SETTINGS, " missing IEEE_8021X_CA_CERT for EAP method '%s'; this is insecure!", - eap_method); - } - - peapver = wpa_get_value (ssid, "phase1"); - /* peap version, default is automatic */ - if (peapver && strstr (peapver, "peapver")) { - if (strstr (peapver, "peapver=0")) - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, - "0", NULL); - else if (strstr (peapver, "peapver=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'", - peapver); - goto done; - } - } - - /* peaplabel */ - if (peapver && strstr (peapver, "peaplabel=1")) - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1", - NULL); - - inner_auth = wpa_get_value (ssid, "phase2"); - if (!inner_auth) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing IEEE_8021X_INNER_AUTH_METHODS."); - goto done; - } - /* Handle options for the inner auth method */ - list = g_strsplit (inner_auth, " ", 0); - for (iter = list; iter && *iter; iter++) { - gchar *pos = NULL; - - if (!strlen (*iter)) - continue; - - if (!(pos = strstr (*iter, "MSCHAPV2")) - || !(pos = strstr (*iter, "MD5")) - || !(pos = strstr (*iter, "GTC"))) { - if (!eap_simple_reader (pos, ssid, s_8021x, TRUE, basepath, error)) - goto done; - } else if (!(pos = strstr (*iter, "TLS"))) { - if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, basepath, error)) - goto done; - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", - *iter); - goto done; - } - - pos = strchr (*iter, '='); - if (pos && *pos) { - pos++; - lower = g_ascii_strdown (pos, -1); - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, lower, - NULL); - g_free (lower); - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "No IEEE_8021X_INNER_AUTH_METHOD."); - goto done; - } - break; - } - - if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "No valid IEEE_8021X_INNER_AUTH_METHODS found."); - goto done; - } - - success = TRUE; - -done: - g_free (ca_cert); - if (list) - g_strfreev (list); - return success; -} - -static gboolean -eap_ttls_reader (const char *eap_method, - const char *ssid, - NMSetting8021x *s_8021x, - gboolean phase2, - const char *basepath, - GError **error) -{ - gboolean success = FALSE; - const char *anon_ident = NULL; - char *ca_cert = NULL; - const char *tmp; - char **list = NULL, **iter, *inner_auth = NULL; - - /* ca cert */ - ca_cert = get_cert (ssid, "ca_cert", basepath); - if (ca_cert) { - if (!nm_setting_802_1x_set_ca_cert (s_8021x, - ca_cert, - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, error)) - goto done; - } else { - nm_log_warn (LOGD_SETTINGS, " missing IEEE_8021X_CA_CERT for EAP method '%s'; this is insecure!", - eap_method); - } - - /* anonymous indentity for tls */ - anon_ident = wpa_get_value (ssid, "anonymous_identity"); - if (anon_ident && strlen (anon_ident)) - g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, - anon_ident, NULL); - - tmp = wpa_get_value (ssid, "phase2"); - if (!tmp) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing IEEE_8021X_INNER_AUTH_METHODS."); - goto done; - } - - /* Handle options for the inner auth method */ - inner_auth = g_ascii_strdown (tmp, -1); - list = g_strsplit (inner_auth, " ", 0); - for (iter = list; iter && *iter; iter++) { - gchar *pos = NULL; - - if (!strlen (*iter)) - continue; - if ((pos = strstr (*iter, "mschapv2")) != NULL - || (pos = strstr (*iter, "mschap")) != NULL - || (pos = strstr (*iter, "pap")) != NULL - || (pos = strstr (*iter, "chap")) != NULL) { - if (!eap_simple_reader (pos, ssid, s_8021x, TRUE, basepath, error)) - goto done; - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, - pos, NULL); - } else if ((pos = strstr (*iter, "tls")) != NULL) { - if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, basepath, error)) - goto done; - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, - "tls", NULL); - } else if ((pos = strstr (*iter, "mschapv2")) != NULL - || (pos = strstr (*iter, "md5")) != NULL) { - if (!eap_simple_reader (pos, ssid, s_8021x, TRUE, basepath, error)) { - nm_log_warn (LOGD_SETTINGS, "SIMPLE ERROR"); - goto done; - } - g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, - pos, NULL); - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", - *iter); - goto done; - } - break; - } - - success = TRUE; -done: - g_free (ca_cert); - if (list) - g_strfreev (list); - g_free (inner_auth); - return success; -} - -/* type is already decided by net_parser, this function is just used to - * doing tansformation*/ -static const gchar * -guess_connection_type (const char *conn_name) -{ - const gchar *type = ifnet_get_data (conn_name, "type"); - const gchar *ret_type = NULL; - - if (!g_strcmp0 (type, "ppp")) - ret_type = NM_SETTING_PPPOE_SETTING_NAME; - - if (!g_strcmp0 (type, "wireless")) - ret_type = NM_SETTING_WIRELESS_SETTING_NAME; - - if (!ret_type) - ret_type = NM_SETTING_WIRED_SETTING_NAME; - - nm_log_info (LOGD_SETTINGS, "guessed connection type (%s) = %s", conn_name, ret_type); - return ret_type; -} - -/* Reading mac address for setting connection option. - * Unmanaged device mac address is required by NetworkManager*/ -static gboolean -read_mac_address (const char *conn_name, const char **mac, GError **error) -{ - const char *value = ifnet_get_data (conn_name, "mac"); - - if (!value || !strlen (value)) - return TRUE; - - if (!nm_utils_hwaddr_valid (value, ETH_ALEN)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "The MAC address '%s' was invalid.", value); - return FALSE; - } - - *mac = value; - return TRUE; -} - -static gboolean -make_wired_connection_setting (NMConnection *connection, - const char *conn_name, - GError **error) -{ - const char *mac = NULL; - NMSettingWired *s_wired = NULL; - const char *value = NULL; - - s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); - - /* mtu_xxx */ - value = ifnet_get_data (conn_name, "mtu"); - if (value) { - long int mtu; - - errno = 0; - mtu = strtol (value, NULL, 10); - if (errno || mtu < 0 || mtu > 65535) { - nm_log_warn (LOGD_SETTINGS, " invalid MTU '%s' for %s", value, conn_name); - } else - g_object_set (s_wired, NM_SETTING_WIRED_MTU, - (guint32) mtu, NULL); - } - - if (!read_mac_address (conn_name, &mac, error)) { - g_object_unref (s_wired); - return FALSE; - } - - if (mac) - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - return TRUE; -} - -/* add NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, - * NM_SETTING_IP_CONFIG_DHCP_CLIENT_ID in future*/ -static gboolean -make_ip4_setting (NMConnection *connection, - const char *conn_name, - GError **error) -{ - - NMSettingIPConfig *ip4_setting = - NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); - const char *value, *method = NULL; - gboolean is_static_block = is_static_ip4 (conn_name); - ip_block *iblock = NULL; - - /* set dhcp options (dhcp_xxx) */ - value = ifnet_get_data (conn_name, "dhcp"); - g_object_set (ip4_setting, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, value - && strstr (value, "nodns") ? TRUE : FALSE, - NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, value - && strstr (value, "nogateway") ? TRUE : FALSE, NULL); - - if (!is_static_block) { - method = ifnet_get_data (conn_name, "config"); - if (!method){ - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Unknown config for %s", conn_name); - g_object_unref (ip4_setting); - return FALSE; - } - if (strstr (method, "dhcp")) - g_object_set (ip4_setting, - NM_SETTING_IP_CONFIG_METHOD, - NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NM_SETTING_IP_CONFIG_NEVER_DEFAULT, FALSE, NULL); - else if (strstr (method, "autoip")) { - g_object_set (ip4_setting, - NM_SETTING_IP_CONFIG_METHOD, - NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, - NM_SETTING_IP_CONFIG_NEVER_DEFAULT, FALSE, NULL); - nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); - return TRUE; - } else if (strstr (method, "shared")) { - g_object_set (ip4_setting, - NM_SETTING_IP_CONFIG_METHOD, - NM_SETTING_IP4_CONFIG_METHOD_SHARED, - NM_SETTING_IP_CONFIG_NEVER_DEFAULT, FALSE, NULL); - nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); - return TRUE; - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Unknown config for %s", conn_name); - g_object_unref (ip4_setting); - return FALSE; - } - nm_log_info (LOGD_SETTINGS, "Using %s method for %s", method, conn_name); - }else { - iblock = convert_ip4_config_block (conn_name); - if (!iblock) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Ifnet plugin: can't aquire ip configuration for %s", - conn_name); - g_object_unref (ip4_setting); - return FALSE; - } - /************** add all ip settings to the connection**********/ - while (iblock) { - ip_block *current_iblock; - NMIPAddress *ip4_addr; - GError *local = NULL; - - ip4_addr = nm_ip_address_new (AF_INET, iblock->ip, iblock->prefix, &local); - if (iblock->next_hop) - g_object_set (ip4_setting, - NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, - TRUE, NULL); - - if (ip4_addr) { - if (!nm_setting_ip_config_add_address (ip4_setting, ip4_addr)) - nm_log_warn (LOGD_SETTINGS, "ignoring duplicate IP4 address"); - nm_ip_address_unref (ip4_addr); - } else { - nm_log_warn (LOGD_SETTINGS, " ignoring invalid address entry: %s", local->message); - g_clear_error (&local); - } - - current_iblock = iblock; - iblock = iblock->next; - destroy_ip_block (current_iblock); - - } - g_object_set (ip4_setting, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_NEVER_DEFAULT, !has_default_ip4_route (conn_name), - NULL); - } - - /* add dhcp hostname and client id */ - if (!is_static_block && strstr (method, "dhcp")) { - gchar *dhcp_hostname, *client_id; - - get_dhcp_hostname_and_client_id (&dhcp_hostname, &client_id); - if (dhcp_hostname) { - g_object_set (ip4_setting, - NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, - dhcp_hostname, NULL); - nm_log_info (LOGD_SETTINGS, "DHCP hostname: %s", dhcp_hostname); - g_free (dhcp_hostname); - } - if (client_id) { - g_object_set (ip4_setting, - NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, - client_id, NULL); - nm_log_info (LOGD_SETTINGS, "DHCP client id: %s", client_id); - g_free (client_id); - } - } - - /* add all IPv4 dns servers, IPv6 servers will be ignored */ - set_ip4_dns_servers (ip4_setting, conn_name); - - /* DNS searches */ - value = ifnet_get_data (conn_name, "dns_search"); - if (value) { - gs_free char *stripped = g_strdup (value); - char **searches = NULL; - - strip_string (stripped, '"'); - - searches = g_strsplit (stripped, " ", 0); - if (searches) { - char **item; - - for (item = searches; *item; item++) { - if (strlen (*item)) { - if (!nm_setting_ip_config_add_dns_search (ip4_setting, *item)) - nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *item); - } - } - g_strfreev (searches); - } - } - - /* static routes */ - iblock = convert_ip4_routes_block (conn_name); - while (iblock) { - ip_block *current_iblock = iblock; - const char *metric_str; - char *stripped; - gint64 metric; - NMIPRoute *route; - GError *local = NULL; - - if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) { - metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); - } else { - metric_str = ifnet_get_global_data ("metric"); - if (metric_str) { - stripped = g_strdup (metric_str); - strip_string (stripped, '"'); - metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); - g_free (stripped); - } else - metric = -1; - } - - route = nm_ip_route_new (AF_INET, iblock->ip, iblock->prefix, iblock->next_hop, metric, &local); - if (route) { - if (nm_setting_ip_config_add_route (ip4_setting, route)) - nm_log_info (LOGD_SETTINGS, "new IP4 route:%s\n", iblock->ip); - else - nm_log_warn (LOGD_SETTINGS, "duplicate IP4 route"); - nm_ip_route_unref (route); - } else { - nm_log_warn (LOGD_SETTINGS, " ignoring invalid route entry: %s", local->message); - g_clear_error (&local); - } - - current_iblock = iblock; - iblock = iblock->next; - destroy_ip_block (current_iblock); - } - - /* Finally add setting to connection */ - nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); - - return TRUE; -} - -static gboolean -make_ip6_setting (NMConnection *connection, - const char *conn_name, - GError **error) -{ - NMSettingIPConfig *s_ip6 = NULL; - gboolean is_static_block = is_static_ip6 (conn_name); - - // used to disable IPv6 - gboolean ipv6_enabled = FALSE; - gchar *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; - const char *value; - ip_block *iblock; - gboolean never_default = !has_default_ip6_route (conn_name); - - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - - value = ifnet_get_data (conn_name, "enable_ipv6"); - if (value && is_true (value)) - ipv6_enabled = TRUE; - - //FIXME Handle other methods that NM supports in future - // Currently only Manual and DHCP are supported - if (!ipv6_enabled) { - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, - NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); - goto done; - } else if (!is_static_block) { - // config_eth* contains "dhcp6" - method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; - never_default = FALSE; - } - // else if (!has_ip6_address(conn_name)) - // doesn't have "dhcp6" && doesn't have any ipv6 address - // method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; - else - // doesn't have "dhcp6" && has at least one ipv6 address - method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; - nm_log_info (LOGD_SETTINGS, "IPv6 for %s enabled, using %s", conn_name, method); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, method, - NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, FALSE, - NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, FALSE, - NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NULL); - - /* Make manual settings */ - if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { - ip_block *current_iblock; - - iblock = convert_ip6_config_block (conn_name); - if (!iblock) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Ifnet plugin: can't aquire ip6 configuration for %s", - conn_name); - goto error; - } - /* add all IPv6 addresses */ - while (iblock) { - NMIPAddress *ip6_addr; - GError *local = NULL; - - ip6_addr = nm_ip_address_new (AF_INET6, iblock->ip, iblock->prefix, &local); - if (ip6_addr) { - if (nm_setting_ip_config_add_address (s_ip6, ip6_addr)) { - nm_log_info (LOGD_SETTINGS, "ipv6 addresses count: %d", - nm_setting_ip_config_get_num_addresses (s_ip6)); - } else { - nm_log_warn (LOGD_SETTINGS, "ignoring duplicate IP6 address"); - } - nm_ip_address_unref (ip6_addr); - } else { - nm_log_warn (LOGD_SETTINGS, " ignoring invalid address entry: %s", local->message); - g_clear_error (&local); - } - - current_iblock = iblock; - iblock = iblock->next; - destroy_ip_block (current_iblock); - } - - } else if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { - /* - autoconf or DHCPv6 stuff goes here */ - } - // DNS Servers, set NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS TRUE here - set_ip6_dns_servers (s_ip6, conn_name); - - /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIPConfig */ - - // Add routes - iblock = convert_ip6_routes_block (conn_name); - if (iblock) - g_object_set (s_ip6, NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, - TRUE, NULL); - /* Add all IPv6 routes */ - while (iblock) { - ip_block *current_iblock = iblock; - const char *metric_str; - char *stripped; - gint64 metric; - NMIPRoute *route; - GError *local = NULL; - - /* metric is not per routes configuration right now - * global metric is also supported (metric="x") */ - if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) - metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); - else { - metric_str = ifnet_get_global_data ("metric"); - if (metric_str) { - stripped = g_strdup (metric_str); - strip_string (stripped, '"'); - metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); - g_free (stripped); - } else - metric = 1; - } - - route = nm_ip_route_new (AF_INET6, iblock->ip, iblock->prefix, iblock->next_hop, metric, &local); - if (route) { - if (nm_setting_ip_config_add_route (s_ip6, route)) - nm_log_info (LOGD_SETTINGS, " new IP6 route"); - else - nm_log_warn (LOGD_SETTINGS, " duplicate IP6 route"); - nm_ip_route_unref (route); - } else { - nm_log_warn (LOGD_SETTINGS, " ignoring invalid route entry: %s", local->message); - g_clear_error (&local); - } - - current_iblock = iblock; - iblock = iblock->next; - destroy_ip_block (current_iblock); - } - -done: - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - return TRUE; - -error: - g_object_unref (s_ip6); - nm_log_warn (LOGD_SETTINGS, " Ignore IPv6 for %s", conn_name); - return FALSE; -} - -static NMSetting * -make_wireless_connection_setting (const char *conn_name, - NMSetting8021x **s_8021x, - GError **error) -{ - const char *mac = NULL; - NMSettingWireless *wireless_setting = NULL; - gboolean adhoc = FALSE; - const char *value; - const char *type; - - /* PPP over WIFI is not supported yet */ - g_return_val_if_fail (conn_name != NULL - && strcmp (ifnet_get_data (conn_name, "type"), - "ppp") != 0, NULL); - type = ifnet_get_data (conn_name, "type"); - if (strcmp (type, "ppp") == 0) { - nm_log_warn (LOGD_SETTINGS, "PPP over WIFI is not supported yet"); - return NULL; - } - - wireless_setting = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - if (read_mac_address (conn_name, &mac, error)) { - if (mac) { - g_object_set (wireless_setting, - NM_SETTING_WIRELESS_MAC_ADDRESS, mac, - NULL); - } - } else { - g_object_unref (wireless_setting); - return NULL; - } - - /* handle ssid (hex and ascii) */ - if (conn_name) { - GBytes *bytes; - gsize ssid_len = 0, value_len = strlen (conn_name); - - ssid_len = value_len; - if ((value_len > 2) && (g_str_has_prefix (conn_name, "0x"))) { - /* Hex representation */ - if (value_len % 2) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid SSID '%s' size (looks like hex but length not multiple of 2)", - conn_name); - goto error; - } - - bytes = nm_utils_hexstr2bin (conn_name); - if (!bytes) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid SSID '%s' (looks like hex SSID but isn't)", - conn_name); - goto error; - } - } else - bytes = g_bytes_new (conn_name, 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)", - conn_name, ssid_len); - goto error; - } - - g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, bytes, NULL); - g_bytes_unref (bytes); - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing SSID"); - goto error; - } - - /* mode=0: infrastructure - * mode=1: adhoc */ - value = wpa_get_value (conn_name, "mode"); - if (value) - adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE; - - if (exist_ssid (conn_name)) { - const char *mode = adhoc ? "adhoc" : "infrastructure"; - - g_object_set (wireless_setting, NM_SETTING_WIRELESS_MODE, mode, - NULL); - nm_log_info (LOGD_SETTINGS, "Using mode: %s", mode); - } - - /* BSSID setting */ - value = wpa_get_value (conn_name, "bssid"); - if (value) { - if (!nm_utils_hwaddr_valid (value, ETH_ALEN)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid BSSID '%s'", value); - goto error; - } - - g_object_set (wireless_setting, NM_SETTING_WIRELESS_BSSID, - value, NULL); - - } - - /* mtu_ssid="xx" */ - value = ifnet_get_data (conn_name, "mtu"); - if (value) { - long int mtu; - - errno = 0; - mtu = strtol (value, NULL, 10); - if (errno || mtu < 0 || mtu > 50000) { - nm_log_warn (LOGD_SETTINGS, " invalid MTU '%s' for %s", value, conn_name); - } else - g_object_set (wireless_setting, NM_SETTING_WIRELESS_MTU, - (guint32) mtu, NULL); - - } - - nm_log_info (LOGD_SETTINGS, "wireless_setting added for %s", conn_name); - return NM_SETTING (wireless_setting); -error: - if (wireless_setting) - g_object_unref (wireless_setting); - return NULL; - -} - -static NMSettingWirelessSecurity * -make_leap_setting (const char *ssid, GError **error) -{ - NMSettingWirelessSecurity *wsec; - const char *value; - - wsec = - NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); - - value = wpa_get_value (ssid, "password"); - if (value && strlen (value)) - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, - value, NULL); - - value = wpa_get_value (ssid, "identity"); - if (!value || !strlen (value)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing LEAP identity"); - goto error; - } - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, value, - NULL); - - g_object_set (wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", NULL); - - return wsec; -error: - if (wsec) - g_object_unref (wsec); - return NULL; -} - -static gboolean -add_one_wep_key (const char *ssid, - const char *key, - int key_idx, - NMSettingWirelessSecurity *s_wsec, - GError **error) -{ - const char *value; - char *converted = NULL; - gboolean success = FALSE; - - g_return_val_if_fail (ssid != NULL, FALSE); - g_return_val_if_fail (key != NULL, FALSE); - g_return_val_if_fail (key_idx >= 0 && key_idx <= 3, FALSE); - g_return_val_if_fail (s_wsec != NULL, FALSE); - - value = wpa_get_value (ssid, key); - if (!value) - return TRUE; - - /* Validate keys */ - if (strlen (value) == 10 || strlen (value) == 26) { - /* Hexadecimal WEP key */ - if (!is_hex (value)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid hexadecimal WEP key."); - goto out; - } - converted = g_strdup (value); - } else if (value[0] == '"' - && (strlen (value) == 7 || strlen (value) == 15)) { - /* ASCII passphrase */ - char *tmp = g_strdup (value); - char *p = strip_string (tmp, '"'); - - if (!is_ascii (p)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid ASCII WEP passphrase."); - g_free (tmp); - goto out; - - } - - converted = nm_utils_bin2hexstr (tmp, strlen (tmp), -1); - g_free (tmp); - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid WEP key length. Key: %s", value); - goto out; - } - - if (converted) { - nm_setting_wireless_security_set_wep_key (s_wsec, key_idx, converted); - g_free (converted); - success = TRUE; - } - -out: - return success; -} - -static gboolean -add_wep_keys (const char *ssid, - NMSettingWirelessSecurity *s_wsec, - GError **error) -{ - if (!add_one_wep_key (ssid, "wep_key0", 0, s_wsec, error)) - return FALSE; - if (!add_one_wep_key (ssid, "wep_key1", 1, s_wsec, error)) - return FALSE; - if (!add_one_wep_key (ssid, "wep_key2", 2, s_wsec, error)) - return FALSE; - if (!add_one_wep_key (ssid, "wep_key3", 3, s_wsec, error)) - return FALSE; - return TRUE; - -} - -static NMSettingWirelessSecurity * -make_wep_setting (const char *ssid, GError **error) -{ - const char *auth_alg, *value; - int default_key_idx = 0; - NMSettingWirelessSecurity *s_wireless_sec; - - s_wireless_sec = - NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); - g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, - "none", NULL); - - /* default key index */ - value = wpa_get_value (ssid, "wep_tx_keyidx"); - if (value) { - default_key_idx = atoi (value); - if (default_key_idx >= 0 && default_key_idx <= 3) { - g_object_set (s_wireless_sec, - NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, - default_key_idx, NULL); - nm_log_info (LOGD_SETTINGS, "Default key index: %d", default_key_idx); - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid default WEP key '%s'", value); - goto error; - } - } - - if (!add_wep_keys (ssid, s_wireless_sec, error)) - goto error; - - /* If there's a default key, ensure that key exists */ - if ((default_key_idx == 1) - && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Default WEP key index was 2, but no valid KEY2 exists."); - goto error; - } else if ((default_key_idx == 2) - && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, - 2)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Default WEP key index was 3, but no valid KEY3 exists."); - goto error; - } else if ((default_key_idx == 3) - && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, - 3)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Default WEP key index was 4, but no valid KEY4 exists."); - goto error; - } - - /* authentication algorithms */ - auth_alg = wpa_get_value (ssid, "auth_alg"); - if (auth_alg) { - if (strcmp (auth_alg, "OPEN") == 0) { - g_object_set (s_wireless_sec, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, - "open", NULL); - nm_log_info (LOGD_SETTINGS, "WEP: Use open system authentication"); - } else if (strcmp (auth_alg, "SHARED") == 0) { - g_object_set (s_wireless_sec, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, - "shared", NULL); - nm_log_info (LOGD_SETTINGS, "WEP: Use shared system authentication"); - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid WEP authentication algorithm '%s'", - auth_alg); - goto error; - } - - } - - if (!nm_setting_wireless_security_get_wep_key (s_wireless_sec, 0) - && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1) - && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 2) - && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 3) - && !nm_setting_wireless_security_get_wep_tx_keyidx (s_wireless_sec)) { - 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."); - goto error; - } - /* Unencrypted */ - g_object_unref (s_wireless_sec); - s_wireless_sec = NULL; - } - return s_wireless_sec; - -error: - if (s_wireless_sec) - g_object_unref (s_wireless_sec); - return NULL; -} - -static char * -parse_wpa_psk (const char *psk, GError **error) -{ - char *hashed = NULL; - gboolean quoted = FALSE; - - if (!psk) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing WPA_PSK for WPA-PSK key management"); - return NULL; - } - - /* 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. - */ - - if (psk[0] == '"' && psk[strlen (psk) - 1] == '"') - quoted = TRUE; - if (!quoted && (strlen (psk) == 64)) { - /* Verify the hex PSK; 64 digits */ - if (!is_hex (psk)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid WPA_PSK (contains non-hexadecimal characters)"); - goto out; - } - hashed = g_strdup (psk); - } else { - char *stripped = g_strdup (psk); - - strip_string (stripped, '"'); - - /* Length check */ - if (strlen (stripped) < 8 || strlen (stripped) > 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))"); - g_free (stripped); - goto out; - } - - hashed = g_strdup (stripped); - g_free (stripped); - } - - if (!hashed) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid WPA_PSK (doesn't look like a passphrase or hex key)"); - goto out; - } - -out: - return hashed; -} - -static gboolean -fill_wpa_ciphers (const char *ssid, - NMSettingWirelessSecurity *wsec, - gboolean group, - gboolean adhoc) -{ - const char *value; - char **list = NULL, **iter; - int i = 0; - - value = wpa_get_value (ssid, group ? "group" : "pairwise"); - if (!value) - return TRUE; - - list = g_strsplit_set (value, " ", 0); - for (iter = list; iter && *iter; iter++, i++) { - /* Ad-Hoc configurations cannot have pairwise ciphers, and can only - * have one group cipher. Ignore any additional group ciphers and - * any pairwise ciphers specified. - */ - if (adhoc) { - if (group && (i > 0)) { - nm_log_warn (LOGD_SETTINGS, " ignoring group cipher '%s' (only one group cipher allowed in Ad-Hoc mode)", - *iter); - continue; - } else if (!group) { - nm_log_warn (LOGD_SETTINGS, " ignoring pairwise cipher '%s' (pairwise not used in Ad-Hoc mode)", - *iter); - continue; - } - } - - 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 { - nm_log_warn (LOGD_SETTINGS, " ignoring invalid %s cipher '%s'", - group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE", - *iter); - } - } - - if (list) - g_strfreev (list); - return TRUE; -} - -static NMSetting8021x * -fill_8021x (const char *ssid, - const char *key_mgmt, - gboolean wifi, - const char *basepath, - GError **error) -{ - NMSetting8021x *s_8021x; - const char *value; - char **list, **iter; - - value = wpa_get_value (ssid, "eap"); - if (!value) { - 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 = g_strsplit (value, " ", 0); - - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - /* Validate and handle each EAP method */ - for (iter = list; iter && *iter; iter++) { - EAPReader *eap = &eap_readers[0]; - gboolean found = FALSE; - 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 WiFi unless they are an inner method - * used with TTLS or PEAP or whatever. - */ - if (wifi && eap->wifi_phase2_only) { - nm_log_warn (LOGD_SETTINGS, " ignored invalid IEEE_8021X_EAP_METHOD '%s'; not allowed for wifi.", - lower); - goto next; - } - - /* Parse EAP method specific options */ - if (!(*eap->reader) (lower, ssid, s_8021x, FALSE, basepath, error)) { - g_free (lower); - goto error; - } - nm_setting_802_1x_add_eap_method (s_8021x, lower); - found = TRUE; - break; - - next: - eap++; - } - - if (!found) { - nm_log_warn (LOGD_SETTINGS, " ignored unknown IEEE_8021X_EAP_METHOD '%s'.", lower); - } - g_free (lower); - } - g_strfreev (list); - - 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."); - goto error; - } - - return s_8021x; - -error: - g_object_unref (s_8021x); - return NULL; -} - -static NMSettingWirelessSecurity * -make_wpa_setting (const char *ssid, - const char *basepath, - NMSetting8021x **s_8021x, - GError **error) -{ - NMSettingWirelessSecurity *wsec; - const char *value; - char *lower; - gboolean adhoc = FALSE; - - if (!exist_ssid (ssid)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "No security info found for ssid: %s", ssid); - return NULL; - } - - wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); - - /* mode=1: adhoc - * mode=0: infrastructure */ - value = wpa_get_value (ssid, "mode"); - if (value) - adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE; - - /* Pairwise and Group ciphers */ - fill_wpa_ciphers (ssid, wsec, FALSE, adhoc); - fill_wpa_ciphers (ssid, wsec, TRUE, adhoc); - - /* WPA and/or RSN */ - if (adhoc) { - /* Ad-Hoc mode only supports WPA proto for now */ - nm_setting_wireless_security_add_proto (wsec, "wpa"); - } else { - nm_setting_wireless_security_add_proto (wsec, "wpa"); - nm_setting_wireless_security_add_proto (wsec, "rsn"); - - } - - value = wpa_get_value (ssid, "key_mgmt"); - if (!strcmp (value, "WPA-PSK")) { - char *psk = parse_wpa_psk (wpa_get_value (ssid, "psk"), error); - - if (!psk) - goto error; - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, - NULL); - g_free (psk); - - if (adhoc) - g_object_set (wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, - "wpa-none", NULL); - else - g_object_set (wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, - "wpa-psk", NULL); - } else if (!strcmp (value, "WPA-EAP") || !strcmp (value, "IEEE8021X")) { - 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'", - value); - goto error; - } - *s_8021x = fill_8021x (ssid, value, TRUE, basepath, error); - if (!*s_8021x) - goto error; - - lower = g_ascii_strdown (value, -1); - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, - lower, NULL); - g_free (lower); - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Unknown wireless KEY_MGMT type '%s'", value); - goto error; - } - return wsec; -error: - if (wsec) - g_object_unref (wsec); - return NULL; -} - -static NMSettingWirelessSecurity * -make_wireless_security_setting (const char *conn_name, - const char *basepath, - NMSetting8021x **s_8021x, - GError ** error) -{ - NMSettingWirelessSecurity *wsec = NULL; - const char *ssid; - gboolean adhoc = FALSE; - const char *value; - - g_return_val_if_fail (conn_name != NULL - && strcmp (ifnet_get_data (conn_name, "type"), - "ppp") != 0, NULL); - nm_log_info (LOGD_SETTINGS, "updating wireless security settings (%s).", conn_name); - - ssid = conn_name; - value = wpa_get_value (ssid, "mode"); - if (value) - adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE; - - value = wpa_get_value (ssid, "key_mgmt"); - if (!adhoc && g_strcmp0 (value, "IEEE8021X") == 0) { - value = wpa_get_value (ssid, "eap"); - if (value && strcasecmp (value, "LEAP") == 0) { - wsec = make_leap_setting (ssid, error); - if (wsec == NULL) - goto error; - } - } else if (g_strcmp0 (value, "WPA-PSK") == 0 || g_strcmp0 (value, "WPA-EAP") == 0) { - wsec = make_wpa_setting (ssid, basepath, s_8021x, error); - if (wsec == NULL) - goto error; - } - if (!wsec) { - wsec = make_wep_setting (ssid, error); - if (wsec == NULL) - goto error; - } - return wsec; - -error: - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Can't handle security information for ssid: %s", - conn_name); - return NULL; -} - -/* Currently only support username and password */ -static gboolean -make_pppoe_connection_setting (NMConnection *connection, - const char *conn_name, - GError **error) -{ - NMSettingPppoe *s_pppoe; - NMSettingPpp *s_ppp; - const char *value; - - s_pppoe = NM_SETTING_PPPOE (nm_setting_pppoe_new ()); - - /* username */ - value = ifnet_get_data (conn_name, "username"); - if (!value) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "ppp requires at lease a username"); - return FALSE; - } - g_object_set (s_pppoe, NM_SETTING_PPPOE_USERNAME, value, NULL); - - /* password */ - value = ifnet_get_data (conn_name, "password"); - if (!value) { - value = ""; - } - - g_object_set (s_pppoe, NM_SETTING_PPPOE_PASSWORD, value, NULL); - nm_connection_add_setting (connection, NM_SETTING (s_pppoe)); - - /* PPP setting */ - s_ppp = (NMSettingPpp *) nm_setting_ppp_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ppp)); - - return TRUE; -} - -NMConnection * -ifnet_update_connection_from_config_block (const char *conn_name, - const char *basepath, - GError **error) -{ - const gchar *type = NULL; - NMConnection *connection = NULL; - NMSettingConnection *setting = NULL; - NMSetting8021x *s_8021x = NULL; - NMSettingWirelessSecurity *wsec = NULL; - gboolean auto_conn = TRUE; - const char *value = NULL; - gchar *id, *uuid; - gboolean success = FALSE; - - connection = nm_simple_connection_new (); - setting = nm_connection_get_setting_connection (connection); - if (!setting) { - setting = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - g_assert (setting); - nm_connection_add_setting (connection, NM_SETTING (setting)); - } - - type = guess_connection_type (conn_name); - value = ifnet_get_data (conn_name, "auto"); - if (value && !strcmp (value, "false")) - auto_conn = FALSE; - - /* Try to read UUID from the ifnet block, otherwise generate UUID from - * the connection ID. - */ - id = connection_id_from_ifnet_name (conn_name); - uuid = g_strdup (ifnet_get_data (conn_name, "uuid")); - if (!uuid) - uuid = nm_utils_uuid_generate_from_string (id, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); - - g_object_set (setting, - NM_SETTING_CONNECTION_TYPE, type, - NM_SETTING_CONNECTION_ID, id, - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_INTERFACE_NAME, conn_name, - NM_SETTING_CONNECTION_READ_ONLY, FALSE, - NM_SETTING_CONNECTION_AUTOCONNECT, auto_conn, - NULL); - nm_log_info (LOGD_SETTINGS, "name:%s, id:%s, uuid: %s", conn_name, id, uuid); - g_free (id); - g_free (uuid); - - if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type) - || !strcmp (NM_SETTING_PPPOE_SETTING_NAME, type)) { - /* wired setting */ - if (!make_wired_connection_setting (connection, conn_name, error)) - goto error; - - /* pppoe setting */ - if (!strcmp (NM_SETTING_PPPOE_SETTING_NAME, type)) { - if (!make_pppoe_connection_setting (connection, conn_name, error)) - goto error; - } - } else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) { - /* wireless setting */ - NMSetting *wireless_setting; - - wireless_setting = make_wireless_connection_setting (conn_name, &s_8021x, error); - if (!wireless_setting) - goto error; - nm_connection_add_setting (connection, wireless_setting); - - /* wireless security setting */ - if (wpa_get_value (conn_name, "ssid")) { - wsec = make_wireless_security_setting (conn_name, basepath, &s_8021x, error); - if (!wsec) - goto error; - nm_connection_add_setting (connection, NM_SETTING (wsec)); - if (s_8021x) - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - } - } else - goto error; - - /* IPv4 setting */ - if (!make_ip4_setting (connection, conn_name, error)) - goto error; - - /* IPv6 setting */ - if (!make_ip6_setting (connection, conn_name, error)) - goto error; - - if (nm_connection_verify (connection, error)) { - nm_log_info (LOGD_SETTINGS, "Connection verified %s:%d", conn_name, success); - } else { - goto error; - } - - return connection; -error: - g_object_unref (connection); - return NULL; -} - -typedef struct Setting8021xSchemeVtable { - const NMSetting8021xSchemeVtable *vtable; - const char *ifnet_key; -} Setting8021xSchemeVtable; - -static const Setting8021xSchemeVtable setting_8021x_scheme_vtable[] = { - [NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT] = { - .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT], - .ifnet_key = "ca_cert", - }, - [NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT] = { - .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT], - .ifnet_key = "ca_cert2", - }, - [NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT] = { - .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT], - .ifnet_key = "client_cert", - }, - [NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT] = { - .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT], - .ifnet_key = "client_cert2", - }, - [NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY] = { - .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY], - .ifnet_key = "private_key", - }, - [NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY] = { - .vtable = &nm_setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY], - .ifnet_key = "private_key2", - }, -}; - -static gboolean -write_object (NMSetting8021x *s_8021x, - const char *conn_name, - GBytes *override_data, - const Setting8021xSchemeVtable *objtype, - GError **error) -{ - NMSetting8021xCKScheme scheme; - const char *path = NULL; - GBytes *blob = NULL; - - g_return_val_if_fail (conn_name != NULL, FALSE); - g_return_val_if_fail (objtype != NULL, FALSE); - if (override_data) - /* if given explicit data to save, always use that instead of asking - * the setting what to do. - */ - blob = override_data; - else { - scheme = (*(objtype->vtable->scheme_func)) (s_8021x); - switch (scheme) { - case NM_SETTING_802_1X_CK_SCHEME_BLOB: - blob = (*(objtype->vtable->blob_func)) (s_8021x); - break; - case NM_SETTING_802_1X_CK_SCHEME_PATH: - path = (*(objtype->vtable->path_func)) (s_8021x); - break; - default: - break; - } - } - - /* If the object path was specified, prefer that over any raw cert data that - * may have been sent. - */ - if (path) { - wpa_set_data (conn_name, (gchar *) objtype->ifnet_key, - (gchar *) path); - return TRUE; - } - - /* does not support writing encryption data now */ - if (blob) - nm_log_warn (LOGD_SETTINGS, " Currently we do not support cert writing."); - - return TRUE; -} - -static gboolean -write_8021x_certs (NMSetting8021x *s_8021x, - gboolean phase2, - const char *conn_name, - GError **error) -{ - char *password = NULL; - const Setting8021xSchemeVtable *otype = NULL; - gboolean is_pkcs12 = FALSE, success = FALSE; - GBytes *blob = NULL; - GBytes *enc_key = NULL; - gchar *generated_pw = NULL; - - /* CA certificate */ - otype = 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]; - - if (!write_object (s_8021x, conn_name, NULL, otype, error)) - return FALSE; - - /* Private key */ - if (phase2) { - if (nm_setting_802_1x_get_phase2_private_key_scheme (s_8021x) != - NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { - if (nm_setting_802_1x_get_phase2_private_key_format - (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) - is_pkcs12 = TRUE; - } - password = (char *) - nm_setting_802_1x_get_phase2_private_key_password (s_8021x); - } else { - if (nm_setting_802_1x_get_private_key_scheme (s_8021x) != - NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { - if (nm_setting_802_1x_get_private_key_format (s_8021x) - == NM_SETTING_802_1X_CK_FORMAT_PKCS12) - is_pkcs12 = TRUE; - } - password = (char *) - nm_setting_802_1x_get_private_key_password (s_8021x); - } - - otype = phase2 - ? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY] - : &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY]; - - if ((*(otype->vtable->scheme_func)) (s_8021x) == - NM_SETTING_802_1X_CK_SCHEME_BLOB) - blob = (*(otype->vtable->blob_func)) (s_8021x); - - /* Only do the private key re-encrypt dance if we got the raw key data, which - * by definition will be unencrypted. If we're given a direct path to the - * private key file, it'll be encrypted, so we don't need to re-encrypt. - */ - if (blob && !is_pkcs12) { - GByteArray *tmp_enc_key; - - /* Encrypt the unencrypted private key with the fake password */ - tmp_enc_key = - nm_utils_rsa_key_encrypt (g_bytes_get_data (blob, NULL), g_bytes_get_size (blob), - password, &generated_pw, error); - if (!tmp_enc_key) - goto out; - - enc_key = g_byte_array_free_to_bytes (tmp_enc_key); - - if (generated_pw) - password = generated_pw; - } - - /* Save the private key */ - if (!write_object - (s_8021x, conn_name, enc_key ? enc_key : blob, otype, error)) - goto out; - - if (phase2) - wpa_set_data (conn_name, "private_key2_passwd", password); - else - wpa_set_data (conn_name, "private_key_passwd", password); - - /* Client certificate */ - if (is_pkcs12) { - wpa_set_data (conn_name, - phase2 ? "client_cert2" : "client_cert", NULL); - } else { - otype = 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]; - - /* Save the client certificate */ - if (!write_object (s_8021x, conn_name, NULL, otype, error)) - goto out; - } - - success = TRUE; -out: - if (generated_pw) { - memset (generated_pw, 0, strlen (generated_pw)); - g_free (generated_pw); - } - if (enc_key) { - memset ((gpointer) g_bytes_get_data (enc_key, NULL), 0, g_bytes_get_size (enc_key)); - g_bytes_unref (enc_key); - } - return success; -} - -static gboolean -write_8021x_setting (NMConnection *connection, - const char *conn_name, - gboolean wired, - GError **error) -{ - NMSetting8021x *s_8021x; - const char *value; - char *tmp = NULL; - gboolean success = FALSE; - GString *phase2_auth; - GString *phase1; - - s_8021x = nm_connection_get_setting_802_1x (connection); - if (!s_8021x) { - return TRUE; - } - - nm_log_info (LOGD_SETTINGS, "Adding 8021x setting for %s", conn_name); - - /* If wired, write KEY_MGMT */ - if (wired) - wpa_set_data (conn_name, "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); - } - wpa_set_data (conn_name, "eap", tmp ? tmp : NULL); - g_free (tmp); - - wpa_set_data (conn_name, "identity", - (gchar *) nm_setting_802_1x_get_identity (s_8021x)); - - wpa_set_data (conn_name, "anonymous_identity", (gchar *) - nm_setting_802_1x_get_anonymous_identity (s_8021x)); - - wpa_set_data (conn_name, "password", - (gchar *) nm_setting_802_1x_get_password (s_8021x)); - - phase1 = g_string_new (NULL); - - /* PEAP version */ - wpa_set_data (conn_name, "phase1", NULL); - value = nm_setting_802_1x_get_phase1_peapver (s_8021x); - if (value && (!strcmp (value, "0") || !strcmp (value, "1"))) - g_string_append_printf (phase1, "peapver=%s ", value); - - /* PEAP label */ - value = nm_setting_802_1x_get_phase1_peaplabel (s_8021x); - if (value && !strcmp (value, "1")) - g_string_append_printf (phase1, "peaplabel=%s ", value); - if (phase1->len) { - tmp = g_strstrip (g_strdup (phase1->str)); - wpa_set_data (conn_name, "phase1", tmp); - g_free (tmp); - } - - /* Phase2 auth methods */ - wpa_set_data (conn_name, "phase2", NULL); - 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_printf (phase2_auth, "auth=%s ", tmp); - g_free (tmp); - } - - /* Phase2 auth heap */ - value = nm_setting_802_1x_get_phase2_autheap (s_8021x); - if (value) { - tmp = g_ascii_strup (value, -1); - g_string_append_printf (phase2_auth, "autheap=%s ", tmp); - g_free (tmp); - } - tmp = g_strstrip (g_strdup (phase2_auth->str)); - wpa_set_data (conn_name, "phase2", phase2_auth->len ? tmp : NULL); - g_free (tmp); - - g_string_free (phase2_auth, TRUE); - g_string_free (phase1, TRUE); - - success = write_8021x_certs (s_8021x, FALSE, conn_name, error); - if (success) { - /* phase2/inner certs */ - success = write_8021x_certs (s_8021x, TRUE, conn_name, error); - } - - return success; -} - -static gboolean -write_wireless_security_setting (NMConnection * connection, - gchar * conn_name, - gboolean adhoc, - gboolean * no_8021x, GError ** error) -{ - NMSettingWirelessSecurity *s_wsec; - const char *key_mgmt, *auth_alg, *key, *cipher, *psk; - gboolean wep = FALSE, wpa = FALSE; - 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_INVALID_CONNECTION, - "Missing '%s' setting", - NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); - return FALSE; - } - - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); - g_assert (key_mgmt); - - auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); - - if (!strcmp (key_mgmt, "none")) { - wpa_set_data (conn_name, "key_mgmt", "NONE"); - wep = TRUE; - *no_8021x = TRUE; - } else if (!strcmp (key_mgmt, "wpa-none") - || !strcmp (key_mgmt, "wpa-psk")) { - wpa_set_data (conn_name, "key_mgmt", "WPA-PSK"); - wpa = TRUE; - *no_8021x = TRUE; - } else if (!strcmp (key_mgmt, "ieee8021x")) { - wpa_set_data (conn_name, "key_mgmt", "IEEE8021X"); - } else if (!strcmp (key_mgmt, "wpa-eap")) { - wpa_set_data (conn_name, "key_mgmt", "WPA-EAP"); - wpa = TRUE; - } else - nm_log_warn (LOGD_SETTINGS, "Unknown key_mgmt: %s", key_mgmt); - - if (auth_alg) { - if (!strcmp (auth_alg, "shared")) - wpa_set_data (conn_name, "auth_alg", "SHARED"); - else if (!strcmp (auth_alg, "open")) - wpa_set_data (conn_name, "auth_alg", "OPEN"); - else if (!strcmp (auth_alg, "leap")) { - wpa_set_data (conn_name, "auth_alg", "LEAP"); - wpa_set_data (conn_name, "eap", "LEAP"); - wpa_set_data (conn_name, "identity", (gchar *) - nm_setting_wireless_security_get_leap_username - (s_wsec)); - wpa_set_data (conn_name, "password", (gchar *) - nm_setting_wireless_security_get_leap_password - (s_wsec)); - *no_8021x = TRUE; - } - } else - wpa_set_data (conn_name, "auth_alg", NULL); - - /* Default WEP TX key index */ - if (wep) { - tmp = - g_strdup_printf ("%d", - nm_setting_wireless_security_get_wep_tx_keyidx - (s_wsec)); - wpa_set_data (conn_name, "wep_tx_keyidx", tmp); - g_free (tmp); - } else - wpa_set_data (conn_name, "wep_tx_keyidx", NULL); - - /* WEP keys */ - for (i = 0; i < 4; i++) { - int length; - - key = nm_setting_wireless_security_get_wep_key (s_wsec, i); - if (!key) - continue; - tmp = g_strdup_printf ("wep_key%d", i); - length = strlen (key); - if (length == 10 || length == 26 || length == 58) - wpa_set_data (conn_name, tmp, (gchar *) key); - else { - gchar *tmp_key = g_strdup_printf ("\"%s\"", key); - - wpa_set_data (conn_name, tmp, tmp_key); - g_free (tmp_key); - } - g_free (tmp); - } - - /* WPA Pairwise ciphers */ - wpa_set_data (conn_name, "pairwise", NULL); - 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); - tmp = g_ascii_strup (cipher, -1); - g_string_append (str, tmp); - g_free (tmp); - } - if (strlen (str->str)) - wpa_set_data (conn_name, "pairwise", str->str); - g_string_free (str, TRUE); - - /* WPA Group ciphers */ - wpa_set_data (conn_name, "group", NULL); - 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)) - wpa_set_data (conn_name, "group", str->str); - g_string_free (str, TRUE); - - /* WPA Passphrase */ - if (wpa) { - GString *quoted = NULL; - - psk = nm_setting_wireless_security_get_psk (s_wsec); - if (psk && (strlen (psk) != 64)) { - quoted = g_string_sized_new (strlen (psk) + 2); - g_string_append_c (quoted, '"'); - g_string_append (quoted, psk); - g_string_append_c (quoted, '"'); - } - /* psk will be lost here if we don't check it for NULL */ - if (psk) - wpa_set_data (conn_name, "psk", - quoted ? quoted->str : (gchar *) psk); - if (quoted) - g_string_free (quoted, TRUE); - } else - wpa_set_data (conn_name, "psk", NULL); - - return TRUE; -} - -/* remove old ssid and add new one*/ -static void -update_wireless_ssid (NMConnection *connection, - const char *conn_name, - const char *ssid, - gboolean hex) -{ - if(strcmp (conn_name, ssid)){ - ifnet_delete_network (conn_name); - wpa_delete_security (conn_name); - } - - ifnet_add_network (ssid, "wireless"); - wpa_add_security (ssid); -} - -static gboolean -write_wireless_setting (NMConnection *connection, - const char *conn_name, - gboolean *no_8021x, - const char **out_new_name, - GError **error) -{ - NMSettingWireless *s_wireless; - GBytes *ssid; - const guint8 *ssid_data; - gsize ssid_len; - const char *mac, *bssid, *mode; - char buf[33]; - guint32 mtu, i; - gboolean adhoc = FALSE, hex_ssid = FALSE; - gchar *ssid_str, *tmp; - - s_wireless = nm_connection_get_setting_wireless (connection); - if (!s_wireless) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing '%s' setting", - NM_SETTING_WIRELESS_SETTING_NAME); - return FALSE; - } - - ssid = nm_setting_wireless_get_ssid (s_wireless); - if (!ssid) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "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_INVALID_CONNECTION, - "Invalid SSID in '%s' setting", - NM_SETTING_WIRELESS_SETTING_NAME); - return FALSE; - } - - /* If the SSID contains any non-alnum characters, we need to use - * the hex notation of the SSID instead. (Because openrc doesn't - * support these characters, see bug #356337) - */ - for (i = 0; i < ssid_len; i++) { - if (!g_ascii_isalnum (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]); - update_wireless_ssid (connection, conn_name, str->str, hex_ssid); - ssid_str = g_string_free (str, FALSE); - } else { - /* Printable SSIDs get quoted */ - memset (buf, 0, sizeof (buf)); - memcpy (buf, ssid_data, ssid_len); - g_strstrip (buf); - update_wireless_ssid (connection, conn_name, buf, hex_ssid); - ssid_str = g_strdup (buf); - } - - ifnet_set_data (ssid_str, "mac", NULL); - mac = nm_setting_wireless_get_mac_address (s_wireless); - if (mac) - ifnet_set_data (ssid_str, "mac", mac); - - ifnet_set_data (ssid_str, "mtu", NULL); - mtu = nm_setting_wireless_get_mtu (s_wireless); - if (mtu) { - tmp = g_strdup_printf ("%u", mtu); - ifnet_set_data (ssid_str, "mtu", tmp); - g_free (tmp); - } - - ifnet_set_data (ssid_str, "mode", NULL); - mode = nm_setting_wireless_get_mode (s_wireless); - if (!mode || !strcmp (mode, "infrastructure")) { - wpa_set_data (ssid_str, "mode", "0"); - } else if (!strcmp (mode, "adhoc")) { - wpa_set_data (ssid_str, "mode", "1"); - adhoc = TRUE; - } else { - nm_log_warn (LOGD_SETTINGS, "Invalid mode '%s' in '%s' setting", - mode, NM_SETTING_WIRELESS_SETTING_NAME); - return FALSE; - } - - wpa_set_data (ssid_str, "bssid", NULL); - bssid = nm_setting_wireless_get_bssid (s_wireless); - if (bssid) - wpa_set_data (ssid_str, "bssid", bssid); - - if (nm_connection_get_setting_wireless_security (connection)) { - if (!write_wireless_security_setting - (connection, ssid_str, adhoc, no_8021x, error)) - return FALSE; - } else - wpa_delete_security (ssid_str); - - if (out_new_name) - *out_new_name = ifnet_get_data (ssid_str, "name"); - g_free (ssid_str); - return TRUE; -} - -static gboolean -write_wired_setting (NMConnection *connection, - const char *conn_name, - GError **error) -{ - NMSettingWired *s_wired; - const char *mac; - char *tmp; - guint32 mtu; - - s_wired = nm_connection_get_setting_wired (connection); - if (!s_wired) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing '%s' setting", - NM_SETTING_WIRED_SETTING_NAME); - return FALSE; - } - - ifnet_set_data (conn_name, "mac", NULL); - mac = nm_setting_wired_get_mac_address (s_wired); - if (mac) - ifnet_set_data (conn_name, "mac", mac); - - ifnet_set_data (conn_name, "mtu", NULL); - mtu = nm_setting_wired_get_mtu (s_wired); - if (mtu) { - tmp = g_strdup_printf ("%u", mtu); - ifnet_set_data (conn_name, "mtu", tmp); - g_free (tmp); - } - //FIXME may add connection type in future - //ifnet_set_data (conn_name, "TYPE", TYPE_ETHERNET); - - return TRUE; -} - -static gboolean -write_ip4_setting (NMConnection *connection, const char *conn_name, GError **error) -{ - NMSettingIPConfig *s_ip4; - const char *value; - guint32 i, num; - GString *searches; - GString *ips; - GString *routes; - GString *dns; - gboolean success = FALSE; - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (!s_ip4) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing '%s' setting", - NM_SETTING_IP4_CONFIG_SETTING_NAME); - return FALSE; - } - routes = g_string_new (NULL); - - value = nm_setting_ip_config_get_method (s_ip4); - g_assert (value); - if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { - - num = nm_setting_ip_config_get_num_addresses (s_ip4); - ips = g_string_new (NULL); - /* IPv4 addresses */ - for (i = 0; i < num; i++) { - NMIPAddress *addr; - - addr = nm_setting_ip_config_get_address (s_ip4, i); - - g_string_append_printf (ips, "\"%s/%u", - nm_ip_address_get_address (addr), - nm_ip_address_get_prefix (addr)); - - /* only the first gateway will be written */ - if (i == 0 && nm_setting_ip_config_get_gateway (s_ip4)) { - g_string_append_printf (routes, - "\"default via %s\" ", - nm_setting_ip_config_get_gateway (s_ip4)); - } - } - ifnet_set_data (conn_name, "config", ips->str); - g_string_free (ips, TRUE); - } else if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) - ifnet_set_data (conn_name, "config", "shared"); - else if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) - ifnet_set_data (conn_name, "config", "autoip"); - else - ifnet_set_data (conn_name, "config", "dhcp"); - - /* DNS Servers */ - num = nm_setting_ip_config_get_num_dns (s_ip4); - if (num > 0) { - dns = g_string_new (NULL); - for (i = 0; i < num; i++) { - const char *ip; - - ip = nm_setting_ip_config_get_dns (s_ip4, i); - g_string_append_printf (dns, " %s", ip); - } - ifnet_set_data (conn_name, "dns_servers", dns->str); - g_string_free (dns, TRUE); - } else - ifnet_set_data (conn_name, "dns_servers", NULL); - - /* DNS Searches */ - 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)); - } - ifnet_set_data (conn_name, "dns_search", searches->str); - g_string_free (searches, TRUE); - } else - ifnet_set_data (conn_name, "dns_search", NULL); - /* FIXME Will be implemented when configuration supports it - if (!strcmp(value, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { - value = nm_setting_ip_config_get_dhcp_hostname(s_ip4); - if (value) - ifnet_set_data(conn_name, "DHCP_HOSTNAME", value, - FALSE); - - value = nm_setting_ip_config_get_dhcp_client_id(s_ip4); - if (value) - ifnet_set_data(conn_name, "DHCP_CLIENT_ID", value, - FALSE); - } - */ - - /* Static routes */ - num = nm_setting_ip_config_get_num_routes (s_ip4); - if (num > 0) { - for (i = 0; i < num; i++) { - NMIPRoute *route; - const char *next_hop; - - route = nm_setting_ip_config_get_route (s_ip4, i); - - next_hop = nm_ip_route_get_next_hop (route); - if (!next_hop) - next_hop = "0.0.0.0"; - - g_string_append_printf (routes, "\"%s/%u via %s\" ", - nm_ip_route_get_dest (route), - nm_ip_route_get_prefix (route), - next_hop); - } - } - if (routes->len > 0) - ifnet_set_data (conn_name, "routes", routes->str); - else - ifnet_set_data (conn_name, "routes", NULL); - g_string_free (routes, TRUE); - - success = TRUE; - - return success; -} - -static void -write_route6_file (NMSettingIPConfig *s_ip6, const char *conn_name) -{ - NMIPRoute *route; - const char *next_hop; - guint32 i, num; - GString *routes_string; - const char *old_routes; - - g_return_if_fail (s_ip6 != NULL); - num = nm_setting_ip_config_get_num_routes (s_ip6); - if (num == 0) - return; - - old_routes = ifnet_get_data (conn_name, "routes"); - routes_string = g_string_new (old_routes); - if (old_routes) - g_string_append (routes_string, "\" "); - for (i = 0; i < num; i++) { - route = nm_setting_ip_config_get_route (s_ip6, i); - - next_hop = nm_ip_route_get_next_hop (route); - if (!next_hop) - next_hop = "::"; - - g_string_append_printf (routes_string, "\"%s/%u via %s\" ", - nm_ip_route_get_dest (route), - nm_ip_route_get_prefix (route), - next_hop); - } - if (num > 0) - ifnet_set_data (conn_name, "routes", routes_string->str); - g_string_free (routes_string, TRUE); -} - -static gboolean -write_ip6_setting (NMConnection *connection, const char *conn_name, GError **error) -{ - NMSettingIPConfig *s_ip6; - const char *value; - guint32 i, num; - GString *searches; - NMIPAddress *addr; - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (!s_ip6) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing '%s' setting", - NM_SETTING_IP6_CONFIG_SETTING_NAME); - return FALSE; - } - - value = nm_setting_ip_config_get_method (s_ip6); - g_assert (value); - if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { - ifnet_set_data (conn_name, "enable_ipv6", "false"); - return TRUE; - } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { - /* nothing to do now */ - } else { - // if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { - const char *config = ifnet_get_data (conn_name, "config"); - gchar *tmp; - - if (!config) - tmp = g_strdup_printf ("dhcp6"); - else - tmp = g_strdup_printf ("%s\" \"dhcp6\"", config); - ifnet_set_data (conn_name, "config", tmp); - g_free (tmp); - } - /* else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { - } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) { - } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { - } */ - - /* Remember to set IPv6 enabled */ - ifnet_set_data (conn_name, "enable_ipv6", "true"); - - if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { - const char *config = ifnet_get_data (conn_name, "config"); - gchar *tmp; - GString *ip_str; - - if (!config) - config = ""; - num = nm_setting_ip_config_get_num_addresses (s_ip6); - - /* IPv6 addresses */ - ip_str = g_string_new (NULL); - for (i = 0; i < num; i++) { - addr = nm_setting_ip_config_get_address (s_ip6, i); - - g_string_append_printf (ip_str, "\"%s/%u\"", - nm_ip_address_get_address (addr), - nm_ip_address_get_prefix (addr)); - } - tmp = g_strdup_printf ("%s\" %s", config, ip_str->str); - ifnet_set_data (conn_name, "config", tmp); - g_free (tmp); - g_string_free (ip_str, TRUE); - } - - /* DNS Servers */ - num = nm_setting_ip_config_get_num_dns (s_ip6); - if (num > 0) { - const char *dns_servers = ifnet_get_data (conn_name, "dns_servers"); - gchar *tmp; - GString *dns_string = g_string_new (NULL); - const char *dns; - - if (!dns_servers) - dns_servers = ""; - for (i = 0; i < num; i++) { - dns = nm_setting_ip_config_get_dns (s_ip6, i); - - if (!strstr (dns_servers, dns)) - g_string_append_printf (dns_string, "%s ", dns); - } - tmp = g_strdup_printf ("%s %s", dns_servers, dns_string->str); - ifnet_set_data (conn_name, "dns_servers", tmp); - g_free (tmp); - g_string_free (dns_string, TRUE); - - } else - /* DNS Searches */ - num = nm_setting_ip_config_get_num_dns_searches (s_ip6); - if (num > 0) { - const char *ip4_domains; - - ip4_domains = ifnet_get_data (conn_name, "dns_search"); - if (!ip4_domains) - ip4_domains = ""; - searches = g_string_new (ip4_domains); - for (i = 0; i < num; i++) { - const gchar *search = NULL; - - search = - nm_setting_ip_config_get_dns_search (s_ip6, i); - if (search && !strstr (searches->str, search)) { - if (searches->len > 0) - g_string_append_c (searches, ' '); - g_string_append (searches, search); - } - } - ifnet_set_data (conn_name, "dns_search", searches->str); - g_string_free (searches, TRUE); - } - - write_route6_file (s_ip6, conn_name); - return TRUE; -} - -static gboolean -write_pppoe_setting (const char *conn_name, NMSettingPppoe * s_pppoe) -{ - const gchar *value; - - value = nm_setting_pppoe_get_username (s_pppoe); - if (!value) { - return FALSE; - } - ifnet_set_data (conn_name, "username", (gchar *) value); - - value = nm_setting_pppoe_get_password (s_pppoe); - /* password could be NULL here */ - if (value) { - ifnet_set_data (conn_name, "password", (gchar *) value); - } - return TRUE; -} - -gboolean -ifnet_update_parsers_by_connection (NMConnection *connection, - const char *conn_name, - const char *config_file, - const char *wpa_file, - gchar **out_new_name, - gchar **out_backup, - GError **error) -{ - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip6; - gboolean success = FALSE; - const char *type; - gboolean no_8021x = FALSE; - gboolean wired = FALSE, pppoe = TRUE; - const char *new_name = NULL; - - if (!ifnet_can_write_connection (connection, error)) - return FALSE; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - - type = nm_setting_connection_get_connection_type (s_con); - if (!type) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing connection type!"); - goto out; - } - - if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) { - /* Writing wired setting */ - if (!write_wired_setting (connection, conn_name, error)) - goto out; - wired = TRUE; - no_8021x = TRUE; - } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) { - /* Writing wireless setting */ - if (!write_wireless_setting (connection, conn_name, &no_8021x, &new_name, error)) - goto out; - } else if (!strcmp (type, NM_SETTING_PPPOE_SETTING_NAME)) { - NMSettingPppoe *s_pppoe; - - /* Writing pppoe setting */ - s_pppoe = nm_connection_get_setting_pppoe (connection); - if (!write_pppoe_setting (conn_name, s_pppoe)) - goto out; - pppoe = TRUE; - wired = TRUE; - no_8021x = TRUE; - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, - "Can't write connection type '%s'", type); - goto out; - } - - /* connection name may have been updated; use it when writing out - * the rest of the settings. - */ - if (new_name) - conn_name = new_name; - - //FIXME wired connection doesn't support 8021x now - if (!no_8021x) { - if (!write_8021x_setting (connection, conn_name, wired, error)) - goto out; - } - - /* IPv4 Setting */ - if (!write_ip4_setting (connection, conn_name, error)) - goto out; - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (s_ip6) { - /* IPv6 Setting */ - if (!write_ip6_setting (connection, conn_name, error)) - goto out; - } - - /* Connection Setting */ - ifnet_set_data (conn_name, "auto", - nm_setting_connection_get_autoconnect (s_con) ? "true" : "false"); - ifnet_set_data (conn_name, "uuid", nm_connection_get_uuid (connection)); - - /* Write changes to disk */ - success = ifnet_flush_to_file (config_file, out_backup); - if (success) - wpa_flush_to_file (wpa_file); - - if (out_new_name) - *out_new_name = g_strdup (conn_name); - -out: - return success; -} - -gboolean -ifnet_delete_connection_in_parsers (const char *conn_name, - const char *config_file, - const char *wpa_file, - gchar **out_backup) -{ - gboolean result = FALSE; - - ifnet_delete_network (conn_name); - result = ifnet_flush_to_file (config_file, out_backup); - if (result) { - /* connection may not have security information - * so simply ignore the return value*/ - wpa_delete_security (conn_name); - wpa_flush_to_file (wpa_file); - } - - return result; -} - -static void -check_unsupported_secrets (NMSetting *setting, - const char *key, - const GValue *value, - GParamFlags flags, - gpointer user_data) -{ - gboolean *unsupported_secret = user_data; - - if (flags & NM_SETTING_PARAM_SECRET) { - NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; - - if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) - g_return_if_reached (); - if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) - *unsupported_secret = TRUE; - } -} - -gboolean -ifnet_can_write_connection (NMConnection *connection, GError **error) -{ - NMSettingConnection *s_con; - gboolean has_unsupported_secrets = FALSE; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - - /* If the connection is not available for all users, ignore - * it as this plugin only deals with System Connections */ - if (nm_setting_connection_get_num_permissions (s_con)) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, - "The ifnet plugin does not support non-system-wide connections."); - return FALSE; - } - - /* Only support wired, wifi, and PPPoE */ - if ( !nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME) - && !nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME) - && !nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, - "The ifnet plugin cannot write the connection '%s' (type '%s')", - nm_connection_get_id (connection), - nm_setting_connection_get_connection_type (s_con)); - return FALSE; - } - - /* If the connection has flagged secrets, ignore - * it as this plugin does not deal with user agent service */ - nm_connection_for_each_setting_value (connection, - check_unsupported_secrets, - &has_unsupported_secrets); - if (has_unsupported_secrets) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, - "The ifnet plugin only supports persistent system secrets."); - return FALSE; - } - - return TRUE; -} - -/* get the available wired name(eth*). */ -static gchar * -get_wired_name (void) -{ - int i = 0; - - for (; i < 256; i++) { - gchar *conn_name = g_strdup_printf ("eth%d", i); - - if (!ifnet_has_network (conn_name)) { - return conn_name; - } else - g_free (conn_name); - } - return NULL; -} - -/* get the available pppoe name(ppp*). */ -static gchar * -get_ppp_name (void) -{ - int i = 0; - - for (; i < 256; i++) { - gchar *conn_name = g_strdup_printf ("ppp%d", i); - - if (!ifnet_has_network (conn_name)) { - return conn_name; - } else - g_free (conn_name); - } - return NULL; -} - -/* get wireless ssid */ -static gchar * -get_wireless_name (NMConnection * connection) -{ - NMSettingWireless *s_wireless; - GBytes *ssid; - const guint8 *ssid_data; - gsize ssid_len; - gboolean hex_ssid = FALSE; - gchar *result = NULL; - char buf[33]; - int i = 0; - - s_wireless = nm_connection_get_setting_wireless (connection); - if (!s_wireless) - return NULL; - - ssid = nm_setting_wireless_get_ssid (s_wireless); - ssid_data = g_bytes_get_data (ssid, &ssid_len); - if (!ssid_len || ssid_len > 32) { - return NULL; - } - - for (i = 0; i < ssid_len; i++) { - if (!g_ascii_isprint (ssid_data[i])) { - hex_ssid = TRUE; - break; - } - } - - if (hex_ssid) { - GString *str; - - 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]); - result = g_strdup (str->str); - g_string_free (str, TRUE); - } else { - memset (buf, 0, sizeof (buf)); - memcpy (buf, ssid_data, ssid_len); - result = g_strdup_printf ("%s", buf); - g_strstrip (result); - } - - return result; -} - -gboolean -ifnet_add_new_connection (NMConnection *connection, - const char *config_file, - const char *wpa_file, - gchar **out_new_name, - gchar **out_backup, - GError **error) -{ - NMSettingConnection *s_con; - gboolean success = FALSE; - const char *type; - gchar *new_type, *new_name = NULL; - - if (!ifnet_can_write_connection (connection, error)) - return FALSE; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - type = nm_setting_connection_get_connection_type (s_con); - g_assert (type); - - nm_log_info (LOGD_SETTINGS, "Adding %s connection", type); - - /* get name and type - * Wireless type: wireless - * Wired type: wired - * PPPoE type: ppp*/ - if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) { - new_name = get_wired_name (); - if (!new_name) - goto out; - new_type = "wired"; - } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) { - new_name = get_wireless_name (connection); - new_type = "wireless"; - } else if (!strcmp (type, NM_SETTING_PPPOE_SETTING_NAME)) { - new_name = get_ppp_name (); - if (!new_name) - goto out; - new_type = "ppp"; - } else { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, - "Can't write connection type '%s'", type); - goto out; - } - - if (ifnet_add_network (new_name, new_type)) { - success = ifnet_update_parsers_by_connection (connection, - new_name, - config_file, - wpa_file, - NULL, - out_backup, - error); - } - - nm_log_info (LOGD_SETTINGS, "Added new connection: %s, result: %s", - new_name, success ? "success" : "fail"); - -out: - if (!success || !out_new_name) - g_free (new_name); - else if (out_new_name) - *out_new_name = new_name; - return success; -} - diff --git a/src/settings/plugins/ifnet/nms-ifnet-connection-parser.h b/src/settings/plugins/ifnet/nms-ifnet-connection-parser.h deleted file mode 100644 index 51bc34b9..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-connection-parser.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#ifndef _CONNECTION_PARSER_H -#define _CONNECTION_PARSER_H - -#include "nm-connection.h" - -#include "nms-ifnet-net-parser.h" - -gboolean ifnet_can_write_connection (NMConnection *connection, GError **error); - -NMConnection *ifnet_update_connection_from_config_block (const char *conn_name, - const char *basepath, - GError **error); - -/* nm_conn_name is used to update nm_ifnet_connection's priv data */ -gboolean ifnet_update_parsers_by_connection (NMConnection *connection, - const char *conn_name, - const char *config_file, - const char *wpa_file, - gchar **out_new_name, - gchar **out_backup, - GError **error); - -gboolean ifnet_delete_connection_in_parsers (const char *conn_name, - const char *config_file, - const char *wpa_file, - gchar **out_backup); - -gboolean ifnet_add_new_connection (NMConnection *connection, - const char *config_file, - const char *wpa_file, - gchar **out_new_name, - gchar **out_backup, - GError ** error); -#endif diff --git a/src/settings/plugins/ifnet/nms-ifnet-connection.c b/src/settings/plugins/ifnet/nms-ifnet-connection.c deleted file mode 100644 index ce0b3f2b..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-connection.c +++ /dev/null @@ -1,233 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#include "nm-default.h" - -#include "nms-ifnet-connection.h" - -#include -#include - -#include "nm-dbus-interface.h" -#include "nm-utils.h" -#include "nm-setting-wireless-security.h" -#include "settings/nm-settings-connection.h" -#include "settings/nm-settings-plugin.h" - -#include "nms-ifnet-connection-parser.h" -#include "nms-ifnet-net-parser.h" -#include "nms-ifnet-net-utils.h" -#include "nms-ifnet-wpa-parser.h" -#include "nms-ifnet-plugin.h" - -/*****************************************************************************/ - -enum { - IFNET_SETUP_MONITORS, - IFNET_CANCEL_MONITORS, - IFNET_LAST_SIGNAL -}; - -static guint signals[IFNET_LAST_SIGNAL] = { 0 }; - -typedef struct { - gchar *conn_name; - NMSettingsPlugin *config; -} NMIfnetConnectionPrivate; - -struct _NMIfnetConnection { - NMSettingsConnection parent; - NMIfnetConnectionPrivate _priv; -}; - -struct _NMIfnetConnectionClass { - NMSettingsConnectionClass parent; -}; - -G_DEFINE_TYPE (NMIfnetConnection, nm_ifnet_connection, NM_TYPE_SETTINGS_CONNECTION) - -#define NM_IFNET_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMIfnetConnection, NM_IS_IFNET_CONNECTION) - -/*****************************************************************************/ - -const char * -nm_ifnet_connection_get_conn_name (NMIfnetConnection *connection) -{ - return NM_IFNET_CONNECTION_GET_PRIVATE (connection)->conn_name; -} - -static gboolean -commit_changes (NMSettingsConnection *connection, - NMConnection *new_connection, - NMSettingsConnectionCommitReason commit_reason, - NMConnection **out_reread_connection, - char **out_logmsg_change, - GError **error) -{ - NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) connection); - char *new_name = NULL; - gboolean success = FALSE; - gboolean added = FALSE; - - nm_assert (out_reread_connection && !*out_reread_connection); - nm_assert (!out_logmsg_change || !*out_logmsg_change); - - g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0); - - if (priv->conn_name) { - success = ifnet_update_parsers_by_connection (new_connection, - priv->conn_name, - CONF_NET_FILE, - WPA_SUPPLICANT_CONF, - &new_name, - NULL, - error); - } else { - added = TRUE; - success = ifnet_add_new_connection (new_connection, - CONF_NET_FILE, - WPA_SUPPLICANT_CONF, - &new_name, - NULL, - error); - } - - g_assert (!!success == (new_name != NULL)); - if (success) { - g_free (priv->conn_name); - priv->conn_name = new_name; - } - - reload_parsers (); - - g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); - - if (success) { - NM_SET_OUT (out_logmsg_change, - g_strdup_printf ("ifcfg-rh: %s %s", - added ? "persist" : "updated", - new_name)); - } - return success; -} - -static gboolean -delete (NMSettingsConnection *connection, - GError **error) -{ - NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) connection); - - /* Only connections which exist in /etc/conf.d/net will have a conn_name */ - if (priv->conn_name) { - g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0); - - if (!ifnet_delete_connection_in_parsers (priv->conn_name, CONF_NET_FILE, WPA_SUPPLICANT_CONF, NULL)) { - nm_log_warn (LOGD_SETTINGS, "Failed to delete %s", priv->conn_name); - reload_parsers (); - /* let's not return an error. */ - } - - g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); - } - - return TRUE; -} - -/*****************************************************************************/ - -static void -nm_ifnet_connection_init (NMIfnetConnection * connection) -{ -} - -NMIfnetConnection * -nm_ifnet_connection_new (NMConnection *source, const char *conn_name) -{ - NMConnection *tmp; - GObject *object; - GError *error = NULL; - gboolean update_unsaved = TRUE; - - g_return_val_if_fail (source || conn_name, NULL); - - if (source) - tmp = g_object_ref (source); - else { - tmp = ifnet_update_connection_from_config_block (conn_name, NULL, &error); - if (!tmp) { - nm_log_warn (LOGD_SETTINGS, "Could not read connection '%s': %s", - conn_name, error->message); - g_error_free (error); - return NULL; - } - - /* If we just read the connection from disk, it's clearly not Unsaved */ - update_unsaved = FALSE; - } - - object = (GObject *) g_object_new (NM_TYPE_IFNET_CONNECTION, NULL); - - NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) object)->conn_name = g_strdup (conn_name); - if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (object), - tmp, - update_unsaved - ? NM_SETTINGS_CONNECTION_PERSIST_MODE_UNSAVED - : NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP_SAVED, - NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, - NULL, - NULL)) { - g_object_unref (object); - return NULL; - } - g_object_unref (tmp); - - return NM_IFNET_CONNECTION (object); -} - -static void -finalize (GObject * object) -{ - g_free (NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) object)->conn_name); - G_OBJECT_CLASS (nm_ifnet_connection_parent_class)->finalize (object); -} - -static void -nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (ifnet_connection_class); - NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (ifnet_connection_class); - - object_class->finalize = finalize; - - settings_class->delete = delete; - settings_class->commit_changes = commit_changes; - - signals[IFNET_SETUP_MONITORS] = - g_signal_new ("ifnet_setup_monitors", - G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[IFNET_CANCEL_MONITORS] = - g_signal_new ("ifnet_cancel_monitors", - G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} diff --git a/src/settings/plugins/ifnet/nms-ifnet-connection.h b/src/settings/plugins/ifnet/nms-ifnet-connection.h deleted file mode 100644 index 1bc06644..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-connection.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#ifndef __NETWORKMANAGER_IFNET_CONNECTION_H__ -#define __NETWORKMANAGER_IFNET_CONNECTION_H__ - -#include "settings/nm-settings-connection.h" - -#include "nms-ifnet-net-parser.h" - -#define NM_TYPE_IFNET_CONNECTION (nm_ifnet_connection_get_type ()) -#define NM_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnection)) -#define NM_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass)) -#define NM_IS_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFNET_CONNECTION)) -#define NM_IS_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IFNET_CONNECTION)) -#define NM_IFNET_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass)) - -typedef struct _NMIfnetConnection NMIfnetConnection; -typedef struct _NMIfnetConnectionClass NMIfnetConnectionClass; - -GType nm_ifnet_connection_get_type (void); - -NMIfnetConnection *nm_ifnet_connection_new (NMConnection *source, - const char *conn_name); - -const char *nm_ifnet_connection_get_conn_name (NMIfnetConnection *connection); - -#endif /* __NETWORKMANAGER_IFNET_CONNECTION_H__ */ diff --git a/src/settings/plugins/ifnet/nms-ifnet-net-parser.c b/src/settings/plugins/ifnet/nms-ifnet-net-parser.c deleted file mode 100644 index d3e47219..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-net-parser.c +++ /dev/null @@ -1,734 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#include "nm-default.h" - -#include "nms-ifnet-net-parser.h" - -#include -#include -#include -#include - -#include "settings/nm-settings-plugin.h" -#include "platform/nm-platform.h" - -#include "nms-ifnet-plugin.h" -#include "nms-ifnet-net-utils.h" - -/* Save all the connection information */ -static GHashTable *conn_table; - -/* Save global settings which are used for writing*/ -static GHashTable *global_settings_table; - -/* Save functions */ -static GList *functions_list; - -/* Used to decide whether to write changes to file*/ -static gboolean net_parser_data_changed = FALSE; - -static GHashTable * -add_new_connection_config (const gchar * type, const gchar * name) -{ - GHashTable *new_conn; - gchar *new_name; - - if (!name) - return NULL; - - /* Return existing connection */ - if ((new_conn = g_hash_table_lookup (conn_table, name)) != NULL) - return new_conn; - new_conn = g_hash_table_new (nm_str_hash, g_str_equal); - new_name = g_strdup (name); - g_hash_table_insert (new_conn, g_strdup ("name"), new_name); - g_hash_table_insert (new_conn, g_strdup ("type"), g_strdup (type)); - g_hash_table_insert (conn_table, new_name, new_conn); - return new_conn; -} - -gboolean -ifnet_add_network (const char *name, const char *type) -{ - if (ifnet_has_network (name)) - return TRUE; - if (add_new_connection_config (type, name)) { - nm_log_info (LOGD_SETTINGS, "Adding network for %s", name); - net_parser_data_changed = TRUE; - return TRUE; - } - return FALSE; -} - -gboolean -ifnet_has_network (const char *conn_name) -{ - return g_hash_table_lookup (conn_table, conn_name) != NULL; -} - -static GHashTable * -get_connection_config (const char *name) -{ - return g_hash_table_lookup (conn_table, name); -} - -/* Ignored name won't be treated as wireless ssid */ -static gchar *ignore_name[] = { - "vlan", "bond", "atm", "ath", "ippp", "vpn", "tap", "tun", "1", - "br", "nas", "6to4", "timeout", "kvm", "force", NULL -}; - -static gboolean -ignore_connection_name (const char *name) -{ - gboolean result = FALSE; - guint i = 0; - - /* check ignore_name list */ - while (ignore_name[i] != NULL) { - if (g_ascii_strncasecmp - (name, ignore_name[i], strlen (ignore_name[i])) == 0) { - return TRUE; - } - i++; - } - /* Ignore mac address based configuration */ - if (strlen (name) == 12 && is_hex (name)) - result = TRUE; - return result; -} - -static gboolean -is_global_setting (char *key) -{ - static gchar *global_settings[] = { "wpa_supplicant_", NULL }; - int i; - - for (i = 0; global_settings[i] != NULL; i++) { - if (strstr (key, global_settings[i])) - return 1; - } - return 0; -} - -/* Parse a complete line */ -/* Connection type is determined here */ -static void -init_block_by_line (gchar * buf) -{ - gchar **key_value; - gchar *pos; - gchar *data; - gchar *tmp; - GHashTable *conn; - - key_value = g_strsplit (buf, "=", 2); - if (g_strv_length (key_value) != 2) { - nm_log_warn (LOGD_SETTINGS, "Can't handle this line: %s\n", buf); - g_strfreev (key_value); - return; - } - pos = g_strrstr (key_value[0], "_"); - if (pos == NULL || is_global_setting (key_value[0])) { - /* global data */ - data = g_strdup (key_value[1]); - tmp = strip_string (data, '"'); - strip_string (tmp, '\''); - nm_log_info (LOGD_SETTINGS, "global:%s-%s\n", key_value[0], tmp); - g_hash_table_insert (global_settings_table, g_strdup (key_value[0]), g_strdup (tmp)); - g_strfreev (key_value); - g_free (data); - return; - } - *pos++ = '\0'; - if ((conn = get_connection_config (pos)) == NULL) { - if (g_ascii_strncasecmp (pos, "eth", 3) == 0 - && strlen (pos) == 4) - /* wired connection */ - conn = add_new_connection_config ("wired", pos); - else if (g_ascii_strncasecmp (pos, "ppp", 3) == 0 - && strlen (pos) == 4) - /* pppoe connection */ - conn = add_new_connection_config ("ppp", pos); - else if (ignore_connection_name (pos)) { - /* ignored connection */ - conn = add_new_connection_config ("ignore", pos); - } else { - int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, pos); - - if (ifindex && nm_platform_link_get_type (NM_PLATFORM_GET, ifindex) != NM_LINK_TYPE_WIFI) - /* wired connection */ - conn = add_new_connection_config ("wired", pos); - else - /* wireless connection */ - conn = add_new_connection_config ("wireless", pos); - } - } - data = g_strdup (key_value[1]); - tmp = strip_string (data, '"'); - strip_string (tmp, '\''); - if (conn) - g_hash_table_insert (conn, strip_string (g_strdup (key_value[0]), ' '), - g_strdup (tmp)); - g_free (data); - g_strfreev (key_value); -} - -static void -destroy_connection_config (GHashTable * conn) -{ - gpointer key, value; - GHashTableIter iter; - - g_hash_table_iter_init (&iter, conn); - while (g_hash_table_iter_next (&iter, &key, &value)) { - g_free (key); - g_free (value); - } - - g_hash_table_destroy (conn); -} - -static void -strip_function (GIOChannel * channel, gchar * line) -{ - - int counter = 0; - gchar *p, *tmp; - gboolean begin = FALSE; - GString *function_str = g_string_new (line); - - g_string_append (function_str, "\n"); - while (1) { - p = line; - while (*p != '\0') { - if (*p == '{') { - counter++; - begin = TRUE; - } else if (*p == '}') - counter--; - p++; - } - if (begin && counter == 0) { - g_free (line); - goto done; - } - while (1) { - g_free (line); - if (g_io_channel_read_line - (channel, &line, NULL, NULL, - NULL) == G_IO_STATUS_EOF) - goto done; - g_string_append (function_str, line); - tmp = g_strdup (line); - g_strstrip (tmp); - if (tmp[0] != '#' && tmp[0] != '\0') { - g_free (tmp); - break; - } else - g_free (tmp); - } - } -done: - functions_list = - g_list_append (functions_list, g_strdup (function_str->str)); - g_string_free (function_str, TRUE); -} - -static gboolean -is_function (gchar * line) -{ - static gchar *func_names[] = - { "preup", "predown", "postup", "postdown", "failup", "faildown", - NULL, - }; - int i; - - for (i = 0; func_names[i]; i++) { - if (g_str_has_prefix (line, func_names[i])) { - nm_log_info (LOGD_SETTINGS, "Ignoring function: %s", func_names[i]); - return TRUE; - } - } - return FALSE; -} - -static void -append_line (GString *buf, gchar* line) -{ - gchar *pos = NULL; - - if ((pos = strchr (line, '#')) != NULL) - *pos = '\0'; - g_strstrip (line); - - if (line[0] != '\0') - g_string_append_printf (buf, " %s", line); - g_free (line); -} - -gboolean -ifnet_init (gchar * config_file) -{ - GIOChannel *channel = NULL; - gchar *line; - - /* Handle multiple lines with brackets */ - gboolean complete = TRUE; - - gboolean openrc_style = TRUE; - - /* line buffer */ - GString *buf; - - net_parser_data_changed = FALSE; - - conn_table = g_hash_table_new (nm_str_hash, g_str_equal); - global_settings_table = g_hash_table_new (nm_str_hash, g_str_equal); - functions_list = NULL; - - if (g_file_test (config_file, G_FILE_TEST_IS_REGULAR)) - channel = g_io_channel_new_file (config_file, "r", NULL); - if (channel == NULL) { - nm_log_warn (LOGD_SETTINGS, "Can't open %s", config_file); - return FALSE; - } - - buf = g_string_new (NULL); - while (g_io_channel_read_line - (channel, &line, NULL, NULL, NULL) != G_IO_STATUS_EOF) { - g_strstrip (line); - /* convert multiple lines to a complete line and - * pass it to init_block_by_line() */ - if (is_function (line)) { - strip_function (channel, line); - continue; - } - - // New openrc style, bash arrays are not allowed. We only care about '"' - if (openrc_style && line[0] != '#' && line[0] != '\0' - && !strchr (line, '(') && !strchr (line, ')')) { - gchar *tmp = line; - - while ((tmp = strchr (tmp, '"')) != NULL) { - complete = !complete; - ++tmp; - } - - append_line (buf, line); - // Add "(separator) for routes. It will be easier for later parsing - if (strstr (buf->str, "via")) - g_string_append_printf (buf, "\""); - - if (!complete) - continue; - - strip_string (buf->str, '"'); - - init_block_by_line (buf->str); - g_string_free (buf, TRUE); - buf = g_string_new (NULL); - } - // Old bash arrays for baselayout-1, to be deleted - else if (line[0] != '#' && line[0] != '\0') { - if (!complete) { - complete = - g_strrstr (line, - ")") == NULL ? FALSE : TRUE; - - append_line (buf, line); - if (!complete) { - openrc_style = FALSE; - continue; - } - else { - openrc_style = TRUE; - } - } else { - complete = - (g_strrstr (line, "(") != NULL - && g_strrstr (line, ")") != NULL) - || g_strrstr (line, "(") == NULL; - - append_line (buf, line); - if (!complete) - { - openrc_style = FALSE; - continue; - } else { - openrc_style = TRUE; - } - } - init_block_by_line (buf->str); - g_string_free (buf, TRUE); - buf = g_string_new (NULL); - } else - /* Blank line or comment line */ - g_free (line); - } - - g_string_free (buf, TRUE); - g_io_channel_shutdown (channel, FALSE, NULL); - g_io_channel_unref (channel); - return TRUE; -} - -const char * -ifnet_get_data (const char *conn_name, const char *key) -{ - GHashTable *conn; - - g_return_val_if_fail (conn_name && key, NULL); - - conn = g_hash_table_lookup (conn_table, conn_name); - - if (conn) - return g_hash_table_lookup (conn, key); - return NULL; -} - -/* format ip values for comparison */ -static gchar* -format_ip_for_comparison (const gchar * value) -{ - gchar **ipset; - guint length, i; - GString *formated_string = g_string_new (NULL); - gchar *formatted = NULL; - - ipset = g_strsplit (value, "\"", 0); - length = g_strv_length (ipset); - - for (i = 0; i < length; i++) - { - strip_string (ipset[i], ' '); - if (ipset[i][0] != '\0') - g_string_append_printf (formated_string, - "%s ", ipset[i]); - } - formatted = g_strdup (formated_string->str); - formatted[formated_string->len - 1] = '\0'; - - g_string_free (formated_string, TRUE); - g_strfreev (ipset); - - return formatted; -} - -void -ifnet_set_data (const char *conn_name, const char *key, const char *value) -{ - gpointer old_key = NULL, old_value = NULL; - GHashTable *conn = g_hash_table_lookup (conn_table, conn_name); - gchar * stripped = NULL; - - if (!conn) { - nm_log_warn (LOGD_SETTINGS, "%s does not exist!", conn_name); - return; - } - if (value){ - stripped = g_strdup (value); - strip_string (stripped, '"'); - } - /* Remove existing key value pair */ - if (g_hash_table_lookup_extended (conn, key, &old_key, &old_value)) { - - /* This ugly hack is due to baselayout compatibility. We have to - * deal with different ip format. So sometimes we have the same ips - * but different strings. - */ - if (stripped && - (!strcmp (key, "config") - || !strcmp (key, "routes") - || !strcmp (key, "pppd") - || !strcmp (key, "chat"))) - { - gchar *old_ips = format_ip_for_comparison (old_value); - gchar *new_ips = format_ip_for_comparison (value); - if(!strcmp (old_ips, new_ips)) - { - g_free (stripped); - g_free (old_ips); - g_free (new_ips); - return; - } - g_free (old_ips); - g_free (new_ips); - } - - if (stripped && !strcmp (old_value, stripped)) { - g_free (stripped); - return; - } - g_hash_table_remove (conn, old_key); - g_free (old_key); - g_free (old_value); - } else if (!value) - return; - if (stripped) - g_hash_table_insert (conn, g_strdup (key), stripped); - net_parser_data_changed = TRUE; -} - -// Remember to free return value -const char * -ifnet_get_global_data (const gchar * key) -{ - return g_hash_table_lookup (global_settings_table, key); -} - -// Return names of legal connections -GList * -ifnet_get_connection_names (void) -{ - GList *names = g_hash_table_get_keys (conn_table); - GList *iter, *result = NULL; - - for (iter = names; iter; iter = iter->next) { - if (!ignore_connection_name (iter->data)) - result = g_list_prepend (result, iter->data); - } - - g_list_free (names); - return g_list_reverse (result); -} - -/* format IP and route for writing */ -static void -format_ips (gchar * value, gchar ** out_line, gchar * key, gchar * name) -{ - gchar **ipset; - guint length, i; - GString *formated_string = g_string_new (NULL); - - strip_string (value, '('); - strip_string (value, ')'); - strip_string (value, '"'); - ipset = g_strsplit (value, "\"", 0); - length = g_strv_length (ipset); - - //only one line - if (length < 2) { - *out_line = - g_strdup_printf ("%s_%s=\"%s\"\n", key, name, value); - goto done; - } - // Multiple lines - g_string_append_printf (formated_string, "%s_%s=\"\n", key, name); - for (i = 0; i < length; i++) - { - strip_string (ipset[i], ' '); - if (ipset[i][0] != '\0') - g_string_append_printf (formated_string, - "%s\n", ipset[i]); - } - g_string_append (formated_string, "\"\n"); - *out_line = g_strdup (formated_string->str); -done: - g_string_free (formated_string, TRUE); - g_strfreev (ipset); -} - -gboolean -ifnet_flush_to_file (const char *config_file, gchar **out_backup) -{ - GIOChannel *channel; - GError *error = NULL; - gpointer key, value, name, network; - GHashTableIter iter, iter_network; - GList *list_iter; - gchar *out_line = NULL; - gsize bytes_written; - gboolean result = FALSE; - gchar *backup; - - if (!net_parser_data_changed) - return TRUE; - if (!conn_table || !global_settings_table) - return FALSE; - - backup = backup_file (config_file); - - channel = g_io_channel_new_file (config_file, "w", NULL); - if (!channel) { - nm_log_warn (LOGD_SETTINGS, "Can't open file %s for writing", config_file); - g_free (backup); - return FALSE; - } - g_hash_table_iter_init (&iter, global_settings_table); - nm_log_info (LOGD_SETTINGS, "Writing to %s", config_file); - g_io_channel_write_chars (channel, - "#Generated by NetworkManager\n" - "###### Global Configuration ######\n", - -1, &bytes_written, &error); - if (error) - goto done; - - /* Writing global data */ - while (g_hash_table_iter_next (&iter, &key, &value)) { - out_line = - g_strdup_printf ("%s=\"%s\"\n", (gchar *) key, (gchar *) value); - g_io_channel_write_chars (channel, out_line, -1, - &bytes_written, &error); - if (bytes_written == 0 || error) - goto done; - g_free (out_line); - } - - /* Writing connection data */ - g_io_channel_write_chars (channel, - "\n###### Connection Configuration ######\n", - -1, &bytes_written, &error); - if (error) - goto done; - - g_hash_table_iter_init (&iter, conn_table); - while (g_hash_table_iter_next (&iter, &name, &network)) { - g_hash_table_iter_init (&iter_network, (GHashTable *) network); - g_io_channel_write_chars (channel, - "#----------------------------------\n", - -1, &bytes_written, &error); - if (error) - goto done; - - while (g_hash_table_iter_next (&iter_network, &key, &value)) { - if (!g_str_has_prefix ((gchar *) key, "name") - && !g_str_has_prefix ((gchar *) key, "type")) { - /* These keys contain brackets */ - if (strcmp - ((gchar *) key, - "config") == 0 - || strcmp ((gchar *) key, - "routes") == 0 - || strcmp ((gchar *) key, - "pppd") == 0 - || strcmp ((gchar *) key, "chat") == 0) - format_ips (value, &out_line, (gchar *) - key, (gchar *) - name); - else - out_line = - g_strdup_printf - ("%s_%s=\"%s\"\n", - (gchar *) key, - (gchar *) name, (gchar *) value); - g_io_channel_write_chars (channel, out_line, -1, &bytes_written, &error); - if (bytes_written == 0 || error) - goto done; - g_free (out_line); - } - } - } - - /* Writing reserved functions */ - if (functions_list) { - g_io_channel_write_chars (channel, - "\n###### Reserved Functions ######\n", - -1, &bytes_written, &error); - if (error) - goto done; - - /* Writing functions */ - for (list_iter = functions_list; list_iter; - list_iter = g_list_next (list_iter)) { - out_line = - g_strdup_printf ("%s\n", (gchar *) list_iter->data); - g_io_channel_write_chars (channel, out_line, -1, - &bytes_written, &error); - if (bytes_written == 0 || error) - goto done; - g_free (out_line); - } - } - - g_io_channel_flush (channel, &error); - if (error) - goto done; - result = TRUE; - net_parser_data_changed = FALSE; - -done: - if (error) { - nm_log_warn (LOGD_SETTINGS, "Error writing the configuration file: %s", error->message); - g_error_free (error); - } - - if (result && out_backup) - *out_backup = backup; - else - g_free (backup); - - g_io_channel_shutdown (channel, FALSE, NULL); - g_io_channel_unref (channel); - return result; -} - -gboolean -ifnet_delete_network (const char *conn_name) -{ - GHashTable *network = NULL; - - g_return_val_if_fail (conn_table != NULL && conn_name != NULL, FALSE); - nm_log_info (LOGD_SETTINGS, "Deleting network for %s", conn_name); - network = g_hash_table_lookup (conn_table, conn_name); - if (!network) - return FALSE; - g_hash_table_remove (conn_table, conn_name); - destroy_connection_config (network); - net_parser_data_changed = TRUE; - return TRUE; -} - -void -ifnet_destroy (void) -{ - GHashTableIter iter; - gpointer key; - gpointer value; - GList *list_iter; - - /* Destroy connection setting */ - if (conn_table) { - g_hash_table_iter_init (&iter, conn_table); - while (g_hash_table_iter_next (&iter, &key, &value)) { - destroy_connection_config ((GHashTable *) - value); - } - g_hash_table_destroy (conn_table); - conn_table = NULL; - } - - /* Destroy global data */ - if (global_settings_table) { - g_hash_table_iter_init (&iter, global_settings_table); - while (g_hash_table_iter_next (&iter, &key, &value)) { - g_free (key); - g_free (value); - } - g_hash_table_destroy (global_settings_table); - global_settings_table = NULL; - } - for (list_iter = functions_list; list_iter; - list_iter = g_list_next (list_iter)) - g_free (list_iter->data); - g_list_free (functions_list); -} diff --git a/src/settings/plugins/ifnet/nms-ifnet-net-parser.h b/src/settings/plugins/ifnet/nms-ifnet-net-parser.h deleted file mode 100644 index 31fc9ead..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-net-parser.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#ifndef _NET_PARSER_H -#define _NET_PARSER_H - -#define CONF_NET_FILE SYSCONFDIR "/conf.d/net" - -gboolean ifnet_init (gchar * config_file); -void ifnet_destroy (void); - -/* Reader functions */ -GList *ifnet_get_connection_names (void); -const char *ifnet_get_data (const char *conn_name, const char *key); -const char *ifnet_get_global_data (const char *key); -gboolean ifnet_has_network (const char *conn_name); - -/* Writer functions */ -gboolean ifnet_flush_to_file (const char *config_file, gchar **out_backup); -void ifnet_set_data (const char *conn_name, const char *key, const char *value); -gboolean ifnet_add_network (const char *name, const char *type); -gboolean ifnet_delete_network (const char *conn_name); - -#endif diff --git a/src/settings/plugins/ifnet/nms-ifnet-net-utils.c b/src/settings/plugins/ifnet/nms-ifnet-net-utils.c deleted file mode 100644 index 6531a238..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-net-utils.c +++ /dev/null @@ -1,830 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#include "nm-default.h" - -#include "nms-ifnet-net-utils.h" - -#include -#include -#include -#include - -#include "nm-utils.h" -#include "NetworkManagerUtils.h" -#include "settings/nm-settings-plugin.h" -#include "nm-config.h" -#include "dhcp/nm-dhcp-manager.h" - -#include "nms-ifnet-wpa-parser.h" -#include "nms-ifnet-net-parser.h" - -/* emit heading and tailing blank space, tab, character t */ -gchar * -strip_string (gchar * str, gchar t) -{ - gchar *ret = str; - gint length = 0; - guint i = 0; - - while (ret[i] != '\0' - && (ret[i] == '\t' || ret[i] == ' ' || ret[i] == t)) { - length++; - i++; - } - i = 0; - while (ret[i + length] != '\0') { - ret[i] = ret[i + length]; - i++; - } - ret[i] = '\0'; - length = strlen (ret); - while ((length - 1) >= 0 - && (ret[length - 1] == ' ' || ret[length - 1] == '\n' - || ret[length - 1] == '\t' || ret[length - 1] == t)) - length--; - ret[length] = '\0'; - return ret; -} - -gboolean -is_hex (const char *value) -{ - const char *p = value; - - if (!p) - return FALSE; - while (*p) { - if (!g_ascii_isxdigit (*p++)) - return FALSE; - } - return TRUE; -} - -gboolean -is_ascii (const char *value) -{ - const char *p = value; - - while (*p) { - if (!g_ascii_isprint (*p++)) - return FALSE; - } - return TRUE; - -} - -gboolean -is_true (const char *str) -{ - if (!g_ascii_strcasecmp (str, "yes") - || !g_ascii_strcasecmp (str, "true")) - return TRUE; - return FALSE; -} - -static char * -find_default_gateway_str (char *str) -{ - char *tmp; - - if ((tmp = strstr (str, "default via ")) != NULL) { - return tmp + strlen ("default via "); - } else if ((tmp = strstr (str, "default gw ")) != NULL) { - return tmp + strlen ("default gw "); - } - return NULL; -} - -static char * -find_gateway_str (char *str) -{ - char *tmp; - - if ((tmp = strstr (str, "via ")) != NULL) { - return tmp + strlen ("via "); - } else if ((tmp = strstr (str, "gw ")) != NULL) { - return tmp + strlen ("gw "); - } - return NULL; -} - -gboolean -reload_parsers (void) -{ - ifnet_destroy (); - wpa_parser_destroy (); - if (!ifnet_init (CONF_NET_FILE)) - return FALSE; - wpa_parser_init (WPA_SUPPLICANT_CONF); - return TRUE; -} - -gboolean -is_static_ip4 (const char *conn_name) -{ - const char *data = ifnet_get_data (conn_name, "config"); - const char *dhcp6; - - if (!data) - return FALSE; - if (!strcmp (data, "shared")) - return FALSE; - if (!strcmp (data, "autoip")) - return FALSE; - dhcp6 = strstr (data, "dhcp6"); - if (dhcp6) { - gchar *dhcp4; - - if (strstr (data, "dhcp ")) - return FALSE; - dhcp4 = strstr (data, "dhcp"); - if (!dhcp4) - return TRUE; - if (dhcp4[4] == '\0') - return FALSE; - return TRUE; - } - return strstr (data, "dhcp") == NULL ? TRUE : FALSE; -} - -gboolean -is_static_ip6 (const char *conn_name) -{ - const char *data = ifnet_get_data (conn_name, "config"); - - if (!data) - return TRUE; - return strstr (data, "dhcp6") == NULL ? TRUE : FALSE; -} - -gboolean -is_ip4_address (const char *in_address) -{ - const char *pattern = - "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.((\\{\\d{1,3}\\.\\.\\d{1,3}\\})|\\d{1,3})$"; - gchar *address = g_strdup (in_address); - gboolean result = FALSE; - gchar *tmp; - GRegex *regex = g_regex_new (pattern, 0, 0, NULL); - GMatchInfo *match_info = NULL; - - if (!address) - goto done; - g_strstrip (address); - if ((tmp = strstr (address, "/")) != NULL) - *tmp = '\0'; - if ((tmp = strstr (address, " ")) != NULL) - *tmp = '\0'; - g_regex_match (regex, address, 0, &match_info); - result = g_match_info_matches (match_info); -done: - if (match_info) - g_match_info_free (match_info); - g_regex_unref (regex); - g_free (address); - return result; -} - -gboolean -is_ip6_address (const char *in_address) -{ - struct in6_addr tmp_ip6_addr; - gchar *tmp, *address; - gboolean result = FALSE; - - if (!in_address) - return FALSE; - address = g_strdup (in_address); - g_strstrip (address); - if ((tmp = strchr (address, '/')) != NULL) - *tmp = '\0'; - if (inet_pton (AF_INET6, address, &tmp_ip6_addr)) - result = TRUE; - g_free (address); - return result; - -} - -// 'c' is only used for openrc style -static gchar ** -split_addresses_by_char (const gchar *addresses, const gchar *c) -{ - gchar **ipset; - - if (addresses == NULL) - return NULL; - - if (strchr (addresses, '(') != NULL) { // old baselayout style - gchar *tmp = g_strdup (addresses); - strip_string (tmp, '('); - strip_string (tmp, ')'); - strip_string (tmp, '"'); - strip_string (tmp, '\''); - ipset = g_strsplit (tmp, "\" \"", 0); - g_free(tmp); - } else { // openrc style - if (strstr (addresses, "netmask")) - // There is only one ip address if "netmask" is specified. - // '\n' is not used in config so there will be only one split. - ipset = g_strsplit (addresses, "\n", 0); - else - ipset = g_strsplit (addresses, c, 0); - } - - return ipset; -} - -static gchar ** -split_addresses (const gchar* addresses) -{ - // " " is only used by openrc style - return split_addresses_by_char (addresses, " "); -} - -static gchar ** -split_routes (const gchar* routes) -{ - // "\"" is only used by openrc style - return split_addresses_by_char (routes, "\""); -} - -gboolean -has_ip6_address (const char *conn_name) -{ - gchar **ipset; - guint length; - guint i; - - g_return_val_if_fail (conn_name != NULL, FALSE); - ipset = split_addresses (ifnet_get_data (conn_name, "config")); - length = ipset ? g_strv_length (ipset) : 0; - for (i = 0; i < length; i++) { - if (!is_ip6_address (ipset[i])) - continue; - else { - g_strfreev (ipset); - return TRUE; - } - - } - g_strfreev (ipset); - return FALSE; -} - -gboolean -has_default_route (const char *conn_name, gboolean (*check_fn) (const char *)) -{ - char *routes = NULL, *end, *tmp; - gboolean success = FALSE; - - g_return_val_if_fail (conn_name != NULL, FALSE); - - routes = g_strdup (ifnet_get_data (conn_name, "routes")); - if (!routes) - return FALSE; - tmp = find_default_gateway_str (routes); - if (tmp) { - g_strstrip (tmp); - if ((end = strstr (tmp, "\"")) != NULL) - *end = '\0'; - if (check_fn (tmp)) - success = TRUE; - } - - g_free (routes); - return success; -} - -static ip_block * -create_ip4_block (gchar * ip) -{ - ip_block *iblock = g_slice_new0 (ip_block); - guint32 tmp_ip4_addr; - int i; - guint length; - gchar **ip_mask; - - /* prefix format */ - if (strstr (ip, "/")) { - gchar *prefix; - - ip_mask = g_strsplit (ip, "/", 0); - length = g_strv_length (ip_mask); - if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0])) - goto error; - iblock->ip = g_strdup (ip_mask[0]); - prefix = ip_mask[1]; - i = 0; - while (i < length && g_ascii_isdigit (prefix[i])) - i++; - prefix[i] = '\0'; - iblock->prefix = (guint32) atoi (ip_mask[1]); - } else if (strstr (ip, "netmask")) { - ip_mask = g_strsplit (ip, " ", 0); - length = g_strv_length (ip_mask); - if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0])) - goto error; - iblock->ip = g_strdup (ip_mask[0]); - i = 0; - while (i < length && !strstr (ip_mask[++i], "netmask")) ; - while (i < length && ip_mask[++i][0] == '\0') ; - if (i >= length) - goto error; - if (!inet_pton (AF_INET, ip_mask[i], &tmp_ip4_addr)) - goto error; - iblock->prefix = nm_utils_ip4_netmask_to_prefix (tmp_ip4_addr); - } else { - g_slice_free (ip_block, iblock); - if (!is_ip6_address (ip) && !strstr (ip, "dhcp")) - nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, missing netmask or prefix", ip); - return NULL; - } - if (iblock->prefix == 0 || iblock->prefix > 32) { - nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, invalid prefix", ip); - goto error; - } - g_strfreev (ip_mask); - return iblock; -error: - if (!is_ip6_address (ip)) - nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 address: %s", ip); - g_strfreev (ip_mask); - g_free (iblock->ip); - g_slice_free (ip_block, iblock); - return NULL; -} - -static ip_block * -create_ip_block (gchar * ip) -{ - ip_block *iblock = g_slice_new0 (ip_block); - gchar *dup_ip = g_strdup (ip); - gchar *prefix = NULL; - - if ((prefix = strstr (dup_ip, "/")) != NULL) { - *prefix = '\0'; - prefix++; - } - if (!nm_utils_ipaddr_valid (AF_INET6, dup_ip)) - goto error; - iblock->ip = dup_ip; - if (prefix) { - errno = 0; - iblock->prefix = strtol (prefix, NULL, 10); - if (errno || iblock->prefix <= 0 || iblock->prefix > 128) { - goto error; - } - } else - iblock->prefix = 64; - return iblock; -error: - if (!is_ip4_address (ip)) - nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 address: %s", ip); - g_slice_free (ip_block, iblock); - g_free (dup_ip); - return NULL; -} - -static char * -get_ip4_gateway (gchar * gateway) -{ - gchar *tmp, *split; - - if (!gateway) - return NULL; - tmp = find_gateway_str (gateway); - if (!tmp) { - nm_log_warn (LOGD_SETTINGS, "Couldn't obtain gateway in \"%s\"", gateway); - return NULL; - } - tmp = g_strdup (tmp); - strip_string (tmp, ' '); - strip_string (tmp, '"'); - - // Only one gateway is selected - if ((split = strstr (tmp, "\"")) != NULL) - *split = '\0'; - - if (!nm_utils_ipaddr_valid (AF_INET, tmp)) - goto error; - return tmp; -error: - if (!is_ip6_address (tmp)) - nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 gateway: %s", tmp); - g_free (tmp); - return NULL; -} - -static char * -get_ip6_next_hop (gchar * next_hop) -{ - gchar *tmp; - - if (!next_hop) - return NULL; - tmp = find_gateway_str (next_hop); - if (!tmp) { - nm_log_warn (LOGD_SETTINGS, "Couldn't obtain next_hop in \"%s\"", next_hop); - return NULL; - } - tmp = g_strdup (tmp); - strip_string (tmp, ' '); - strip_string (tmp, '"'); - g_strstrip (tmp); - if (!nm_utils_ipaddr_valid (AF_INET6, tmp)) - goto error; - return tmp; -error: - if (!is_ip4_address (tmp)) - nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 next_hop: %s", tmp); - g_free (tmp); - - return NULL; -} - -ip_block * -convert_ip4_config_block (const char *conn_name) -{ - gchar **ipset; - guint length; - guint i; - gchar *ip; - char *def_gateway = NULL; - const char *routes; - ip_block *start = NULL, *current = NULL, *iblock = NULL; - - g_return_val_if_fail (conn_name != NULL, NULL); - - ipset = split_addresses (ifnet_get_data (conn_name, "config")); - length = ipset ? g_strv_length (ipset) : 0; - - routes = ifnet_get_data (conn_name, "routes"); - if (routes) - def_gateway = get_ip4_gateway (strstr (routes, "default")); - - for (i = 0; i < length; i++) { - ip = ipset[i]; - ip = strip_string (ip, '"'); - iblock = create_ip4_block (ip); - if (iblock == NULL) - continue; - if (!iblock->next_hop && def_gateway != NULL) - iblock->next_hop = g_strdup (def_gateway); - if (start == NULL) - start = current = iblock; - else { - current->next = iblock; - current = iblock; - } - } - g_strfreev (ipset); - g_free (def_gateway); - return start; -} - -ip_block * -convert_ip6_config_block (const char *conn_name) -{ - gchar **ipset; - guint length; - guint i; - gchar *ip; - ip_block *start = NULL, *current = NULL, *iblock = NULL; - - g_return_val_if_fail (conn_name != NULL, NULL); - ipset = split_addresses (ifnet_get_data (conn_name, "config")); - length = ipset ? g_strv_length (ipset) : 0; - for (i = 0; i < length; i++) { - ip = ipset[i]; - ip = strip_string (ip, '"'); - iblock = create_ip_block (ip); - if (iblock == NULL) - continue; - if (start == NULL) - start = current = iblock; - else { - current->next = iblock; - current = iblock; - } - } - g_strfreev (ipset); - return start; -} - -ip_block * -convert_ip4_routes_block (const char *conn_name) -{ - gchar **ipset; - guint length; - guint i; - gchar *ip; - ip_block *start = NULL, *current = NULL, *iblock = NULL; - - g_return_val_if_fail (conn_name != NULL, NULL); - - ipset = split_routes (ifnet_get_data (conn_name, "routes")); - length = ipset ? g_strv_length (ipset) : 0; - for (i = 0; i < length; i++) { - ip = ipset[i]; - if (find_default_gateway_str (ip) || strstr (ip, "::") - || !find_gateway_str (ip)) - continue; - ip = strip_string (ip, '"'); - iblock = create_ip4_block (ip); - if (iblock == NULL) - continue; - iblock->next_hop = get_ip4_gateway (ip); - if (start == NULL) - start = current = iblock; - else { - current->next = iblock; - current = iblock; - } - } - g_strfreev (ipset); - return start; -} - -ip_block * -convert_ip6_routes_block (const char *conn_name) -{ - gchar **ipset; - guint length; - guint i; - gchar *ip, *tmp_addr; - ip_block *start = NULL, *current = NULL, *iblock = NULL; - - g_return_val_if_fail (conn_name != NULL, NULL); - ipset = split_routes (ifnet_get_data (conn_name, "routes")); - length = ipset ? g_strv_length (ipset) : 0; - for (i = 0; i < length; i++) { - ip = ipset[i]; - ip = strip_string (ip, '"'); - if (ip[0] == '\0') - continue; - if ((tmp_addr = find_default_gateway_str (ip)) != NULL) { - if (!is_ip6_address (tmp_addr)) - continue; - else { - iblock = g_slice_new0 (ip_block); - iblock->ip = g_strdup ("::"); - iblock->prefix = 128; - } - } else - iblock = create_ip_block (ip); - if (iblock == NULL) - continue; - iblock->next_hop = get_ip6_next_hop (ip); - if (iblock->next_hop == NULL) { - destroy_ip_block (iblock); - continue; - } - if (start == NULL) - start = current = iblock; - else { - current->next = iblock; - current = iblock; - } - } - g_strfreev (ipset); - return start; -} - -void -destroy_ip_block (ip_block * iblock) -{ - g_free (iblock->ip); - g_free (iblock->next_hop); - g_slice_free (ip_block, iblock); -} - -void -set_ip4_dns_servers (NMSettingIPConfig *s_ip4, const char *conn_name) -{ - const char *dns_servers; - gchar **server_list, *stripped; - guint length, i; - guint32 tmp_ip4_addr; - - dns_servers = ifnet_get_data (conn_name, "dns_servers"); - if (!dns_servers) - return; - stripped = g_strdup (dns_servers); - strip_string (stripped, '"'); - server_list = g_strsplit (stripped, " ", 0); - g_free (stripped); - - length = g_strv_length (server_list); - if (length) - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, - TRUE, NULL); - for (i = 0; i < length; i++) { - g_strstrip (server_list[i]); - if (server_list[i][0] == '\0') - continue; - if (!inet_pton (AF_INET, server_list[i], &tmp_ip4_addr)) { - if (!is_ip6_address (server_list[i])) - nm_log_warn (LOGD_SETTINGS, "ignored dns: %s\n", server_list[i]); - continue; - } - if (!nm_setting_ip_config_add_dns (s_ip4, server_list[i])) - nm_log_warn (LOGD_SETTINGS, "warning: duplicate DNS server %s", server_list[i]); - } - g_strfreev (server_list); -} - -void -set_ip6_dns_servers (NMSettingIPConfig *s_ip6, const char *conn_name) -{ - const char *dns_servers; - gchar **server_list, *stripped; - guint length, i; - struct in6_addr tmp_ip6_addr; - - dns_servers = ifnet_get_data (conn_name, "dns_servers"); - if (!dns_servers) - return; - - stripped = g_strdup (dns_servers); - strip_string (stripped, '"'); - server_list = g_strsplit (stripped, " ", 0); - g_free (stripped); - - length = g_strv_length (server_list); - if (length) - g_object_set (s_ip6, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, - TRUE, NULL); - for (i = 0; i < length; i++) { - g_strstrip (server_list[i]); - if (server_list[i][0] == '\0') - continue; - if (!inet_pton (AF_INET6, server_list[i], &tmp_ip6_addr)) { - if (is_ip6_address (server_list[i])) - nm_log_warn (LOGD_SETTINGS, "ignored dns: %s\n", server_list[i]); - continue; - } - if (!nm_setting_ip_config_add_dns (s_ip6, server_list[i])) - nm_log_warn (LOGD_SETTINGS, "warning: duplicate DNS server %s", server_list[i]); - } - g_strfreev (server_list); -} - -gboolean -is_managed (const char *conn_name) -{ - gchar *config; - - g_return_val_if_fail (conn_name != NULL, FALSE); - config = (gchar *) ifnet_get_data (conn_name, "managed"); - if (!config) - return TRUE; - if (strcmp (config, "false") == 0) - return FALSE; - return TRUE; -} - -static char * -_has_prefix_impl (char *str, const char *prefix, gsize prefix_len) -{ - if (!g_str_has_prefix (str, prefix)) - return NULL; - str += prefix_len; - if (!g_ascii_isspace (str[0])) - return NULL; - do { - str++; - } while (g_ascii_isspace (str[0])); - return str; -} -#define _has_prefix(STR, PREFIX) _has_prefix_impl (STR, PREFIX, NM_STRLEN (PREFIX)) - -void -get_dhcp_hostname_and_client_id (char **hostname, char **client_id) -{ - const char *dhcp_client; - const gchar *dhcpcd_conf = SYSCONFDIR "/dhcpcd.conf"; - const gchar *dhclient_conf = SYSCONFDIR "/dhcp/dhclient.conf"; - gchar *line = NULL, *tmp = NULL, *contents = NULL, *tmp1; - gchar **all_lines; - guint line_num, i; - gboolean use_dhclient = FALSE; - - *hostname = NULL; - *client_id = NULL; - dhcp_client = nm_dhcp_manager_get_config (nm_dhcp_manager_get ()); - if (dhcp_client) { - if (!strcmp (dhcp_client, "dhclient")) { - g_file_get_contents (dhclient_conf, &contents, NULL, - NULL); - use_dhclient = TRUE; - } else if (!strcmp (dhcp_client, "dhcpcd")) { - g_file_get_contents (dhcpcd_conf, &contents, NULL, - NULL); - } - } else { - if (g_file_test (dhclient_conf, G_FILE_TEST_IS_REGULAR)) { - g_file_get_contents (dhclient_conf, &contents, NULL, - NULL); - use_dhclient = TRUE; - } else if (g_file_test (dhcpcd_conf, G_FILE_TEST_IS_REGULAR)) { - g_file_get_contents (dhcpcd_conf, &contents, NULL, - NULL); - } - } - if (!contents) - return; - all_lines = g_strsplit (contents, "\n", 0); - line_num = g_strv_length (all_lines); - for (i = 0; i < line_num; i++) { - line = all_lines[i]; - g_strstrip (line); - if (line[0] == '#' || line[0] == '\0') - continue; - if (!use_dhclient) { - // dhcpcd.conf - if ((tmp = _has_prefix (line, "hostname"))) { - if (tmp[0] != '\0') { - g_free (*hostname); - *hostname = g_strdup (tmp); - } else - nm_log_info (LOGD_SETTINGS, "dhcpcd hostname not defined, ignoring"); - } else if ((tmp = _has_prefix (line, "clientid"))) { - if (tmp[0] != '\0') { - g_free (*client_id); - *client_id = g_strdup (tmp); - } else - nm_log_info (LOGD_SETTINGS, "dhcpcd clientid not defined, ignoring"); - } - } else { - // dhclient.conf - if ((tmp1 = _has_prefix (line, "send"))) { - if ((tmp = _has_prefix (tmp1, "host-name"))) { - strip_string (tmp, ';'); - strip_string (tmp, '"'); - if (tmp[0] != '\0') { - g_free (*hostname); - *hostname = g_strdup (tmp); - } else - nm_log_info (LOGD_SETTINGS, "dhclient hostname not defined, ignoring"); - } else if ((tmp = _has_prefix (tmp1, "dhcp-client-identifier"))) { - strip_string (tmp, ';'); - if (tmp[0] != '\0') { - g_free (*client_id); - *client_id = g_strdup (tmp); - } else - nm_log_info (LOGD_SETTINGS, "dhclient clientid not defined, ignoring"); - } - } - } - } - g_strfreev (all_lines); - g_free (contents); -} - -gchar *backup_file (const gchar* target) -{ - GFile *source, *backup; - gchar* backup_path; - GError *error = NULL; - - source = g_file_new_for_path (target); - - if (!g_file_query_exists (source, NULL)) { - g_object_unref (source); - return NULL; - } - - backup_path = g_strdup_printf ("%s.bak", target); - backup = g_file_new_for_path (backup_path); - - if (!g_file_copy (source, backup, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error)) { - nm_log_warn (LOGD_SETTINGS, "Backup failed: %s", error->message); - g_free (backup_path); - backup_path = NULL; - g_error_free (error); - } - - g_object_unref (source); - g_object_unref (backup); - - return backup_path; -} diff --git a/src/settings/plugins/ifnet/nms-ifnet-net-utils.h b/src/settings/plugins/ifnet/nms-ifnet-net-utils.h deleted file mode 100644 index cc273aa7..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-net-utils.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#ifndef _IFNET_UTILS_H -#define _IFNET_UTILS_H - -#define IFNET_PLUGIN_NAME "SettingsPlugin-Ifnet" - -#include - -#include "nm-setting-ip6-config.h" -#include "nm-setting-ip4-config.h" - -#include "nms-ifnet-net-parser.h" - -#define has_default_ip4_route(conn_name) has_default_route((conn_name), &is_ip4_address) -#define has_default_ip6_route(conn_name) has_default_route((conn_name), &is_ip6_address) - -typedef struct _ip_block { - char *ip; - guint32 prefix; - char *next_hop; - struct _ip_block *next; -} ip_block; - -gboolean is_static_ip4 (const char *conn_name); -gboolean is_static_ip6 (const char *conn_name); -gboolean is_ip4_address (const char *in_address); -gboolean is_ip6_address (const char *in_address); -gboolean has_ip6_address (const char *conn_name); -gboolean has_default_route (const char *conn_name, gboolean (*check_fn) (const char *)); -gboolean reload_parsers (void); - -ip_block *convert_ip4_config_block (const char *conn_name); -ip_block *convert_ip6_config_block (const char *conn_name); -ip_block *convert_ip4_routes_block (const char *conn_name); -ip_block *convert_ip6_routes_block (const char *conn_name); -void destroy_ip_block (ip_block * iblock); - -void set_ip4_dns_servers (NMSettingIPConfig * s_ip4, const char *conn_name); -void set_ip6_dns_servers (NMSettingIPConfig * s_ip6, const char *conn_name); - -gchar *strip_string (gchar *str, gchar t); -gboolean is_managed (const char *conn_name); - -gboolean is_hex (const char *value); -gboolean is_ascii (const char *value); -gboolean is_true (const char *str); - -void get_dhcp_hostname_and_client_id (char **hostname, char **client_id); - -gchar *backup_file (const gchar* target); -#endif diff --git a/src/settings/plugins/ifnet/nms-ifnet-plugin.c b/src/settings/plugins/ifnet/nms-ifnet-plugin.c deleted file mode 100644 index 8332358f..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-plugin.c +++ /dev/null @@ -1,524 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service (ifnet) - * - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#include "nm-default.h" - -#include "nms-ifnet-plugin.h" - -#include -#include - -#include "nm-utils.h" -#include "nm-setting-connection.h" -#include "nm-dbus-interface.h" -#include "settings/nm-settings-plugin.h" -#include "nm-config.h" -#include "NetworkManagerUtils.h" - -#include "nms-ifnet-connection.h" -#include "nms-ifnet-net-utils.h" -#include "nms-ifnet-net-parser.h" -#include "nms-ifnet-wpa-parser.h" -#include "nms-ifnet-connection-parser.h" - -#define IFNET_PLUGIN_NAME_PRINT "ifnet" -#define IFNET_PLUGIN_INFO "(C) 1999-2010 Gentoo Foundation, Inc. To report bugs please use bugs.gentoo.org with [networkmanager] or [qiaomuf] prefix." -#define IFNET_MANAGE_WELL_KNOWN_DEFAULT TRUE - -/*****************************************************************************/ - -typedef void (*FileChangedFn) (gpointer user_data); - -typedef struct { - FileChangedFn callback; - gpointer user_data; -} FileMonitorInfo; - -/*****************************************************************************/ - -typedef struct { - GHashTable *connections; /* uuid::connection */ - gboolean unmanaged_well_known; - - GFileMonitor *net_monitor; - GFileMonitor *wpa_monitor; -} SettingsPluginIfnetPrivate; - -struct _SettingsPluginIfnet { - GObject parent; - SettingsPluginIfnetPrivate _priv; -}; - -struct _SettingsPluginIfnetClass { - GObjectClass parent; -}; - -static void settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface); - -G_DEFINE_TYPE_EXTENDED (SettingsPluginIfnet, settings_plugin_ifnet, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_PLUGIN, - settings_plugin_interface_init)) - -#define SETTINGS_PLUGIN_IFNET_GET_PRIVATE(self) _NM_GET_PRIVATE (self, SettingsPluginIfnet, SETTINGS_IS_PLUGIN_IFNET) - -/*****************************************************************************/ - -static SettingsPluginIfnet *settings_plugin_ifnet_get (void); - -NM_DEFINE_SINGLETON_GETTER (SettingsPluginIfnet, settings_plugin_ifnet_get, SETTINGS_TYPE_PLUGIN_IFNET); - -/*****************************************************************************/ - -static void reload_connections (NMSettingsPlugin *config); - -/*****************************************************************************/ - -static gboolean -is_managed_plugin (void) -{ - return nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG, - NM_CONFIG_KEYFILE_GROUP_IFNET, NM_CONFIG_KEYFILE_KEY_IFNET_MANAGED, - IFNET_MANAGE_WELL_KNOWN_DEFAULT); -} - -static void -file_changed (GFileMonitor * monitor, - GFile * file, - GFile * other_file, - GFileMonitorEvent event_type, gpointer user_data) -{ - FileMonitorInfo *info; - - switch (event_type) { - case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - info = (FileMonitorInfo *) user_data; - info->callback (info->user_data); - break; - default: - break; - } -} - -static GFileMonitor * -monitor_file_changes (const char *filename, - FileChangedFn callback, gpointer user_data) -{ - GFile *file; - GFileMonitor *monitor; - FileMonitorInfo *info; - GError **error = NULL; - - if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) - return NULL; - file = g_file_new_for_path (filename); - monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, error); - g_object_unref (file); - - if (monitor) { - info = g_new0 (FileMonitorInfo, 1); - info->callback = callback; - info->user_data = user_data; - g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free, - info); - g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), - info); - } else { - nm_log_warn (LOGD_SETTINGS, "Monitoring %s failed, error: %s", filename, - error == NULL ? "nothing" : (*error)->message); - } - - return monitor; -} - -static void -setup_monitors (NMIfnetConnection *connection, gpointer user_data) -{ - SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (user_data); - SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self); - - if (!nm_config_get_monitor_connection_files (nm_config_get ())) - return; - - if (priv->net_monitor || priv->wpa_monitor) - return; - - priv->net_monitor = monitor_file_changes (CONF_NET_FILE, - (FileChangedFn) reload_connections, - user_data); - priv->wpa_monitor = monitor_file_changes (WPA_SUPPLICANT_CONF, - (FileChangedFn) reload_connections, - user_data); -} - -static void -cancel_monitors (NMIfnetConnection *connection, gpointer user_data) -{ - SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (user_data); - SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self); - - if (priv->net_monitor) { - g_file_monitor_cancel (priv->net_monitor); - g_clear_object (&priv->net_monitor); - } - if (priv->wpa_monitor) { - g_file_monitor_cancel (priv->wpa_monitor); - g_clear_object (&priv->wpa_monitor); - } -} - -static void -connection_removed_cb (NMSettingsConnection *obj, gpointer user_data) -{ - g_hash_table_remove (SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) user_data)->connections, - nm_connection_get_uuid (NM_CONNECTION (obj))); -} - -static void -track_new_connection (SettingsPluginIfnet *self, NMIfnetConnection *connection) -{ - g_hash_table_insert (SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self)->connections, - g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection))), - g_object_ref (connection)); - g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, - G_CALLBACK (connection_removed_cb), - self); -} - -static void -reload_connections (NMSettingsPlugin *config) -{ - SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (config); - SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self); - GList *conn_names = NULL, *n_iter = NULL; - gboolean auto_refresh; - GError *error = NULL; - - /* save names for removing unused connections */ - GHashTable *new_connections = NULL; - GHashTableIter iter; - const char *uuid; - NMSettingsConnection *candidate; - - if (priv->unmanaged_well_known) - return; - - if (!reload_parsers ()) - return; - - nm_log_info (LOGD_SETTINGS, "Loading connections"); - - auto_refresh = nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG, - NM_CONFIG_KEYFILE_GROUP_IFNET, NM_CONFIG_KEYFILE_KEY_IFNET_AUTO_REFRESH, - FALSE); - - new_connections = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref); - - /* Reread on-disk data and refresh in-memory connections from it */ - conn_names = ifnet_get_connection_names (); - for (n_iter = conn_names; n_iter; n_iter = g_list_next (n_iter)) { - NMIfnetConnection *new; - NMIfnetConnection *old; - const char *conn_name = n_iter->data; - - /* read the new connection */ - new = nm_ifnet_connection_new (NULL, conn_name); - if (!new) - continue; - - g_signal_connect (G_OBJECT (new), "ifnet_setup_monitors", - G_CALLBACK (setup_monitors), config); - g_signal_connect (G_OBJECT (new), "ifnet_cancel_monitors", - G_CALLBACK (cancel_monitors), config); - - old = g_hash_table_lookup (priv->connections, - nm_connection_get_uuid (NM_CONNECTION (new))); - if (old && new) { - if (auto_refresh) { - /* If connection has changed, remove the old one and add the - * new one to force a disconnect/reconnect with new settings - */ - if (!nm_connection_compare (NM_CONNECTION (old), - NM_CONNECTION (new), - NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | - NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) { - nm_log_info (LOGD_SETTINGS, "Auto refreshing %s", conn_name); - - nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (old)); - track_new_connection (self, new); - if (is_managed_plugin () && is_managed (conn_name)) - g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, new); - } - } else { - /* Update existing connection with new settings */ - if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (old), - NM_CONNECTION (new), - NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP_SAVED, - NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, - "ifnet-update", - &error)) { - /* Shouldn't ever get here as 'new' was verified by the reader already - * and the UUID did not change. */ - g_assert_not_reached (); - } - g_assert_no_error (error); - nm_log_info (LOGD_SETTINGS, "Connection %s updated", - nm_connection_get_id (NM_CONNECTION (new))); - } - g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED); - } else if (new) { - track_new_connection (self, new); - if (is_managed_plugin () && is_managed (conn_name)) - g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, new); - } - - /* Track all valid connections so we can remove deleted ones later */ - g_hash_table_insert (new_connections, - (gpointer) nm_connection_get_uuid (NM_CONNECTION (new)), - new); - } - - /* remove deleted/unused connections */ - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, (gpointer) &uuid, (gpointer) &candidate)) { - /* only saved connections (which have a conn_name) get removed; unsaved - * ones obviously don't exist in /etc/conf.d/net yet and shouldn't get - * blown away by net file changes. - */ - if ( nm_ifnet_connection_get_conn_name (NM_IFNET_CONNECTION (candidate)) - && !g_hash_table_lookup (new_connections, uuid)) { - nm_settings_connection_signal_remove (candidate); - g_hash_table_iter_remove (&iter); - } - } - g_hash_table_destroy (new_connections); - g_list_free (conn_names); -} - -static NMSettingsConnection * -add_connection (NMSettingsPlugin *config, - NMConnection *source, - gboolean save_to_disk, - GError **error) -{ - SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) config); - NMIfnetConnection *new = NULL; - - /* Ensure we reject attempts to add the connection long before we're - * asked to write it to disk. - */ - if (!ifnet_can_write_connection (source, error)) - goto out; - - if (save_to_disk) { - if (!ifnet_add_new_connection (source, CONF_NET_FILE, WPA_SUPPLICANT_CONF, NULL, NULL, error)) - goto out; - reload_connections (config); - new = g_hash_table_lookup (priv->connections, nm_connection_get_uuid (source)); - } else { - new = nm_ifnet_connection_new (source, NULL); - if (new) { - track_new_connection (SETTINGS_PLUGIN_IFNET (config), new); - /* track_new_connection refs 'new' */ - g_object_unref (new); - } - } - -out: - if (!new && error && !*error) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "The ifnet plugin cannot add the connection (unknown error)."); - } - return (NMSettingsConnection *) new; -} - -static void -check_unmanaged (gpointer key, gpointer data, gpointer user_data) -{ - NMIfnetConnection *connection = NM_IFNET_CONNECTION (data); - GSList **list = (GSList **) user_data; - const char *mac, *conn_name; - char *unmanaged_spec; - GSList *iter; - - conn_name = nm_ifnet_connection_get_conn_name (connection); - - if (!conn_name || is_managed (conn_name)) - return; - - nm_log_info (LOGD_SETTINGS, "Checking unmanaged: %s", conn_name); - mac = ifnet_get_data (conn_name, "mac"); - if (mac) - unmanaged_spec = g_strdup_printf ("mac:%s", mac); - else - unmanaged_spec = g_strdup_printf ("interface-name:%s", conn_name); - - /* Just return if the unmanaged spec is already in the list */ - for (iter = *list; iter; iter = g_slist_next (iter)) { - if (g_str_equal (iter->data, unmanaged_spec)) { - g_free (unmanaged_spec); - return; - } - } - - nm_log_info (LOGD_SETTINGS, "Add unmanaged: %s", unmanaged_spec); - *list = g_slist_prepend (*list, unmanaged_spec); -} - -static GSList * -get_unmanaged_specs (NMSettingsPlugin * config) -{ - SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) config); - GSList *list = NULL; - - nm_log_info (LOGD_SETTINGS, "getting unmanaged specs..."); - g_hash_table_foreach (priv->connections, check_unmanaged, &list); - return list; -} - -static GSList * -get_connections (NMSettingsPlugin *config) -{ - SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) config); - GSList *connections = NULL; - GHashTableIter iter; - NMIfnetConnection *connection; - - nm_log_info (LOGD_SETTINGS, "(%p) ... get_connections.", config); - - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) { - const char *conn_name = nm_ifnet_connection_get_conn_name (connection); - - if (!conn_name || (!priv->unmanaged_well_known && is_managed (conn_name))) - connections = g_slist_prepend (connections, connection); - } - nm_log_info (LOGD_SETTINGS, "(%p) connections count: %d", - config, g_slist_length (connections)); - return connections; -} - -/*****************************************************************************/ - -static void -get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - switch (prop_id) { - case NM_SETTINGS_PLUGIN_PROP_NAME: - g_value_set_string (value, IFNET_PLUGIN_NAME_PRINT); - break; - case NM_SETTINGS_PLUGIN_PROP_INFO: - g_value_set_string (value, IFNET_PLUGIN_INFO); - break; - case NM_SETTINGS_PLUGIN_PROP_CAPABILITIES: - g_value_set_uint (value, - NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/*****************************************************************************/ - -static void -init (NMSettingsPlugin *config) -{ - SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (config); - SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self); - - nm_log_info (LOGD_SETTINGS, "Initializing!"); - - priv->connections = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); - priv->unmanaged_well_known = !is_managed_plugin (); - nm_log_info (LOGD_SETTINGS, "management mode: %s", - priv->unmanaged_well_known ? "unmanaged" : "managed"); - - setup_monitors (NULL, config); - reload_connections (config); - - nm_log_info (LOGD_SETTINGS, "Initialzation complete!"); -} - -/*****************************************************************************/ - -static void -settings_plugin_ifnet_init (SettingsPluginIfnet * plugin) -{ -} - -static void -dispose (GObject * object) -{ - SettingsPluginIfnet *plugin = SETTINGS_PLUGIN_IFNET (object); - SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) plugin); - - cancel_monitors (NULL, object); - if (priv->connections) { - g_hash_table_destroy (priv->connections); - priv->connections = NULL; - } - - ifnet_destroy (); - wpa_parser_destroy (); - G_OBJECT_CLASS (settings_plugin_ifnet_parent_class)->dispose (object); -} - -static void -settings_plugin_ifnet_class_init (SettingsPluginIfnetClass * req_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (req_class); - - object_class->dispose = dispose; - object_class->get_property = get_property; - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_NAME, - NM_SETTINGS_PLUGIN_NAME); - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_INFO, - NM_SETTINGS_PLUGIN_INFO); - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_CAPABILITIES, - NM_SETTINGS_PLUGIN_CAPABILITIES); -} - -static void -settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface) -{ - plugin_iface->init = init; - plugin_iface->get_connections = get_connections; - plugin_iface->get_unmanaged_specs = get_unmanaged_specs; - plugin_iface->add_connection = add_connection; - plugin_iface->reload_connections = reload_connections; -} - -/*****************************************************************************/ - -G_MODULE_EXPORT GObject * -nm_settings_plugin_factory (void) -{ - return G_OBJECT (g_object_ref (settings_plugin_ifnet_get ())); -} diff --git a/src/settings/plugins/ifnet/nms-ifnet-plugin.h b/src/settings/plugins/ifnet/nms-ifnet-plugin.h deleted file mode 100644 index f006e7e4..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-plugin.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service (ifnet) - * - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#ifndef _PLUGIN_H_ -#define _PLUGIN_H_ - -#define SETTINGS_TYPE_PLUGIN_IFNET (settings_plugin_ifnet_get_type ()) -#define SETTINGS_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SETTINGS_TYPE_PLUGIN_IFNET, SettingsPluginIfnet)) -#define SETTINGS_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SETTINGS_TYPE_PLUGIN_IFNET, SettingsPluginIfnetClass)) -#define SETTINGS_IS_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SETTINGS_TYPE_PLUGIN_IFNET)) -#define SETTINGS_IS_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SETTINGS_TYPE_PLUGIN_IFNET)) -#define SETTINGS_PLUGIN_IFNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SETTINGS_TYPE_PLUGIN_IFNET, SettingsPluginIfnetClass)) - -typedef struct _SettingsPluginIfnet SettingsPluginIfnet; -typedef struct _SettingsPluginIfnetClass SettingsPluginIfnetClass; - -GType settings_plugin_ifnet_get_type (void); - -#endif diff --git a/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c b/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c deleted file mode 100644 index 2b62e886..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c +++ /dev/null @@ -1,584 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#include "nm-default.h" - -#include "nms-ifnet-wpa-parser.h" - -#include -#include - -#include "nm-utils/nm-hash-utils.h" -#include "settings/nm-settings-plugin.h" - -#include "nms-ifnet-net-parser.h" -#include "nms-ifnet-net-utils.h" - -/* Security information */ -static GHashTable *wsec_table = NULL; - -/* Global information used for writing */ -static GHashTable *wsec_global_table = NULL; - -static gboolean wpa_parser_data_changed = FALSE; - -static long -wpa_get_long (GHashTable *table, const char *key) -{ - return atol (g_hash_table_lookup (table, key)); -} - -static void -destroy_security (GHashTable * network) -{ - gpointer key, value; - GHashTableIter iter; - - g_return_if_fail (network); - g_hash_table_iter_init (&iter, network); - while (g_hash_table_iter_next (&iter, &key, &value)) { - g_free (key); - g_free (value); - } - - g_hash_table_destroy (network); -} - -static GHashTable * -add_security (GHashTable *security) -{ - GHashTable *oldsecurity; - const char *ssid, *value; - char *ssid_key; - gboolean is_hex_ssid; - - /* Every security information should have a ssid */ - ssid = g_hash_table_lookup (security, "ssid"); - if (!ssid) { - destroy_security (security); - return NULL; - } - - /* Hex format begins with " */ - is_hex_ssid = (ssid[0] != '"'); - if ((value = g_hash_table_lookup (security, "disabled")) != NULL) { - if (strcmp (value, "1") == 0) { - destroy_security (security); - return NULL; - } - } - - /* Default priority is 1 */ - if (g_hash_table_lookup (security, "priority") == NULL) - g_hash_table_insert (security, g_strdup ("priority"), - g_strdup ("1")); - - oldsecurity = g_hash_table_lookup (wsec_table, ssid); - /* Security with lower priority will be ignored */ - if (oldsecurity != NULL) { - if (wpa_get_long (oldsecurity, "priority") >= - wpa_get_long (security, "priority")) { - destroy_security (security); - return NULL; - } else { - g_hash_table_remove (wsec_table, ssid); - destroy_security (oldsecurity); - } - } - - /* format ssid */ - ssid_key = - is_hex_ssid ? g_strdup_printf ("0x%s", - ssid) : - strip_string (g_strdup (ssid), '"'); - g_hash_table_insert (wsec_table, ssid_key, security); - return security; -} - -static void -add_key_value (GHashTable * network, gchar * line) -{ - gpointer orig_key, orig_value; - gchar **key_value; - - if (g_str_has_prefix (line, "network={")) - line += 9; - strip_string (line, '{'); - strip_string (line, '}'); - if (line[0] == '\0') - return; - key_value = g_strsplit (line, "=", 2); - if (g_strv_length (key_value) != 2) { - g_strfreev (key_value); - return; - } - g_strstrip (key_value[0]); - g_strstrip (key_value[1]); - - /* Reserve quotes for psk, wep_key, ssid - * Quotes will determine whether they are hex format */ - if (strcmp (key_value[0], "psk") != 0 - && !g_str_has_prefix (key_value[0], "wep_key") - && strcmp (key_value[0], "ssid") != 0) - strip_string (key_value[1], '"'); - - /* This sucks */ - if (g_hash_table_lookup_extended (network, key_value[0], &orig_key, &orig_value)) { - g_hash_table_remove (network, orig_key); - g_free (orig_key); - g_free (orig_value); - } - - g_hash_table_insert (network, g_strdup (key_value[0]), - g_strdup (key_value[1])); - g_strfreev (key_value); -} - -static void -add_one_wep_key (GHashTable * table, int key_num, gchar * one_wep_key) -{ - if (one_wep_key[0] == 's') { - //asc key - g_hash_table_insert (table, - g_strdup_printf ("wep_key%d", key_num - 1), - g_strdup_printf ("\"%s\"", - one_wep_key + 2)); - } else { - gchar buf[30]; - int i = 0, j = 0; - - //hex key - while (one_wep_key[i] != '\0') { - if (one_wep_key[i] != '-') - buf[j++] = one_wep_key[i]; - i++; - } - buf[j] = '\0'; - g_hash_table_insert (table, - g_strdup_printf ("wep_key%d", key_num - 1), - g_strdup (buf)); - - } -} - -/* Reading wep security information from /etc/conf.d/net. - * This should not be used in future, use wpa_supplicant instead. */ -static void -add_keys_from_net (void) -{ - GList *names = ifnet_get_connection_names (); - GList *iter = names; - gchar *wep_keys = "(\\[([1-4])\\]\\s+(s:\\w{5}|s:\\w{13}|" - "([\\da-fA-F]{4}\\-){2}[\\da-fA-F]{2}|" - "([\\da-fA-F]{4}\\-){6}[\\da-fA-F]{2})\\s+)"; - gchar *key_method = - "\\s+key\\s+\\[([1-4])\\]\\s+enc\\s+(open|restricted)"; - GRegex *regex_keys = g_regex_new (wep_keys, 0, 0, NULL); - GRegex *regex_method = g_regex_new (key_method, 0, 0, NULL); - GMatchInfo *keys_info; - GMatchInfo *method_info; - - while (iter) { - gchar *conn_name = iter->data; - GHashTable *table; - const char *key_str; - - if ((key_str = ifnet_get_data (conn_name, "key")) == NULL) { - iter = g_list_next (iter); - continue; - } - - wpa_add_security (conn_name); - table = _get_hash_table (conn_name); - /* Give lowest priority */ - wpa_set_data (conn_name, "priority", "0"); - g_regex_match (regex_keys, key_str, 0, &keys_info); - /* add wep keys */ - while (g_match_info_matches (keys_info)) { - gchar *key_num = g_match_info_fetch (keys_info, 2); - gchar *one_wep_key = g_match_info_fetch (keys_info, 3); - - add_one_wep_key (table, atoi (key_num), one_wep_key); - g_free (key_num); - g_free (one_wep_key); - g_match_info_next (keys_info, NULL); - } - g_match_info_free (keys_info); - - g_regex_match (regex_method, key_str, 0, &method_info); - /* set default key index and auth alg */ - if (g_match_info_matches (method_info)) { - gchar *default_idx = - g_match_info_fetch (method_info, 1); - gchar *method = g_match_info_fetch (method_info, 2); - - default_idx[0]--; - g_hash_table_insert (table, g_strdup ("wep_tx_keyidx"), - default_idx); - g_hash_table_insert (table, g_strdup ("auth_alg"), - g_ascii_strup (method, -1)); - } - g_match_info_free (method_info); - add_security (table); - iter = g_list_next (iter); - } - g_list_free (names); - g_regex_unref (regex_keys); - g_regex_unref (regex_method); -} - -static void -add_global_data (gchar * line) -{ - gchar **key_value; - - g_strstrip (line); - key_value = g_strsplit (line, "=", 2); - if (g_strv_length (key_value) != 2) { - nm_log_warn (LOGD_SETTINGS, "Can't handle this line: %s\n", line); - g_strfreev (key_value); - return; - } - g_hash_table_insert (wsec_global_table, - g_strdup (g_strstrip (key_value[0])), - g_strdup (g_strstrip (key_value[1]))); - g_strfreev (key_value); -} - -void -wpa_parser_init (const char *wpa_supplicant_conf) -{ - GIOChannel *channel = NULL; - gchar *line; - gboolean complete = FALSE; - - wpa_parser_data_changed = FALSE; - wsec_table = g_hash_table_new (nm_str_hash, g_str_equal); - wsec_global_table = g_hash_table_new (nm_str_hash, g_str_equal); - - if (g_file_test (wpa_supplicant_conf, G_FILE_TEST_IS_REGULAR)) - channel = - g_io_channel_new_file (wpa_supplicant_conf, "r", NULL); - if (channel == NULL) { - nm_log_warn (LOGD_SETTINGS, "Can't open %s for wireless security", - wpa_supplicant_conf); - return; - } - - while (g_io_channel_read_line (channel, &line, NULL, NULL, NULL) - != G_IO_STATUS_EOF) { - g_strstrip (line); - if (line[0] != '#' && line[0] != '\0') { - if (strstr (line, "network={") == NULL) { - add_global_data (line); - g_free (line); - continue; - } else { - GHashTable *network = - g_hash_table_new (nm_str_hash, g_str_equal); - - do { - gchar *quote_start, *quote_end = NULL, *comment; - - if (line[0] == '#' || line[0] == '\0') { - g_free (line); - continue; - } - /* ignore inline comments unless inside - a double-quoted string */ - if ((quote_start = strchr (line, '"')) != NULL) - quote_end = strrchr (quote_start + 1, '"'); - if ((comment = strchr ((quote_end != NULL) ? - quote_end : line, '#')) != NULL) - *comment = '\0'; - if (strstr (line, "}") != NULL) - complete = TRUE; - add_key_value (network, line); - g_free (line); - } while (complete == FALSE - && - g_io_channel_read_line - (channel, &line, NULL, - NULL, NULL) != G_IO_STATUS_EOF); - add_security (network); - //EOF in inner loop - if (complete == FALSE) { - g_free (line); - break; - } - complete = FALSE; - } - } else - g_free (line); - } - - g_io_channel_shutdown (channel, FALSE, NULL); - g_io_channel_unref (channel); - - add_keys_from_net (); -} - -const char * -wpa_get_value (const char *ssid, const char *key) -{ - GHashTable *target = g_hash_table_lookup (wsec_table, ssid); - - if (target) - return g_hash_table_lookup (target, key); - return NULL; -} - -gboolean -exist_ssid (const char *ssid) -{ - return g_hash_table_lookup (wsec_table, ssid) != NULL; -} - -GHashTable * -_get_hash_table (const char *ssid) -{ - return g_hash_table_lookup (wsec_table, ssid); -} - -static gchar *quoted_keys[] = - { "identity", "cert", "private", "phase", "password", NULL }; - -/* tell whether the key needs quotes when writing is performed */ -static gboolean -need_quote (gchar * key) -{ - int i = 0; - - while (quoted_keys[i] != NULL) { - if (strstr (key, quoted_keys[i])) - return TRUE; - i++; - } - return FALSE; -} - -gboolean -wpa_flush_to_file (const char *config_file) -{ - GIOChannel *channel; - GError *error = NULL; - gpointer key, value, ssid, security; - GHashTableIter iter, iter_security; - gchar *out_line; - gsize bytes_written; - gboolean result = FALSE; - - if (!wpa_parser_data_changed) - return TRUE; - if (!wsec_table || !wsec_global_table) - return FALSE; - - backup_file (config_file); - - channel = g_io_channel_new_file (config_file, "w", NULL); - if (!channel) { - nm_log_warn (LOGD_SETTINGS, "Can't open file %s for writing", config_file); - return FALSE; - } - g_hash_table_iter_init (&iter, wsec_global_table); - nm_log_info (LOGD_SETTINGS, "Writing to %s", config_file); - g_io_channel_write_chars (channel, - "#Generated by NetworkManager\n" - "###### Global Configuration ######\n", - -1, &bytes_written, &error); - if (error) - goto done; - - /* Writing global information */ - while (g_hash_table_iter_next (&iter, &key, &value)) { - out_line = - g_strdup_printf ("%s=%s\n", (gchar *) key, (gchar *) value); - g_io_channel_write_chars (channel, out_line, -1, &bytes_written, - &error); - if (bytes_written == 0 || error) - break; - g_free (out_line); - } - if (error) - goto done; - g_io_channel_write_chars (channel, - "\n###### Security Configuration ######\n", - -1, &bytes_written, &error); - if (error) - goto done; - - g_hash_table_iter_init (&iter, wsec_table); - /* Writing security */ - while (g_hash_table_iter_next (&iter, &ssid, &security)) { - g_hash_table_iter_init (&iter_security, - (GHashTable *) security); - g_io_channel_write_chars (channel, "network={\n", -1, - &bytes_written, &error); - if (error) - goto done; - while (g_hash_table_iter_next (&iter_security, &key, &value)) { - out_line = - g_strdup_printf (need_quote ((gchar *) key) ? - "\t%s=\"%s\"\n" : "\t%s=%s\n", - (gchar *) key, (gchar *) value); - g_io_channel_write_chars (channel, out_line, -1, - &bytes_written, &error); - if (bytes_written == 0 || error) - goto done; - g_free (out_line); - } - g_io_channel_write_chars (channel, "}\n\n", -1, &bytes_written, &error); - - } - g_io_channel_flush (channel, &error); - if (error) - goto done; - - wpa_parser_data_changed = FALSE; - result = TRUE; -done: - if (error) { - nm_log_warn (LOGD_SETTINGS, "Error writing WPA configuration: %s", error->message); - g_error_free (error); - } - g_io_channel_shutdown (channel, FALSE, NULL); - g_io_channel_unref (channel); - return result; -} - -/* If value is NULL, this method will delete old key value pair */ -void -wpa_set_data (const char *ssid, const char *key, const char *value) -{ - gpointer old_key = NULL, old_value = NULL; - GHashTable *security = g_hash_table_lookup (wsec_table, ssid); - gchar * stripped = NULL; - - g_return_if_fail (security != NULL); - - if (value){ - stripped = g_strdup(value); - if (strcmp (key, "ssid") != 0 && strcmp (key, "psk") != 0 - && !g_str_has_prefix (key, "wep_key")) - strip_string (stripped, '"'); - } - - /* Remove old key value pairs */ - if (g_hash_table_lookup_extended - (security, key, &old_key, &old_value)) { - if (stripped && !strcmp(old_value, stripped)){ - g_free (stripped); - return; - } - g_hash_table_remove (security, old_key); - g_free (old_key); - g_free (old_value); - } else if (!value) - return; - - /* Add new key value */ - if (stripped) - g_hash_table_insert (security, g_strdup (key), stripped); - wpa_parser_data_changed = TRUE; -} - -gboolean -wpa_has_security (const char *ssid) -{ - return g_hash_table_lookup (wsec_table, ssid) != NULL; -} - -gboolean -wpa_add_security (const char *ssid) -{ - if (wpa_has_security (ssid)) - return TRUE; - else { - GHashTable *security = - g_hash_table_new (nm_str_hash, g_str_equal); - gchar *ssid_i; - - nm_log_info (LOGD_SETTINGS, "Adding security for %s", ssid); - if (g_str_has_prefix (ssid, "0x")) { - /* hex ssid */ - ssid_i = g_strdup (ssid + 2); - } else { - /* ascii ssid requires quotes */ - ssid_i = g_strdup_printf ("\"%s\"", ssid); - } - g_hash_table_insert (security, strdup ("ssid"), ssid_i); - g_hash_table_insert (security, strdup ("priority"), - strdup ("1")); - g_hash_table_insert (wsec_table, g_strdup (ssid), security); - wpa_parser_data_changed = TRUE; - return TRUE; - } -} - -gboolean -wpa_delete_security (const char *ssid) -{ - gpointer old_key, old_value; - - g_return_val_if_fail (wsec_table != NULL && ssid != NULL, FALSE); - nm_log_info (LOGD_SETTINGS, "Deleting security for %s", ssid); - if (!g_hash_table_lookup_extended - (wsec_table, ssid, &old_key, &old_value)) - return FALSE; - g_hash_table_remove (wsec_table, old_key); - g_free (old_key); - destroy_security ((GHashTable *) old_value); - wpa_parser_data_changed = TRUE; - return TRUE; - -} - -void -wpa_parser_destroy (void) -{ - GHashTableIter iter; - gpointer key; - gpointer value; - - /* Destroy security */ - if (wsec_table) { - g_hash_table_iter_init (&iter, wsec_table); - while (g_hash_table_iter_next (&iter, &key, &value)) { - destroy_security ((GHashTable *) value); - g_free (key); - } - - g_hash_table_destroy (wsec_table); - wsec_table = NULL; - } - - /* Destroy global data */ - if (wsec_global_table) { - g_hash_table_iter_init (&iter, wsec_global_table); - while (g_hash_table_iter_next (&iter, &key, &value)) { - g_free (key); - g_free (value); - } - - g_hash_table_destroy (wsec_global_table); - wsec_global_table = NULL; - } -} diff --git a/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.h b/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.h deleted file mode 100644 index d096f468..00000000 --- a/src/settings/plugins/ifnet/nms-ifnet-wpa-parser.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#ifndef _WPA_PARSER_H -#define _WPA_PARSER_H - -#define WPA_SUPPLICANT_CONF SYSCONFDIR "/wpa_supplicant/wpa_supplicant.conf" - -void wpa_parser_init (const char *wpa_supplicant_conf); -void wpa_parser_destroy (void); - -/* reader functions */ -const char *wpa_get_value (const char *ssid, const char *key); -gboolean exist_ssid (const char *ssid); -GHashTable *_get_hash_table (const char *ssid); -gboolean wpa_has_security (const char *ssid); - -/* writer functions */ -gboolean wpa_flush_to_file (const char *config_file); -void wpa_set_data (const char *ssid, const char *key, const char *value); -gboolean wpa_add_security (const char *ssid); -gboolean wpa_delete_security (const char *ssid); -#endif diff --git a/src/settings/plugins/ifnet/tests/net b/src/settings/plugins/ifnet/tests/net deleted file mode 100644 index a5ac9ca2..00000000 --- a/src/settings/plugins/ifnet/tests/net +++ /dev/null @@ -1,158 +0,0 @@ -# This blank configuration will automatically use DHCP for any net.* -# scripts in /etc/init.d. To create a more complete configuration, -# please review /etc/conf.d/net.example and save your configuration -# in /etc/conf.d/net (this file :]!). - -modules="!wpa_supplicant" - -config_eth0=( -"202.117.16.121 netmask 255.255.255.0 brd 202.117.16.255" -"192.168.4.121/24" -"dhcp6" -) -routes_eth0=( "default via 202.117.16.1" - "192.168.4.0/24 via 192.168.4.1") -dns_servers_eth0="202.117.0.20 202.117.0.21" -dns_search_eth0="p12.edu.cn p13.edu.cn" - -config_eth1=( - "dhcp" -) -enable_ipv6_eth1="true" -routes_eth1=( "default via 202.117.16.1" ) -dns_servers_eth1="202.117.0.20 202.117.0.21" -config_eth2=( -"202.117.16.1211 netmask 255.255.255.0 brd 202.117.16.255" -"192.168.4.121/24" -"4321:0:1:2:3:4:567:89ab/64" -) -routes_eth2=("default via 4321:0:1:2:3:4:567:89ab") -enable_ipv6_eth2="true" -config_eth3=("nufjlsjlll") -managed_eth4="false" -routes_eth4=("default via 4321:0:1:2:3:4:567:89ab") -config_eth5=("dhcp") - -config_eth7=( "dhcp" ) -auto_eth7="true" - -# missing config_eth8 -auto_eth8="true" - -#new openrc style -config_eth9="202.117.16.10/24 202.117.17.10/24" -routes_eth9="default via 202.117.16.1 -10.0.0.0/8 via 192.168.0.1 -" -config_eth10="202.117.16.2 netmask 255.255.255.0" -routes_eth10="10.0.0.0/8 via 192.168.0.1" - -config_myxjtu2=("202.117.16.121/24 brd 202.117.16.255") -routes_myxjtu2=("default via 202.117.16.1") -dns_servers_myxjtu2="202.117.0.20 202.117.0.21" -#key_myxjtu2="[1] s:xjtud key [1] enc restricted" -#key_eth6="[1] aaaa-4444-3d [2] s:xjtudlc key [1] enc open" - - -username_ppp0='user' -password_ppp0='password' - -config_qiaomuf=("dhcp") - -config_1xtest=("dhcp") - -config_0xab3ace=("dhcp") - -modules=( "iproute2" ) - config_kvm0=( "null" ) - config_kvm1=( "null" ) - - tuntap_kvm0="tap" - tuntap_kvm1="tap" - tunctl_kvm0="-u user" - tunctl_kvm1="-u user" - -bridge_br0="eth0 kvm0 kvm1" -config_br0=( "192.168.1.10/24" ) - brctl_br0=( "setfd 0") - dhcp_eth1="nosendhost nontp -I" - -predown() { - # The default in the script is to test for NFS root and disallow - # downing interfaces in that case. Note that if you specify a - # predown() function you will override that logic. Here it is, in - # case you still want it... - if is_net_fs /; then - eerror "root filesystem is network mounted -- can't stop ${IFACE}" - return 1 - fi - - # Remember to return 0 on success - return 0 -} - -postup() { - # This function could be used, for example, to register with a - # dynamic DNS service. Another possibility would be to - # send/receive mail once the interface is brought up. - - # Here is an example that allows the use of iproute rules - # which have been configured using the rules_eth0 variable. - #rules_eth0=" \ - # 'from 24.80.102.112/32 to 192.168.1.0/24 table localnet priority 100' \ - # 'from 216.113.223.51/32 to 192.168.1.0/24 table localnet priority 100' \ - #" - eval set -- \$rules_${IFVAR} - if [ $# != 0 ]; then - einfo "Adding IP policy routing rules" - eindent - # Ensure that the kernel supports policy routing - if ! ip rule list | grep -q "^"; then - eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)" - eerror "in your kernel to use ip rules" - else - for x; do - ebegin "${x}" - ip rule add ${x} - eend $? - done - fi - eoutdent - # Flush the cache - ip route flush cache dev "${IFACE}" - fi - -} - -postdown() { - # Enable Wake-On-LAN for every interface except for lo - # Probably a good idea to set ifdown="no" in /etc/conf.d/net - # as well ;) - [ "${IFACE}" != "lo" ] && ethtool -s "${IFACE}" wol g - - Automatically erase any ip rules created in the example postup above - if interface_exists "${IFACE}"; then - # Remove any rules for this interface - local rule - ip rule list | grep " iif ${IFACE}[ ]*" | { - while read rule; do - rule="${rule#*:}" - ip rule del ${rule} - done - } - # Flush the route cache - ip route flush cache dev "${IFACE}" - fi - - # Return 0 always - return 0 -} - -failup() { - # This function is mostly here for completeness... I haven't - # thought of anything nifty to do with it yet ;-) -} - -faildown() -{} - diff --git a/src/settings/plugins/ifnet/tests/net.all b/src/settings/plugins/ifnet/tests/net.all deleted file mode 100644 index 285a4cdf..00000000 --- a/src/settings/plugins/ifnet/tests/net.all +++ /dev/null @@ -1,864 +0,0 @@ -############################################################################## -# QUICK-START -# -# The quickest start is if you want to use DHCP. -# In that case, everything should work out of the box, no configuration -# necessary, though the startup script will warn you that you haven't -# specified anything. - -# WARNING :- some examples have a mixture of IPv4 (ie 192.168.0.1) and IPv6 -# (ie 4321:0:1:2:3:4:567:89ab) internet addresses. They only work if you have -# the relevant kernel option enabled. So if you don't have an IPv6 enabled -# kernel then remove the IPv6 address from your config. - -# If you want to use a static address or use DHCP explicitly, jump -# down to the section labelled INTERFACE HANDLERS. -# -# If you want to do anything more fancy, you should take the time to -# read through the rest of this file. - -############################################################################## -# MODULES -# -# We now support modular networking scripts which means we can easily -# add support for new interface types and modules while keeping -# compatability with existing ones. -# -# Modules load by default if the package they need is installed. If -# you specify a module here that doesn't have it's package installed -# then you get an error stating which package you need to install. -# Ideally, you only use the modules setting when you have two or more -# packages installed that supply the same service. -# -# In other words, you probably should DO NOTHING HERE... - -# Prefer ifconfig over iproute2 -modules=( "ifconfig" ) - -# You can also specify other modules for an interface -# In this case we prefer udhcpc over dhcpcd -modules_eth0=( "udhcpc" ) - -# You can also specify which modules not to use - for example you may be -# using a supplicant or linux-wlan-ng to control wireless configuration but -# you still want to configure network settings per ESSID associated with. -modules=( "!iwconfig" "!wpa_supplicant" ) -# IMPORTANT: If you need the above, please disable modules in that order - - -############################################################################## -# INTERFACE HANDLERS -# -# We provide two interface handlers presently: ifconfig and iproute2. -# You need one of these to do any kind of network configuration. -# For ifconfig support, emerge sys-apps/net-tools -# For iproute2 support, emerge sys-apps/iproute2 - -# If you don't specify an interface then we prefer iproute2 if it's installed -# To prefer ifconfig over iproute2 -modules=( "ifconfig" ) - -# For a static configuration, use something like this -# (They all do exactly the same thing btw) -config_eth0=( "192.168.0.2/24" ) -config_eth0=( "192.168.0.2 netmask 255.255.255.0" ) - -# We can also specify a broadcast -config_eth0=( "192.168.0.2/24 brd 192.168.0.255" ) -config_eth0=( "192.168.0.2 netmask 255.255.255.0 broadcast 192.168.0.255" ) - -# If you need more than one address, you can use something like this -# NOTE: ifconfig creates an aliased device for each extra IPv4 address -# (eth0:1, eth0:2, etc) -# iproute2 does not do this as there is no need to -config_eth0=( - "192.168.0.2/24" - "192.168.0.3/24" - "192.168.0.4/24" -) -# Or you can use sequence expressions -config_eth0=( "192.168.0.{2..4}/24" ) -# which does the same as above. Be careful though as if you use this and -# fallbacks, you have to ensure that both end up with the same number of -# values otherwise your fallback won't work correctly. - -# You can also use IPv6 addresses -# (you should always specify a prefix length with IPv6 here) -config_eth0=( - "192.168.0.2/24" - "4321:0:1:2:3:4:567:89ab/64" - "4321:0:1:2:3:4:567:89ac/64" -) - -# If you wish to keep existing addresses + routing and the interface is up, -# you can specify a noop (no operation). If the interface is down or there -# are no addresses assigned, then we move onto the next step (default dhcp) -# This is useful when configuring your interface with a kernel command line -# or similar -config_eth0=( "noop" "192.168.0.2/24" ) - -# If you don't want ANY address (only useful when calling for advanced stuff) -config_eth0=( "null" ) - -# Here's how to do routing if you need it -routes_eth0=( - "default via 192.168.0.1" # IPv4 default route - "10.0.0.0/8 via 192.168.0.1" # IPv4 subnet route - "::/0" # IPv6 unicast -) - -# If a specified module fails (like dhcp - see below), you can specify a -# fallback like so -fallback_eth0=( "192.168.0.2 netmask 255.255.255.0" ) -fallback_route_eth0=( "default via 192.168.0.1" ) - -# NOTE: fallback entry must match the entry location in config_eth0 -# As such you can only have one fallback route. - -# Some users may need to alter the MTU - here's how -mtu_eth0="1500" - -# Each module described below can set a default base metric, lower is -# preferred over higher. This is so we can prefer a wired route over a -# wireless route automaticaly. You can override this by setting -metric_eth0="100" -# or on a global basis -metric="100" -# The only downside of the global setting is that you have to ensure that -# there are no conflicting routes yourself. For users with large routing -# tables you may have to set a global metric as the due to a simple read of -# the routing table taking over a minute at a time. - -############################################################################## -# OPTIONAL MODULES - -# INTERFACE RENAMING -# There is no consistent device renaming scheme for Linux. -# The preferred way of naming devices is via the kernel module directly or -# by using udev (http://www.reactivated.net/udevrules.php) - -# If you are unable to write udev rules, then we do provide a way of renaming -# the interface based on it's MAC address, but it is not optimal. -# Here is how to rename an interface whose MAC address is 00:11:22:33:44:55 -# to foo1 -rename_001122334455="foo1" - -# You can also do this based on current device name - although this is not -# recommended. Here we rename eth1 to foo2. -rename_eth1="foo2" - -#----------------------------------------------------------------------------- -# WIRELESS (802.11 support) -# Wireless can be provided by iwconfig or wpa_supplicant - -# iwconfig -# emerge net-wireless/wireless-tools -# Wireless options are held in /etc/conf.d/wireless - but could be here too -# Consult the sample file /etc/conf.d/wireless.example for instructions -# iwconfig is the default - -# wpa_supplicant -# emerge net-wireless/wpa-supplicant -# Wireless options are held in /etc/wpa_supplicant.conf -# Consult the sample file /etc/wpa_supplicant.conf.example for instructions -# To choose wpa_supplicant over iwconfig -modules=( "wpa_supplicant" ) -# To configure wpa_supplicant -wpa_supplicant_eth0="-Dwext" # For generic wireless -wpa_supplicant_ath0="-Dmadwifi" # For Atheros based cards -# Consult wpa_supplicant for more drivers -# By default don't wait for wpa_suppliant to associate and authenticate. -# If you would like to, so can specify how long in seconds -associate_timeout_eth0=60 -# A value of 0 means wait forever. - -# GENERIC WIRELESS OPTIONS -# PLEASE READ THE INSTRUCTIONS IN /etc/conf.d/wireless.example FOR -# HOW TO USE THIS ESSID VARIABLE -# You can also override any settings found here per ESSID - which is very -# handy if you use different networks a lot -config_ESSID=( "dhcp" ) -dhcpcd_ESSID="-t 5" - -# Setting name/domain server causes /etc/resolv.conf to be overwritten -# Note that if DHCP is used, and you want this to take precedence then - set dhcp_ESSID="nodns" -dns_servers_ESSID=( "192.168.0.1" "192.168.0.2" ) -dns_domain_ESSID="some.domain" -dns_search_ESSID="search.this.domain search.that.domain" -# Please check the man page for resolv.conf for more information -# as domain and search are mutually exclusive. - -# You can also override any settings found here per MAC address of the AP -# in case you use Access Points with the same ESSID but need different -# networking configs. Below is an example - of course you use the same -# method with other variables -mac_config_001122334455=( "dhcp" ) -mac_dhcpcd_001122334455="-t 10" -mac_dns_servers_001122334455=( "192.168.0.1" "192.168.0.2" ) - -# When an interface has been associated with an Access Point, a global -# variable called ESSID is set to the Access Point's ESSID for use in the -# pre/post user functions below (although it's not available in preup as you -# won't have associated then) - -# If you're using anything else to configure wireless on your interface AND -# you have installed any of the above packages, you need to disable them -modules=( "!iwconfig" "!wpa_supplicant" ) - -#----------------------------------------------------------------------------- -# DHCP -# DHCP can be provided by dhclient, dhcpcd, pump or udhcpc. -# -# dhclient: emerge net-misc/dhcp -# dhcpcd: emerge net-misc/dhcpcd -# pump: emerge net-misc/pump -# udhcpc: emerge net-misc/udhcp - -# If you have more than one DHCP client installed, you need to specify which -# one to use - otherwise we default to dhcpcd if available. -modules=( "dhclient" ) # to select dhclient over dhcpcd -# -# Notes: -# - All clients send the current hostname to the DHCP server by default -# - dhcpcd does not daemonize when the lease time is infinite -# - udhcp-0.9.3-r3 and earlier do not support getting NTP servers -# - pump does not support getting NIS servers -# - DHCP tends to erase any existing device information - so add -# static addresses after dhcp if you need them -# - dhclient and udhcpc can set other resolv.conf options such as "option" -# and "sortlist"- see the System module for more details - -# Regardless of which DHCP client you prefer, you configure them the -# same way using one of following depending on which interface modules -# you're using. -config_eth0=( "dhcp" ) - -# For passing custom options to dhcpcd use something like the following. This -# example reduces the timeout for retrieving an address from 60 seconds (the -# default) to 10 seconds. -dhcpcd_eth0="-t 10" - -# dhclient, udhcpc and pump don't have many runtime options -# You can pass options to them in a similar manner to dhcpcd though -dhclient_eth0="..." -udhcpc_eth0="..." -pump_eth0="..." - -# GENERIC DHCP OPTIONS -# Set generic DHCP options like so -dhcp_eth0="release nodns nontp nonis nogateway nosendhost" - -# This tells the dhcp client to release it's lease when it stops, not to -# overwrite dns, ntp and nis settings, not to set a default route and not to -# send the current hostname to the dhcp server and when it starts. -# You can use any combination of the above options - the default is not to -# use any of them. - -#----------------------------------------------------------------------------- -# For APIPA support, emerge net-misc/iputils or net-analyzer/arping - -# APIPA is a module that tries to find a free address in the range -# 169.254.0.0-169.254.255.255 by arping a random address in that range on the -# interface. If no reply is found then we assign that address to the interface - -# This is only useful for LANs where there is no DHCP server and you don't -# connect directly to the internet. -config_eth0=( "dhcp" ) -fallback_eth0=( "apipa" ) - -#----------------------------------------------------------------------------- -# ARPING Gateway configuration -# and -# Automatic Private IP Addressing (APIPA) -# For arpingnet / apipa support, emerge net-misc/iputils or net-analyzer/arping -# -# This is a module that tries to find a gateway IP. If it exists then we use -# that gateways configuration for our own. For the configuration variables -# simply ensure that each octet is zero padded and the dots are removed. -# Below is an example. -# -gateways_eth0="192.168.0.1 10.0.0.1" -config_192168000001=( "192.168.0.2/24" ) -routes_192168000001=( "default via 192.168.0.1" ) -dns_servers_192168000001=( "192.168.0.1" ) -config_010000000001=( "10.0.0.254/8" ) -routes_010000000001=( "default via 10.0.0.1" ) -dns_servers_010000000001=( "10.0.0.1" ) - -# We can also specify a specific MAC address for each gateway if different -# networks have the same gateway. -gateways_eth0="192.168.0.1,00:11:22:AA:BB:CC 10.0.0.1,33:44:55:DD:EE:FF" -config_192168000001_001122AABBCC=( "192.168.0.2/24" ) -routes_192168000001_001122AABBCC=( "default via 192.168.0.1" ) -dns_servers_192168000001_001122AABBCC=( "192.168.0.1" ) -config_010000000001_334455DDEEFF=( "10.0.0.254/8" ) -routes_010000000001_334455DDEEFF=( "default via 10.0.0.1" ) -dns_servers_010000000001_334455DDEEFF=( "10.0.0.1" ) - -# If we don't find any gateways (or there are none configured) then we try and -# use APIPA to find a free address in the range 169.254.0.0-169.254.255.255 -# by arping a random address in that range on the interface. If no reply is -# found then we assign that address to the interface. - -# This is only useful for LANs where there is no DHCP server. -config_eth0=( "arping" ) - -# or if no DHCP server can be found -config_eth0=( "dhcp" ) -fallback_eth0=( "arping" ) - -# NOTE: We default to sleeping for 1 second the first time we attempt an -# arping to give the interface time to settle on the LAN. This appears to -# be a good default for most instances, but if not you can alter it here. -arping_sleep=5 -arping_sleep_lan=7 - -# NOTE: We default to waiting 3 seconds to get an arping response. You can -# change the default wait like so. -arping_wait=3 -arping_wait_lan=2 - -#----------------------------------------------------------------------------- -# VLAN (802.1q support) -# For VLAN support, emerge net-misc/vconfig - -# Specify the VLAN numbers for the interface like so -# Please ensure your VLAN IDs are NOT zero-padded -vlans_eth0="1 2" - -# You may not want to assign an IP to the physical interface, but we still -# need it up. -config_eth0=( "null" ) - -# You can also configure the VLAN - see for vconfig man page for more details -vconfig_eth0=( "set_name_type VLAN_PLUS_VID_NO_PAD" ) -vconfig_vlan1=( "set_flag 1" "set_egress_map 2 6" ) -config_vlan1=( "172.16.3.1 netmask 255.255.254.0" ) -config_vlan2=( "172.16.2.1 netmask 255.255.254.0" ) - -# NOTE: Vlans can be configured with a . in their interface names -# When configuring vlans with this name type, you need to replace . with a _ -config_eth0.1=( "dhcp" ) - does not work -config_eth0_1=( "dhcp" ) - does work - -# NOTE: Vlans are controlled by their physical interface and not per vlan -# This means you do not need to create init scripts in /etc/init.d for each -# vlan, you must need to create one for the physical interface. -# If you wish to control the configuration of each vlan through a separate -# script, or wish to rename the vlan interface to something that vconfig -# cannot then you need to do this. -vlan_start_eth0="no" - -# If you do the above then you may want to depend on eth0 like so - RC_NEED_vlan1="net.eth0" -# NOTE: depend functions only work in /etc/conf.d/net -# and not in profile configs such as /etc/conf.d/net.foo - -#----------------------------------------------------------------------------- -# Bonding -# For link bonding/trunking emerge net-misc/ifenslave - -# To bond interfaces together -slaves_bond0="eth0 eth1 eth2" -config_bond0=( "null" ) # You may not want to assign an IP to the bond - -# If any of the slaves require extra configuration - for example wireless or -# ppp devices - we need to depend function on the bonded interfaces -RC_NEED_bond0="net.eth0 net.eth1" - - -#----------------------------------------------------------------------------- -# Classical IP over ATM -# For CLIP support emerge net-dialup/linux-atm - -# Ensure that you have /etc/atmsigd.conf setup correctly -# Now setup each clip interface like so -clip_atm0=( "peer_ip [if.]vpi.vci [opts]" ... ) -# where "peer_ip" is the IP address of a PVC peer (in case of an ATM connection -# with your ISP, your only peer is usually the ISP gateway closest to you), -# "if" is the number of the ATM interface which will carry the PVC, "vpi.vci" -# is the ATM VC address, and "opts" may optionally specify VC parameters like -# qos, pcr, and the like (see "atmarp -s" for further reference). Please also -# note quoting: it is meant to distinguish the VCs you want to create. You may, -# in example, create an atm0 interface to more peers, like this: -clip_atm0=( "1.1.1.254 0.8.35" "1.1.1.253 1.8.35" ) - -# By default, the PVC will use the LLC/SNAP encapsulation. If you rather need a -# null encapsulation (aka "VC mode"), please add the keyword "null" to opts. - - -#----------------------------------------------------------------------------- -# PPP -# For PPP support, emerge net-dialup/ppp -# PPP is used for most dialup connections, including ADSL. -# The older ADSL module is documented below, but you are encouraged to try -# this module first. -# -# You need to create the PPP net script yourself. Make it like so -#ln -s net.lo /etc/init.d/net.ppp0 -# -# We have to instruct ppp0 to actually use ppp -config_ppp0=( "ppp" ) -# -# Each PPP interface requires an interface to use as a "Link" -link_ppp0="/dev/ttyS0" # Most PPP links will use a serial port -link_ppp0="eth0" # PPPoE requires an ethernet interface -link_ppp0="[itf.]vpi.vci" # PPPoA requires the ATM VC's address -link_ppp0="/dev/null" # ISDN links should have this -link_ppp0="pty 'your_link_command'" # PPP links over ssh, rsh, etc -# -# Here you should specify what pppd plugins you want to use -# Available plugins are: pppoe, pppoa, capi, dhcpc, minconn, radius, -# radattr, radrealms and winbind -plugins_ppp0=( - "pppoe" # Required plugin for PPPoE - "pppoa vc-encaps" # Required plugin for PPPoA with an option - "capi" # Required plugin for ISDN -) -# -# PPP requires at least a username. You can optionally set a password here too -# If you don't, then it will use the password specified in /etc/ppp/*-secrets -# against the specified username -username_ppp0='user' -password_ppp0='password' -# NOTE: You can set a blank password like so -password_ppp0= -# -# The PPP daemon has many options you can specify - although there are many -# and may seem daunting, it is recommended that you read the pppd man page -# before enabling any of them -pppd_ppp0=( - "maxfail 0" # WARNING: It's not recommended you use this - # if you don't specify maxfail then we assume 0 - "updetach" # If not set, "/etc/init.d/net.ppp0 start" will return - # immediately, without waiting the link to come up - # for the first time. - # Do not use it for dial-on-demand links! - "debug" # Enables syslog debugging - "noauth" # Do not require the peer to authenticate itself - "defaultroute" # Make this PPP interface the default route - "usepeerdns" # Use the DNS settings provided by PPP - -# On demand options - "demand" # Enable dial on demand - "idle 30" # Link goes down after 30 seconds of inactivity - "10.112.112.112:10.112.112.113" # Phony IP addresses - "ipcp-accept-remote" # Accept the peers idea of remote address - "ipcp-accept-local" # Accept the peers idea of local address - "holdoff 3" # Wait 3 seconds after link dies before re-starting - -# Dead peer detection - "lcp-echo-interval 15" # Send a LCP echo every 15 seconds - "lcp-echo-failure 3" # Make peer dead after 3 consective - # echo-requests - -# Compression options - use these to completely disable compression -# noaccomp noccp nobsdcomp nodeflate nopcomp novj novjccomp - -# Dial-up settings - "lock" # Lock serial port - "115200" # Set the serial port baud rate - "modem crtscts" # Enable hardware flow control - "192.168.0.1:192.168.0.2" # Local and remote IP addresses -) -# -# Dial-up PPP users need to specify at least one telephone number -phone_number_ppp0=( "12345689" ) # Maximum 2 phone numbers are supported -# They will also need a chat script - here's a good one -chat_ppp0=( -# 'ABORT' 'BUSY' -# 'ABORT' 'ERROR' -# 'ABORT' 'NO ANSWER' -# 'ABORT' 'NO CARRIER' -# 'ABORT' 'NO DIALTONE' -# 'ABORT' 'Invalid Login' -# 'ABORT' 'Login incorrect' -# 'TIMEOUT' '5' -# '' 'ATZ' -# 'OK' 'AT' # Put your modem initialization string here -# 'OK' 'ATDT\T' -# 'TIMEOUT' '60' -# 'CONNECT' '' -# 'TIMEOUT' '5' -# '~--' '' -) - -# If the link require extra configuration - for example wireless or -# RFC 268 bridge - we need to depend on the bridge so they get -# configured correctly. -RC_NEED_ppp0="net.nas0" - -#WARNING: if MTU of the PPP interface is less than 1500 and you use this -#machine as a router, you should add the following rule to your firewall -# -#iptables -I FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu - -#----------------------------------------------------------------------------- -# ADSL -# For ADSL support, emerge net-dialup/rp-pppoe -# WARNING: This ADSL module is being deprecated in favour of the PPP module -# above. -# You should make the following settings and also put your -# username/password information in /etc/ppp/pap-secrets - -# Configure the interface to use ADSL -config_eth0=( "adsl" ) - -# You probably won't need to edit /etc/ppp/pppoe.conf if you set this -adsl_user_eth0="my-adsl-username" - -#----------------------------------------------------------------------------- -# ISDN -# For ISDN support, emerge net-dialup/isdn4k-utils -# You should make the following settings and also put your -# username/password information in /etc/ppp/pap-secrets - -# Configure the interface to use ISDN -config_ippp0=( "dhcp" ) -# It's important to specify dhcp if you need it! -config_ippp0=( "192.168.0.1/24" ) -# Otherwise, you can use a static IP - -# NOTE: The interface name must be either ippp or isdn followed by a number - -# You may need this option to set the default route -ipppd_eth0="defaultroute" - -#----------------------------------------------------------------------------- -# MAC changer -# To set a specific MAC address -mac_eth0="00:11:22:33:44:55" - -# For changing MAC addresses using the below, emerge net-analyzer/macchanger -# - to randomize the last 3 bytes only -mac_eth0="random-ending" -# - to randomize between the same physical type of connection (e.g. fibre, -# copper, wireless) , all vendors -mac_eth0="random-samekind" -# - to randomize between any physical type of connection (e.g. fibre, copper, -# wireless) , all vendors -mac_eth0="random-anykind" -# - full randomization - WARNING: some MAC addresses generated by this may NOT -# act as expected -mac_eth0="random-full" -# custom - passes all parameters directly to net-analyzer/macchanger -mac_eth0="some custom set of parameters" - -# You can also set other options based on the MAC address of your network card -# Handy if you use different docking stations with laptops -config_001122334455=( "dhcp" ) - -#----------------------------------------------------------------------------- -# TUN/TAP -# For TUN/TAP support emerge net-misc/openvpn or sys-apps/usermode-utilities -# -# You must specify if we're a tun or tap device. Then you can give it any -# name you like - such as vpn -tuntap_vpn="tun" -config_vpn=( "192.168.0.1/24") - -# Or stick wit the generic names - like tap0 -tuntap_tap0="tap" -config_tap0=( "192.168.0.1/24") - -# For passing custom options to tunctl use something like the following. This -# example sets the owner to adm -tunctl_tun1="-u adm" -# When using openvpn, there are no options - -#----------------------------------------------------------------------------- -# Bridging (802.1d) -# For bridging support emerge net-misc/bridge-utils - -# To add ports to bridge br0 -bridge_br0="eth0 eth1" -# or dynamically add them when the interface comes up -bridge_add_eth0="br0" -bridge_add_eth1="br0" - -# You need to configure the ports to null values so dhcp does not get started -config_eth0=( "null" ) -config_eth1=( "null" ) - -# Finally give the bridge an address - dhcp or a static IP -config_br0=( "dhcp" ) # may not work when adding ports dynamically -config_br0=( "192.168.0.1/24" ) - -# If any of the ports require extra configuration - for example wireless or -# ppp devices - we need to depend on them like so. -RC_NEED_br0="net.eth0 net.eth1" - -# Below is an example of configuring the bridge -# Consult "man brctl" for more details -brctl_br0=( "setfd 0" "sethello 0" "stp off" ) - -#----------------------------------------------------------------------------- -# RFC 2684 Bridge Support -# For RFC 2684 bridge support emerge net-misc/br2684ctl - -# Interface names have to be of the form nas0, nas1, nas2, etc. -# You have to specify a VPI and VCI for the interface like so -br2684ctl_nas0="-a 0.38" # UK VPI and VCI - -# You may want to configure the encapsulation method as well by adding the -e -# option to the command above (may need to be before the -a command) -# -e 0 # LLC (default) -# -e 1 # VC mux - -# Then you can configure the interface as normal -config_nas0=( "192.168.0.1/24" ) - -#----------------------------------------------------------------------------- -# Tunnelling -# WARNING: For tunnelling it is highly recommended that you -# emerge sys-apps/iproute2 -# -# For GRE tunnels -iptunnel_vpn0="mode gre remote 207.170.82.1 key 0xffffffff ttl 255" - -# For IPIP tunnels -iptunnel_vpn0="mode ipip remote 207.170.82.2 ttl 255" - -# To configure the interface -config_vpn0=( "192.168.0.2 pointopoint 192.168.1.2" ) # ifconfig style -config_vpn0=( "192.168.0.2 peer 192.168.1.1" ) # iproute2 style - -# 6to4 Tunnels allow IPv6 to work over IPv4 addresses, provided you -# have a non-private address configured on an interface. - link_6to4="eth0" # Interface to base it's addresses on - config_6to4=( "ip6to4" ) -# You may want to depend on eth0 like so -RC_NEED_6to4="net.eth0" -# To ensure that eth0 is configured before 6to4. Of course, the tunnel could be -# any name and this also works for any configured interface. -# NOTE: If you're not using iproute2 then your 6to4 tunnel has to be called -# sit0 - otherwise use a different name like 6to4 in the example above. - - -#----------------------------------------------------------------------------- -# System -# For configuring system specifics such as domain, dns, ntp and nis servers -# It's rare that you would need todo this, but you can anyway. -# This is most benefit to wireless users who don't use DHCP so they can change -# their configs based on ESSID. See wireless.example for more details - -# To use dns settings such as these, dns_servers_eth0 must be set! -# If you omit the _eth0 suffix, then it applies to all interfaces unless -# overridden by the interface suffix. -dns_domain_eth0="your.domain" -dns_servers_eth0="192.168.0.2 192.168.0.3" -dns_search_eth0="this.domain that.domain" -dns_options_eth0=( "timeout 1" "rotate" ) -dns_sortlist_eth0="130.155.160.0/255.255.240.0 130.155.0.0" -# See the man page for resolv.conf for details about the options and sortlist -# directives - -ntp_servers_eth0="192.168.0.2 192.168.0.3" - -nis_domain_eth0="domain" -nis_servers_eth0="192.168.0.2 192.168.0.3" - -# NOTE: Setting any of these will stamp on the files in question. So if you -# don't specify dns_servers but you do specify dns_domain then no nameservers -# will be listed in /etc/resolv.conf even if there were any there to start -# with. -# If this is an issue for you then maybe you should look into a resolv.conf -# manager like resolvconf-gentoo to manage this file for you. All packages -# that baselayout supports use resolvconf-gentoo if installed. - -#----------------------------------------------------------------------------- -# Cable in/out detection -# Sometimes the cable is in, others it's out. Obviously you don't want to -# restart net.eth0 every time when you plug it in either. -# -# netplug is a package that detects this and requires no extra configuration -# on your part. -# emerge sys-apps/netplug -# or -# emerge sys-apps/ifplugd -# and you're done :) - -# By default we don't wait for netplug/ifplugd to configure the interface. -# If you would like it to wait so that other services now that network is up -# then you can specify a timeout here. -plug_timeout="10" -# A value of 0 means wait forever. - -# If you don't want to use netplug on a specific interface but you have it -# installed, you can disable it for that interface via the modules statement -modules_eth0=( "!netplug" ) -# You can do the same for ifplugd -# -# You can disable them both with the generic plug -modules_eth0=( "!plug" ) - -# To use specific ifplugd options, fex specifying wireless mode -ifplugd_eth0="--api-mode=wlan" -# man ifplugd for more options - -############################################################################## -# ADVANCED CONFIGURATION -# -# Four functions can be defined which will be called surrounding the -# start/stop operations. The functions are called with the interface -# name first so that one function can control multiple adapters. An extra two -# functions can be defined when an interface fails to start or stop. -# -# The return values for the preup and predown functions should be 0 -# (success) to indicate that configuration or deconfiguration of the -# interface can continue. If preup returns a non-zero value, then -# interface configuration will be aborted. If predown returns a -# non-zero value, then the interface will not be allowed to continue -# deconfiguration. -# -# The return values for the postup, postdown, failup and faildown functions are -# ignored since there's nothing to do if they indicate failure. -# -# ${IFACE} is set to the interface being brought up/down -# ${IFVAR} is ${IFACE} converted to variable name bash allows - -#preup() { -# # Test for link on the interface prior to bringing it up. This -# # only works on some network adapters and requires the mii-diag -# # package to be installed. -# if mii-tool "${IFACE}" 2> /dev/null | grep -q 'no link'; then -# ewarn "No link on ${IFACE}, aborting configuration" -# return 1 -# fi -# -# # Test for link on the interface prior to bringing it up. This -# # only works on some network adapters and requires the ethtool -# # package to be installed. -# if ethtool "${IFACE}" | grep -q 'Link detected: no'; then -# ewarn "No link on ${IFACE}, aborting configuration" -# return 1 -# fi -# -# -# # Remember to return 0 on success -# return 0 -#} - -#predown() { -# # The default in the script is to test for NFS root and disallow -# # downing interfaces in that case. Note that if you specify a -# # predown() function you will override that logic. Here it is, in -# # case you still want it... -# if is_net_fs /; then -# eerror "root filesystem is network mounted -- can't stop ${IFACE}" -# return 1 -# fi -# -# # Remember to return 0 on success -# return 0 -#} - -#postup() { -# # This function could be used, for example, to register with a -# # dynamic DNS service. Another possibility would be to -# # send/receive mail once the interface is brought up. - -# # Here is an example that allows the use of iproute rules -# # which have been configured using the rules_eth0 variable. -# #rules_eth0=( -# # "from 24.80.102.112/32 to 192.168.1.0/24 table localnet priority 100" -# # "from 216.113.223.51/32 to 192.168.1.0/24 table localnet priority 100" -# #) -# local x="rules_${IFVAR}[@]" -# local -a rules=( "${!x}" ) -# if [[ -n ${rules} ]] ; then -# einfo "Adding IP policy routing rules" -# eindent -# # Ensure that the kernel supports policy routing -# if ! ip rule list | grep -q "^" ; then -# eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)" -# eerror "in your kernel to use ip rules" -# else -# for x in "${rules[@]}" ; do -# ebegin "${x}" -# ip rule add ${x} dev "${IFACE}" -# eend $? -# done -# fi -# eoutdent -# # Flush the cache -# ip route flush cache dev "${IFACE}" -# fi - -#} - -#postdown() { -# # Enable Wake-On-LAN for every interface except for lo -# # Probably a good idea to set RC_DOWN_INTERFACE="no" in /etc/conf.d/rc -# # as well ;) -# [[ ${IFACE} != "lo" ]] && ethtool -s "${IFACE}" wol g - -# Automatically erase any ip rules created in the example postup above -# if interface_exists "${IFACE}" ; then -# # Remove any rules for this interface -# local rule -# ip rule list | grep " iif ${IFACE}[ ]*" | { -# while read rule ; do -# rule="${rule#*:}" -# ip rule del ${rule} -# done -# } -# # Flush the route cache -# ip route flush cache dev "${IFACE}" -# fi - -# # Return 0 always -# return 0 -#} - -#failup() { -# # This function is mostly here for completeness... I haven't -# # thought of anything nifty to do with it yet ;-) -#} - -#faildown() { -# # This function is mostly here for completeness... I haven't -# # thought of anything nifty to do with it yet ;-) -#} - -############################################################################## -# FORCING MODULES -# The Big Fat Warning :- If you use module forcing do not complain to us or -# file bugs about it not working! -# -# Loading modules is a slow affair - we have to check each one for the following -# 1) Code sanity -# 2) Has the required package been emerged? -# 3) Has it modified anything? -# 4) Have all the dependant modules been loaded? - -# Then we have to strip out the conflicting modules based on user preference -# and default configuration and sort them into the correct order. -# Finally we check the end result for dependencies. - -# This, of course, takes valuable CPU time so we provide module forcing as a -# means to speed things up. We still do *some* checking but not much. - -# It is essential that you force modules in the correct order and supply all -# the modules you need. You must always supply an interface module - we -# supply ifconfig or iproute2. - -# The Big Fat Warning :- If you use module forcing do not complain to us or -# file bugs about it not working! - -# Now that we've warned you twice, here's how to do it -modules_force=( "ifconfig" ) -modules_force=( "iproute2" "dhcpcd" ) - -# We can also apply this to a specific interface -modules_force_eth1=( "iproute2" ) - -# The below will not work -modules_force=( "dhcpcd" ) -# No interface (ifconfig/iproute2) -modules_force=( "ifconfig" "essidnet" "iwconfig" ) -# Although it will not crash, essidnet will not work as it has to come after -# iwconfig -modules_force=( "iproute2" "ifconfig" ) -# The interface will be setup twice which will cause problems diff --git a/src/settings/plugins/ifnet/tests/nm-system-settings.conf b/src/settings/plugins/ifnet/tests/nm-system-settings.conf deleted file mode 100644 index 39bc87b8..00000000 --- a/src/settings/plugins/ifnet/tests/nm-system-settings.conf +++ /dev/null @@ -1,5 +0,0 @@ -[main] -plugins=ifnet,keyfile - -[ifnet] -managed=false diff --git a/src/settings/plugins/ifnet/tests/test-ifnet.c b/src/settings/plugins/ifnet/tests/test-ifnet.c deleted file mode 100644 index 68f2b928..00000000 --- a/src/settings/plugins/ifnet/tests/test-ifnet.c +++ /dev/null @@ -1,396 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service (ifnet) - * - * Mu Qiao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 1999-2010 Gentoo Foundation, Inc. - */ - -#include "nm-default.h" - -#include -#include -#include -#include -#include - -#include "nm-utils.h" - -#include "platform/nm-linux-platform.h" -#include "dhcp/nm-dhcp-manager.h" - -#include "settings/plugins/ifnet/nms-ifnet-net-parser.h" -#include "settings/plugins/ifnet/nms-ifnet-net-utils.h" -#include "settings/plugins/ifnet/nms-ifnet-wpa-parser.h" -#include "settings/plugins/ifnet/nms-ifnet-connection-parser.h" - -#include "nm-test-utils-core.h" - -/* Fake config handling; the values it returns don't matter, so this - * is easier than forcing it to read our own config file, etc. - */ -NMDhcpManager * -nm_dhcp_manager_get (void) -{ - return NULL; -} - -const char * -nm_dhcp_manager_get_config (NMDhcpManager *dhcp_manager) -{ - return "dhclient"; -} - -static void -test_getdata (void) -{ - g_assert (ifnet_get_data ("eth1", "config") && - strcmp (ifnet_get_data ("eth1", "config"), "( \"dhcp\" )") == 0); - g_assert (ifnet_get_data ("ppp0", "username") && - strcmp (ifnet_get_data ("ppp0", "username"), "user") == 0); - g_assert (ifnet_get_data ("ppp0", "password") && - strcmp (ifnet_get_data ("ppp0", "password"), "password") == 0); - g_assert (ifnet_get_global_data ("modules") && - strcmp ("!wpa_supplicant", ifnet_get_global_data ("modules")) == 0); -} - -static void -test_is_static (void) -{ - g_assert (!is_static_ip4 ("eth1")); - g_assert (is_static_ip4 ("eth0")); - g_assert (!is_static_ip6 ("eth0")); -} - -static void -test_has_default_route (void) -{ - g_assert (has_default_ip4_route ("eth0")); - g_assert (has_default_ip6_route ("eth4")); - g_assert (!has_default_ip4_route ("eth5") && - !has_default_ip6_route ("eth5")); -} - -static void -test_has_ip6_address (void) -{ - g_assert (has_ip6_address ("eth2")); - g_assert (!has_ip6_address ("eth0")); -} - -static void -test_is_ip4_address (void) -{ - gchar *address1 = "192.168.4.232/24"; - gchar *address2 = "192.168.100.{1..254}/24"; - gchar *address3 = "192.168.4.2555/24"; - - g_assert (is_ip4_address (address1)); - g_assert (is_ip4_address (address2)); - g_assert (!is_ip4_address (address3)); -} - -static void -test_is_ip6_address (void) -{ - gchar *address1 = "4321:0:1:2:3:4:567:89ac/24"; - - g_assert (is_ip6_address (address1)); -} - -static void -check_ip_block (ip_block * iblock, gchar * ip, guint32 prefix, gchar * gateway) -{ - g_assert_cmpstr (ip, ==, iblock->ip); - g_assert (prefix == iblock->prefix); - g_assert_cmpstr (gateway, ==, iblock->next_hop); -} - -static void -test_convert_ipv4_config_block (void) -{ - ip_block *iblock = convert_ip4_config_block ("eth0"); - ip_block *tmp = iblock; - - g_assert (iblock != NULL); - check_ip_block (iblock, "202.117.16.121", 24, "202.117.16.1"); - iblock = iblock->next; - destroy_ip_block (tmp); - g_assert (iblock != NULL); - check_ip_block (iblock, "192.168.4.121", 24, "202.117.16.1"); - destroy_ip_block (iblock); - - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*Can't handle IPv4 address*202.117.16.1211*"); - iblock = convert_ip4_config_block ("eth2"); - g_test_assert_expected_messages (); - g_assert (iblock != NULL && iblock->next == NULL); - check_ip_block (iblock, "192.168.4.121", 24, NULL); - destroy_ip_block (iblock); - - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*missing netmask or prefix*"); - iblock = convert_ip4_config_block ("eth3"); - g_assert (iblock == NULL); -} - -static void -test_convert_ipv4_routes_block (void) -{ - ip_block *iblock = convert_ip4_routes_block ("eth0"); - ip_block *tmp = iblock; - - g_assert (iblock != NULL); - check_ip_block (iblock, "192.168.4.0", 24, "192.168.4.1"); - iblock = iblock->next; - destroy_ip_block (tmp); - g_assert (iblock == NULL); - - iblock = convert_ip4_routes_block ("eth9"); - tmp = iblock; - - g_assert (iblock != NULL); - check_ip_block (iblock, "10.0.0.0", 8, "192.168.0.1"); - iblock = iblock->next; - destroy_ip_block (tmp); - g_assert (iblock == NULL); -} - -static void -test_wpa_parser (void) -{ - const char *value; - - g_assert (exist_ssid ("example")); - - g_assert (exist_ssid ("static-wep-test")); - value = wpa_get_value ("static-wep-test", "key_mgmt"); - g_assert_cmpstr (value, ==, "NONE"); - value = wpa_get_value ("static-wep-test", "wep_key0"); - g_assert_cmpstr (value, ==, "\"abcde\""); - - g_assert (exist_ssid ("leap-example")); - - value = wpa_get_value ("test-with-hash-in-psk", "psk"); - g_assert_cmpstr (value, ==, "\"xjtudlc3731###asdfasdfasdf\""); -} - -static void -test_strip_string (void) -{ - gchar *str = "( \"default via 202.117.16.1\" )"; - gchar *result = g_strdup (str); - gchar *result_b = result; - - result = strip_string (result, '('); - result = strip_string (result, ')'); - result = strip_string (result, '"'); - g_assert_cmpstr (result, ==, "default via 202.117.16.1"); - g_free (result_b); -} - -static void -test_is_unmanaged (void) -{ - g_assert (is_managed ("eth0")); - g_assert (!is_managed ("eth4")); -} - -static void -test_new_connection (void) -{ - GError *error = NULL; - NMConnection *connection; - - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*Can't handle IPv4 address*202.117.16.1211*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*Can't handle IPv6 address*202.117.16.1211*"); - connection = ifnet_update_connection_from_config_block ("eth2", NULL, &error); - g_test_assert_expected_messages (); - g_assert (connection != NULL); - g_object_unref (connection); - - connection = ifnet_update_connection_from_config_block ("qiaomuf", NULL, &error); - g_assert (connection != NULL); - g_object_unref (connection); - - connection = ifnet_update_connection_from_config_block ("myxjtu2", NULL, &error); - g_assert (connection != NULL); - g_object_unref (connection); - - connection = ifnet_update_connection_from_config_block ("eth9", NULL, &error); - g_assert (connection != NULL); - g_object_unref (connection); - - connection = ifnet_update_connection_from_config_block ("eth10", NULL, &error); - g_assert (connection != NULL); - g_object_unref (connection); -} - -static void -kill_backup (char **path) -{ - if (*path) { - unlink (*path); - g_free (*path); - *path = NULL; - } -} - -#define NET_GEN_NAME "net.generate" -#define SUP_GEN_NAME "wpa_supplicant.conf.generate" - -static void -test_update_connection (void) -{ - GError *error = NULL; - NMConnection *connection; - gboolean success; - char *backup = NULL; - char *basepath = TEST_IFNET_DIR; - - connection = ifnet_update_connection_from_config_block ("eth0", basepath, &error); - g_assert (connection != NULL); - - success = ifnet_update_parsers_by_connection (connection, "eth0", - NET_GEN_NAME, - SUP_GEN_NAME, - NULL, - &backup, - &error); - kill_backup (&backup); - g_assert (success); - g_object_unref (connection); - - connection = ifnet_update_connection_from_config_block ("0xab3ace", basepath, &error); - g_assert (connection != NULL); - - success = ifnet_update_parsers_by_connection (connection, "0xab3ace", - NET_GEN_NAME, - SUP_GEN_NAME, - NULL, - &backup, - &error); - kill_backup (&backup); - g_assert (success); - g_object_unref (connection); - - unlink (NET_GEN_NAME); - unlink (SUP_GEN_NAME); -} - -static void -test_add_connection (void) -{ - NMConnection *connection; - char *backup = NULL; - const char *basepath = TEST_IFNET_DIR; - - connection = ifnet_update_connection_from_config_block ("eth0", basepath, NULL); - g_assert (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL, &backup, NULL)); - kill_backup (&backup); - g_object_unref (connection); - - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*Can't handle ipv4 address: brd, missing netmask or prefix*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*Can't handle ipv4 address: 202.117.16.255, missing netmask or prefix*"); - connection = ifnet_update_connection_from_config_block ("myxjtu2", basepath, NULL); - g_test_assert_expected_messages (); - g_assert (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL, &backup, NULL)); - kill_backup (&backup); - g_object_unref (connection); - - unlink (NET_GEN_NAME); - unlink (SUP_GEN_NAME); -} - -static void -test_delete_connection (void) -{ - GError *error = NULL; - NMConnection *connection; - char *backup = NULL; - - connection = ifnet_update_connection_from_config_block ("eth7", NULL, &error); - g_assert (connection != NULL); - g_assert (ifnet_delete_connection_in_parsers ("eth7", NET_GEN_NAME, SUP_GEN_NAME, &backup)); - kill_backup (&backup); - g_object_unref (connection); - - connection = ifnet_update_connection_from_config_block ("qiaomuf", NULL, &error); - g_assert (connection != NULL); - g_assert (ifnet_delete_connection_in_parsers ("qiaomuf", NET_GEN_NAME, SUP_GEN_NAME, &backup)); - kill_backup (&backup); - g_object_unref (connection); - - unlink (NET_GEN_NAME); - unlink (SUP_GEN_NAME); -} - -static void -test_missing_config (void) -{ - gs_free_error GError *error = NULL; - NMConnection *connection; - - connection = ifnet_update_connection_from_config_block ("eth8", NULL, &error); - g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); - g_assert (connection == NULL && error != NULL); -} - -NMTST_DEFINE (); - -#define TPATH "/settings/plugins/ifnet/" - -int -main (int argc, char **argv) -{ - int ret; - - nm_linux_platform_setup (); - - nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT"); - - ifnet_init (TEST_IFNET_DIR "/net"); - wpa_parser_init (TEST_IFNET_DIR "/wpa_supplicant.conf"); - - g_test_add_func (TPATH "strip-string", test_strip_string); - g_test_add_func (TPATH "is-static", test_is_static); - g_test_add_func (TPATH "has-ip6-address", test_has_ip6_address); - g_test_add_func (TPATH "has-default-route", test_has_default_route); - g_test_add_func (TPATH "get-data", test_getdata); - g_test_add_func (TPATH "is-ip4-address", test_is_ip4_address); - g_test_add_func (TPATH "is-ip6-address", test_is_ip6_address); - g_test_add_func (TPATH "convert-ip4-config", test_convert_ipv4_config_block); - g_test_add_func (TPATH "convert-ip4-routes", test_convert_ipv4_routes_block); - g_test_add_func (TPATH "is-unmanaged", test_is_unmanaged); - g_test_add_func (TPATH "wpa-parser", test_wpa_parser); - g_test_add_func (TPATH "new-connection", test_new_connection); - g_test_add_func (TPATH "update-connection", test_update_connection); - g_test_add_func (TPATH "add-connection", test_add_connection); - g_test_add_func (TPATH "delete-connection", test_delete_connection); - g_test_add_func (TPATH "missing-config", test_missing_config); - - ret = g_test_run (); - - ifnet_destroy (); - wpa_parser_destroy (); - - return ret; -} diff --git a/src/settings/plugins/ifnet/tests/test_ca_cert.pem b/src/settings/plugins/ifnet/tests/test_ca_cert.pem deleted file mode 100644 index ef1be20d..00000000 --- a/src/settings/plugins/ifnet/tests/test_ca_cert.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEjzCCA3egAwIBAgIJAOvnZPt59yIZMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD -VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw -FQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UE -AxMEdGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAzMTAx -NTEyMTRaFw0xOTAzMDgxNTEyMTRaMIGLMQswCQYDVQQGEwJVUzESMBAGA1UECBMJ -QmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55 -IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3 -DQEJARYNdGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAKot9j+/+CX1/gZLgJHIXCRgCItKLGnf7qGbgqB9T2ACBqR0jllKWwDKrcWU -xjXNIc+GF9Wnv+lX6G0Okn4Zt3/uRNobL+2b/yOF7M3Td3/9W873zdkQQX930YZc -Rr8uxdRPP5bxiCgtcw632y21sSEbG9mjccAUnV/0jdvfmMNj0i8gN6E0fMBiJ9S3 -FkxX/KFvt9JWE9CtoyL7ki7UIDq+6vj7Gd5N0B3dOa1y+rRHZzKlJPcSXQSEYUS4 -HmKDwiKSVahft8c4tDn7KPi0vex91hlgZVd3usL2E/Vq7o5D9FAZ5kZY0AdFXwdm -J4lO4Mj7ac7GE4vNERNcXVIX59sCAwEAAaOB8zCB8DAdBgNVHQ4EFgQUuDU3Mr7P -T3n1e3Sy8hBauoDFahAwgcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDF -ahChgZGkgY4wgYsxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO -BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQL -EwdUZXN0aW5nMQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRl -c3QuY29tggkA6+dk+3n3IhkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC -AQEAVRG4aALIvCXCiKfe7K+iJxjBVRDFPEf7JWA9LGgbFOn6pNvbxonrR+0BETdc -JV1ET4ct2xsE7QNFIkp9GKRC+6J32zCo8qtLCD5+v436r8TUG2/t2JRMkb9I2XVT -p7RJoot6M0Ltf8KNQUPYh756xmKZ4USfQUwc58MOSDGY8VWEXJOYij9Pf0e0c52t -qiCEjXH7uXiS8Pgq9TYm7AkWSOrglYhSa83x0f8mtT8Q15nBESIHZ6o8FAS2bBgn -B0BkrKRjtBUkuJG3vTox+bYINh2Gxi1JZHWSV1tN5z3hd4VFcKqanW5OgQwToBqp -3nniskIjbH0xjgZf/nVMyLnjxg== ------END CERTIFICATE----- diff --git a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf deleted file mode 100644 index 917d495d..00000000 --- a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf +++ /dev/null @@ -1,70 +0,0 @@ -# Only WPA-PSK is used. Any valid cipher combination is accepted. -network={ - ssid="example" - proto=WPA - key_mgmt=WPA-PSK - pairwise=CCMP TKIP - group=CCMP TKIP WEP104 WEP40 - psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb - priority=2 -} - -# LEAP with dynamic WEP keys -network={ - ssid="leap-example" - key_mgmt=IEEE8021X - eap=LEAP - identity="user" - password="foobar" -} - -# Shared WEP key connection (no WPA, no IEEE 802.1X) -network={ - ssid="static-wep-test" - key_mgmt=NONE - wep_key0="abcde" - wep_key1=0102030405 - wep_key2="1234567890123" - wep_tx_keyidx=0 - priority=5 -} - -# Wildcard match for SSID (plaintext APs only). This example select any -# open AP regardless of its SSID. -network={ - key_mgmt=NONE -} - -network={ - ssid="myxjtu2" - scan_ssid=1 - key_mgmt=WPA-PSK - psk="xjtudlc3731" - disabled=0 - key_mgmt=NONE - wep_key0="12345" - wep_key1=1234567890 - wep_key2="zxcvb" - wep_tx_keyidx=1 - auth_alg=OPEN - mode=1 -} - -network={ - ssid=ab3ace - key_mgmt=WPA-EAP - eap=TTLS - identity="user@example.com" - anonymous_identity="anonymous@example.com" - password="foobar" - ca_cert="test_ca_cert.pem" - phase2="auth=CHAP" - priority=20 -} - -network={ - ssid="test-with-hash-in-psk" - key_mgmt=WPA-PSK - psk="xjtudlc3731###asdfasdfasdf" -} - diff --git a/src/settings/plugins/ifupdown/meson.build b/src/settings/plugins/ifupdown/meson.build new file mode 100644 index 00000000..fd028f4d --- /dev/null +++ b/src/settings/plugins/ifupdown/meson.build @@ -0,0 +1,53 @@ +sources = files( + 'nms-ifupdown-interface-parser.c', + 'nms-ifupdown-parser.c' +) + +deps = [ + libudev_dep, + nm_dep +] + +cflags = '-DSYSCONFDIR="@0@"'.format(nm_sysconfdir) + +libnms_ifupdown_core = static_library( + 'nms-ifupdown-core', + sources: sources, + dependencies: deps, + c_args: cflags +) + +sources = files( + 'nms-ifupdown-connection.c', + 'nms-ifupdown-plugin.c' +) + +libnm_settings_plugin_ifupdown = shared_module( + 'nm-settings-plugin-ifupdown', + sources: sources, + dependencies: deps, + c_args: cflags, + link_with: libnms_ifupdown_core, + link_args: ldflags_linker_script_settings, + link_depends: linker_script_settings, + install: true, + install_dir: nm_plugindir +) + +core_plugins += libnm_settings_plugin_ifupdown + +# FIXME: check_so_symbols replacement +''' +run_target( + 'check-local-symbols-settings-ifupdown', + command: [check_so_symbols, libnm_settings_plugin_ifupdown.full_path()], + depends: libnm_settings_plugin_ifupdown +) + +check-local-symbols-settings-ifupdown: src/settings/plugins/ifupdown/libnm-settings-plugin-ifupdown.la + $(call check_so_symbols,$(builddir)/src/settings/plugins/ifupdown/.libs/libnm-settings-plugin-ifupdown.so) +''' + +if enable_tests + subdir('tests') +endif diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c index 8421afc2..94a65ecb 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c @@ -126,11 +126,10 @@ _recursive_ifparser (const char *eni_file, int quiet) if (!quiet) nm_log_info (LOGD_SETTINGS, " interface-parser: parsing file %s\n", 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 *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; @@ -169,7 +168,7 @@ _recursive_ifparser (const char *eni_file, int quiet) continue; } -#define SPACES " \t" +#define SPACES " \t" /* tokenize input; */ for (toknum = 0, token[toknum] = strtok_r(line, SPACES, &safeptr); token[toknum] != NULL; diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h index bf9c4465..7e6c8e34 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h +++ b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h @@ -20,7 +20,6 @@ * (C) Copyright 2004 Tom Parker */ - #ifndef _INTERFACE_PARSER_H #define _INTERFACE_PARSER_H diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-parser.c b/src/settings/plugins/ifupdown/nms-ifupdown-parser.c index 99879c92..884c6591 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-parser.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-parser.c @@ -37,7 +37,6 @@ #include "nms-ifupdown-plugin.h" #include "nms-ifupdown-parser.h" - static const gchar* _ifupdownplugin_guess_connection_type (if_block *block) { @@ -63,7 +62,6 @@ _ifupdownplugin_guess_connection_type (if_block *block) return ret_type; } - struct _Mapping { const gchar *domain; const gpointer target; @@ -340,7 +338,7 @@ update_wireless_security_setting_from_if_block(NMConnection *connection, } g_object_set(wireless_security_setting, - newkey, typed_property_value ? typed_property_value : property_value, + newkey, typed_property_value ?: property_value, NULL); security = TRUE; @@ -388,7 +386,7 @@ update_wireless_security_setting_from_if_block(NMConnection *connection, } g_object_set(wireless_security_setting, - newkey, typed_property_value ? typed_property_value : property_value, + newkey, typed_property_value ?: property_value, NULL); security = TRUE; @@ -401,7 +399,6 @@ update_wireless_security_setting_from_if_block(NMConnection *connection, curr = curr->next; } - if (security) nm_connection_add_setting (connection, NM_SETTING (wireless_security_setting)); } diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c index bfad9d15..8bd72d02 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c @@ -50,9 +50,6 @@ #define ENI_INTERFACES_FILE "/etc/network/interfaces" -#define IFUPDOWN_PLUGIN_NAME "ifupdown" -#define IFUPDOWN_PLUGIN_INFO "(C) 2008 Canonical Ltd. To report bugs please use the NetworkManager mailing list." - #define IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT TRUE /* #define ALWAYS_UNMANAGE TRUE */ @@ -302,28 +299,6 @@ get_unmanaged_specs (NMSettingsPlugin *config) /*****************************************************************************/ -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - switch (prop_id) { - case NM_SETTINGS_PLUGIN_PROP_NAME: - g_value_set_string (value, IFUPDOWN_PLUGIN_NAME); - break; - case NM_SETTINGS_PLUGIN_PROP_INFO: - g_value_set_string (value, IFUPDOWN_PLUGIN_INFO); - break; - case NM_SETTINGS_PLUGIN_PROP_CAPABILITIES: - g_value_set_uint (value, NM_SETTINGS_PLUGIN_CAP_NONE); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/*****************************************************************************/ - static void _udev_device_unref (gpointer ptr) { @@ -513,19 +488,6 @@ settings_plugin_ifupdown_class_init (SettingsPluginIfupdownClass *req_class) GObjectClass *object_class = G_OBJECT_CLASS (req_class); object_class->dispose = dispose; - object_class->get_property = get_property; - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_NAME, - NM_SETTINGS_PLUGIN_NAME); - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_INFO, - NM_SETTINGS_PLUGIN_INFO); - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_CAPABILITIES, - NM_SETTINGS_PLUGIN_CAPABILITIES); } static void diff --git a/src/settings/plugins/ifupdown/tests/meson.build b/src/settings/plugins/ifupdown/tests/meson.build new file mode 100644 index 00000000..ee3b6a34 --- /dev/null +++ b/src/settings/plugins/ifupdown/tests/meson.build @@ -0,0 +1,15 @@ +test_unit = 'test-ifupdown' + +exe = executable( + test_unit, + test_unit + '.c', + dependencies: test_nm_dep, + c_args: nm_build_cflags, + link_with: libnms_ifupdown_core +) + +test( + 'ifupdown/' + test_unit, + test_script, + args: test_args + [exe.full_path()] +) diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c index d037b8a6..18bad65e 100644 --- a/src/settings/plugins/ifupdown/tests/test-ifupdown.c +++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c @@ -29,6 +29,10 @@ #include "nm-test-utils-core.h" +#define TEST_DIR NM_BUILD_SRCDIR"/src/settings/plugins/ifupdown/tests" + +/*****************************************************************************/ + typedef struct { char *key; char *data; @@ -168,7 +172,7 @@ dump_blocks (void) for (n = ifparser_getfirst (); n != NULL; n = n->next) { if_data *m; - // each block start with its type & 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); @@ -659,45 +663,45 @@ main (int argc, char **argv) if (0) dump_blocks (); - g_test_add_data_func ("/ifupdate/ignore_line_before_first_block", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/ignore_line_before_first_block", TEST_DIR, (GTestDataFunc) test1_ignore_line_before_first_block); - g_test_add_data_func ("/ifupdate/wrapped_line", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/wrapped_line", TEST_DIR, (GTestDataFunc) test2_wrapped_line); - g_test_add_data_func ("/ifupdate/wrapped_multiline_multiarg", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/wrapped_multiline_multiarg", TEST_DIR, (GTestDataFunc) test3_wrapped_multiline_multiarg); - g_test_add_data_func ("/ifupdate/allow_auto_is_auto", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/allow_auto_is_auto", TEST_DIR, (GTestDataFunc) test4_allow_auto_is_auto); - g_test_add_data_func ("/ifupdate/allow_auto_multiarg", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/allow_auto_multiarg", TEST_DIR, (GTestDataFunc) test5_allow_auto_multiarg); - g_test_add_data_func ("/ifupdate/mixed_whitespace", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/mixed_whitespace", TEST_DIR, (GTestDataFunc) test6_mixed_whitespace); - g_test_add_data_func ("/ifupdate/long_line", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/long_line", TEST_DIR, (GTestDataFunc) test7_long_line); - g_test_add_data_func ("/ifupdate/long_line_wrapped", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/long_line_wrapped", TEST_DIR, (GTestDataFunc) test8_long_line_wrapped); - g_test_add_data_func ("/ifupdate/wrapped_lines_in_block", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/wrapped_lines_in_block", TEST_DIR, (GTestDataFunc) test9_wrapped_lines_in_block); - g_test_add_data_func ("/ifupdate/complex_wrap", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/complex_wrap", TEST_DIR, (GTestDataFunc) test11_complex_wrap); - g_test_add_data_func ("/ifupdate/complex_wrap_split_word", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/complex_wrap_split_word", TEST_DIR, (GTestDataFunc) test12_complex_wrap_split_word); - g_test_add_data_func ("/ifupdate/more_mixed_whitespace", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/more_mixed_whitespace", TEST_DIR, (GTestDataFunc) test13_more_mixed_whitespace); - g_test_add_data_func ("/ifupdate/mixed_whitespace_block_start", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/mixed_whitespace_block_start", TEST_DIR, (GTestDataFunc) test14_mixed_whitespace_block_start); - g_test_add_data_func ("/ifupdate/trailing_space", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/trailing_space", TEST_DIR, (GTestDataFunc) test15_trailing_space); - g_test_add_data_func ("/ifupdate/missing_newline", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/missing_newline", TEST_DIR, (GTestDataFunc) test16_missing_newline); - g_test_add_data_func ("/ifupdate/read_static_ipv4", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/read_static_ipv4", TEST_DIR, (GTestDataFunc) test17_read_static_ipv4); - g_test_add_data_func ("/ifupdate/read_static_ipv6", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/read_static_ipv6", TEST_DIR, (GTestDataFunc) test18_read_static_ipv6); - g_test_add_data_func ("/ifupdate/read_static_ipv4_plen", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/read_static_ipv4_plen", TEST_DIR, (GTestDataFunc) test19_read_static_ipv4_plen); - g_test_add_data_func ("/ifupdate/source_stanza", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/source_stanza", TEST_DIR, (GTestDataFunc) test20_source_stanza); - g_test_add_data_func ("/ifupdate/source_dir_stanza", TEST_ENI_DIR, + g_test_add_data_func ("/ifupdate/source_dir_stanza", TEST_DIR, (GTestDataFunc) test21_source_dir_stanza); 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 e6299d1e..3723db94 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-plugin.c +++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.c @@ -436,7 +436,7 @@ read_connections (NMSettingsPlugin *config) return; } - alive_connections = g_hash_table_new (NULL, NULL); + alive_connections = g_hash_table_new (nm_direct_hash, NULL); filenames = g_ptr_array_new_with_free_func (g_free); while ((item = g_dir_read_name (dir))) { @@ -561,28 +561,6 @@ get_unmanaged_specs (NMSettingsPlugin *config) /*****************************************************************************/ -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - switch (prop_id) { - case NM_SETTINGS_PLUGIN_PROP_NAME: - g_value_set_string (value, NMS_KEYFILE_PLUGIN_NAME); - break; - case NM_SETTINGS_PLUGIN_PROP_INFO: - g_value_set_string (value, NMS_KEYFILE_PLUGIN_INFO); - break; - case NM_SETTINGS_PLUGIN_PROP_CAPABILITIES: - g_value_set_uint (value, NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/*****************************************************************************/ - static void nms_keyfile_plugin_init (NMSKeyfilePlugin *plugin) { @@ -644,19 +622,6 @@ nms_keyfile_plugin_class_init (NMSKeyfilePluginClass *req_class) object_class->constructed = constructed; object_class->dispose = dispose; - object_class->get_property = get_property; - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_NAME, - NM_SETTINGS_PLUGIN_NAME); - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_INFO, - NM_SETTINGS_PLUGIN_INFO); - - g_object_class_override_property (object_class, - NM_SETTINGS_PLUGIN_PROP_CAPABILITIES, - NM_SETTINGS_PLUGIN_CAPABILITIES); } static void diff --git a/src/settings/plugins/keyfile/nms-keyfile-utils.h b/src/settings/plugins/keyfile/nms-keyfile-utils.h index be7d668a..cd3f42b9 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-utils.h +++ b/src/settings/plugins/keyfile/nms-keyfile-utils.h @@ -23,9 +23,6 @@ #include "NetworkManagerUtils.h" -#define NMS_KEYFILE_PLUGIN_NAME "keyfile" -#define NMS_KEYFILE_PLUGIN_INFO "(c) 2007 - 2016 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." - #define NMS_KEYFILE_CONNECTION_LOG_PATH(path) ((path) ?: "in-memory") #define NMS_KEYFILE_CONNECTION_LOG_FMT "%s (%s,\"%s\")" #define NMS_KEYFILE_CONNECTION_LOG_ARG(con) NMS_KEYFILE_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_connection_get_uuid ((NMConnection *) (con)), nm_connection_get_id ((NMConnection *) (con)) diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection index 5cb4d726..1e62f4b3 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection @@ -15,7 +15,7 @@ mtu=1400 [ipv4] method=manual -dns=4.2.2.1;4.2.2.2; +dns=4.2.2.1;bogus;4.2.2.2; addresses1=192.168.0.5;24;192.168.0.1; addresses2=1.2.3.4;16;1.2.1.1; address=2.3.4.5/24,2.3.4.6 @@ -26,15 +26,21 @@ routes1=1.2.3.0/24,2.3.4.8,99 route=5.6.7.8/32 routes2=1.1.1.2/12, routes3=1.1.1.3/13,, +routes7=1.1.1.7/17,0.0.0.0 routes4=1.1.1.4/14,2.2.2.4 +address30=1.2.3.130/24 routes5=1.1.1.5/15,2.2.2.5, routes6=1.1.1.6/16,2.2.2.6,0 -routes7=1.1.1.7/17,0.0.0.0 routes8=1.1.1.8/18,0.0.0.0, routes9=1.1.1.9/19,0.0.0.0,0 +route10=1.1.1.10/21,,0 routes10=1.1.1.10/20,,0 routes11=1.1.1.11/21,,21 routes11_options=cwnd=10,lock-cwnd=true,mtu=1430,src=7.7.7.7 +address30=1.2.3.30/24 +addresses30=1.2.3.30/25 +addresses31=1.2.3.31/25 +address31=1.2.3.31/24 ignore-auto-routes=false ignore-auto-dns=false diff --git a/src/settings/plugins/keyfile/tests/meson.build b/src/settings/plugins/keyfile/tests/meson.build new file mode 100644 index 00000000..33aaa264 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/meson.build @@ -0,0 +1,16 @@ +test_unit = 'test-keyfile' + +test_keyfiles_dir = join_paths(meson.current_source_dir(), 'keyfiles') + +exe = executable( + test_unit, + test_unit + '.c', + dependencies: test_nm_dep, + c_args: nm_build_cflags, +) + +test( + 'keyfile/' + test_unit, + test_script, + args: test_args + [exe.full_path()] +) diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c index f27efddd..a3045f7d 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile.c @@ -37,6 +37,9 @@ #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" + /*****************************************************************************/ static void @@ -231,34 +234,21 @@ test_read_valid_wired_connection (void) char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; gboolean success; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv4.addresses:*semicolon at the end*addresses1*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv4.addresses:*semicolon at the end*addresses2*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*missing prefix length*address4*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*missing prefix length*address5*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv4.routes*semicolon at the end*routes2*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv4.routes*semicolon at the end*routes3*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv4.routes*semicolon at the end*routes5*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv4.routes*semicolon at the end*routes8*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*missing prefix length*address4*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv6.address*semicolon at the end*address5*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*missing prefix length*address5*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv6.address*semicolon at the end*address7*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv6.routes*semicolon at the end*routes1*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv6.route*semicolon at the end*route6*"); + 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 = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Wired_Connection", &error); g_assert_no_error (error); g_test_assert_expected_messages (); @@ -294,19 +284,23 @@ test_read_valid_wired_connection (void) 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), ==, 6); + 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), ==, 12); + g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 13); 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); @@ -317,11 +311,12 @@ test_read_valid_wired_connection (void) 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", 20, NULL, 0); - check_ip_route (s_ip4, 11, "1.1.1.11", 21, NULL, 21); + 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); /* Route attributes */ - route = nm_setting_ip_config_get_route (s_ip4, 11); + 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); @@ -408,7 +403,6 @@ add_one_ip_route (NMSettingIPConfig *s_ip, nm_ip_route_unref (route); } - static void test_write_wired_connection (void) { @@ -649,12 +643,9 @@ test_read_wired_mac_case (void) char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55 }; gboolean success; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv4.addresses*semicolon at the end*addresses1*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv4.addresses*semicolon at the end*addresses2*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*ipv6.routes*semicolon at the end*routes1*"); + 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 = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Wired_Connection_MAC_Case", NULL); g_test_assert_expected_messages (); g_assert (connection); @@ -1415,10 +1406,8 @@ test_read_wired_8021x_tls_blob_connection (void) gboolean success; GBytes *blob; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "* * keyfile: 802-1x.client-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "* * keyfile: 802-1x.private-key: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.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 = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Wired_TLS_Blob", &error); g_assert_no_error (error); g_assert (connection); @@ -1447,8 +1436,7 @@ test_read_wired_8021x_tls_blob_connection (void) g_assert_cmpint (nm_setting_802_1x_get_ca_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_BLOB); /* Make sure it's not a path, since it's a blob */ - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, - NMTST_G_RETURN_MSG (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)); + 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); @@ -1476,8 +1464,7 @@ test_read_wired_8021x_tls_bad_path_connection (void) char *tmp2; gboolean success; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*does not exist*"); + NMTST_EXPECT_NM_WARN ("*does not exist*"); connection = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Wired_TLS_Path_Missing", &error); g_test_assert_expected_messages (); g_assert_no_error (error); @@ -1530,12 +1517,9 @@ test_read_wired_8021x_tls_old_connection (void) const char *tmp; gboolean success; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "* * keyfile: 802-1x.ca-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem' does not exist*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "* * keyfile: 802-1x.client-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "* * keyfile: 802-1x.private-key: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); + 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 = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Wired_TLS_Old", &error); g_assert_no_error (error); g_assert (connection); @@ -2433,7 +2417,6 @@ test_read_minimal (void) &s_con); 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), @@ -2442,7 +2425,6 @@ test_read_minimal (void) 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), @@ -2469,7 +2451,6 @@ test_read_minimal_slave (void) NULL); nmtst_connection_normalize (con_archetype); - 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), @@ -2478,7 +2459,6 @@ test_read_minimal_slave (void) 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), diff --git a/src/settings/plugins/meson.build b/src/settings/plugins/meson.build new file mode 100644 index 00000000..a1aa7823 --- /dev/null +++ b/src/settings/plugins/meson.build @@ -0,0 +1,15 @@ +if enable_ibft + subdir('ibft') +endif + +if enable_ifcfg_rh + subdir('ifcfg-rh') +endif + +if enable_ifupdown + subdir('ifupdown') +endif + +if enable_tests + subdir('keyfile/tests') +endif -- cgit 1.3.0-6-gf8a5