Mercurial > pidgin
diff libpurple/proxy.c @ 23970:54eb782d4721
Add support for reading SOCKS proxy information from the Windows proxy settings.
Fixes #1614
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Tue, 26 Aug 2008 04:36:29 +0000 |
parents | 64585aab233a |
children | 4a1bbe955690 |
line wrap: on
line diff
--- a/libpurple/proxy.c Tue Aug 26 04:08:22 2008 +0000 +++ b/libpurple/proxy.c Tue Aug 26 04:36:29 2008 +0000 @@ -347,6 +347,143 @@ return &info; } + +#ifdef _WIN32 + +typedef BOOL (CALLBACK* LPFNWINHTTPGETIEPROXYCONFIG)(/*IN OUT*/ WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* pProxyConfig); + +/* This modifies "host" in-place evilly */ +static void +_proxy_fill_hostinfo(PurpleProxyInfo *info, char *host, int default_port) +{ + int port = default_port; + char *d; + + d = g_strrstr(host, ":"); + if (d) + *d = '\0'; + d++; + if (*d) + sscanf(d, "%d", &port); + + purple_proxy_info_set_host(info, host); + purple_proxy_info_set_port(info, port); +} + +static PurpleProxyInfo * +purple_win32_proxy_get_info(void) +{ + static LPFNWINHTTPGETIEPROXYCONFIG MyWinHttpGetIEProxyConfig = NULL; + static gboolean loaded = FALSE; + static PurpleProxyInfo info = {0, NULL, 0, NULL, NULL}; + + WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_proxy_config; + + if (!loaded) { + loaded = TRUE; + MyWinHttpGetIEProxyConfig = (LPFNWINHTTPGETIEPROXYCONFIG) + wpurple_find_and_loadproc("winhttp.dll", "WinHttpGetIEProxyConfigForCurrentUser"); + if (!MyWinHttpGetIEProxyConfig) + purple_debug_info("proxy", "Unable to read Windows Proxy Settings.\n"); + } + + if (!MyWinHttpGetIEProxyConfig) + return NULL; + + ZeroMemory(&ie_proxy_config, sizeof(ie_proxy_config)); + if (!MyWinHttpGetIEProxyConfig(&ie_proxy_config)) { + purple_debug_error("proxy", "Error reading Windows Proxy Settings(%lu).\n", GetLastError()); + return NULL; + } + + /* We can't do much if it is autodetect*/ + if (ie_proxy_config.fAutoDetect) { + purple_debug_error("proxy", "Windows Proxy Settings set to autodetect (not supported).\n"); + + /* TODO: For 3.0.0 we'll revisit this (maybe)*/ + + return NULL; + + } else if (ie_proxy_config.lpszProxy) { + gchar *proxy_list = g_utf16_to_utf8(ie_proxy_config.lpszProxy, -1, + NULL, NULL, NULL); + + /* We can't do anything about the bypass list, as we don't have the url */ + /* TODO: For 3.0.0 we'll revisit this*/ + + /* There are proxy settings for several protocols */ + if (proxy_list && *proxy_list) { + char *specific = NULL, *tmp; + + /* If there is only a global proxy, which means "HTTP" */ + if (!strchr(proxy_list, ';') || (specific = g_strstr_len(proxy_list, -1, "http=")) != NULL) { + + if (specific) { + specific += strlen("http="); + tmp = strchr(specific, ';'); + if (tmp) + *tmp = '\0'; + /* specific now points the proxy server (and port) */ + } else + specific = proxy_list; + + purple_proxy_info_set_type(&info, PURPLE_PROXY_HTTP); + _proxy_fill_hostinfo(&info, specific, 80); + /* TODO: is there a way to set the username/password? */ + purple_proxy_info_set_username(&info, NULL); + purple_proxy_info_set_password(&info, NULL); + + purple_debug_info("proxy", "Windows Proxy Settings: HTTP proxy: '%s:%d'.\n", + purple_proxy_info_get_host(&info), + purple_proxy_info_get_port(&info)); + + } else if ((specific = g_strstr_len(proxy_list, -1, "socks=")) != NULL) { + + specific += strlen("socks="); + tmp = strchr(specific, ';'); + if (tmp) + *tmp = '\0'; + /* specific now points the proxy server (and port) */ + + purple_proxy_info_set_type(&info, PURPLE_PROXY_SOCKS5); + _proxy_fill_hostinfo(&info, specific, 1080); + /* TODO: is there a way to set the username/password? */ + purple_proxy_info_set_username(&info, NULL); + purple_proxy_info_set_password(&info, NULL); + + purple_debug_info("proxy", "Windows Proxy Settings: SOCKS5 proxy: '%s:%d'.\n", + purple_proxy_info_get_host(&info), + purple_proxy_info_get_port(&info)); + + } else { + + purple_debug_info("proxy", "Windows Proxy Settings: No supported proxy specified.\n"); + + purple_proxy_info_set_type(&info, PURPLE_PROXY_NONE); + + } + } + + /* TODO: Fix API to be able look at proxy bypass settings */ + + g_free(proxy_list); + } else { + purple_debug_info("proxy", "No Windows proxy set.\n"); + purple_proxy_info_set_type(&info, PURPLE_PROXY_NONE); + } + + if (ie_proxy_config.lpszAutoConfigUrl) + GlobalFree(ie_proxy_config.lpszAutoConfigUrl); + if (ie_proxy_config.lpszProxy) + GlobalFree(ie_proxy_config.lpszProxy); + if (ie_proxy_config.lpszProxyBypass) + GlobalFree(ie_proxy_config.lpszProxyBypass); + + return &info; +} +#endif + + /************************************************************************** * Proxy API **************************************************************************/ @@ -1878,9 +2015,6 @@ } if (purple_proxy_info_get_type(gpi) == PURPLE_PROXY_USE_ENVVAR) { -#ifdef _WIN32 - wpurple_check_for_proxy_changes(); -#endif if ((tmp = g_getenv("HTTP_PROXY")) != NULL || (tmp = g_getenv("http_proxy")) != NULL || (tmp = g_getenv("HTTPPROXY")) != NULL) { @@ -1922,6 +2056,11 @@ } } else { +#ifdef _WIN32 + PurpleProxyInfo *wgpi; + if ((wgpi = purple_win32_proxy_get_info()) != NULL) + return wgpi; +#endif /* no proxy environment variable found, don't use a proxy */ purple_debug_info("proxy", "No environment settings found, not using a proxy\n"); gpi = tmp_none_proxy_info;