summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Michael Brummer <jan.brummer@tabos.org>2023-03-21 02:50:57 -0400
committerJan-Michael Brummer <jan.brummer@tabos.org>2023-03-27 16:31:58 +0200
commit595451331b1e91907d987ca4b0b2ebb7e8f538bd (patch)
tree8effdda2146d78739693cda90465cfbabce1bcde
parentc82feb2cbeabc5bac70e2b5d65d2e58652bba9c0 (diff)
downloadlibproxy-git-595451331b1e91907d987ca4b0b2ebb7e8f538bd.tar.gz
Add common ignore handling (#99)
Co-authored-by: Jan-Michael Brummer <jan-michael.brummer1@volkswagen.de>
-rw-r--r--src/backend/plugins/config-env/config-env.c3
-rw-r--r--src/backend/plugins/config-gnome/config-gnome.c3
-rw-r--r--src/backend/plugins/config-kde/config-kde.c14
-rw-r--r--src/backend/plugins/config-osx/config-osx.c2
-rw-r--r--src/backend/plugins/config-sysconfig/config-sysconfig.c8
-rw-r--r--src/backend/plugins/config-windows/config-windows.c4
-rw-r--r--src/backend/px-manager.c109
-rw-r--r--src/backend/px-manager.h2
-rw-r--r--tests/config-gnome-test.c1
-rw-r--r--tests/px-manager-test.c90
10 files changed, 225 insertions, 11 deletions
diff --git a/src/backend/plugins/config-env/config-env.c b/src/backend/plugins/config-env/config-env.c
index 397fdd9..d7f5a73 100644
--- a/src/backend/plugins/config-env/config-env.c
+++ b/src/backend/plugins/config-env/config-env.c
@@ -143,9 +143,8 @@ px_config_env_get_config (PxConfig *config,
const char *proxy = NULL;
const char *scheme = g_uri_get_scheme (uri);
- if (self->no_proxy && (g_strv_contains ((const char * const *)self->no_proxy, g_uri_get_host (uri)) || g_strv_contains ((const char * const *)self->no_proxy, "*"))) {
+ if (px_manager_is_ignore (uri, self->no_proxy))
return;
- }
if (g_strcmp0 (scheme, "ftp") == 0)
proxy = self->ftp_proxy;
diff --git a/src/backend/plugins/config-gnome/config-gnome.c b/src/backend/plugins/config-gnome/config-gnome.c
index a41f54d..1d4f182 100644
--- a/src/backend/plugins/config-gnome/config-gnome.c
+++ b/src/backend/plugins/config-gnome/config-gnome.c
@@ -170,6 +170,9 @@ px_config_gnome_get_config (PxConfig *config,
g_autofree char *proxy = NULL;
GnomeProxyMode mode;
+ 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");
diff --git a/src/backend/plugins/config-kde/config-kde.c b/src/backend/plugins/config-kde/config-kde.c
index f30a130..fba7ed3 100644
--- a/src/backend/plugins/config-kde/config-kde.c
+++ b/src/backend/plugins/config-kde/config-kde.c
@@ -44,7 +44,7 @@ struct _PxConfigKde {
gboolean available;
GFileMonitor *monitor;
- char *no_proxy;
+ GStrv no_proxy;
char *http_proxy;
char *https_proxy;
char *ftp_proxy;
@@ -142,7 +142,8 @@ px_config_kde_set_config_file (PxConfigKde *self,
} else if (strcmp (kv[0], "socksProxy") == 0) {
self->socks_proxy = g_strdup (value->str);
} else if (strcmp (kv[0], "NoProxyFor") == 0) {
- self->no_proxy = g_strdup (value->str);
+ g_autofree char *no_proxy_for = g_strdup (value->str);
+ self->no_proxy = g_strsplit (no_proxy_for, ",", -1);
} else if (strcmp (kv[0], "Proxy Config Script") == 0) {
self->pac_script = g_strdup (value->str);
} else if (strcmp (kv[0], "ProxyType") == 0) {
@@ -166,7 +167,14 @@ px_config_kde_dispose (GObject *object)
{
PxConfigKde *self = PX_CONFIG_KDE (object);
+ g_clear_pointer (&self->config_file, g_free);
g_clear_object (&self->monitor);
+ g_clear_pointer (&self->no_proxy, g_strfreev);
+ g_clear_pointer (&self->http_proxy, g_free);
+ g_clear_pointer (&self->https_proxy, g_free);
+ g_clear_pointer (&self->ftp_proxy, g_free);
+ g_clear_pointer (&self->socks_proxy, g_free);
+ g_clear_pointer (&self->pac_script, g_free);
G_OBJECT_CLASS (px_config_kde_parent_class)->dispose (object);
}
@@ -241,7 +249,7 @@ px_config_kde_get_config (PxConfig *config,
if (!self->proxy_type)
return;
- if (self->no_proxy && strstr (self->no_proxy, g_uri_get_host (uri)))
+ if (px_manager_is_ignore (uri, self->no_proxy))
return;
switch (self->proxy_type) {
diff --git a/src/backend/plugins/config-osx/config-osx.c b/src/backend/plugins/config-osx/config-osx.c
index f733c93..68ce0f2 100644
--- a/src/backend/plugins/config-osx/config-osx.c
+++ b/src/backend/plugins/config-osx/config-osx.c
@@ -254,7 +254,7 @@ px_config_osx_get_config (PxConfig *self,
ignore_list = get_ignore_list (proxies);
- if (ignore_list && g_strv_contains ((const char * const *)ignore_list, g_uri_get_host (uri)))
+ if (px_manager_is_ignore (uri, ignore_list))
return;
if (getbool (proxies, "ProxyAutoDiscoveryEnable")) {
diff --git a/src/backend/plugins/config-sysconfig/config-sysconfig.c b/src/backend/plugins/config-sysconfig/config-sysconfig.c
index 1f90a44..1adc1e8 100644
--- a/src/backend/plugins/config-sysconfig/config-sysconfig.c
+++ b/src/backend/plugins/config-sysconfig/config-sysconfig.c
@@ -37,7 +37,7 @@ struct _PxConfigSysConfig {
char *https_proxy;
char *http_proxy;
char *ftp_proxy;
- char *no_proxy;
+ GStrv no_proxy;
};
static void px_config_iface_init (PxConfigInterface *iface);
@@ -133,7 +133,8 @@ px_config_sysconfig_set_config_file (PxConfigSysConfig *self,
} else if (strcmp (kv[0], "FTP_PROXY") == 0) {
self->ftp_proxy = g_strdup (value->str);
} else if (strcmp (kv[0], "NO_PROXY") == 0) {
- self->no_proxy = g_strdup (value->str);
+ g_autofree char *tmp = g_strdup (value->str);
+ self->no_proxy = g_strsplit (tmp, ",", -1);
}
}
} while (line);
@@ -190,6 +191,7 @@ px_config_sysconfig_dispose (GObject *object)
PxConfigSysConfig *self = PX_CONFIG_SYSCONFIG (object);
g_clear_object (&self->monitor);
+ g_clear_pointer (&self->no_proxy, g_strfreev);
G_OBJECT_CLASS (px_config_sysconfig_parent_class)->dispose (object);
}
@@ -226,7 +228,7 @@ px_config_sysconfig_get_config (PxConfig *config,
if (!self->proxy_enabled)
return;
- if (self->no_proxy && strstr (self->no_proxy, g_uri_get_host (uri)))
+ if (px_manager_is_ignore (uri, self->no_proxy))
return;
if (g_strcmp0 (scheme, "ftp") == 0) {
diff --git a/src/backend/plugins/config-windows/config-windows.c b/src/backend/plugins/config-windows/config-windows.c
index b623c2d..73a889a 100644
--- a/src/backend/plugins/config-windows/config-windows.c
+++ b/src/backend/plugins/config-windows/config-windows.c
@@ -159,9 +159,9 @@ px_config_windows_get_config (PxConfig *self,
guint32 enabled = 0;
if (get_registry (W32REG_BASEKEY, "ProxyOverride", &tmp, NULL, NULL)) {
- const char *host = g_uri_get_host (uri);
+ g_auto (GStrv) no_proxy = g_strsplit (tmp, ",", -1);
- if (g_strcmp0 (tmp, "<local>") == 0 && g_strcmp0 (host, "127.0.0.1") == 0)
+ if (px_manager_is_ignore (uri, no_proxy))
return;
}
diff --git a/src/backend/px-manager.c b/src/backend/px-manager.c
index 69d94fd..ef81eb1 100644
--- a/src/backend/px-manager.c
+++ b/src/backend/px-manager.c
@@ -594,3 +594,112 @@ px_strv_builder_add_proxy (GStrvBuilder *builder,
g_strv_builder_add (builder, value);
}
+
+static gboolean
+ignore_domain (GUri *uri,
+ char *ignore)
+{
+ g_auto (GStrv) ignore_split = g_strsplit (ignore, ":", -1);
+ const char *host = g_uri_get_host (uri);
+ char *ig_host;
+ int ig_port = -1;
+ int port = g_uri_get_port (uri);
+
+ /* Get our ignore pattern's hostname and port */
+ ig_host = ignore_split[0];
+ if (g_strv_length (ignore_split) == 2)
+ ig_port = atoi (ignore_split[1]);
+
+ /* Hostname match (domain.com or domain.com:80) */
+ if (g_strcmp0 (host, ig_host) == 0)
+ return (ig_port == -1 || port == ig_port);
+
+ /* Endswith (.domain.com or .domain.com:80) */
+ if (ig_host[0] == '.' && g_str_has_suffix (host, ig_host))
+ return (ig_port == -1 || port == ig_port);
+
+ /* Glob (*.domain.com or *.domain.com:80) */
+ if (ig_host[0] == '*' && g_str_has_suffix (host, ig_host + 1))
+ return (ig_port == -1 || port == ig_port);
+
+ /* No match was found */
+ return FALSE;
+}
+
+static gboolean
+ignore_hostname (GUri *uri,
+ char *ignore)
+{
+ const char *host = g_uri_get_host (uri);
+
+ g_print ("%s %s\n", ignore, host);
+
+ if (g_strcmp0 (ignore, "<local>") == 0 && strchr (host, ':') == NULL && strchr (host, '.') == NULL)
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean
+ignore_ip (GUri *uri,
+ char *ignore)
+{
+ GInetAddress *inet_address1;
+ GInetAddress *inet_address2;
+ g_auto (GStrv) ignore_split = NULL;
+ gboolean is_ip1 = g_hostname_is_ip_address (g_uri_get_host (uri));
+ gboolean is_ip2 = g_hostname_is_ip_address (ignore);
+ int port = g_uri_get_port (uri);
+ int ig_port = -1;
+ gboolean result;
+
+ /*
+ * IPv4
+ * IPv6
+ */
+ if (!is_ip1 || !is_ip2)
+ return FALSE;
+
+ /*
+ * IPv4/CIDR
+ * IPv4/IPv4
+ * IPv6/CIDR
+ * IPv6/IPv6
+ */
+
+ /* MISSING */
+
+ /*
+ * IPv4:port
+ * [IPv6]:port
+ */
+ ignore_split = g_strsplit (ignore, ":", -1);
+ if (g_strv_length (ignore_split) == 2)
+ ig_port = atoi (ignore_split[1]);
+
+ inet_address1 = g_inet_address_new_from_string (g_uri_get_host (uri));
+ inet_address2 = g_inet_address_new_from_string (ignore);
+ result = g_inet_address_equal (inet_address1, inet_address2);
+
+ return port != -1 ? ((port == ig_port) && result) : result;
+}
+gboolean
+px_manager_is_ignore (GUri *uri,
+ GStrv ignores)
+{
+ if (!ignores)
+ return FALSE;
+
+ for (int idx = 0; idx < g_strv_length (ignores); idx++) {
+ if (ignore_hostname (uri, ignores[idx]))
+ return TRUE;
+
+ if (ignore_domain (uri, ignores[idx]))
+ return TRUE;
+
+ if (ignore_ip (uri, ignores[idx]))
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/src/backend/px-manager.h b/src/backend/px-manager.h
index 2bb816b..558ddba 100644
--- a/src/backend/px-manager.h
+++ b/src/backend/px-manager.h
@@ -54,4 +54,6 @@ char **px_manager_get_configuration (PxManager *self,
void px_strv_builder_add_proxy (GStrvBuilder *builder,
const char *value);
+gboolean px_manager_is_ignore (GUri *uri, GStrv ignores);
+
G_END_DECLS
diff --git a/tests/config-gnome-test.c b/tests/config-gnome-test.c
index fc688bd..71ddb28 100644
--- a/tests/config-gnome-test.c
+++ b/tests/config-gnome-test.c
@@ -86,6 +86,7 @@ test_config_gnome_manual (Fixture *self,
g_auto (GStrv) config = NULL;
ConfigGnomeTest test = config_gnome_test_set[idx];
+ g_settings_set_strv (self->proxy_settings, "ignore-hosts", NULL);
g_settings_set_enum (self->proxy_settings, "mode", test.mode);
g_settings_set_string (self->http_proxy_settings, "host", test.proxy);
g_settings_set_int (self->http_proxy_settings, "port", test.proxy_port);
diff --git a/tests/px-manager-test.c b/tests/px-manager-test.c
index 1b1eb06..bfd3112 100644
--- a/tests/px-manager-test.c
+++ b/tests/px-manager-test.c
@@ -196,6 +196,92 @@ test_get_wpad (Fixture *self,
g_main_loop_run (self->loop);
}
+static void
+test_ignore_domain (Fixture *self,
+ const void *user_data)
+{
+ g_autoptr (GUri) uri = g_uri_parse("http://10.10.1.12", G_URI_FLAGS_PARSE_RELAXED, NULL);
+ char **ignore_list = g_malloc0 (sizeof (char *) * 2);
+ gboolean ret;
+
+ /* Invalid test */
+ ignore_list[0] = g_strdup ("10.10.1.13");
+ ignore_list[1] = NULL;
+
+ ret = px_manager_is_ignore (uri, ignore_list);
+ g_assert_false (ret);
+
+ /* Valid test */
+ ignore_list[0] = g_strdup ("10.10.1.12");
+ ignore_list[1] = NULL;
+
+ ret = px_manager_is_ignore (uri, ignore_list);
+ g_assert_true (ret);
+
+ g_free (ignore_list[0]);
+ g_free (ignore_list);
+}
+
+static void
+test_ignore_domain_port (Fixture *self,
+ const void *user_data)
+{
+ g_autoptr (GUri) uri = g_uri_parse("http://10.10.1.12:22", G_URI_FLAGS_PARSE_RELAXED, NULL);
+ char **ignore_list = g_malloc0 (sizeof (char *) * 2);
+ gboolean ret;
+
+ /* Invalid test */
+ ignore_list[0] = g_strdup ("10.10.1.13");
+ ignore_list[1] = NULL;
+
+ ret = px_manager_is_ignore (uri, ignore_list);
+ g_free (ignore_list[0]);
+ g_assert_false (ret);
+
+ /* Invalid test */
+ ignore_list[0] = g_strdup ("10.10.1.12:24");
+ ignore_list[1] = NULL;
+
+ ret = px_manager_is_ignore (uri, ignore_list);
+ g_free (ignore_list[0]);
+ g_assert_false (ret);
+
+ /* Valid test */
+ ignore_list[0] = g_strdup ("10.10.1.12:22");
+ ignore_list[1] = NULL;
+
+ ret = px_manager_is_ignore (uri, ignore_list);
+ g_assert_true (ret);
+
+ g_free (ignore_list[0]);
+ g_free (ignore_list);
+}
+
+static void
+test_ignore_hostname (Fixture *self,
+ const void *user_data)
+{
+ g_autoptr (GUri) uri = g_uri_parse("http://18.10.1.12", G_URI_FLAGS_PARSE_RELAXED, NULL);
+ char **ignore_list = g_malloc0 (sizeof (char *) * 2);
+ gboolean ret;
+
+ /* Invalid test */
+ ignore_list[0] = g_strdup ("<local>");
+ ignore_list[1] = NULL;
+
+ ret = px_manager_is_ignore (uri, ignore_list);
+ g_assert_false (ret);
+ g_uri_unref (uri);
+
+ /* Valid test */
+ uri = g_uri_parse("http://127.0.0.1", G_URI_FLAGS_PARSE_RELAXED, NULL);
+ ret = px_manager_is_ignore (uri, ignore_list);
+ g_assert_false (ret);
+
+ g_free (ignore_list[0]);
+ g_free (ignore_list);
+}
+
int
main (int argc,
char **argv)
@@ -219,6 +305,10 @@ main (int argc,
g_test_add ("/pac/get_proxies_pac", Fixture, "px-manager-pac", fixture_setup, test_get_proxies_pac, fixture_teardown);
g_test_add ("/pac/wpad", Fixture, "px-manager-wpad", fixture_setup, test_get_wpad, fixture_teardown);
+ g_test_add ("/ignore/domain", Fixture, "px-manager-ignore", fixture_setup, test_ignore_domain, fixture_teardown);
+ g_test_add ("/ignore/domain_port", Fixture, "px-manager-ignore", fixture_setup, test_ignore_domain_port, fixture_teardown);
+ g_test_add ("/ignore/hostname", Fixture, "px-manager-ignore", fixture_setup, test_ignore_hostname, fixture_teardown);
+
return g_test_run ();
}