diff --git a/webrtc/base/BUILD.gn b/webrtc/base/BUILD.gn index 13ad5fdc00..fca0e0e8f3 100644 --- a/webrtc/base/BUILD.gn +++ b/webrtc/base/BUILD.gn @@ -378,8 +378,6 @@ rtc_static_library("rtc_base") { "asynctcpsocket.h", "asyncudpsocket.cc", "asyncudpsocket.h", - "autodetectproxy.cc", - "autodetectproxy.h", "common.cc", "common.h", "crc32.cc", @@ -429,8 +427,6 @@ rtc_static_library("rtc_base") { "opensslstreamadapter.h", "physicalsocketserver.cc", "physicalsocketserver.h", - "proxydetect.cc", - "proxydetect.h", "proxyinfo.cc", "proxyinfo.h", "ratelimiter.cc", @@ -469,8 +465,6 @@ rtc_static_library("rtc_base") { "sslfingerprint.h", "sslidentity.cc", "sslidentity.h", - "sslsocketfactory.cc", - "sslsocketfactory.h", "sslstreamadapter.cc", "sslstreamadapter.h", "stream.cc", @@ -504,8 +498,6 @@ rtc_static_library("rtc_base") { sources += [ "callback.h", "fileutils_mock.h", - "httpserver.cc", - "httpserver.h", "json.cc", "json.h", "logsinks.cc", @@ -513,8 +505,6 @@ rtc_static_library("rtc_base") { "mathutils.h", "optionsfile.cc", "optionsfile.h", - "proxyserver.cc", - "proxyserver.h", "rollingaccumulator.h", "scopedptrcollection.h", "sslroots.h", @@ -710,12 +700,16 @@ if (rtc_include_tests) { "firewallsocketserver.cc", "firewallsocketserver.h", "gunit.h", + "httpserver.cc", + "httpserver.h", "natserver.cc", "natserver.h", "natsocketfactory.cc", "natsocketfactory.h", "nattypes.cc", "nattypes.h", + "proxyserver.cc", + "proxyserver.h", "sigslottester.h", "sigslottester.h.pump", "testbase64.h", @@ -853,7 +847,6 @@ if (rtc_include_tests) { rtc_source_set("rtc_base_unittests") { testonly = true sources = [ - "autodetectproxy_unittest.cc", "callback_unittest.cc", "crc32_unittest.cc", "filerotatingstream_unittest.cc", @@ -869,7 +862,6 @@ if (rtc_include_tests) { "network_unittest.cc", "optionsfile_unittest.cc", "proxy_unittest.cc", - "proxydetect_unittest.cc", "ratelimiter_unittest.cc", "rollingaccumulator_unittest.cc", "rtccertificate_unittest.cc", diff --git a/webrtc/base/autodetectproxy.cc b/webrtc/base/autodetectproxy.cc deleted file mode 100644 index 0ec6ecc3d4..0000000000 --- a/webrtc/base/autodetectproxy.cc +++ /dev/null @@ -1,302 +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/autodetectproxy.h" -#include "webrtc/base/checks.h" -#include "webrtc/base/httpcommon.h" -#include "webrtc/base/httpcommon-inl.h" -#include "webrtc/base/nethelpers.h" - -namespace rtc { - -static const ProxyType TEST_ORDER[] = { - PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN -}; - -static const int kSavedStringLimit = 128; - -static void SaveStringToStack(char *dst, - const std::string &src, - size_t dst_size) { - strncpy(dst, src.c_str(), dst_size - 1); - dst[dst_size - 1] = '\0'; -} - -AutoDetectProxy::AutoDetectProxy(const std::string& user_agent) - : agent_(user_agent), resolver_(NULL), socket_(NULL), next_(0) { -} - -bool AutoDetectProxy::GetProxyForUrl(const char* agent, - const char* url, - rtc::ProxyInfo* proxy) { - return GetProxySettingsForUrl(agent, url, proxy, true); -} - -AutoDetectProxy::~AutoDetectProxy() { - if (resolver_) { - resolver_->Destroy(false); - } -} - -void AutoDetectProxy::DoWork() { - // TODO: Try connecting to server_url without proxy first here? - if (!server_url_.empty()) { - LOG(LS_INFO) << "GetProxySettingsForUrl(" << server_url_ << ") - start"; - GetProxyForUrl(agent_.c_str(), server_url_.c_str(), &proxy_); - LOG(LS_INFO) << "GetProxySettingsForUrl - stop"; - } - Url url(proxy_.address.HostAsURIString()); - if (url.valid()) { - LOG(LS_WARNING) << "AutoDetectProxy removing http prefix on proxy host"; - proxy_.address.SetIP(url.host()); - } - LOG(LS_INFO) << "AutoDetectProxy found proxy at " << proxy_.address; - if (proxy_.type == PROXY_UNKNOWN) { - LOG(LS_INFO) << "AutoDetectProxy initiating proxy classification"; - Next(); - // Process I/O until Stop() - Thread::Current()->ProcessMessages(Thread::kForever); - // Clean up the autodetect socket, from the thread that created it - delete socket_; - } - // TODO: If we found a proxy, try to use it to verify that it - // works by sending a request to server_url. This could either be - // done here or by the HttpPortAllocator. -} - -void AutoDetectProxy::OnMessage(Message *msg) { - if (MSG_UNRESOLVABLE == msg->message_id) { - // If we can't resolve the proxy, skip straight to failure. - Complete(PROXY_UNKNOWN); - } else if (MSG_TIMEOUT == msg->message_id) { - OnTimeout(); - } else { - // This must be the ST_MSG_WORKER_DONE message that deletes the - // AutoDetectProxy object. We have observed crashes within this stack that - // seem to be highly reproducible for a small subset of users and thus are - // probably correlated with a specific proxy setting, so copy potentially - // relevant information onto the stack to make it available in Windows - // minidumps. - - // Save the user agent and the number of auto-detection passes that we - // needed. - char agent[kSavedStringLimit]; - SaveStringToStack(agent, agent_, sizeof agent); - - int next = next_; - - // Now the detected proxy config (minus the password field, which could be - // sensitive). - ProxyType type = proxy().type; - - char address_hostname[kSavedStringLimit]; - SaveStringToStack(address_hostname, - proxy().address.hostname(), - sizeof address_hostname); - - IPAddress address_ip = proxy().address.ipaddr(); - - uint16_t address_port = proxy().address.port(); - - char autoconfig_url[kSavedStringLimit]; - SaveStringToStack(autoconfig_url, - proxy().autoconfig_url, - sizeof autoconfig_url); - - bool autodetect = proxy().autodetect; - - char bypass_list[kSavedStringLimit]; - SaveStringToStack(bypass_list, proxy().bypass_list, sizeof bypass_list); - - char username[kSavedStringLimit]; - SaveStringToStack(username, proxy().username, sizeof username); - - SignalThread::OnMessage(msg); - - // Log the gathered data at a log level that will never actually be enabled - // so that the compiler is forced to retain the data on the stack. - LOG(LS_SENSITIVE) << agent << " " << next << " " << type << " " - << address_hostname << " " << address_ip << " " - << address_port << " " << autoconfig_url << " " - << autodetect << " " << bypass_list << " " << username; - } -} - -void AutoDetectProxy::OnResolveResult(AsyncResolverInterface* resolver) { - if (resolver != resolver_) { - return; - } - int error = resolver_->GetError(); - if (error == 0) { - LOG(LS_VERBOSE) << "Resolved " << proxy_.address << " to " - << resolver_->address(); - proxy_.address = resolver_->address(); - if (!DoConnect()) { - Thread::Current()->Post(RTC_FROM_HERE, this, MSG_TIMEOUT); - } - } else { - LOG(LS_INFO) << "Failed to resolve " << resolver_->address(); - resolver_->Destroy(false); - resolver_ = NULL; - proxy_.address = SocketAddress(); - Thread::Current()->Post(RTC_FROM_HERE, this, MSG_UNRESOLVABLE); - } -} - -void AutoDetectProxy::Next() { - if (TEST_ORDER[next_] >= PROXY_UNKNOWN) { - Complete(PROXY_UNKNOWN); - return; - } - - LOG(LS_VERBOSE) << "AutoDetectProxy connecting to " - << proxy_.address.ToSensitiveString(); - - if (socket_) { - Thread::Current()->Clear(this, MSG_TIMEOUT); - Thread::Current()->Clear(this, MSG_UNRESOLVABLE); - socket_->Close(); - Thread::Current()->Dispose(socket_); - socket_ = NULL; - } - int timeout = 2000; - if (proxy_.address.IsUnresolvedIP()) { - // Launch an asyncresolver. This thread will spin waiting for it. - timeout += 2000; - if (!resolver_) { - resolver_ = new AsyncResolver(); - } - resolver_->SignalDone.connect(this, &AutoDetectProxy::OnResolveResult); - resolver_->Start(proxy_.address); - } else { - if (!DoConnect()) { - Thread::Current()->Post(RTC_FROM_HERE, this, MSG_TIMEOUT); - return; - } - } - Thread::Current()->PostDelayed(RTC_FROM_HERE, timeout, this, MSG_TIMEOUT); -} - -bool AutoDetectProxy::DoConnect() { - if (resolver_) { - resolver_->Destroy(false); - resolver_ = NULL; - } - socket_ = - Thread::Current()->socketserver()->CreateAsyncSocket( - proxy_.address.family(), SOCK_STREAM); - if (!socket_) { - LOG(LS_VERBOSE) << "Unable to create socket for " << proxy_.address; - return false; - } - socket_->SignalConnectEvent.connect(this, &AutoDetectProxy::OnConnectEvent); - socket_->SignalReadEvent.connect(this, &AutoDetectProxy::OnReadEvent); - socket_->SignalCloseEvent.connect(this, &AutoDetectProxy::OnCloseEvent); - socket_->Connect(proxy_.address); - return true; -} - -void AutoDetectProxy::Complete(ProxyType type) { - Thread::Current()->Clear(this, MSG_TIMEOUT); - Thread::Current()->Clear(this, MSG_UNRESOLVABLE); - if (socket_) { - socket_->Close(); - } - - proxy_.type = type; - LoggingSeverity sev = (proxy_.type == PROXY_UNKNOWN) ? LS_ERROR : LS_INFO; - LOG_V(sev) << "AutoDetectProxy detected " - << proxy_.address.ToSensitiveString() - << " as type " << proxy_.type; - - Thread::Current()->Quit(); -} - -void AutoDetectProxy::OnConnectEvent(AsyncSocket * socket) { - std::string probe; - - switch (TEST_ORDER[next_]) { - case PROXY_HTTPS: - probe.assign("CONNECT www.google.com:443 HTTP/1.0\r\n" - "User-Agent: "); - probe.append(agent_); - probe.append("\r\n" - "Host: www.google.com\r\n" - "Content-Length: 0\r\n" - "Proxy-Connection: Keep-Alive\r\n" - "\r\n"); - break; - case PROXY_SOCKS5: - probe.assign("\005\001\000", 3); - break; - default: - RTC_NOTREACHED(); - return; - } - - LOG(LS_VERBOSE) << "AutoDetectProxy probing type " << TEST_ORDER[next_] - << " sending " << probe.size() << " bytes"; - socket_->Send(probe.data(), probe.size()); -} - -void AutoDetectProxy::OnReadEvent(AsyncSocket * socket) { - char data[257]; - int len = socket_->Recv(data, 256, nullptr); - if (len > 0) { - data[len] = 0; - LOG(LS_VERBOSE) << "AutoDetectProxy read " << len << " bytes"; - } - - switch (TEST_ORDER[next_]) { - case PROXY_HTTPS: - if ((len >= 2) && (data[0] == '\x05')) { - Complete(PROXY_SOCKS5); - return; - } - if ((len >= 5) && (strncmp(data, "HTTP/", 5) == 0)) { - Complete(PROXY_HTTPS); - return; - } - break; - case PROXY_SOCKS5: - if ((len >= 2) && (data[0] == '\x05')) { - Complete(PROXY_SOCKS5); - return; - } - break; - default: - RTC_NOTREACHED(); - return; - } - - ++next_; - Next(); -} - -void AutoDetectProxy::OnTimeout() { - LOG(LS_VERBOSE) << "Timed out waiting for AsyncResolver."; - // If a resolver timed out we shouldn't try to use it again since it may be - // in the middle of resolving the last address. - if (resolver_) { - resolver_->SignalDone.disconnect(this); - resolver_->Destroy(false); - resolver_ = nullptr; - } - ++next_; - Next(); -} - -void AutoDetectProxy::OnCloseEvent(AsyncSocket * socket, int error) { - LOG(LS_VERBOSE) << "AutoDetectProxy closed with error: " << error; - ++next_; - Next(); -} - -} // namespace rtc diff --git a/webrtc/base/autodetectproxy.h b/webrtc/base/autodetectproxy.h deleted file mode 100644 index 1788a0333d..0000000000 --- a/webrtc/base/autodetectproxy.h +++ /dev/null @@ -1,90 +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. - */ - -#ifndef WEBRTC_BASE_AUTODETECTPROXY_H_ -#define WEBRTC_BASE_AUTODETECTPROXY_H_ - -#include - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/cryptstring.h" -#include "webrtc/base/proxydetect.h" -#include "webrtc/base/proxyinfo.h" -#include "webrtc/base/signalthread.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// AutoDetectProxy -/////////////////////////////////////////////////////////////////////////////// - -class AsyncResolverInterface; -class AsyncSocket; - -class AutoDetectProxy : public SignalThread { - public: - explicit AutoDetectProxy(const std::string& user_agent); - - const ProxyInfo& proxy() const { return proxy_; } - - void set_server_url(const std::string& url) { - server_url_ = url; - } - void set_proxy(const SocketAddress& proxy) { - proxy_.type = PROXY_UNKNOWN; - proxy_.address = proxy; - } - void set_auth_info(bool use_auth, const std::string& username, - const CryptString& password) { - if (use_auth) { - proxy_.username = username; - proxy_.password = password; - } - } - // Default implementation of GetProxySettingsForUrl. Override for special - // implementation. - virtual bool GetProxyForUrl(const char* agent, - const char* url, - rtc::ProxyInfo* proxy); - enum { MSG_TIMEOUT = SignalThread::ST_MSG_FIRST_AVAILABLE, - MSG_UNRESOLVABLE, - ADP_MSG_FIRST_AVAILABLE}; - - protected: - ~AutoDetectProxy() override; - - // SignalThread Interface - void DoWork() override; - void OnMessage(Message* msg) override; - - void Next(); - void Complete(ProxyType type); - - void OnConnectEvent(AsyncSocket * socket); - void OnReadEvent(AsyncSocket * socket); - void OnCloseEvent(AsyncSocket * socket, int error); - void OnTimeout(); - void OnResolveResult(AsyncResolverInterface* resolver); - bool DoConnect(); - - private: - std::string agent_; - std::string server_url_; - ProxyInfo proxy_; - AsyncResolverInterface* resolver_; - AsyncSocket* socket_; - int next_; - - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AutoDetectProxy); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_AUTODETECTPROXY_H_ diff --git a/webrtc/base/autodetectproxy_unittest.cc b/webrtc/base/autodetectproxy_unittest.cc deleted file mode 100644 index 2ae7a6aa25..0000000000 --- a/webrtc/base/autodetectproxy_unittest.cc +++ /dev/null @@ -1,131 +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/autodetectproxy.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/httpcommon.h" -#include "webrtc/base/httpcommon-inl.h" - -namespace rtc { - -static const char kUserAgent[] = ""; -static const char kPath[] = "/"; -static const char kHost[] = "relay.google.com"; -static const uint16_t kPort = 443; -static const bool kSecure = true; -// At most, AutoDetectProxy should take ~6 seconds. Each connect step is -// allotted 2 seconds, with the initial resolution + connect given an -// extra 2 seconds. The slowest case is: -// 1) Resolution + HTTPS takes full 4 seconds and fails (but resolution -// succeeds). -// 2) SOCKS5 takes the full 2 seconds. -// Socket creation time seems unbounded, and has been observed to take >1 second -// on a linux machine under load. As such, we allow for 10 seconds for timeout, -// though could still end up with some flakiness. -static const int kTimeoutMs = 10000; - -class AutoDetectProxyTest : public testing::Test, public sigslot::has_slots<> { - public: - AutoDetectProxyTest() : auto_detect_proxy_(NULL), done_(false) {} - - protected: - bool Create(const std::string& user_agent, - const std::string& path, - const std::string& host, - uint16_t port, - bool secure, - bool startnow) { - auto_detect_proxy_ = new AutoDetectProxy(user_agent); - EXPECT_TRUE(auto_detect_proxy_ != NULL); - if (!auto_detect_proxy_) { - return false; - } - Url host_url(path, host, port); - host_url.set_secure(secure); - auto_detect_proxy_->set_server_url(host_url.url()); - auto_detect_proxy_->SignalWorkDone.connect( - this, - &AutoDetectProxyTest::OnWorkDone); - if (startnow) { - auto_detect_proxy_->Start(); - } - return true; - } - - bool Run(int timeout_ms) { - EXPECT_TRUE_WAIT(done_, timeout_ms); - return done_; - } - - void SetProxy(const SocketAddress& proxy) { - auto_detect_proxy_->set_proxy(proxy); - } - - void Start() { - auto_detect_proxy_->Start(); - } - - void TestCopesWithProxy(const SocketAddress& proxy) { - // Tests that at least autodetect doesn't crash for a given proxy address. - ASSERT_TRUE(Create(kUserAgent, - kPath, - kHost, - kPort, - kSecure, - false)); - SetProxy(proxy); - Start(); - ASSERT_TRUE(Run(kTimeoutMs)); - } - - private: - void OnWorkDone(rtc::SignalThread *thread) { - AutoDetectProxy *auto_detect_proxy = - static_cast(thread); - EXPECT_TRUE(auto_detect_proxy == auto_detect_proxy_); - auto_detect_proxy_ = NULL; - auto_detect_proxy->Release(); - done_ = true; - } - - AutoDetectProxy *auto_detect_proxy_; - bool done_; -}; - -TEST_F(AutoDetectProxyTest, TestDetectUnresolvedProxy) { - TestCopesWithProxy(rtc::SocketAddress("localhost", 9999)); -} - -TEST_F(AutoDetectProxyTest, TestDetectUnresolvableProxy) { - TestCopesWithProxy(rtc::SocketAddress("invalid", 9999)); -} - -TEST_F(AutoDetectProxyTest, TestDetectIPv6Proxy) { - TestCopesWithProxy(rtc::SocketAddress("::1", 9999)); -} - -TEST_F(AutoDetectProxyTest, TestDetectIPv4Proxy) { - TestCopesWithProxy(rtc::SocketAddress("127.0.0.1", 9999)); -} - -// Test that proxy detection completes successfully. (Does not actually verify -// the correct detection result since we don't know what proxy to expect on an -// arbitrary machine.) -TEST_F(AutoDetectProxyTest, TestProxyDetection) { - ASSERT_TRUE(Create(kUserAgent, - kPath, - kHost, - kPort, - kSecure, - true)); - ASSERT_TRUE(Run(kTimeoutMs)); -} - -} // namespace rtc diff --git a/webrtc/base/proxy_unittest.cc b/webrtc/base/proxy_unittest.cc index 4dba0dd8f3..5c5a7489f7 100644 --- a/webrtc/base/proxy_unittest.cc +++ b/webrtc/base/proxy_unittest.cc @@ -10,7 +10,6 @@ #include #include -#include "webrtc/base/autodetectproxy.h" #include "webrtc/base/gunit.h" #include "webrtc/base/httpserver.h" #include "webrtc/base/proxyserver.h" @@ -29,18 +28,6 @@ static const SocketAddress kHttpsProxyIntAddr("1.2.3.4", 443); static const SocketAddress kHttpsProxyExtAddr("1.2.3.5", 0); static const SocketAddress kBogusProxyIntAddr("1.2.3.4", 999); -// Used to run a proxy detect on the current thread. Otherwise we would need -// to make both threads share the same VirtualSocketServer. -class AutoDetectProxyRunner : public rtc::AutoDetectProxy { - public: - explicit AutoDetectProxyRunner(const std::string& agent) - : AutoDetectProxy(agent) {} - void Run() { - DoWork(); - Thread::Current()->Restart(); // needed to reset the messagequeue - } -}; - // Sets up a virtual socket server and HTTPS/SOCKS5 proxy servers. class ProxyTest : public testing::Test { public: @@ -57,16 +44,6 @@ class ProxyTest : public testing::Test { rtc::SocketServer* ss() { return ss_.get(); } - rtc::ProxyType DetectProxyType(const SocketAddress& address) { - rtc::ProxyType type; - AutoDetectProxyRunner* detect = new AutoDetectProxyRunner("unittest/1.0"); - detect->set_proxy(address); - detect->Run(); // blocks until done - type = detect->proxy().type; - detect->Destroy(false); - return type; - } - private: std::unique_ptr ss_; std::unique_ptr socks_; @@ -99,38 +76,3 @@ TEST_F(ProxyTest, TestSocks5Connect) { EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL)); EXPECT_TRUE(client.CheckNoPacket()); } - -/* -// Tests whether we can use a HTTPS proxy to connect to a server. -TEST_F(ProxyTest, TestHttpsConnect) { - AsyncSocket* socket = ss()->CreateAsyncSocket(SOCK_STREAM); - AsyncHttpsProxySocket* proxy_socket = new AsyncHttpsProxySocket( - socket, "unittest/1.0", kHttpsProxyIntAddress, "", CryptString()); - TestClient client(new AsyncTCPSocket(proxy_socket)); - TestEchoServer server(Thread::Current(), SocketAddress()); - - EXPECT_TRUE(client.Connect(server.address())); - EXPECT_TRUE(client.CheckConnected()); - EXPECT_EQ(server.address(), client.remote_address()); - client.Send("foo", 3); - EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL)); - EXPECT_TRUE(client.CheckNoPacket()); -} -*/ - -// Tests whether we can autodetect a SOCKS5 proxy. -TEST_F(ProxyTest, TestAutoDetectSocks5) { - EXPECT_EQ(rtc::PROXY_SOCKS5, DetectProxyType(kSocksProxyIntAddr)); -} - -/* -// Tests whether we can autodetect a HTTPS proxy. -TEST_F(ProxyTest, TestAutoDetectHttps) { - EXPECT_EQ(rtc::PROXY_HTTPS, DetectProxyType(kHttpsProxyIntAddr)); -} -*/ - -// Tests whether we fail properly for no proxy. -TEST_F(ProxyTest, TestAutoDetectBogus) { - EXPECT_EQ(rtc::PROXY_UNKNOWN, DetectProxyType(kBogusProxyIntAddr)); -} diff --git a/webrtc/base/proxydetect.cc b/webrtc/base/proxydetect.cc deleted file mode 100644 index b0fa30488a..0000000000 --- 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 -#endif // WEBRTC_WIN - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include -#include -#include -#include -#include "macconversion.h" -#include "webrtc/base/unixfilesystem.h" -#endif - -#ifdef WEBRTC_IOS -#include -#include "macconversion.h" -#endif - -#include -#include - -#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::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 map_; - mutable std::string def_; -}; - -enum UserAgent { - UA_FIREFOX, - UA_INTERNETEXPLORER, - UA_OTHER, - UA_UNKNOWN -}; - -#if _TRY_WINHTTP -//#include -// 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 -#include -#include -#endif // _TRY_WM_FINDPROXY - -#if _TRY_IE_LAN_SETTINGS -#include -#include -#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& 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& 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(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 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 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 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(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 purl(url); - pfnWinHttpGetIEProxyConfig pWHGIEPC = - reinterpret_cast( - 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 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(GetProcAddress(winhttp_handle, - "WinHttpOpen")); - pfnWinHttpCloseHandle pWHCH = - reinterpret_cast( - GetProcAddress(winhttp_handle, "WinHttpCloseHandle")); - pfnWinHttpGetProxyForUrl pWHGPFU = - reinterpret_cast( - 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 purl(url); - bool success = false; - - if (HMODULE hModJS = LoadLibrary(_T("jsproxy.dll"))) { - pfnInternetGetProxyInfo pIGPI = - reinterpret_cast( - 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 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 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 purl(url); - bool success = false; - - wchar_t buffer[1024]; - memset(buffer, 0, sizeof(buffer)); - INTERNET_PROXY_INFO * info = reinterpret_cast(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( - info->lpszProxyBypass)), ' ')) { - ParseProxy(nonnull(reinterpret_cast(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(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(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(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 diff --git a/webrtc/base/proxydetect.h b/webrtc/base/proxydetect.h deleted file mode 100644 index 708c332ae9..0000000000 --- a/webrtc/base/proxydetect.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2007 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. - */ - -#ifndef _PROXYDETECT_H_ -#define _PROXYDETECT_H_ - -#include "webrtc/base/proxyinfo.h" - -namespace rtc { -// Auto-detect the proxy server. Returns true if a proxy is configured, -// although hostname may be empty if the proxy is not required for -// the given URL. - -bool GetProxySettingsForUrl(const char* agent, const char* url, - rtc::ProxyInfo* proxy, - bool long_operation = false); - -} // namespace rtc - -#endif // _PROXYDETECT_H_ diff --git a/webrtc/base/proxydetect_unittest.cc b/webrtc/base/proxydetect_unittest.cc deleted file mode 100644 index ca0b428fce..0000000000 --- a/webrtc/base/proxydetect_unittest.cc +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2010 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 - -#include "webrtc/base/fileutils_mock.h" -#include "webrtc/base/proxydetect.h" - -namespace rtc { - -static const std::string kFirefoxProfilesIni = - "[Profile0]\n" - "Name=default\n" - "IsRelative=1\n" - "Path=Profiles/2de53ejb.default\n" - "Default=1\n"; - -static const std::string kFirefoxHeader = - "# Mozilla User Preferences\n" - "\n" - "/* Some Comments\n" - "*\n" - "*/\n" - "\n"; - -static const std::string kFirefoxCorruptHeader = - "iuahueqe32164"; - -static const std::string kProxyAddress = "proxy.net.com"; - -// Mocking out platform specific path to firefox prefs file. -class FirefoxPrefsFileSystem : public FakeFileSystem { - public: - explicit FirefoxPrefsFileSystem(const std::vector& all_files) : - FakeFileSystem(all_files) { - } - virtual FileStream* OpenFile(const Pathname& filename, - const std::string& mode) { - // TODO: We could have a platform dependent check of paths here. - std::string name = filename.basename(); - name.append(filename.extension()); - EXPECT_TRUE(name.compare("prefs.js") == 0 || - name.compare("profiles.ini") == 0); - FileStream* stream = FakeFileSystem::OpenFile(name, mode); - return stream; - } -}; - -class ProxyDetectTest : public testing::Test { -}; - -bool GetProxyInfo(const std::string prefs, ProxyInfo* info) { - std::vector files; - files.push_back(rtc::FakeFileSystem::File("profiles.ini", - kFirefoxProfilesIni)); - files.push_back(rtc::FakeFileSystem::File("prefs.js", prefs)); - rtc::FilesystemScope fs(new rtc::FirefoxPrefsFileSystem(files)); - return GetProxySettingsForUrl("Firefox", "www.google.com", info, false); -} - -// Verifies that an empty Firefox prefs file results in no proxy detected. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxEmptyPrefs) { - ProxyInfo proxy_info; - EXPECT_TRUE(GetProxyInfo(kFirefoxHeader, &proxy_info)); - EXPECT_EQ(PROXY_NONE, proxy_info.type); -} - -// Verifies that corrupted prefs file results in no proxy detected. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxCorruptedPrefs) { - ProxyInfo proxy_info; - EXPECT_TRUE(GetProxyInfo(kFirefoxCorruptHeader, &proxy_info)); - EXPECT_EQ(PROXY_NONE, proxy_info.type); -} - -// Verifies that SOCKS5 proxy is detected if configured. SOCKS uses a -// handshake protocol to inform the proxy software about the -// connection that the client is trying to make and may be used for -// any form of TCP or UDP socket connection. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxySocks) { - ProxyInfo proxy_info; - SocketAddress proxy_address("proxy.socks.com", 6666); - std::string prefs(kFirefoxHeader); - prefs.append("user_pref(\"network.proxy.socks\", \"proxy.socks.com\");\n"); - prefs.append("user_pref(\"network.proxy.socks_port\", 6666);\n"); - prefs.append("user_pref(\"network.proxy.type\", 1);\n"); - - EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info)); - - EXPECT_EQ(PROXY_SOCKS5, proxy_info.type); - EXPECT_EQ(proxy_address, proxy_info.address); -} - -// Verified that SSL proxy is detected if configured. SSL proxy is an -// extention of a HTTP proxy to support secure connections. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxySsl) { - ProxyInfo proxy_info; - SocketAddress proxy_address("proxy.ssl.com", 7777); - std::string prefs(kFirefoxHeader); - - prefs.append("user_pref(\"network.proxy.ssl\", \"proxy.ssl.com\");\n"); - prefs.append("user_pref(\"network.proxy.ssl_port\", 7777);\n"); - prefs.append("user_pref(\"network.proxy.type\", 1);\n"); - - EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info)); - - EXPECT_EQ(PROXY_HTTPS, proxy_info.type); - EXPECT_EQ(proxy_address, proxy_info.address); -} - -// Verifies that a HTTP proxy is detected if configured. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyHttp) { - ProxyInfo proxy_info; - SocketAddress proxy_address("proxy.http.com", 8888); - std::string prefs(kFirefoxHeader); - - prefs.append("user_pref(\"network.proxy.http\", \"proxy.http.com\");\n"); - prefs.append("user_pref(\"network.proxy.http_port\", 8888);\n"); - prefs.append("user_pref(\"network.proxy.type\", 1);\n"); - - EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info)); - - EXPECT_EQ(PROXY_HTTPS, proxy_info.type); - EXPECT_EQ(proxy_address, proxy_info.address); -} - -// Verifies detection of automatic proxy detection. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyAuto) { - ProxyInfo proxy_info; - std::string prefs(kFirefoxHeader); - - prefs.append("user_pref(\"network.proxy.type\", 4);\n"); - - EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info)); - - EXPECT_EQ(PROXY_NONE, proxy_info.type); - EXPECT_TRUE(proxy_info.autodetect); - EXPECT_TRUE(proxy_info.autoconfig_url.empty()); -} - -// Verifies detection of automatic proxy detection using a static url -// to config file. -TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyAutoUrl) { - ProxyInfo proxy_info; - std::string prefs(kFirefoxHeader); - - prefs.append( - "user_pref(\"network.proxy.autoconfig_url\", \"http://a/b.pac\");\n"); - prefs.append("user_pref(\"network.proxy.type\", 2);\n"); - - EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info)); - - EXPECT_FALSE(proxy_info.autodetect); - EXPECT_EQ(PROXY_NONE, proxy_info.type); - EXPECT_EQ(0, proxy_info.autoconfig_url.compare("http://a/b.pac")); -} - -} // namespace rtc diff --git a/webrtc/base/sslsocketfactory.cc b/webrtc/base/sslsocketfactory.cc deleted file mode 100644 index 01d7d81457..0000000000 --- a/webrtc/base/sslsocketfactory.cc +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2007 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 - -#include "webrtc/base/autodetectproxy.h" -#include "webrtc/base/checks.h" -#include "webrtc/base/httpcommon.h" -#include "webrtc/base/httpcommon-inl.h" -#include "webrtc/base/socketadapters.h" -#include "webrtc/base/ssladapter.h" -#include "webrtc/base/sslsocketfactory.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// ProxySocketAdapter -// TODO: Consider combining AutoDetectProxy and ProxySocketAdapter. I think -// the socket adapter is the more appropriate idiom for automatic proxy -// detection. We may or may not want to combine proxydetect.* as well. -/////////////////////////////////////////////////////////////////////////////// - -class ProxySocketAdapter : public AsyncSocketAdapter { - public: - ProxySocketAdapter(SslSocketFactory* factory, int family, int type) - : AsyncSocketAdapter(NULL), factory_(factory), family_(family), - type_(type), detect_(NULL) { - } - ~ProxySocketAdapter() override { - Close(); - } - - int Connect(const SocketAddress& addr) override { - RTC_DCHECK(NULL == detect_); - RTC_DCHECK(NULL == socket_); - remote_ = addr; - if (remote_.IsAnyIP() && remote_.hostname().empty()) { - LOG_F(LS_ERROR) << "Empty address"; - return SOCKET_ERROR; - } - Url url("/", remote_.HostAsURIString(), remote_.port()); - detect_ = new AutoDetectProxy(factory_->agent_); - detect_->set_server_url(url.url()); - detect_->SignalWorkDone.connect(this, - &ProxySocketAdapter::OnProxyDetectionComplete); - detect_->Start(); - return SOCKET_ERROR; - } - int GetError() const override { - if (socket_) { - return socket_->GetError(); - } - return detect_ ? EWOULDBLOCK : EADDRNOTAVAIL; - } - int Close() override { - if (socket_) { - return socket_->Close(); - } - if (detect_) { - detect_->Destroy(false); - detect_ = NULL; - } - return 0; - } - ConnState GetState() const override { - if (socket_) { - return socket_->GetState(); - } - return detect_ ? CS_CONNECTING : CS_CLOSED; - } - -private: - // AutoDetectProxy Slots - void OnProxyDetectionComplete(SignalThread* thread) { - RTC_DCHECK(detect_ == thread); - Attach(factory_->CreateProxySocket(detect_->proxy(), family_, type_)); - detect_->Release(); - detect_ = NULL; - if (0 == AsyncSocketAdapter::Connect(remote_)) { - SignalConnectEvent(this); - } else if (!IsBlockingError(socket_->GetError())) { - SignalCloseEvent(this, socket_->GetError()); - } - } - - SslSocketFactory* factory_; - int family_; - int type_; - SocketAddress remote_; - AutoDetectProxy* detect_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// SslSocketFactory -/////////////////////////////////////////////////////////////////////////////// - -SslSocketFactory::SslSocketFactory(SocketFactory* factory, - const std::string& user_agent) - : factory_(factory), - agent_(user_agent), - autodetect_proxy_(true), - force_connect_(false), - logging_level_(LS_VERBOSE), - binary_mode_(false), - ignore_bad_cert_(false) { -} - -SslSocketFactory::~SslSocketFactory() = default; - -Socket* SslSocketFactory::CreateSocket(int type) { - return CreateSocket(AF_INET, type); -} - -Socket* SslSocketFactory::CreateSocket(int family, int type) { - return factory_->CreateSocket(family, type); -} - -AsyncSocket* SslSocketFactory::CreateAsyncSocket(int type) { - return CreateAsyncSocket(AF_INET, type); -} - -AsyncSocket* SslSocketFactory::CreateAsyncSocket(int family, int type) { - if (autodetect_proxy_) { - return new ProxySocketAdapter(this, family, type); - } else { - return CreateProxySocket(proxy_, family, type); - } -} - - -AsyncSocket* SslSocketFactory::CreateProxySocket(const ProxyInfo& proxy, - int family, - int type) { - AsyncSocket* socket = factory_->CreateAsyncSocket(family, type); - if (!socket) - return NULL; - - // Binary logging happens at the lowest level - if (!logging_label_.empty() && binary_mode_) { - socket = new LoggingSocketAdapter(socket, logging_level_, - logging_label_.c_str(), binary_mode_); - } - - if (proxy.type) { - AsyncSocket* proxy_socket = 0; - if (proxy_.type == PROXY_SOCKS5) { - proxy_socket = new AsyncSocksProxySocket(socket, proxy.address, - proxy.username, proxy.password); - } else { - // Note: we are trying unknown proxies as HTTPS currently - AsyncHttpsProxySocket* http_proxy = - new AsyncHttpsProxySocket(socket, agent_, proxy.address, - proxy.username, proxy.password); - http_proxy->SetForceConnect(force_connect_ || !hostname_.empty()); - proxy_socket = http_proxy; - } - if (!proxy_socket) { - delete socket; - return NULL; - } - socket = proxy_socket; // for our purposes the proxy is now the socket - } - - if (!hostname_.empty()) { - std::unique_ptr ssl_adapter(SSLAdapter::Create(socket)); - if (!ssl_adapter) { - LOG_F(LS_ERROR) << "SSL unavailable"; - delete socket; - return NULL; - } - - ssl_adapter->set_ignore_bad_cert(ignore_bad_cert_); - if (ssl_adapter->StartSSL(hostname_.c_str(), true) != 0) { - LOG_F(LS_ERROR) << "SSL failed to start."; - return NULL; - } - socket = ssl_adapter.release(); - } - - // Regular logging occurs at the highest level - if (!logging_label_.empty() && !binary_mode_) { - socket = new LoggingSocketAdapter(socket, logging_level_, - logging_label_.c_str(), binary_mode_); - } - return socket; -} - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc diff --git a/webrtc/base/sslsocketfactory.h b/webrtc/base/sslsocketfactory.h deleted file mode 100644 index 792c15c37a..0000000000 --- a/webrtc/base/sslsocketfactory.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2007 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. - */ - -#ifndef WEBRTC_BASE_SSLSOCKETFACTORY_H__ -#define WEBRTC_BASE_SSLSOCKETFACTORY_H__ - -#include "webrtc/base/proxyinfo.h" -#include "webrtc/base/socketserver.h" - -namespace rtc { - -/////////////////////////////////////////////////////////////////////////////// -// SslSocketFactory -/////////////////////////////////////////////////////////////////////////////// - -class SslSocketFactory : public SocketFactory { - public: - SslSocketFactory(SocketFactory* factory, const std::string& user_agent); - ~SslSocketFactory() override; - - void SetAutoDetectProxy() { - autodetect_proxy_ = true; - } - void SetForceConnect(bool force) { - force_connect_ = force; - } - void SetProxy(const ProxyInfo& proxy) { - autodetect_proxy_ = false; - proxy_ = proxy; - } - bool autodetect_proxy() const { return autodetect_proxy_; } - const ProxyInfo& proxy() const { return proxy_; } - - void UseSSL(const char* hostname) { hostname_ = hostname; } - void DisableSSL() { hostname_.clear(); } - void SetIgnoreBadCert(bool ignore) { ignore_bad_cert_ = ignore; } - bool ignore_bad_cert() const { return ignore_bad_cert_; } - - void SetLogging(LoggingSeverity level, const std::string& label, - bool binary_mode = false) { - logging_level_ = level; - logging_label_ = label; - binary_mode_ = binary_mode; - } - - // SocketFactory Interface - Socket* CreateSocket(int type) override; - Socket* CreateSocket(int family, int type) override; - - AsyncSocket* CreateAsyncSocket(int type) override; - AsyncSocket* CreateAsyncSocket(int family, int type) override; - - private: - friend class ProxySocketAdapter; - AsyncSocket* CreateProxySocket(const ProxyInfo& proxy, int family, int type); - - SocketFactory* factory_; - std::string agent_; - bool autodetect_proxy_, force_connect_; - ProxyInfo proxy_; - std::string hostname_, logging_label_; - LoggingSeverity logging_level_; - bool binary_mode_; - bool ignore_bad_cert_; -}; - -/////////////////////////////////////////////////////////////////////////////// - -} // namespace rtc - -#endif // WEBRTC_BASE_SSLSOCKETFACTORY_H__