diff options
| author | Michael Biebl <biebl@debian.org> | 2021-02-11 18:11:46 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2021-02-11 18:11:46 +0100 |
| commit | 80ec1decc49c72efec2a8b87c06245c92c0ab807 (patch) | |
| tree | e3b229aa94e8dcf0590f2317664176e7b8f7607b /src/nm-pacrunner-manager.c | |
| parent | 65f86e8f56267192d42f2b629fc6b0c99fb9cd0c (diff) | |
New upstream version 1.29.90 upstream/1.29.90
Diffstat (limited to 'src/nm-pacrunner-manager.c')
| -rw-r--r-- | src/nm-pacrunner-manager.c | 616 |
1 files changed, 0 insertions, 616 deletions
diff --git a/src/nm-pacrunner-manager.c b/src/nm-pacrunner-manager.c deleted file mode 100644 index 0fb31984..00000000 --- a/src/nm-pacrunner-manager.c +++ /dev/null @@ -1,616 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2016 Atul Anand <atulhjp@gmail.com>. - */ - -#include "nm-default.h" - -#include "nm-pacrunner-manager.h" - -#include "nm-utils.h" -#include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" -#include "nm-dbus-manager.h" -#include "nm-proxy-config.h" -#include "nm-ip4-config.h" -#include "nm-ip6-config.h" -#include "c-list/src/c-list.h" -#include "nm-glib-aux/nm-dbus-aux.h" - -#define PACRUNNER_DBUS_SERVICE "org.pacrunner" -#define PACRUNNER_DBUS_INTERFACE "org.pacrunner.Manager" -#define PACRUNNER_DBUS_PATH "/org/pacrunner/manager" - -/*****************************************************************************/ - -struct _NMPacrunnerConfId { - CList conf_id_lst; - - NMPacrunnerManager *self; - - GVariant *parameters; - - char * path; - guint64 log_id; - guint refcount; -}; - -typedef struct { - GDBusConnection *dbus_connection; - GCancellable * cancellable; - CList conf_id_lst_head; - guint64 log_id_counter; - guint name_owner_changed_id; - bool dbus_initied : 1; - bool has_name_owner : 1; - bool try_start_blocked : 1; -} NMPacrunnerManagerPrivate; - -struct _NMPacrunnerManager { - GObject parent; - NMPacrunnerManagerPrivate _priv; -}; - -struct _NMPacrunnerManagerClass { - GObjectClass parent; -}; - -G_DEFINE_TYPE(NMPacrunnerManager, nm_pacrunner_manager, G_TYPE_OBJECT) - -#define NM_PACRUNNER_MANAGER_GET_PRIVATE(self) \ - _NM_GET_PRIVATE(self, NMPacrunnerManager, NM_IS_PACRUNNER_MANAGER) - -/*****************************************************************************/ - -NM_DEFINE_SINGLETON_GETTER(NMPacrunnerManager, nm_pacrunner_manager_get, NM_TYPE_PACRUNNER_MANAGER); - -/*****************************************************************************/ - -#define _NMLOG_DOMAIN LOGD_PROXY -#define _NMLOG(level, ...) __NMLOG_DEFAULT(level, _NMLOG_DOMAIN, "pacrunner", __VA_ARGS__) - -#define _NMLOG2_PREFIX_NAME "pacrunner" -#define _NMLOG2(level, conf_id, ...) \ - G_STMT_START \ - { \ - nm_log((level), \ - _NMLOG_DOMAIN, \ - NULL, \ - NULL, \ - "%s%" G_GUINT64_FORMAT "]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG2_PREFIX_NAME ": call[", \ - (conf_id)->log_id _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - G_STMT_END - -/*****************************************************************************/ - -static void _call_destroy_proxy_configuration(NMPacrunnerManager *self, - NMPacrunnerConfId * conf_id, - const char * path, - gboolean verbose_log); - -/*****************************************************************************/ - -static NMPacrunnerConfId * -conf_id_ref(NMPacrunnerConfId *conf_id) -{ - nm_assert(conf_id); - nm_assert(conf_id->refcount > 0); - - conf_id->refcount++; - return conf_id; -} - -static void -conf_id_unref(NMPacrunnerConfId *conf_id) -{ - nm_assert(conf_id); - nm_assert(conf_id->refcount > 0); - - if (conf_id->refcount == 1) { - g_variant_unref(conf_id->parameters); - g_free(conf_id->path); - c_list_unlink_stale(&conf_id->conf_id_lst); - g_object_unref(conf_id->self); - g_slice_free(NMPacrunnerConfId, conf_id); - } else - conf_id->refcount--; -} - -NM_AUTO_DEFINE_FCN0(NMPacrunnerConfId *, _nm_auto_unref_conf_id, conf_id_unref); -#define nm_auto_unref_conf_id nm_auto(_nm_auto_unref_conf_id) - -/*****************************************************************************/ - -static void -get_ip_domains(GPtrArray *domains, NMIPConfig *ip_config) -{ - NMDedupMultiIter ipconf_iter; - char * cidr; - guint i, num; - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - int addr_family; - - if (!ip_config) - return; - - addr_family = nm_ip_config_get_addr_family(ip_config); - - num = nm_ip_config_get_num_searches(ip_config); - for (i = 0; i < num; i++) - g_ptr_array_add(domains, g_strdup(nm_ip_config_get_search(ip_config, i))); - - num = nm_ip_config_get_num_domains(ip_config); - for (i = 0; i < num; i++) - g_ptr_array_add(domains, g_strdup(nm_ip_config_get_domain(ip_config, i))); - - if (addr_family == AF_INET) { - const NMPlatformIP4Address *address; - - nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, (NMIP4Config *) ip_config, &address) { - cidr = g_strdup_printf("%s/%u", - _nm_utils_inet4_ntop(address->address, sbuf), - address->plen); - g_ptr_array_add(domains, cidr); - } - } else { - const NMPlatformIP6Address *address; - - nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, (NMIP6Config *) ip_config, &address) { - cidr = g_strdup_printf("%s/%u", - _nm_utils_inet6_ntop(&address->address, sbuf), - address->plen); - g_ptr_array_add(domains, cidr); - } - } - - if (addr_family == AF_INET) { - const NMPlatformIP4Route *routes; - - nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, (NMIP4Config *) ip_config, &routes) { - if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(routes)) - continue; - cidr = - g_strdup_printf("%s/%u", _nm_utils_inet4_ntop(routes->network, sbuf), routes->plen); - g_ptr_array_add(domains, cidr); - } - } else { - const NMPlatformIP6Route *routes; - - nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, (NMIP6Config *) ip_config, &routes) { - if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(routes)) - continue; - cidr = g_strdup_printf("%s/%u", - _nm_utils_inet6_ntop(&routes->network, sbuf), - routes->plen); - g_ptr_array_add(domains, cidr); - } - } -} - -static GVariant * -_make_request_create_proxy_configuration(NMProxyConfig *proxy_config, - const char * iface, - NMIP4Config * ip4_config, - NMIP6Config * ip6_config) -{ - GVariantBuilder builder; - NMProxyConfigMethod method; - const char * pac_url; - const char * pac_script; - - nm_assert(NM_IS_PROXY_CONFIG(proxy_config)); - - g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); - - if (iface) { - g_variant_builder_add(&builder, "{sv}", "Interface", g_variant_new_string(iface)); - } - - method = nm_proxy_config_get_method(proxy_config); - switch (method) { - case NM_PROXY_CONFIG_METHOD_AUTO: - g_variant_builder_add(&builder, "{sv}", "Method", g_variant_new_string("auto")); - - pac_url = nm_proxy_config_get_pac_url(proxy_config); - if (pac_url) { - g_variant_builder_add(&builder, "{sv}", "URL", g_variant_new_string(pac_url)); - } - - pac_script = nm_proxy_config_get_pac_script(proxy_config); - if (pac_script) { - g_variant_builder_add(&builder, "{sv}", "Script", g_variant_new_string(pac_script)); - } - break; - case NM_PROXY_CONFIG_METHOD_NONE: - g_variant_builder_add(&builder, "{sv}", "Method", g_variant_new_string("direct")); - break; - } - - g_variant_builder_add(&builder, - "{sv}", - "BrowserOnly", - g_variant_new_boolean(nm_proxy_config_get_browser_only(proxy_config))); - - if (ip4_config || ip6_config) { - gs_unref_ptrarray GPtrArray *domains = NULL; - - domains = g_ptr_array_new_with_free_func(g_free); - - get_ip_domains(domains, NM_IP_CONFIG_CAST(ip4_config)); - get_ip_domains(domains, NM_IP_CONFIG_CAST(ip6_config)); - - if (domains->len > 0) { - g_variant_builder_add( - &builder, - "{sv}", - "Domains", - g_variant_new_strv((const char *const *) domains->pdata, domains->len)); - } - } - - return g_variant_new("(a{sv})", &builder); -} - -/*****************************************************************************/ - -static void -_call_destroy_proxy_configuration_cb(GObject *source, GAsyncResult *res, gpointer user_data) -{ - nm_auto_unref_conf_id NMPacrunnerConfId *conf_id = user_data; - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *ret = NULL; - - ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error); - if (!ret) { - if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - _LOG2T(conf_id, "destroy proxy configuration: failed with %s", error->message); - else - _LOG2T(conf_id, "destroy proxy configuration: cancelled"); - return; - } - _LOG2T(conf_id, "destroy proxy configuration: success"); -} - -static void -_call_create_proxy_configuration_cb(GObject *source, GAsyncResult *res, gpointer user_data) -{ - nm_auto_unref_conf_id NMPacrunnerConfId *conf_id = user_data; - NMPacrunnerManager * self = NM_PACRUNNER_MANAGER(conf_id->self); - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *variant = NULL; - const char * path = NULL; - - nm_assert(!conf_id->path); - - variant = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error); - - if (!variant) { - if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - _LOG2T(conf_id, "create proxy configuration failed: %s", error->message); - else - _LOG2T(conf_id, "create proxy configuration cancelled"); - return; - } - - g_variant_get(variant, "(&o)", &path); - - if (c_list_is_empty(&conf_id->conf_id_lst)) { - _LOG2T(conf_id, - "create proxy configuration succeeded (%s), but destroy it right away", - path); - _call_destroy_proxy_configuration(self, conf_id, path, FALSE); - } else { - _LOG2T(conf_id, "create proxy configuration succeeded (%s)", path); - conf_id->path = g_strdup(path); - } -} - -static void -_call_destroy_proxy_configuration(NMPacrunnerManager *self, - NMPacrunnerConfId * conf_id, - const char * path, - gboolean verbose_log) -{ - NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self); - - if (verbose_log) - _LOG2T(conf_id, "destroy proxy configuration %s...", path); - - g_dbus_connection_call(priv->dbus_connection, - PACRUNNER_DBUS_SERVICE, - PACRUNNER_DBUS_PATH, - PACRUNNER_DBUS_INTERFACE, - "DestroyProxyConfiguration", - g_variant_new("(o)", path), - G_VARIANT_TYPE("()"), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - NM_SHUTDOWN_TIMEOUT_MS, - priv->cancellable, - _call_destroy_proxy_configuration_cb, - conf_id_ref(conf_id)); -} - -static void -_call_create_proxy_configuration(NMPacrunnerManager *self, - NMPacrunnerConfId * conf_id, - gboolean verbose_log) -{ - NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self); - - if (verbose_log) - _LOG2T(conf_id, "create proxy configuration..."); - - g_dbus_connection_call(priv->dbus_connection, - PACRUNNER_DBUS_SERVICE, - PACRUNNER_DBUS_PATH, - PACRUNNER_DBUS_INTERFACE, - "CreateProxyConfiguration", - conf_id->parameters, - G_VARIANT_TYPE("(o)"), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - NM_SHUTDOWN_TIMEOUT_MS, - priv->cancellable, - _call_create_proxy_configuration_cb, - conf_id_ref(conf_id)); -} - -static gboolean -_try_start_service_by_name(NMPacrunnerManager *self) -{ - NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self); - - if (priv->try_start_blocked || !priv->dbus_initied) - return FALSE; - - _LOGD("try D-Bus activating pacrunner..."); - priv->try_start_blocked = TRUE; - nm_dbus_connection_call_start_service_by_name(priv->dbus_connection, - PACRUNNER_DBUS_SERVICE, - -1, - NULL, - NULL, - NULL); - return TRUE; -} - -/*****************************************************************************/ - -/** - * nm_pacrunner_manager_add: - * @self: the #NMPacrunnerManager - * @proxy_config: proxy config of the connection - * @iface: the iface for the connection or %NULL - * @ip4_config: IP4 config of the connection to extract domain info from - * @ip6_config: IP6 config of the connection to extract domain info from - * - * Returns: a #NMPacrunnerConfId id. The function cannot - * fail and always returns a non NULL pointer. The conf-id may - * be used to remove the configuration later via nm_pacrunner_manager_remove(). - * Note that the conf-id keeps the @self instance alive. - */ -NMPacrunnerConfId * -nm_pacrunner_manager_add(NMPacrunnerManager *self, - NMProxyConfig * proxy_config, - const char * iface, - NMIP4Config * ip4_config, - NMIP6Config * ip6_config) -{ - NMPacrunnerManagerPrivate *priv; - NMPacrunnerConfId * conf_id; - gs_free char * log_msg = NULL; - - g_return_val_if_fail(NM_IS_PACRUNNER_MANAGER(self), NULL); - g_return_val_if_fail(proxy_config, NULL); - - priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self); - - conf_id = g_slice_new(NMPacrunnerConfId); - *conf_id = (NMPacrunnerConfId){ - .log_id = ++priv->log_id_counter, - .refcount = 1, - .self = g_object_ref(self), - .parameters = g_variant_ref_sink( - _make_request_create_proxy_configuration(proxy_config, iface, ip4_config, ip6_config)), - }; - c_list_link_tail(&priv->conf_id_lst_head, &conf_id->conf_id_lst); - - if (!priv->has_name_owner) { - _LOG2T(conf_id, - "add config: %s (%s)", - (log_msg = g_variant_print(conf_id->parameters, FALSE)), - "pacrunner D-Bus service not running"); - _try_start_service_by_name(self); - } else { - _LOG2T(conf_id, - "add config: %s (%s)", - (log_msg = g_variant_print(conf_id->parameters, FALSE)), - "create proxy configuration"); - _call_create_proxy_configuration(self, conf_id, FALSE); - } - - return conf_id; -} - -/** - * nm_pacrunner_manager_remove: - * @conf_id: the conf id obtained from nm_pacrunner_manager_add() - */ -void -nm_pacrunner_manager_remove(NMPacrunnerConfId *conf_id) -{ - _nm_unused nm_auto_unref_conf_id NMPacrunnerConfId *conf_id_free = conf_id; - NMPacrunnerManager * self; - NMPacrunnerManagerPrivate * priv; - - g_return_if_fail(conf_id); - - self = conf_id->self; - - g_return_if_fail(NM_IS_PACRUNNER_MANAGER(self)); - - priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self); - - _LOG2T(conf_id, "removing..."); - - nm_assert(c_list_contains(&priv->conf_id_lst_head, &conf_id->conf_id_lst)); - - c_list_unlink(&conf_id->conf_id_lst); - - if (!conf_id->path) { - /* There is no ID to destroy the configuration. - * - * That can happen because: - * - * - pacrunner D-Bus service is not running (no name owner) and we didn't call CreateProxyConfiguration. - * - CreateProxyConfiguration failed. - * - CreateProxyConfiguration is in progress. - * - * In all cases there is nothing to do. Note that if CreateProxyConfiguration is in progress - * it has a reference on the conf-id and it will automatically destroy the configuration - * when it completes. - */ - return; - } - - _call_destroy_proxy_configuration(self, conf_id, conf_id->path, TRUE); -} - -gboolean -nm_pacrunner_manager_remove_clear(NMPacrunnerConfId **p_conf_id) -{ - g_return_val_if_fail(p_conf_id, FALSE); - - if (!*p_conf_id) - return FALSE; - nm_pacrunner_manager_remove(g_steal_pointer(p_conf_id)); - return TRUE; -} - -/*****************************************************************************/ - -static void -name_owner_changed(NMPacrunnerManager *self, const char *name_owner) -{ - NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self); - NMPacrunnerConfId * conf_id; - gboolean has_name_owner; - - has_name_owner = (name_owner && name_owner[0]); - - if (priv->dbus_initied && priv->has_name_owner == has_name_owner) - return; - - priv->has_name_owner = has_name_owner; - - nm_clear_g_cancellable(&priv->cancellable); - - if (has_name_owner) { - priv->dbus_initied = TRUE; - priv->try_start_blocked = FALSE; - _LOGD("pacrunner appeared on D-Bus (%s)", name_owner); - priv->cancellable = g_cancellable_new(); - c_list_for_each_entry (conf_id, &priv->conf_id_lst_head, conf_id_lst) - _call_create_proxy_configuration(self, conf_id, TRUE); - } else { - if (!priv->dbus_initied) { - priv->dbus_initied = TRUE; - nm_assert(!priv->try_start_blocked); - _LOGD("pacrunner not on D-Bus"); - } else - _LOGD("pacrunner disappeared from D-Bus"); - if (!c_list_is_empty(&priv->conf_id_lst_head)) { - c_list_for_each_entry (conf_id, &priv->conf_id_lst_head, conf_id_lst) - nm_clear_g_free(&conf_id->path); - _try_start_service_by_name(self); - } - } -} - -static void -name_owner_changed_cb(GDBusConnection *connection, - const char * sender_name, - const char * object_path, - const char * interface_name, - const char * signal_name, - GVariant * parameters, - gpointer user_data) -{ - const char *new_owner; - - if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) - return; - - g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_owner); - - name_owner_changed(user_data, new_owner); -} - -static void -get_name_owner_cb(const char *name_owner, GError *error, gpointer user_data) -{ - if (!name_owner && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - name_owner_changed(user_data, name_owner); -} - -/*****************************************************************************/ - -static void -nm_pacrunner_manager_init(NMPacrunnerManager *self) -{ - NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self); - - c_list_init(&priv->conf_id_lst_head); - - priv->dbus_connection = nm_g_object_ref(NM_MAIN_DBUS_CONNECTION_GET); - - if (!priv->dbus_connection) { - _LOGD("no D-Bus connection to talk to pacrunner"); - return; - } - - priv->name_owner_changed_id = - nm_dbus_connection_signal_subscribe_name_owner_changed(priv->dbus_connection, - PACRUNNER_DBUS_SERVICE, - name_owner_changed_cb, - self, - NULL); - priv->cancellable = g_cancellable_new(); - - nm_dbus_connection_call_get_name_owner(priv->dbus_connection, - PACRUNNER_DBUS_SERVICE, - -1, - priv->cancellable, - get_name_owner_cb, - self); -} - -static void -dispose(GObject *object) -{ - NMPacrunnerManagerPrivate *priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(object); - - nm_assert(c_list_is_empty(&priv->conf_id_lst_head)); - - /* we cancel all pending operations. Note that pacrunner automatically - * removes all configuration once NetworkManager disconnects from - * the bus -- which happens soon after we destroy the pacrunner manager. - */ - nm_clear_g_cancellable(&priv->cancellable); - - nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->name_owner_changed_id); - g_clear_object(&priv->dbus_connection); - - G_OBJECT_CLASS(nm_pacrunner_manager_parent_class)->dispose(object); -} - -static void -nm_pacrunner_manager_class_init(NMPacrunnerManagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS(klass); - - object_class->dispose = dispose; -} |