summaryrefslogtreecommitdiff
path: root/src/backend/plugins/config-gnome/config-gnome.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/plugins/config-gnome/config-gnome.c')
-rw-r--r--src/backend/plugins/config-gnome/config-gnome.c246
1 files changed, 246 insertions, 0 deletions
diff --git a/src/backend/plugins/config-gnome/config-gnome.c b/src/backend/plugins/config-gnome/config-gnome.c
new file mode 100644
index 0000000..9d6fd68
--- /dev/null
+++ b/src/backend/plugins/config-gnome/config-gnome.c
@@ -0,0 +1,246 @@
+/* config-gnome.c
+ *
+ * Copyright 2022-2023 The Libproxy Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include <gio/gio.h>
+
+#include "config-gnome.h"
+
+#include "px-plugin-config.h"
+#include "px-manager.h"
+
+struct _PxConfigGnome {
+ GObject parent_instance;
+ GSettings *proxy_settings;
+ GSettings *http_proxy_settings;
+ GSettings *https_proxy_settings;
+ GSettings *ftp_proxy_settings;
+ GSettings *socks_proxy_settings;
+ gboolean available;
+};
+
+typedef enum {
+ GNOME_PROXY_MODE_NONE,
+ GNOME_PROXY_MODE_MANUAL,
+ GNOME_PROXY_MODE_AUTO
+} GnomeProxyMode;
+
+static void px_config_iface_init (PxConfigInterface *iface);
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (PxConfigGnome,
+ px_config_gnome,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (PX_TYPE_CONFIG, px_config_iface_init))
+
+enum {
+ PROP_0,
+ PROP_CONFIG_OPTION
+};
+
+static void
+px_config_gnome_init (PxConfigGnome *self)
+{
+ GSettingsSchemaSource *source;
+ GSettingsSchema *proxy_schema;
+ const char *desktops;
+
+ self->available = FALSE;
+
+ desktops = getenv ("XDG_CURRENT_DESKTOP");
+ if (!desktops)
+ return;
+
+ /* Remember that XDG_CURRENT_DESKTOP is a list of strings. */
+ if (strstr (desktops, "GNOME") == NULL)
+ return;
+
+ source = g_settings_schema_source_get_default ();
+ if (!source) {
+ g_warning ("GNOME desktop detected but no schemes installed, aborting.");
+ return;
+ }
+
+ proxy_schema = g_settings_schema_source_lookup (source, "org.gnome.system.proxy", TRUE);
+
+ self->available = proxy_schema != NULL;
+ g_clear_pointer (&proxy_schema, g_settings_schema_unref);
+
+ if (!self->available)
+ return;
+
+ self->proxy_settings = g_settings_new ("org.gnome.system.proxy");
+ self->http_proxy_settings = g_settings_new ("org.gnome.system.proxy.http");
+ self->https_proxy_settings = g_settings_new ("org.gnome.system.proxy.https");
+ self->ftp_proxy_settings = g_settings_new ("org.gnome.system.proxy.ftp");
+ self->socks_proxy_settings = g_settings_new ("org.gnome.system.proxy.socks");
+}
+
+static void
+px_config_gnome_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_CONFIG_OPTION:
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+px_config_gnome_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_CONFIG_OPTION:
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+px_config_gnome_class_init (PxConfigGnomeClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->set_property = px_config_gnome_set_property;
+ object_class->get_property = px_config_gnome_get_property;
+
+ g_object_class_override_property (object_class, PROP_CONFIG_OPTION, "config-option");
+}
+
+static gboolean
+px_config_gnome_is_available (PxConfig *config)
+{
+ PxConfigGnome *self = PX_CONFIG_GNOME (config);
+
+ return self->available;
+}
+
+static void
+store_response (GStrvBuilder *builder,
+ const char *type,
+ char *host,
+ int port,
+ gboolean auth,
+ char *username,
+ char *password)
+{
+ if (type && host && strlen (type) > 0 && strlen (host) > 0 && port != 0) {
+ g_autoptr (GString) tmp = g_string_new (type);
+
+ g_string_append (tmp, "://");
+ if (auth)
+ g_string_append_printf (tmp, "%s:%s@", username, password);
+
+ g_string_append_printf (tmp, "%s:%d", host, port);
+
+ px_strv_builder_add_proxy (builder, tmp->str);
+ }
+}
+
+static void
+px_config_gnome_get_config (PxConfig *config,
+ GUri *uri,
+ GStrvBuilder *builder)
+{
+ PxConfigGnome *self = PX_CONFIG_GNOME (config);
+ g_autofree char *proxy = NULL;
+ GnomeProxyMode mode;
+
+ if (!self->available)
+ return;
+
+ if (px_manager_is_ignore (uri, g_settings_get_strv (self->proxy_settings, "ignore-hosts")))
+ return;
+
+ mode = g_settings_get_enum (self->proxy_settings, "mode");
+ if (mode == GNOME_PROXY_MODE_AUTO) {
+ char *autoconfig_url = g_settings_get_string (self->proxy_settings, "autoconfig-url");
+
+ if (strlen (autoconfig_url) != 0)
+ proxy = g_strdup_printf ("pac+%s", autoconfig_url);
+ else
+ proxy = g_strdup ("wpad://");
+
+ px_strv_builder_add_proxy (builder, proxy);
+ } else if (mode == GNOME_PROXY_MODE_MANUAL) {
+ g_autofree char *username = g_settings_get_string (self->http_proxy_settings, "authentication-user");
+ g_autofree char *password = g_settings_get_string (self->http_proxy_settings, "authentication-password");
+ const char *scheme = g_uri_get_scheme (uri);
+ gboolean auth = g_settings_get_boolean (self->http_proxy_settings, "use-authentication");
+
+ if (g_strcmp0 (scheme, "http") == 0) {
+ g_autofree char *host = g_settings_get_string (self->http_proxy_settings, "host");
+ store_response (builder,
+ "http",
+ host,
+ g_settings_get_int (self->http_proxy_settings, "port"),
+ auth,
+ username,
+ password);
+ } else if (g_strcmp0 (scheme, "https") == 0) {
+ g_autofree char *host = g_settings_get_string (self->https_proxy_settings, "host");
+ store_response (builder,
+ "http",
+ host,
+ g_settings_get_int (self->https_proxy_settings, "port"),
+ auth,
+ username,
+ password);
+ } else if (g_strcmp0 (scheme, "ftp") == 0) {
+ g_autofree char *host = g_settings_get_string (self->ftp_proxy_settings, "host");
+ store_response (builder,
+ "http",
+ host,
+ g_settings_get_int (self->ftp_proxy_settings, "port"),
+ auth,
+ username,
+ password);
+ } else {
+ g_autofree char *host = g_settings_get_string (self->socks_proxy_settings, "host");
+ store_response (builder,
+ "socks",
+ host,
+ g_settings_get_int (self->socks_proxy_settings, "port"),
+ auth,
+ username,
+ password);
+ }
+ }
+}
+
+static void
+px_config_iface_init (PxConfigInterface *iface)
+{
+ iface->name = "config-gnome";
+ iface->priority = PX_CONFIG_PRIORITY_DEFAULT;
+ iface->is_available = px_config_gnome_is_available;
+ iface->get_config = px_config_gnome_get_config;
+}