diff --git a/pidgin-add-no_proxy-support.patch b/pidgin-add-no_proxy-support.patch new file mode 100644 index 0000000..304e343 --- /dev/null +++ b/pidgin-add-no_proxy-support.patch @@ -0,0 +1,305 @@ +diff --unified --recursive --text --new-file --color pidgin-2.14.5.old/ChangeLog pidgin-2.14.5.new/ChangeLog +--- pidgin-2.14.5.old/ChangeLog 2021-06-24 14:17:08.444727946 +0800 ++++ pidgin-2.14.5.new/ChangeLog 2021-06-24 14:17:17.098045115 +0800 +@@ -103,6 +103,10 @@ + Bonjour: + * Always use port fallback for IPv4 addresses. (PR #382 Michael Osborne) + ++ libpurple: ++ * added support for the no_proxy environment variable. (PIDGIN-17518) ++ (RR #667) (Alynx Zhou and Gary Kramlich) ++ + XMPP: + * Support for XEP-0198 Stream Management (PR #309 defanor) + * Decrease delay for file transfer using streamhosts (PR #464 #627 Evert +diff --unified --recursive --text --new-file --color pidgin-2.14.5.old/COPYRIGHT pidgin-2.14.5.new/COPYRIGHT +--- pidgin-2.14.5.old/COPYRIGHT 2021-06-24 14:17:08.438061292 +0800 ++++ pidgin-2.14.5.new/COPYRIGHT 2021-06-24 14:17:17.098045115 +0800 +@@ -651,6 +651,7 @@ + Jan Zachorowski + zelch + Nickolai Zeldovich ++Alynx Zhou + Tom Zickel + Marco Ziech + Piotr Zielinski +diff --unified --recursive --text --new-file --color pidgin-2.14.5.old/libpurple/proxy.c pidgin-2.14.5.new/libpurple/proxy.c +--- pidgin-2.14.5.old/libpurple/proxy.c 2021-06-24 14:17:08.454727928 +0800 ++++ pidgin-2.14.5.new/libpurple/proxy.c 2021-06-24 14:17:17.098045115 +0800 +@@ -90,6 +90,12 @@ + + static PurpleProxyInfo *global_proxy_info = NULL; + ++typedef struct { ++ gchar *hostname; ++ gint port; ++} PurpleProxyNoProxyEntry; ++static GList *no_proxy_entries = NULL; ++ + static GSList *handles = NULL; + + static void try_connect(PurpleProxyConnectData *connect_data); +@@ -205,6 +211,118 @@ + } + + /************************************************************************** ++ * no proxy helpers ++ **************************************************************************/ ++static PurpleProxyNoProxyEntry * ++purple_proxy_no_proxy_entry_new(const gchar *hostname, gint port) { ++ PurpleProxyNoProxyEntry *entry = NULL; ++ ++ entry = g_new(PurpleProxyNoProxyEntry, 1); ++ entry->hostname = g_strdup(hostname); ++ entry->port = port; ++ ++ return entry; ++} ++ ++static void ++purple_proxy_no_proxy_entry_free(PurpleProxyNoProxyEntry *entry) { ++ g_free(entry->hostname); ++ g_free(entry); ++} ++ ++static gint ++purple_proxy_no_proxy_compare(gconstpointer a, gconstpointer b) { ++ const PurpleProxyNoProxyEntry *entry, *connection; ++ ++ entry = (const PurpleProxyNoProxyEntry *)a; ++ connection = (const PurpleProxyNoProxyEntry *)b; ++ ++ /* check port first as it's quicker */ ++ if(entry->port != 0 && entry->port != connection->port) { ++ return -1; ++ } ++ ++ /* * is used to match any host, but this check needs to be after the port ++ * because *:6667 is a valid entry. ++ */ ++ if(purple_strequal(entry->hostname, "*")) { ++ return 0; ++ } ++ ++ /* if the host name matches, don't proxy it */ ++ if(purple_strequal(connection->hostname, entry->hostname)) { ++ return 0; ++ } ++ ++ /* finally check if the requested host has a known suffix */ ++ if(g_str_has_suffix(connection->hostname, entry->hostname)) { ++ size_t clen = strlen(connection->hostname); ++ size_t elen = strlen(entry->hostname); ++ ++ /* make sure the connection hostname has at least one more character ++ * than the entry so that we don't do an out of bound read. ++ */ ++ if(clen > elen) { ++ if(connection->hostname[clen - elen - 1] == '.') { ++ return 0; ++ } ++ } ++ } ++ ++ return -1; ++} ++ ++static void ++parse_no_proxy_list(const gchar *no_proxy) { ++ gchar **items; ++ gint i; ++ ++ g_return_if_fail(no_proxy != NULL); ++ g_return_if_fail(no_proxy_entries == NULL); ++ ++ /* The no_proxy value is comma separated */ ++ items = g_strsplit(no_proxy, ",", -1); ++ ++ for(i = 0; items[i] != NULL; i++) { ++ PurpleProxyNoProxyEntry *entry = NULL; ++ gchar *hostname = NULL; ++ gchar *s_port = NULL; ++ gint port = 0; ++ ++ s_port = g_strstr_len(items[i], -1, ":"); ++ if(s_port != NULL && *s_port + 1 != '\0') { ++ /* read the port starting with the next character */ ++ port = atoi(s_port + 1); ++ ++ /* since we're done with the port, now turn item into a null ++ * terminated string of just the hostname. ++ */ ++ *s_port = '\0'; ++ } ++ ++ /* items[i] is currently either the original or with :port removed */ ++ hostname = items[i]; ++ ++ g_strstrip(hostname); ++ ++ /* finally remove any leading .'s from hostname */ ++ while(hostname[0] == '.') { ++ hostname += 1; ++ } ++ ++ if(*hostname == '\0') { ++ continue; ++ } ++ ++ /* finally add the new entry to the list */ ++ entry = purple_proxy_no_proxy_entry_new(hostname, port); ++ no_proxy_entries = g_list_prepend(no_proxy_entries, entry); ++ } ++ ++ g_strfreev(items); ++} ++ ++/************************************************************************** + * Global Proxy API + **************************************************************************/ + PurpleProxyInfo * +@@ -2312,6 +2430,8 @@ + const char *connecthost = host; + int connectport = port; + PurpleProxyConnectData *connect_data; ++ PurpleProxyNoProxyEntry entry; ++ GList *found = NULL; + + g_return_val_if_fail(host != NULL, NULL); + g_return_val_if_fail(port > 0, NULL); +@@ -2325,9 +2445,31 @@ + connect_data->data = data; + connect_data->host = g_strdup(host); + connect_data->port = port; +- connect_data->gpi = purple_proxy_get_setup(account); + connect_data->account = account; + ++ /* Check if the hostname:port matches anything in the no_proxy environment ++ * variable to determine if this connection should be proxied or not. ++ */ ++ entry.hostname = connect_data->host; ++ entry.port = connect_data->port; ++ found = g_list_find_custom(no_proxy_entries, &entry, ++ purple_proxy_no_proxy_compare); ++ ++ if(found != NULL) { ++ purple_debug_info( ++ "proxy", ++ "directly connecting to %s:%d because it matched the no_proxy " ++ "environment variable.\n", ++ connect_data->host, ++ connect_data->port ++ ); ++ ++ connect_data->gpi = purple_proxy_info_new(); ++ purple_proxy_info_set_type(connect_data->gpi, PURPLE_PROXY_NONE); ++ } else { ++ connect_data->gpi = purple_proxy_get_setup(account); ++ } ++ + if ((purple_proxy_info_get_type(connect_data->gpi) != PURPLE_PROXY_NONE) && + (purple_proxy_info_get_host(connect_data->gpi) == NULL || + purple_proxy_info_get_port(connect_data->gpi) <= 0)) { +@@ -2380,6 +2522,8 @@ + const char *connecthost = host; + int connectport = port; + PurpleProxyConnectData *connect_data; ++ PurpleProxyNoProxyEntry entry; ++ GList *found; + + g_return_val_if_fail(host != NULL, NULL); + g_return_val_if_fail(port > 0, NULL); +@@ -2393,9 +2537,27 @@ + connect_data->data = data; + connect_data->host = g_strdup(host); + connect_data->port = port; +- connect_data->gpi = purple_proxy_get_setup(account); + connect_data->account = account; + ++ entry.hostname = connect_data->host; ++ entry.port = connect_data->port; ++ found = g_list_find_custom(no_proxy_entries, &entry, ++ purple_proxy_no_proxy_compare); ++ if(found != NULL) { ++ purple_debug_info( ++ "proxy", ++ "directly connecting to %s:%d because it matched the no_proxy " ++ "environment variable.\n", ++ connect_data->host, ++ connect_data->port ++ ); ++ ++ connect_data->gpi = purple_proxy_info_new(); ++ purple_proxy_info_set_type(connect_data->gpi, PURPLE_PROXY_NONE); ++ } else { ++ connect_data->gpi = purple_proxy_get_setup(account); ++ } ++ + if ((purple_proxy_info_get_type(connect_data->gpi) != PURPLE_PROXY_NONE) && + (purple_proxy_info_get_host(connect_data->gpi) == NULL || + purple_proxy_info_get_port(connect_data->gpi) <= 0)) { +@@ -2613,6 +2775,55 @@ + purple_proxy_init(void) + { + void *handle; ++ const gchar *no_proxy_value = NULL; ++ ++ /* ++ * See Standardizing no_proxy in for this patch. ++ */ ++ no_proxy_value = g_getenv("no_proxy"); ++ if(no_proxy_value == NULL) { ++ no_proxy_value = g_getenv("NO_PROXY"); ++ } ++ ++ if(no_proxy_value != NULL) { ++ /* ++ * Some test cases (when we are connecting to libera with SOCKS5 on port ++ * 6667): ++ * ++ * Use proxy because empty list. ++ * $ no_proxy= pidgin --debug ++ * ++ * Ignore the leading ., match suffix and skip proxy. ++ * $ no_proxy=.libera.chat:6667 pidgin --debug ++ * ++ * Treat empty port as unspecified and skip proxy. ++ * $ no_proxy=libera.chat: pidgin --debug ++ * ++ * Ignore the first empty element and skip proxy. ++ * $ no_proxy=,libera.chat:6667 pidgin --debug ++ * ++ * Should not work with empty host, if you want to skip proxy for ++ * all hosts with a specific port please see next example. ++ * $ no_proxy=:6667 pidgin --debug ++ * ++ * Should skip proxy. ++ * $ no_proxy="*:6667" pidgin --debug ++ * ++ * Should NOT skip proxy. ++ * $ no_proxy="*:6669" pidgin --debug ++ * ++ * Should skip proxy. ++ * $ no_proxy="*" pidgin --debug ++ */ ++ ++ parse_no_proxy_list(no_proxy_value); ++ ++ purple_debug_info("proxy", ++ "Found no_proxy envrionment variable ('%s')\n", ++ no_proxy_value); ++ purple_debug_info("proxy", "Loaded %d no_proxy exceptions\n", ++ g_list_length(no_proxy_entries)); ++ } + + /* Initialize a default proxy info struct. */ + global_proxy_info = purple_proxy_info_new(); +@@ -2660,4 +2871,8 @@ + + purple_proxy_info_destroy(global_proxy_info); + global_proxy_info = NULL; ++ ++ g_list_free_full(no_proxy_entries, ++ (GDestroyNotify)purple_proxy_no_proxy_entry_free); ++ no_proxy_entries = NULL; + } diff --git a/pidgin.changes b/pidgin.changes index 868ea37..aa9625e 100644 --- a/pidgin.changes +++ b/pidgin.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Jun 24 06:24:45 UTC 2021 - Alynx Zhou + +- Add pidgin-add-no_proxy-support.patch: add support of no_proxy + environment variable. (jsc#SLE-17111, pidgin.im#17518) + ------------------------------------------------------------------- Sun Jun 13 09:48:17 UTC 2021 - Andreas Stieger diff --git a/pidgin.spec b/pidgin.spec index 3e457ae..8e7f131 100644 --- a/pidgin.spec +++ b/pidgin.spec @@ -38,6 +38,8 @@ Patch2: pidgin-fix-perl-build.patch Patch3: pidgin-use-default-alsa.patch # PATCH-FIX-OPENSUSE pidgin-always-enable-intltool.patch mgorse@suse.com -- always enable intltool, needed for autoconf 2.71. Patch4: pidgin-always-enable-intltool.patch +# PATCH-FEATURE-UPSTREAM pidgin-add-no_proxy-support.patch jsc#SLE-17111 pidgin.im#17518 alynx.zhou@suse.com -- add support for no_proxy env. +Patch5: pidgin-add-no_proxy-support.patch BuildRequires: ca-certificates-mozilla BuildRequires: doxygen BuildRequires: fdupes @@ -222,6 +224,7 @@ translation-update-upstream %patch3 -p1 %endif %patch4 -p1 +%patch5 -p1 cp -f %{SOURCE3} %{name}-prefs.xml