Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Unified Diff: webrtc/base/proxydetect.cc

Issue 2541453002: Delete unused classes AutoDetectProxy and SslSocketFactory. (Closed)
Patch Set: Rebased. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/base/proxydetect.h ('k') | webrtc/base/proxydetect_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/base/proxydetect.cc
diff --git a/webrtc/base/proxydetect.cc b/webrtc/base/proxydetect.cc
deleted file mode 100644
index b0fa30488a1eed3f770bf78afe6fe242b50447a5..0000000000000000000000000000000000000000
--- a/webrtc/base/proxydetect.cc
+++ /dev/null
@@ -1,1292 +0,0 @@
-/*
- * Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "webrtc/base/proxydetect.h"
-
-#if defined(WEBRTC_WIN)
-#include "webrtc/base/win32.h"
-#include <shlobj.h>
-#endif // WEBRTC_WIN
-
-#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
-#include <SystemConfiguration/SystemConfiguration.h>
-#include <CoreFoundation/CoreFoundation.h>
-#include <CoreServices/CoreServices.h>
-#include <Security/Security.h>
-#include "macconversion.h"
-#include "webrtc/base/unixfilesystem.h"
-#endif
-
-#ifdef WEBRTC_IOS
-#include <CFNetwork/CFNetwork.h>
-#include "macconversion.h"
-#endif
-
-#include <map>
-#include <memory>
-
-#include "webrtc/base/arraysize.h"
-#include "webrtc/base/checks.h"
-#include "webrtc/base/common.h"
-#include "webrtc/base/fileutils.h"
-#include "webrtc/base/httpcommon.h"
-#include "webrtc/base/httpcommon-inl.h"
-#include "webrtc/base/pathutils.h"
-#include "webrtc/base/stringutils.h"
-
-#define _TRY_JSPROXY 0
-#define _TRY_WM_FINDPROXY 0
-
-#if defined(WEBRTC_WIN)
-#define _TRY_WINHTTP 1
-#define _TRY_IE_LAN_SETTINGS 1
-#else
-#define _TRY_WINHTTP 0
-#define _TRY_IE_LAN_SETTINGS 0
-#endif // WEBRTC_WIN
-
-// For all platforms try Firefox.
-#define _TRY_FIREFOX 1
-
-// Use profiles.ini to find the correct profile for this user.
-// If not set, we'll just look for the default one.
-#define USE_FIREFOX_PROFILES_INI 1
-
-static const size_t kMaxLineLength = 1024;
-static const char kFirefoxPattern[] = "Firefox";
-static const char kInternetExplorerPattern[] = "MSIE";
-
-struct StringMap {
- public:
- void Add(const char * name, const char * value) { map_[name] = value; }
- const std::string& Get(const char * name, const char * def = "") const {
- std::map<std::string, std::string>::const_iterator it =
- map_.find(name);
- if (it != map_.end())
- return it->second;
- def_ = def;
- return def_;
- }
- bool IsSet(const char * name) const {
- return (map_.find(name) != map_.end());
- }
- private:
- std::map<std::string, std::string> map_;
- mutable std::string def_;
-};
-
-enum UserAgent {
- UA_FIREFOX,
- UA_INTERNETEXPLORER,
- UA_OTHER,
- UA_UNKNOWN
-};
-
-#if _TRY_WINHTTP
-//#include <winhttp.h>
-// Note: From winhttp.h
-
-const char WINHTTP[] = "winhttp";
-
-typedef LPVOID HINTERNET;
-
-typedef struct {
- DWORD dwAccessType; // see WINHTTP_ACCESS_* types below
- LPWSTR lpszProxy; // proxy server list
- LPWSTR lpszProxyBypass; // proxy bypass list
-} WINHTTP_PROXY_INFO, * LPWINHTTP_PROXY_INFO;
-
-typedef struct {
- DWORD dwFlags;
- DWORD dwAutoDetectFlags;
- LPCWSTR lpszAutoConfigUrl;
- LPVOID lpvReserved;
- DWORD dwReserved;
- BOOL fAutoLogonIfChallenged;
-} WINHTTP_AUTOPROXY_OPTIONS;
-
-typedef struct {
- BOOL fAutoDetect;
- LPWSTR lpszAutoConfigUrl;
- LPWSTR lpszProxy;
- LPWSTR lpszProxyBypass;
-} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;
-
-extern "C" {
- typedef HINTERNET (WINAPI * pfnWinHttpOpen)
- (
- IN LPCWSTR pwszUserAgent,
- IN DWORD dwAccessType,
- IN LPCWSTR pwszProxyName OPTIONAL,
- IN LPCWSTR pwszProxyBypass OPTIONAL,
- IN DWORD dwFlags
- );
- typedef BOOL (STDAPICALLTYPE * pfnWinHttpCloseHandle)
- (
- IN HINTERNET hInternet
- );
- typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetProxyForUrl)
- (
- IN HINTERNET hSession,
- IN LPCWSTR lpcwszUrl,
- IN WINHTTP_AUTOPROXY_OPTIONS * pAutoProxyOptions,
- OUT WINHTTP_PROXY_INFO * pProxyInfo
- );
- typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetIEProxyConfig)
- (
- IN OUT WINHTTP_CURRENT_USER_IE_PROXY_CONFIG * pProxyConfig
- );
-
-} // extern "C"
-
-#define WINHTTP_AUTOPROXY_AUTO_DETECT 0x00000001
-#define WINHTTP_AUTOPROXY_CONFIG_URL 0x00000002
-#define WINHTTP_AUTOPROXY_RUN_INPROCESS 0x00010000
-#define WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY 0x00020000
-#define WINHTTP_AUTO_DETECT_TYPE_DHCP 0x00000001
-#define WINHTTP_AUTO_DETECT_TYPE_DNS_A 0x00000002
-#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0
-#define WINHTTP_ACCESS_TYPE_NO_PROXY 1
-#define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3
-#define WINHTTP_NO_PROXY_NAME NULL
-#define WINHTTP_NO_PROXY_BYPASS NULL
-
-#endif // _TRY_WINHTTP
-
-#if _TRY_JSPROXY
-extern "C" {
- typedef BOOL (STDAPICALLTYPE * pfnInternetGetProxyInfo)
- (
- LPCSTR lpszUrl,
- DWORD dwUrlLength,
- LPSTR lpszUrlHostName,
- DWORD dwUrlHostNameLength,
- LPSTR * lplpszProxyHostName,
- LPDWORD lpdwProxyHostNameLength
- );
-} // extern "C"
-#endif // _TRY_JSPROXY
-
-#if _TRY_WM_FINDPROXY
-#include <comutil.h>
-#include <wmnetsourcecreator.h>
-#include <wmsinternaladminnetsource.h>
-#endif // _TRY_WM_FINDPROXY
-
-#if _TRY_IE_LAN_SETTINGS
-#include <wininet.h>
-#include <string>
-#endif // _TRY_IE_LAN_SETTINGS
-
-namespace rtc {
-
-//////////////////////////////////////////////////////////////////////
-// Utility Functions
-//////////////////////////////////////////////////////////////////////
-
-#if defined(WEBRTC_WIN)
-#ifdef _UNICODE
-
-typedef std::wstring tstring;
-std::string Utf8String(const tstring& str) { return ToUtf8(str); }
-
-#else // !_UNICODE
-
-typedef std::string tstring;
-std::string Utf8String(const tstring& str) { return str; }
-
-#endif // !_UNICODE
-#endif // WEBRTC_WIN
-
-bool ProxyItemMatch(const Url<char>& url, char * item, size_t len) {
- // hostname:443
- if (char * port = ::strchr(item, ':')) {
- *port++ = '\0';
- if (url.port() != atol(port)) {
- return false;
- }
- }
-
- // A.B.C.D or A.B.C.D/24
- int a, b, c, d, m;
- int match = sscanf(item, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &m);
- if (match >= 4) {
- uint32_t ip = ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) |
- (d & 0xFF);
- if ((match < 5) || (m > 32))
- m = 32;
- else if (m < 0)
- m = 0;
- uint32_t mask = (m == 0) ? 0 : (~0UL) << (32 - m);
- SocketAddress addr(url.host(), 0);
- // TODO: Support IPv6 proxyitems. This code block is IPv4 only anyway.
- return !addr.IsUnresolvedIP() &&
- ((addr.ipaddr().v4AddressAsHostOrderInteger() & mask) == (ip & mask));
- }
-
- // .foo.com
- if (*item == '.') {
- size_t hostlen = url.host().length();
- return (hostlen > len)
- && (stricmp(url.host().c_str() + (hostlen - len), item) == 0);
- }
-
- // localhost or www.*.com
- if (!string_match(url.host().c_str(), item))
- return false;
-
- return true;
-}
-
-bool ProxyListMatch(const Url<char>& url, const std::string& proxy_list,
- char sep) {
- const size_t BUFSIZE = 256;
- char buffer[BUFSIZE];
- const char* list = proxy_list.c_str();
- while (*list) {
- // Remove leading space
- if (isspace(*list)) {
- ++list;
- continue;
- }
- // Break on separator
- size_t len;
- const char * start = list;
- if (const char * end = ::strchr(list, sep)) {
- len = (end - list);
- list += len + 1;
- } else {
- len = strlen(list);
- list += len;
- }
- // Remove trailing space
- while ((len > 0) && isspace(start[len-1]))
- --len;
- // Check for oversized entry
- if (len >= BUFSIZE)
- continue;
- memcpy(buffer, start, len);
- buffer[len] = 0;
- if (!ProxyItemMatch(url, buffer, len))
- continue;
- return true;
- }
- return false;
-}
-
-bool Better(ProxyType lhs, const ProxyType rhs) {
- // PROXY_NONE, PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN
- const int PROXY_VALUE[5] = { 0, 2, 3, 1 };
- return (PROXY_VALUE[lhs] > PROXY_VALUE[rhs]);
-}
-
-bool ParseProxy(const std::string& saddress, ProxyInfo* proxy) {
- const size_t kMaxAddressLength = 1024;
- // Allow semicolon, space, or tab as an address separator
- const char* const kAddressSeparator = " ;\t";
-
- ProxyType ptype;
- std::string host;
- uint16_t port;
-
- const char* address = saddress.c_str();
- while (*address) {
- size_t len;
- const char * start = address;
- if (const char * sep = strchr(address, kAddressSeparator)) {
- len = (sep - address);
- address += len + 1;
- while (*address != '\0' && ::strchr(kAddressSeparator, *address)) {
- address += 1;
- }
- } else {
- len = strlen(address);
- address += len;
- }
-
- if (len > kMaxAddressLength - 1) {
- LOG(LS_WARNING) << "Proxy address too long [" << start << "]";
- continue;
- }
-
- char buffer[kMaxAddressLength];
- memcpy(buffer, start, len);
- buffer[len] = 0;
-
- char * colon = ::strchr(buffer, ':');
- if (!colon) {
- LOG(LS_WARNING) << "Proxy address without port [" << buffer << "]";
- continue;
- }
-
- *colon = 0;
- char * endptr;
- port = static_cast<uint16_t>(strtol(colon + 1, &endptr, 0));
- if (*endptr != 0) {
- LOG(LS_WARNING) << "Proxy address with invalid port [" << buffer << "]";
- continue;
- }
-
- if (char * equals = ::strchr(buffer, '=')) {
- *equals = 0;
- host = equals + 1;
- if (_stricmp(buffer, "socks") == 0) {
- ptype = PROXY_SOCKS5;
- } else if (_stricmp(buffer, "https") == 0) {
- ptype = PROXY_HTTPS;
- } else {
- LOG(LS_WARNING) << "Proxy address with unknown protocol ["
- << buffer << "]";
- ptype = PROXY_UNKNOWN;
- }
- } else {
- host = buffer;
- ptype = PROXY_UNKNOWN;
- }
-
- if (Better(ptype, proxy->type)) {
- proxy->type = ptype;
- proxy->address.SetIP(host);
- proxy->address.SetPort(port);
- }
- }
-
- return proxy->type != PROXY_NONE;
-}
-
-UserAgent GetAgent(const char* agent) {
- if (agent) {
- std::string agent_str(agent);
- if (agent_str.find(kFirefoxPattern) != std::string::npos) {
- return UA_FIREFOX;
- } else if (agent_str.find(kInternetExplorerPattern) != std::string::npos) {
- return UA_INTERNETEXPLORER;
- } else if (agent_str.empty()) {
- return UA_UNKNOWN;
- }
- }
- return UA_OTHER;
-}
-
-bool EndsWith(const std::string& a, const std::string& b) {
- if (b.size() > a.size()) {
- return false;
- }
- int result = a.compare(a.size() - b.size(), b.size(), b);
- return result == 0;
-}
-
-bool GetFirefoxProfilePath(Pathname* path) {
-#if defined(WEBRTC_WIN)
- wchar_t w_path[MAX_PATH];
- if (SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, w_path) !=
- S_OK) {
- LOG(LS_ERROR) << "SHGetFolderPath failed";
- return false;
- }
- path->SetFolder(ToUtf8(w_path, wcslen(w_path)));
- path->AppendFolder("Mozilla");
- path->AppendFolder("Firefox");
-#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
- rtc::UnixFilesystem filesystem;
- filesystem.SetApplicationName("Firefox");
- bool result = filesystem.GetAppDataFolder(path, true);
- return result;
-#else
- char* user_home = getenv("HOME");
- if (user_home == NULL) {
- return false;
- }
- path->SetFolder(std::string(user_home));
- path->AppendFolder(".mozilla");
- path->AppendFolder("firefox");
-#endif // WEBRTC_WIN
- return true;
-}
-
-bool GetDefaultFirefoxProfile(Pathname* profile_path) {
- RTC_DCHECK(NULL != profile_path);
- Pathname path;
- if (!GetFirefoxProfilePath(&path)) {
- return false;
- }
-
-#if USE_FIREFOX_PROFILES_INI
- // [Profile0]
- // Name=default
- // IsRelative=1
- // Path=Profiles/2de53ejb.default
- // Default=1
-
- // Note: we are looking for the first entry with "Default=1", or the last
- // entry in the file
- path.SetFilename("profiles.ini");
- std::unique_ptr<FileStream> fs(Filesystem::OpenFile(path, "r"));
- if (!fs) {
- return false;
- }
- Pathname candidate;
- bool relative = true;
- std::string line;
- while (fs->ReadLine(&line) == SR_SUCCESS) {
- if (line.length() == 0) {
- continue;
- }
- if (line.at(0) == '[') {
- relative = true;
- candidate.clear();
- } else if (line.find("IsRelative=") == 0 &&
- line.length() >= 12) {
- // TODO: The initial Linux public launch revealed a fairly
- // high number of machines where IsRelative= did not have anything after
- // it. Perhaps that is legal profiles.ini syntax?
- relative = (line.at(11) != '0');
- } else if (line.find("Path=") == 0 &&
- line.length() >= 6) {
- if (relative) {
- candidate = path;
- } else {
- candidate.clear();
- }
- candidate.AppendFolder(line.substr(5));
- } else if (line.find("Default=") == 0 &&
- line.length() >= 9) {
- if ((line.at(8) != '0') && !candidate.empty()) {
- break;
- }
- }
- }
- fs->Close();
- if (candidate.empty()) {
- return false;
- }
- profile_path->SetPathname(candidate.pathname());
-
-#else // !USE_FIREFOX_PROFILES_INI
- path.AppendFolder("Profiles");
- DirectoryIterator* it = Filesystem::IterateDirectory();
- it->Iterate(path);
- std::string extension(".default");
- while (!EndsWith(it->Name(), extension)) {
- if (!it->Next()) {
- return false;
- }
- }
-
- profile_path->SetPathname(path);
- profile->AppendFolder("Profiles");
- profile->AppendFolder(it->Name());
- delete it;
-
-#endif // !USE_FIREFOX_PROFILES_INI
-
- return true;
-}
-
-bool ReadFirefoxPrefs(const Pathname& filename,
- const char * prefix,
- StringMap* settings) {
- std::unique_ptr<FileStream> fs(Filesystem::OpenFile(filename, "r"));
- if (!fs) {
- LOG(LS_ERROR) << "Failed to open file: " << filename.pathname();
- return false;
- }
-
- std::string line;
- while (fs->ReadLine(&line) == SR_SUCCESS) {
- size_t prefix_len = strlen(prefix);
-
- // Skip blank lines and too long lines.
- if ((line.length() == 0) || (line.length() > kMaxLineLength)
- || (line.at(0) == '#') || line.compare(0, 2, "/*") == 0
- || line.compare(0, 2, " *") == 0) {
- continue;
- }
-
- char buffer[kMaxLineLength];
- strcpyn(buffer, sizeof(buffer), line.c_str());
- int nstart = 0, nend = 0, vstart = 0, vend = 0;
- sscanf(buffer, "user_pref(\"%n%*[^\"]%n\", %n%*[^)]%n);",
- &nstart, &nend, &vstart, &vend);
- if (vend > 0) {
- char* name = buffer + nstart;
- name[nend - nstart] = 0;
- if ((vend - vstart >= 2) && (buffer[vstart] == '"')) {
- vstart += 1;
- vend -= 1;
- }
- char* value = buffer + vstart;
- value[vend - vstart] = 0;
- if ((strncmp(name, prefix, prefix_len) == 0) && *value) {
- settings->Add(name + prefix_len, value);
- }
- } else {
- LOG_F(LS_WARNING) << "Unparsed pref [" << buffer << "]";
- }
- }
- fs->Close();
- return true;
-}
-
-bool GetFirefoxProxySettings(const char* url, ProxyInfo* proxy) {
- Url<char> purl(url);
- Pathname path;
- bool success = false;
- if (GetDefaultFirefoxProfile(&path)) {
- StringMap settings;
- path.SetFilename("prefs.js");
- if (ReadFirefoxPrefs(path, "network.proxy.", &settings)) {
- success = true;
- proxy->bypass_list =
- settings.Get("no_proxies_on", "localhost, 127.0.0.1");
- if (settings.Get("type") == "1") {
- // User has manually specified a proxy, try to figure out what
- // type it is.
- if (ProxyListMatch(purl, proxy->bypass_list.c_str(), ',')) {
- // Our url is in the list of url's to bypass proxy.
- } else if (settings.Get("share_proxy_settings") == "true") {
- proxy->type = PROXY_UNKNOWN;
- proxy->address.SetIP(settings.Get("http"));
- proxy->address.SetPort(atoi(settings.Get("http_port").c_str()));
- } else if (settings.IsSet("socks")) {
- proxy->type = PROXY_SOCKS5;
- proxy->address.SetIP(settings.Get("socks"));
- proxy->address.SetPort(atoi(settings.Get("socks_port").c_str()));
- } else if (settings.IsSet("ssl")) {
- proxy->type = PROXY_HTTPS;
- proxy->address.SetIP(settings.Get("ssl"));
- proxy->address.SetPort(atoi(settings.Get("ssl_port").c_str()));
- } else if (settings.IsSet("http")) {
- proxy->type = PROXY_HTTPS;
- proxy->address.SetIP(settings.Get("http"));
- proxy->address.SetPort(atoi(settings.Get("http_port").c_str()));
- }
- } else if (settings.Get("type") == "2") {
- // Browser is configured to get proxy settings from a given url.
- proxy->autoconfig_url = settings.Get("autoconfig_url").c_str();
- } else if (settings.Get("type") == "4") {
- // Browser is configured to auto detect proxy config.
- proxy->autodetect = true;
- } else {
- // No proxy set.
- }
- }
- }
- return success;
-}
-
-#if defined(WEBRTC_WIN) // Windows specific implementation for reading Internet
- // Explorer proxy settings.
-
-void LogGetProxyFault() {
- LOG_GLEM(LERROR, WINHTTP) << "WinHttpGetProxyForUrl faulted!!";
-}
-
-BOOL MyWinHttpGetProxyForUrl(pfnWinHttpGetProxyForUrl pWHGPFU,
- HINTERNET hWinHttp, LPCWSTR url,
- WINHTTP_AUTOPROXY_OPTIONS *options,
- WINHTTP_PROXY_INFO *info) {
- // WinHttpGetProxyForUrl() can call plugins which can crash.
- // In the case of McAfee scriptproxy.dll, it does crash in
- // older versions. Try to catch crashes here and treat as an
- // error.
- BOOL success = FALSE;
-
-#if (_HAS_EXCEPTIONS == 0)
- __try {
- success = pWHGPFU(hWinHttp, url, options, info);
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- // This is a separate function to avoid
- // Visual C++ error 2712 when compiling with C++ EH
- LogGetProxyFault();
- }
-#else
- success = pWHGPFU(hWinHttp, url, options, info);
-#endif // (_HAS_EXCEPTIONS == 0)
-
- return success;
-}
-
-bool IsDefaultBrowserFirefox() {
- HKEY key;
- LONG result = RegOpenKeyEx(HKEY_CLASSES_ROOT, L"http\\shell\\open\\command",
- 0, KEY_READ, &key);
- if (ERROR_SUCCESS != result)
- return false;
-
- DWORD size, type;
- bool success = false;
- result = RegQueryValueEx(key, L"", 0, &type, NULL, &size);
- if (result == ERROR_SUCCESS && type == REG_SZ) {
- wchar_t* value = new wchar_t[size+1];
- BYTE* buffer = reinterpret_cast<BYTE*>(value);
- result = RegQueryValueEx(key, L"", 0, &type, buffer, &size);
- if (result == ERROR_SUCCESS) {
- // Size returned by RegQueryValueEx is in bytes, convert to number of
- // wchar_t's.
- size /= sizeof(value[0]);
- value[size] = L'\0';
- for (size_t i = 0; i < size; ++i) {
- value[i] = tolowercase(value[i]);
- }
- success = (NULL != strstr(value, L"firefox.exe"));
- }
- delete[] value;
- }
-
- RegCloseKey(key);
- return success;
-}
-
-bool GetWinHttpProxySettings(const char* url, ProxyInfo* proxy) {
- HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll");
- if (winhttp_handle == NULL) {
- LOG(LS_ERROR) << "Failed to load winhttp.dll.";
- return false;
- }
- WINHTTP_CURRENT_USER_IE_PROXY_CONFIG iecfg;
- memset(&iecfg, 0, sizeof(iecfg));
- Url<char> purl(url);
- pfnWinHttpGetIEProxyConfig pWHGIEPC =
- reinterpret_cast<pfnWinHttpGetIEProxyConfig>(
- GetProcAddress(winhttp_handle,
- "WinHttpGetIEProxyConfigForCurrentUser"));
- bool success = false;
- if (pWHGIEPC && pWHGIEPC(&iecfg)) {
- // We were read proxy config successfully.
- success = true;
- if (iecfg.fAutoDetect) {
- proxy->autodetect = true;
- }
- if (iecfg.lpszAutoConfigUrl) {
- proxy->autoconfig_url = ToUtf8(iecfg.lpszAutoConfigUrl);
- GlobalFree(iecfg.lpszAutoConfigUrl);
- }
- if (iecfg.lpszProxyBypass) {
- proxy->bypass_list = ToUtf8(iecfg.lpszProxyBypass);
- GlobalFree(iecfg.lpszProxyBypass);
- }
- if (iecfg.lpszProxy) {
- if (!ProxyListMatch(purl, proxy->bypass_list, ';')) {
- ParseProxy(ToUtf8(iecfg.lpszProxy), proxy);
- }
- GlobalFree(iecfg.lpszProxy);
- }
- }
- FreeLibrary(winhttp_handle);
- return success;
-}
-
-// Uses the WinHTTP API to auto detect proxy for the given url. Firefox and IE
-// have slightly different option dialogs for proxy settings. In Firefox,
-// either a location of a proxy configuration file can be specified or auto
-// detection can be selected. In IE theese two options can be independently
-// selected. For the case where both options are selected (only IE) we try to
-// fetch the config file first, and if that fails we'll perform an auto
-// detection.
-//
-// Returns true if we successfully performed an auto detection not depending on
-// whether we found a proxy or not. Returns false on error.
-bool WinHttpAutoDetectProxyForUrl(const char* agent, const char* url,
- ProxyInfo* proxy) {
- Url<char> purl(url);
- bool success = true;
- HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll");
- if (winhttp_handle == NULL) {
- LOG(LS_ERROR) << "Failed to load winhttp.dll.";
- return false;
- }
- pfnWinHttpOpen pWHO =
- reinterpret_cast<pfnWinHttpOpen>(GetProcAddress(winhttp_handle,
- "WinHttpOpen"));
- pfnWinHttpCloseHandle pWHCH =
- reinterpret_cast<pfnWinHttpCloseHandle>(
- GetProcAddress(winhttp_handle, "WinHttpCloseHandle"));
- pfnWinHttpGetProxyForUrl pWHGPFU =
- reinterpret_cast<pfnWinHttpGetProxyForUrl>(
- GetProcAddress(winhttp_handle, "WinHttpGetProxyForUrl"));
- if (pWHO && pWHCH && pWHGPFU) {
- if (HINTERNET hWinHttp = pWHO(ToUtf16(agent).c_str(),
- WINHTTP_ACCESS_TYPE_NO_PROXY,
- WINHTTP_NO_PROXY_NAME,
- WINHTTP_NO_PROXY_BYPASS,
- 0)) {
- BOOL result = FALSE;
- WINHTTP_PROXY_INFO info;
- memset(&info, 0, sizeof(info));
- if (proxy->autodetect) {
- // Use DHCP and DNS to try to find any proxy to use.
- WINHTTP_AUTOPROXY_OPTIONS options;
- memset(&options, 0, sizeof(options));
- options.fAutoLogonIfChallenged = TRUE;
-
- options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT;
- options.dwAutoDetectFlags |= WINHTTP_AUTO_DETECT_TYPE_DHCP
- | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
- result = MyWinHttpGetProxyForUrl(
- pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info);
- }
- if (!result && !proxy->autoconfig_url.empty()) {
- // We have the location of a proxy config file. Download it and
- // execute it to find proxy settings for our url.
- WINHTTP_AUTOPROXY_OPTIONS options;
- memset(&options, 0, sizeof(options));
- memset(&info, 0, sizeof(info));
- options.fAutoLogonIfChallenged = TRUE;
-
- std::wstring autoconfig_url16((ToUtf16)(proxy->autoconfig_url));
- options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
- options.lpszAutoConfigUrl = autoconfig_url16.c_str();
-
- result = MyWinHttpGetProxyForUrl(
- pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info);
- }
- if (result) {
- // Either the given auto config url was valid or auto
- // detection found a proxy on this network.
- if (info.lpszProxy) {
- // TODO: Does this bypass list differ from the list
- // retreived from GetWinHttpProxySettings earlier?
- if (info.lpszProxyBypass) {
- proxy->bypass_list = ToUtf8(info.lpszProxyBypass);
- GlobalFree(info.lpszProxyBypass);
- } else {
- proxy->bypass_list.clear();
- }
- if (!ProxyListMatch(purl, proxy->bypass_list, ';')) {
- // Found proxy for this URL. If parsing the address turns
- // out ok then we are successful.
- success = ParseProxy(ToUtf8(info.lpszProxy), proxy);
- }
- GlobalFree(info.lpszProxy);
- }
- } else {
- // We could not find any proxy for this url.
- LOG(LS_INFO) << "No proxy detected for " << url;
- }
- pWHCH(hWinHttp);
- }
- } else {
- LOG(LS_ERROR) << "Failed loading WinHTTP functions.";
- success = false;
- }
- FreeLibrary(winhttp_handle);
- return success;
-}
-
-#if 0 // Below functions currently not used.
-
-bool GetJsProxySettings(const char* url, ProxyInfo* proxy) {
- Url<char> purl(url);
- bool success = false;
-
- if (HMODULE hModJS = LoadLibrary(_T("jsproxy.dll"))) {
- pfnInternetGetProxyInfo pIGPI =
- reinterpret_cast<pfnInternetGetProxyInfo>(
- GetProcAddress(hModJS, "InternetGetProxyInfo"));
- if (pIGPI) {
- char proxy[256], host[256];
- memset(proxy, 0, sizeof(proxy));
- char * ptr = proxy;
- DWORD proxylen = sizeof(proxy);
- std::string surl = Utf8String(url);
- DWORD hostlen = _snprintf(host, sizeof(host), "http%s://%S",
- purl.secure() ? "s" : "", purl.server());
- if (pIGPI(surl.data(), surl.size(), host, hostlen, &ptr, &proxylen)) {
- LOG(INFO) << "Proxy: " << proxy;
- } else {
- LOG_GLE(INFO) << "InternetGetProxyInfo";
- }
- }
- FreeLibrary(hModJS);
- }
- return success;
-}
-
-bool GetWmProxySettings(const char* url, ProxyInfo* proxy) {
- Url<char> purl(url);
- bool success = false;
-
- INSNetSourceCreator * nsc = 0;
- HRESULT hr = CoCreateInstance(CLSID_ClientNetManager, 0, CLSCTX_ALL,
- IID_INSNetSourceCreator, (LPVOID *) &nsc);
- if (SUCCEEDED(hr)) {
- if (SUCCEEDED(hr = nsc->Initialize())) {
- VARIANT dispatch;
- VariantInit(&dispatch);
- if (SUCCEEDED(hr = nsc->GetNetSourceAdminInterface(L"http", &dispatch))) {
- IWMSInternalAdminNetSource * ians = 0;
- if (SUCCEEDED(hr = dispatch.pdispVal->QueryInterface(
- IID_IWMSInternalAdminNetSource, (LPVOID *) &ians))) {
- _bstr_t host(purl.server());
- BSTR proxy = 0;
- BOOL bProxyEnabled = FALSE;
- DWORD port, context = 0;
- if (SUCCEEDED(hr = ians->FindProxyForURL(
- L"http", host, &bProxyEnabled, &proxy, &port, &context))) {
- success = true;
- if (bProxyEnabled) {
- _bstr_t sproxy = proxy;
- proxy->ptype = PT_HTTPS;
- proxy->host = sproxy;
- proxy->port = port;
- }
- }
- SysFreeString(proxy);
- if (FAILED(hr = ians->ShutdownProxyContext(context))) {
- LOG(LS_INFO) << "IWMSInternalAdminNetSource::ShutdownProxyContext"
- << "failed: " << hr;
- }
- ians->Release();
- }
- }
- VariantClear(&dispatch);
- if (FAILED(hr = nsc->Shutdown())) {
- LOG(LS_INFO) << "INSNetSourceCreator::Shutdown failed: " << hr;
- }
- }
- nsc->Release();
- }
- return success;
-}
-
-bool GetIePerConnectionProxySettings(const char* url, ProxyInfo* proxy) {
- Url<char> purl(url);
- bool success = false;
-
- INTERNET_PER_CONN_OPTION_LIST list;
- INTERNET_PER_CONN_OPTION options[3];
- memset(&list, 0, sizeof(list));
- memset(&options, 0, sizeof(options));
-
- list.dwSize = sizeof(list);
- list.dwOptionCount = 3;
- list.pOptions = options;
- options[0].dwOption = INTERNET_PER_CONN_FLAGS;
- options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
- options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
- DWORD dwSize = sizeof(list);
-
- if (!InternetQueryOption(0, INTERNET_OPTION_PER_CONNECTION_OPTION, &list,
- &dwSize)) {
- LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError();
- } else if ((options[0].Value.dwValue & PROXY_TYPE_PROXY) != 0) {
- success = true;
- if (!ProxyListMatch(purl, nonnull(options[2].Value.pszValue), _T(';'))) {
- ParseProxy(nonnull(options[1].Value.pszValue), proxy);
- }
- } else if ((options[0].Value.dwValue & PROXY_TYPE_DIRECT) != 0) {
- success = true;
- } else {
- LOG(LS_INFO) << "unknown internet access type: "
- << options[0].Value.dwValue;
- }
- if (options[1].Value.pszValue) {
- GlobalFree(options[1].Value.pszValue);
- }
- if (options[2].Value.pszValue) {
- GlobalFree(options[2].Value.pszValue);
- }
- return success;
-}
-
-#endif // 0
-
-// Uses the InternetQueryOption function to retrieve proxy settings
-// from the registry. This will only give us the 'static' settings,
-// ie, not any information about auto config etc.
-bool GetIeLanProxySettings(const char* url, ProxyInfo* proxy) {
- Url<char> purl(url);
- bool success = false;
-
- wchar_t buffer[1024];
- memset(buffer, 0, sizeof(buffer));
- INTERNET_PROXY_INFO * info = reinterpret_cast<INTERNET_PROXY_INFO *>(buffer);
- DWORD dwSize = sizeof(buffer);
-
- if (!InternetQueryOption(0, INTERNET_OPTION_PROXY, info, &dwSize)) {
- LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError();
- } else if (info->dwAccessType == INTERNET_OPEN_TYPE_DIRECT) {
- success = true;
- } else if (info->dwAccessType == INTERNET_OPEN_TYPE_PROXY) {
- success = true;
- if (!ProxyListMatch(purl, nonnull(reinterpret_cast<const char*>(
- info->lpszProxyBypass)), ' ')) {
- ParseProxy(nonnull(reinterpret_cast<const char*>(info->lpszProxy)),
- proxy);
- }
- } else {
- LOG(LS_INFO) << "unknown internet access type: " << info->dwAccessType;
- }
- return success;
-}
-
-bool GetIeProxySettings(const char* agent, const char* url, ProxyInfo* proxy) {
- bool success = GetWinHttpProxySettings(url, proxy);
- if (!success) {
- // TODO: Should always call this if no proxy were detected by
- // GetWinHttpProxySettings?
- // WinHttp failed. Try using the InternetOptionQuery method instead.
- return GetIeLanProxySettings(url, proxy);
- }
- return true;
-}
-
-#endif // WEBRTC_WIN
-
-#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) // WEBRTC_MAC && !defined(WEBRTC_IOS) specific implementation for reading system wide
- // proxy settings.
-
-bool p_getProxyInfoForTypeFromDictWithKeys(ProxyInfo* proxy,
- ProxyType type,
- const CFDictionaryRef proxyDict,
- const CFStringRef enabledKey,
- const CFStringRef hostKey,
- const CFStringRef portKey) {
- // whether or not we set up the proxy info.
- bool result = false;
-
- // we use this as a scratch variable for determining if operations
- // succeeded.
- bool converted = false;
-
- // the data we need to construct the SocketAddress for the proxy.
- std::string hostname;
- int port;
-
- if ((proxyDict != NULL) &&
- (CFGetTypeID(proxyDict) == CFDictionaryGetTypeID())) {
- // CoreFoundation stuff that we'll have to get from
- // the dictionaries and interpret or convert into more usable formats.
- CFNumberRef enabledCFNum;
- CFNumberRef portCFNum;
- CFStringRef hostCFStr;
-
- enabledCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, enabledKey);
-
- if (p_isCFNumberTrue(enabledCFNum)) {
- // let's see if we can get the address and port.
- hostCFStr = (CFStringRef)CFDictionaryGetValue(proxyDict, hostKey);
- converted = p_convertHostCFStringRefToCPPString(hostCFStr, hostname);
- if (converted) {
- portCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, portKey);
- converted = p_convertCFNumberToInt(portCFNum, &port);
- if (converted) {
- // we have something enabled, with a hostname and a port.
- // That's sufficient to set up the proxy info.
- proxy->type = type;
- proxy->address.SetIP(hostname);
- proxy->address.SetPort(port);
- result = true;
- }
- }
- }
- }
-
- return result;
-}
-
-// Looks for proxy information in the given dictionary,
-// return true if it found sufficient information to define one,
-// false otherwise. This is guaranteed to not change the values in proxy
-// unless a full-fledged proxy description was discovered in the dictionary.
-// However, at the present time this does not support username or password.
-// Checks first for a SOCKS proxy, then for HTTPS, then HTTP.
-bool GetMacProxySettingsFromDictionary(ProxyInfo* proxy,
- const CFDictionaryRef proxyDict) {
- // the function result.
- bool gotProxy = false;
-
-
- // first we see if there's a SOCKS proxy in place.
- gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy,
- PROXY_SOCKS5,
- proxyDict,
- kSCPropNetProxiesSOCKSEnable,
- kSCPropNetProxiesSOCKSProxy,
- kSCPropNetProxiesSOCKSPort);
-
- if (!gotProxy) {
- // okay, no SOCKS proxy, let's look for https.
- gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy,
- PROXY_HTTPS,
- proxyDict,
- kSCPropNetProxiesHTTPSEnable,
- kSCPropNetProxiesHTTPSProxy,
- kSCPropNetProxiesHTTPSPort);
- if (!gotProxy) {
- // Finally, try HTTP proxy. Note that flute doesn't
- // differentiate between HTTPS and HTTP, hence we are using the
- // same flute type here, ie. PROXY_HTTPS.
- gotProxy = p_getProxyInfoForTypeFromDictWithKeys(
- proxy, PROXY_HTTPS, proxyDict, kSCPropNetProxiesHTTPEnable,
- kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort);
- }
- }
- return gotProxy;
-}
-
-// TODO(hughv) Update keychain functions. They work on 10.8, but are depricated.
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-bool p_putPasswordInProxyInfo(ProxyInfo* proxy) {
- bool result = true; // by default we assume we're good.
- // for all we know there isn't any password. We'll set to false
- // if we find a problem.
-
- // Ask the keychain for an internet password search for the given protocol.
- OSStatus oss = 0;
- SecKeychainAttributeList attrList;
- attrList.count = 3;
- SecKeychainAttribute attributes[3];
- attrList.attr = attributes;
-
- attributes[0].tag = kSecProtocolItemAttr;
- attributes[0].length = sizeof(SecProtocolType);
- SecProtocolType protocol;
- switch (proxy->type) {
- case PROXY_HTTPS :
- protocol = kSecProtocolTypeHTTPS;
- break;
- case PROXY_SOCKS5 :
- protocol = kSecProtocolTypeSOCKS;
- break;
- default :
- LOG(LS_ERROR) << "asked for proxy password for unknown proxy type.";
- result = false;
- break;
- }
- attributes[0].data = &protocol;
-
- UInt32 port = proxy->address.port();
- attributes[1].tag = kSecPortItemAttr;
- attributes[1].length = sizeof(UInt32);
- attributes[1].data = &port;
-
- std::string ip = proxy->address.ipaddr().ToString();
- attributes[2].tag = kSecServerItemAttr;
- attributes[2].length = ip.length();
- attributes[2].data = const_cast<char*>(ip.c_str());
-
- if (result) {
- LOG(LS_INFO) << "trying to get proxy username/password";
- SecKeychainSearchRef sref;
- oss = SecKeychainSearchCreateFromAttributes(NULL,
- kSecInternetPasswordItemClass,
- &attrList, &sref);
- if (0 == oss) {
- LOG(LS_INFO) << "SecKeychainSearchCreateFromAttributes was good";
- // Get the first item, if there is one.
- SecKeychainItemRef iref;
- oss = SecKeychainSearchCopyNext(sref, &iref);
- if (0 == oss) {
- LOG(LS_INFO) << "...looks like we have the username/password data";
- // If there is, get the username and the password.
-
- SecKeychainAttributeInfo attribsToGet;
- attribsToGet.count = 1;
- UInt32 tag = kSecAccountItemAttr;
- UInt32 format = CSSM_DB_ATTRIBUTE_FORMAT_STRING;
- void *data;
- UInt32 length;
- SecKeychainAttributeList *localList;
-
- attribsToGet.tag = &tag;
- attribsToGet.format = &format;
- OSStatus copyres = SecKeychainItemCopyAttributesAndData(iref,
- &attribsToGet,
- NULL,
- &localList,
- &length,
- &data);
- if (0 == copyres) {
- LOG(LS_INFO) << "...and we can pull it out.";
- // now, we know from experimentation (sadly not from docs)
- // that the username is in the local attribute list,
- // and the password in the data,
- // both without null termination but with info on their length.
- // grab the password from the data.
- std::string password;
- password.append(static_cast<const char*>(data), length);
-
- // make the password into a CryptString
- // huh, at the time of writing, you can't.
- // so we'll skip that for now and come back to it later.
-
- // now put the username in the proxy.
- if (1 <= localList->attr->length) {
- proxy->username.append(
- static_cast<const char*>(localList->attr->data),
- localList->attr->length);
- LOG(LS_INFO) << "username is " << proxy->username;
- } else {
- LOG(LS_ERROR) << "got keychain entry with no username";
- result = false;
- }
- } else {
- LOG(LS_ERROR) << "couldn't copy info from keychain.";
- result = false;
- }
- SecKeychainItemFreeAttributesAndData(localList, data);
- } else if (errSecItemNotFound == oss) {
- LOG(LS_INFO) << "...username/password info not found";
- } else {
- // oooh, neither 0 nor itemNotFound.
- LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss;
- result = false;
- }
- } else if (errSecItemNotFound == oss) { // noop
- } else {
- // oooh, neither 0 nor itemNotFound.
- LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss;
- result = false;
- }
- }
-
- return result;
-}
-
-bool GetMacProxySettings(ProxyInfo* proxy) {
- // based on the Apple Technical Q&A QA1234
- // http://developer.apple.com/qa/qa2001/qa1234.html
- CFDictionaryRef proxyDict = SCDynamicStoreCopyProxies(NULL);
- bool result = false;
-
- if (proxyDict != NULL) {
- // sending it off to another function makes it easier to unit test
- // since we can make our own dictionary to hand to that function.
- result = GetMacProxySettingsFromDictionary(proxy, proxyDict);
-
- if (result) {
- result = p_putPasswordInProxyInfo(proxy);
- }
-
- CFRelease(proxyDict);
- } else {
- LOG(LS_ERROR) << "SCDynamicStoreCopyProxies failed";
- }
-
- return result;
-}
-#endif // WEBRTC_MAC && !defined(WEBRTC_IOS)
-
-#ifdef WEBRTC_IOS
-// iOS has only http proxy
-bool GetiOSProxySettings(ProxyInfo* proxy) {
-
- bool result = false;
-
- CFDictionaryRef proxy_dict = CFNetworkCopySystemProxySettings();
- if (!proxy_dict) {
- LOG(LS_ERROR) << "CFNetworkCopySystemProxySettings failed";
- return false;
- }
-
- CFNumberRef proxiesHTTPEnable = (CFNumberRef)CFDictionaryGetValue(
- proxy_dict, kCFNetworkProxiesHTTPEnable);
- if (!p_isCFNumberTrue(proxiesHTTPEnable)) {
- CFRelease(proxy_dict);
- return false;
- }
-
- CFStringRef proxy_address = (CFStringRef)CFDictionaryGetValue(
- proxy_dict, kCFNetworkProxiesHTTPProxy);
- CFNumberRef proxy_port = (CFNumberRef)CFDictionaryGetValue(
- proxy_dict, kCFNetworkProxiesHTTPPort);
-
- // the data we need to construct the SocketAddress for the proxy.
- std::string hostname;
- int port;
- if (p_convertHostCFStringRefToCPPString(proxy_address, hostname) &&
- p_convertCFNumberToInt(proxy_port, &port)) {
- // We have something enabled, with a hostname and a port.
- // That's sufficient to set up the proxy info.
- // Finally, try HTTP proxy. Note that flute doesn't
- // differentiate between HTTPS and HTTP, hence we are using the
- // same flute type here, ie. PROXY_HTTPS.
- proxy->type = PROXY_HTTPS;
-
- proxy->address.SetIP(hostname);
- proxy->address.SetPort(port);
- result = true;
- }
-
- CFRelease(proxy_dict);
-
- return result;
-}
-#endif // WEBRTC_IOS
-
-bool AutoDetectProxySettings(const char* agent, const char* url,
- ProxyInfo* proxy) {
-#if defined(WEBRTC_WIN)
- return WinHttpAutoDetectProxyForUrl(agent, url, proxy);
-#else
- LOG(LS_WARNING) << "Proxy auto-detection not implemented for this platform";
- return false;
-#endif
-}
-
-bool GetSystemDefaultProxySettings(const char* agent, const char* url,
- ProxyInfo* proxy) {
-#if defined(WEBRTC_WIN)
- return GetIeProxySettings(agent, url, proxy);
-#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
- return GetMacProxySettings(proxy);
-#elif defined(WEBRTC_IOS)
- return GetiOSProxySettings(proxy);
-#else
- // TODO: Get System settings if browser is not firefox.
- return GetFirefoxProxySettings(url, proxy);
-#endif
-}
-
-bool GetProxySettingsForUrl(const char* agent, const char* url,
- ProxyInfo* proxy, bool long_operation) {
- UserAgent a = GetAgent(agent);
- bool result;
- switch (a) {
- case UA_FIREFOX: {
- result = GetFirefoxProxySettings(url, proxy);
- break;
- }
-#if defined(WEBRTC_WIN)
- case UA_INTERNETEXPLORER:
- result = GetIeProxySettings(agent, url, proxy);
- break;
- case UA_UNKNOWN:
- // Agent not defined, check default browser.
- if (IsDefaultBrowserFirefox()) {
- result = GetFirefoxProxySettings(url, proxy);
- } else {
- result = GetIeProxySettings(agent, url, proxy);
- }
- break;
-#endif // WEBRTC_WIN
- default:
- result = GetSystemDefaultProxySettings(agent, url, proxy);
- break;
- }
-
- // TODO: Consider using the 'long_operation' parameter to
- // decide whether to do the auto detection.
- if (result && (proxy->autodetect ||
- !proxy->autoconfig_url.empty())) {
- // Use WinHTTP to auto detect proxy for us.
- result = AutoDetectProxySettings(agent, url, proxy);
- if (!result) {
- // Either auto detection is not supported or we simply didn't
- // find any proxy, reset type.
- proxy->type = rtc::PROXY_NONE;
- }
- }
- return result;
-}
-
-} // namespace rtc
« no previous file with comments | « webrtc/base/proxydetect.h ('k') | webrtc/base/proxydetect_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698