147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * 447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Use of this source code is governed by a BSD-style license 547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * in the file PATENTS. All contributing project authors may 847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */ 1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/proxydetect.h" 1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/win32.h" 1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <shlobj.h> 1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_WIN 1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifdef HAVE_CONFIG_H 1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "config.h" 2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) 2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <SystemConfiguration/SystemConfiguration.h> 2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <CoreFoundation/CoreFoundation.h> 2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <CoreServices/CoreServices.h> 2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <Security/Security.h> 2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "macconversion.h" 2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <map> 3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/fileutils.h" 3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/httpcommon.h" 3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/httpcommon-inl.h" 3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/pathutils.h" 3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/stringutils.h" 3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define _TRY_WINHTTP 1 4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define _TRY_JSPROXY 0 4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define _TRY_WM_FINDPROXY 0 4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define _TRY_IE_LAN_SETTINGS 1 4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_WIN 4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// For all platforms try Firefox. 4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define _TRY_FIREFOX 1 4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Use profiles.ini to find the correct profile for this user. 4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// If not set, we'll just look for the default one. 5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define USE_FIREFOX_PROFILES_INI 1 5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const size_t kMaxLineLength = 1024; 5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const char kFirefoxPattern[] = "Firefox"; 5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const char kInternetExplorerPattern[] = "MSIE"; 5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct StringMap { 5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void Add(const char * name, const char * value) { map_[name] = value; } 5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const std::string& Get(const char * name, const char * def = "") const { 6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::map<std::string, std::string>::const_iterator it = 6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org map_.find(name); 6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (it != map_.end()) 6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return it->second; 6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org def_ = def; 6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return def_; 6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool IsSet(const char * name) const { 6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (map_.find(name) != map_.end()); 6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private: 7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::map<std::string, std::string> map_; 7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org mutable std::string def_; 7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgenum UserAgent { 7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org UA_FIREFOX, 7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org UA_INTERNETEXPLORER, 7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org UA_OTHER, 7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org UA_UNKNOWN 8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if _TRY_WINHTTP 8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//#include <winhttp.h> 8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Note: From winhttp.h 8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst char WINHTTP[] = "winhttp"; 8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef LPVOID HINTERNET; 8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef struct { 9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD dwAccessType; // see WINHTTP_ACCESS_* types below 9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LPWSTR lpszProxy; // proxy server list 9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LPWSTR lpszProxyBypass; // proxy bypass list 9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} WINHTTP_PROXY_INFO, * LPWINHTTP_PROXY_INFO; 9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef struct { 9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD dwFlags; 9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD dwAutoDetectFlags; 9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LPCWSTR lpszAutoConfigUrl; 10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LPVOID lpvReserved; 10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD dwReserved; 10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BOOL fAutoLogonIfChallenged; 10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} WINHTTP_AUTOPROXY_OPTIONS; 10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef struct { 10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BOOL fAutoDetect; 10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LPWSTR lpszAutoConfigUrl; 10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LPWSTR lpszProxy; 10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LPWSTR lpszProxyBypass; 11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG; 11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgextern "C" { 11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org typedef HINTERNET (WINAPI * pfnWinHttpOpen) 11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ( 11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IN LPCWSTR pwszUserAgent, 11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IN DWORD dwAccessType, 11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IN LPCWSTR pwszProxyName OPTIONAL, 11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IN LPCWSTR pwszProxyBypass OPTIONAL, 11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IN DWORD dwFlags 12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ); 12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org typedef BOOL (STDAPICALLTYPE * pfnWinHttpCloseHandle) 12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ( 12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IN HINTERNET hInternet 12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ); 12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetProxyForUrl) 12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ( 12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IN HINTERNET hSession, 12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IN LPCWSTR lpcwszUrl, 12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IN WINHTTP_AUTOPROXY_OPTIONS * pAutoProxyOptions, 13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org OUT WINHTTP_PROXY_INFO * pProxyInfo 13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ); 13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetIEProxyConfig) 13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ( 13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IN OUT WINHTTP_CURRENT_USER_IE_PROXY_CONFIG * pProxyConfig 13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ); 13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // extern "C" 13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTOPROXY_AUTO_DETECT 0x00000001 14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTOPROXY_CONFIG_URL 0x00000002 14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTOPROXY_RUN_INPROCESS 0x00010000 14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY 0x00020000 14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTO_DETECT_TYPE_DHCP 0x00000001 14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTO_DETECT_TYPE_DNS_A 0x00000002 14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0 14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_ACCESS_TYPE_NO_PROXY 1 14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3 14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_NO_PROXY_NAME NULL 14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_NO_PROXY_BYPASS NULL 15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // _TRY_WINHTTP 15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if _TRY_JSPROXY 15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgextern "C" { 15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org typedef BOOL (STDAPICALLTYPE * pfnInternetGetProxyInfo) 15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ( 15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LPCSTR lpszUrl, 15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD dwUrlLength, 15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LPSTR lpszUrlHostName, 16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD dwUrlHostNameLength, 16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LPSTR * lplpszProxyHostName, 16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LPDWORD lpdwProxyHostNameLength 16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ); 16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // extern "C" 16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // _TRY_JSPROXY 16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if _TRY_WM_FINDPROXY 16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <comutil.h> 16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <wmnetsourcecreator.h> 17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <wmsinternaladminnetsource.h> 17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // _TRY_WM_FINDPROXY 17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if _TRY_IE_LAN_SETTINGS 17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <wininet.h> 17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string> 17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // _TRY_IE_LAN_SETTINGS 17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc { 17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org////////////////////////////////////////////////////////////////////// 18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Utility Functions 18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org////////////////////////////////////////////////////////////////////// 18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifdef _UNICODE 18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef std::wstring tstring; 18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string Utf8String(const tstring& str) { return ToUtf8(str); } 18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else // !_UNICODE 19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef std::string tstring; 19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string Utf8String(const tstring& str) { return str; } 19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // !_UNICODE 19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_WIN 19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool ProxyItemMatch(const Url<char>& url, char * item, size_t len) { 19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // hostname:443 20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (char * port = ::strchr(item, ':')) { 20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *port++ = '\0'; 20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (url.port() != atol(port)) { 20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // A.B.C.D or A.B.C.D/24 20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int a, b, c, d, m; 20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int match = sscanf(item, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &m); 21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (match >= 4) { 21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org uint32 ip = ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | 21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org (d & 0xFF); 21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ((match < 5) || (m > 32)) 21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org m = 32; 21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org else if (m < 0) 21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org m = 0; 21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org uint32 mask = (m == 0) ? 0 : (~0UL) << (32 - m); 21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SocketAddress addr(url.host(), 0); 21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO: Support IPv6 proxyitems. This code block is IPv4 only anyway. 22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return !addr.IsUnresolved() && 22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ((addr.ipaddr().v4AddressAsHostOrderInteger() & mask) == (ip & mask)); 22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // .foo.com 22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (*item == '.') { 22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t hostlen = url.host().length(); 22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (hostlen > len) 22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org && (stricmp(url.host().c_str() + (hostlen - len), item) == 0); 22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // localhost or www.*.com 23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!string_match(url.host().c_str(), item)) 23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool ProxyListMatch(const Url<char>& url, const std::string& proxy_list, 23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char sep) { 24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const size_t BUFSIZE = 256; 24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char buffer[BUFSIZE]; 24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const char* list = proxy_list.c_str(); 24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org while (*list) { 24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Remove leading space 24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (isspace(*list)) { 24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ++list; 24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org continue; 24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Break on separator 25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t len; 25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const char * start = list; 25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (const char * end = ::strchr(list, sep)) { 25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len = (end - list); 25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org list += len + 1; 25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len = strlen(list); 25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org list += len; 25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Remove trailing space 26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org while ((len > 0) && isspace(start[len-1])) 26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org --len; 26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Check for oversized entry 26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (len >= BUFSIZE) 26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org continue; 26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memcpy(buffer, start, len); 26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org buffer[len] = 0; 26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ProxyItemMatch(url, buffer, len)) 26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org continue; 26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Better(ProxyType lhs, const ProxyType rhs) { 27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // PROXY_NONE, PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN 27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const int PROXY_VALUE[5] = { 0, 2, 3, 1 }; 27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (PROXY_VALUE[lhs] > PROXY_VALUE[rhs]); 27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool ParseProxy(const std::string& saddress, ProxyInfo* proxy) { 28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const size_t kMaxAddressLength = 1024; 28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Allow semicolon, space, or tab as an address separator 28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const char* const kAddressSeparator = " ;\t"; 28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ProxyType ptype; 28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string host; 28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org uint16 port; 28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const char* address = saddress.c_str(); 29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org while (*address) { 29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t len; 29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const char * start = address; 29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (const char * sep = strchr(address, kAddressSeparator)) { 29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len = (sep - address); 29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org address += len + 1; 29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org while (*address != '\0' && ::strchr(kAddressSeparator, *address)) { 29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org address += 1; 29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org len = strlen(address); 30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org address += len; 30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (len > kMaxAddressLength - 1) { 30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_WARNING) << "Proxy address too long [" << start << "]"; 30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org continue; 30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char buffer[kMaxAddressLength]; 31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memcpy(buffer, start, len); 31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org buffer[len] = 0; 31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char * colon = ::strchr(buffer, ':'); 31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!colon) { 31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_WARNING) << "Proxy address without port [" << buffer << "]"; 31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org continue; 31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *colon = 0; 32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char * endptr; 32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org port = static_cast<uint16>(strtol(colon + 1, &endptr, 0)); 32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (*endptr != 0) { 32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_WARNING) << "Proxy address with invalid port [" << buffer << "]"; 32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org continue; 32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (char * equals = ::strchr(buffer, '=')) { 32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *equals = 0; 32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org host = equals + 1; 33047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (_stricmp(buffer, "socks") == 0) { 33147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptype = PROXY_SOCKS5; 33247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (_stricmp(buffer, "https") == 0) { 33347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptype = PROXY_HTTPS; 33447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 33547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_WARNING) << "Proxy address with unknown protocol [" 33647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << buffer << "]"; 33747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptype = PROXY_UNKNOWN; 33847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 33947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 34047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org host = buffer; 34147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptype = PROXY_UNKNOWN; 34247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 34347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 34447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (Better(ptype, proxy->type)) { 34547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->type = ptype; 34647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetIP(host); 34747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetPort(port); 34847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 34947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 35047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 35147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return proxy->type != PROXY_NONE; 35247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 35347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 35447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgUserAgent GetAgent(const char* agent) { 35547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (agent) { 35647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string agent_str(agent); 35747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (agent_str.find(kFirefoxPattern) != std::string::npos) { 35847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return UA_FIREFOX; 35947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (agent_str.find(kInternetExplorerPattern) != std::string::npos) { 36047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return UA_INTERNETEXPLORER; 36147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (agent_str.empty()) { 36247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return UA_UNKNOWN; 36347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 36447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 36547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return UA_OTHER; 36647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 36747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 36847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool EndsWith(const std::string& a, const std::string& b) { 36947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (b.size() > a.size()) { 37047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 37147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 37247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int result = a.compare(a.size() - b.size(), b.size(), b); 37347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return result == 0; 37447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 37547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 37647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetFirefoxProfilePath(Pathname* path) { 37747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 37847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org wchar_t w_path[MAX_PATH]; 37947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, w_path) != 38047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org S_OK) { 38147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "SHGetFolderPath failed"; 38247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 38347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 38447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path->SetFolder(ToUtf8(w_path, wcslen(w_path))); 38547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path->AppendFolder("Mozilla"); 38647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path->AppendFolder("Firefox"); 38747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) 38847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FSRef fr; 38947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (0 != FSFindFolder(kUserDomain, kApplicationSupportFolderType, 39047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org kCreateFolder, &fr)) { 39147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "FSFindFolder failed"; 39247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 39347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 39447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char buffer[NAME_MAX + 1]; 39547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (0 != FSRefMakePath(&fr, reinterpret_cast<uint8*>(buffer), 39647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ARRAY_SIZE(buffer))) { 39747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "FSRefMakePath failed"; 39847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 39947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 40047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path->SetFolder(std::string(buffer)); 40147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path->AppendFolder("Firefox"); 40247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else 40347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char* user_home = getenv("HOME"); 40447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (user_home == NULL) { 40547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 40647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 40747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path->SetFolder(std::string(user_home)); 40847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path->AppendFolder(".mozilla"); 40947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path->AppendFolder("firefox"); 41047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_WIN 41147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 41247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 41347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 41447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetDefaultFirefoxProfile(Pathname* profile_path) { 41547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(NULL != profile_path); 41647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Pathname path; 41747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!GetFirefoxProfilePath(&path)) { 41847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 41947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 42047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 42147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if USE_FIREFOX_PROFILES_INI 42247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // [Profile0] 42347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Name=default 42447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // IsRelative=1 42547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Path=Profiles/2de53ejb.default 42647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Default=1 42747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 42847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Note: we are looking for the first entry with "Default=1", or the last 42947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // entry in the file 43047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path.SetFilename("profiles.ini"); 43147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_ptr<FileStream> fs(Filesystem::OpenFile(path, "r")); 43247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!fs) { 43347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 43447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 43547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Pathname candidate; 43647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool relative = true; 43747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string line; 43847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org while (fs->ReadLine(&line) == SR_SUCCESS) { 43947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (line.length() == 0) { 44047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org continue; 44147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 44247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (line.at(0) == '[') { 44347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org relative = true; 44447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org candidate.clear(); 44547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (line.find("IsRelative=") == 0 && 44647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org line.length() >= 12) { 44747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO: The initial Linux public launch revealed a fairly 44847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // high number of machines where IsRelative= did not have anything after 44947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // it. Perhaps that is legal profiles.ini syntax? 45047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org relative = (line.at(11) != '0'); 45147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (line.find("Path=") == 0 && 45247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org line.length() >= 6) { 45347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (relative) { 45447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org candidate = path; 45547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 45647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org candidate.clear(); 45747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 45847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org candidate.AppendFolder(line.substr(5)); 45947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (line.find("Default=") == 0 && 46047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org line.length() >= 9) { 46147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ((line.at(8) != '0') && !candidate.empty()) { 46247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 46347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 46447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 46547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 46647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org fs->Close(); 46747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (candidate.empty()) { 46847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 46947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 47047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org profile_path->SetPathname(candidate.pathname()); 47147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 47247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else // !USE_FIREFOX_PROFILES_INI 47347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path.AppendFolder("Profiles"); 47447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DirectoryIterator* it = Filesystem::IterateDirectory(); 47547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org it->Iterate(path); 47647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string extension(".default"); 47747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org while (!EndsWith(it->Name(), extension)) { 47847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!it->Next()) { 47947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 48047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 48147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 48247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 48347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org profile_path->SetPathname(path); 48447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org profile->AppendFolder("Profiles"); 48547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org profile->AppendFolder(it->Name()); 48647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete it; 48747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 48847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // !USE_FIREFOX_PROFILES_INI 48947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 49047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 49147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 49247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 49347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool ReadFirefoxPrefs(const Pathname& filename, 49447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const char * prefix, 49547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org StringMap* settings) { 49647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_ptr<FileStream> fs(Filesystem::OpenFile(filename, "r")); 49747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!fs) { 49847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "Failed to open file: " << filename.pathname(); 49947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 50047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 50147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 50247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string line; 50347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org while (fs->ReadLine(&line) == SR_SUCCESS) { 50447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t prefix_len = strlen(prefix); 50547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 50647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Skip blank lines and too long lines. 50747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ((line.length() == 0) || (line.length() > kMaxLineLength) 50847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org || (line.at(0) == '#') || line.compare(0, 2, "/*") == 0 50947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org || line.compare(0, 2, " *") == 0) { 51047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org continue; 51147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 51247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 51347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char buffer[kMaxLineLength]; 51447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org strcpyn(buffer, sizeof(buffer), line.c_str()); 51547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int nstart = 0, nend = 0, vstart = 0, vend = 0; 51647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org sscanf(buffer, "user_pref(\"%n%*[^\"]%n\", %n%*[^)]%n);", 51747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &nstart, &nend, &vstart, &vend); 51847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (vend > 0) { 51947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char* name = buffer + nstart; 52047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org name[nend - nstart] = 0; 52147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ((vend - vstart >= 2) && (buffer[vstart] == '"')) { 52247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org vstart += 1; 52347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org vend -= 1; 52447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 52547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char* value = buffer + vstart; 52647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org value[vend - vstart] = 0; 52747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ((strncmp(name, prefix, prefix_len) == 0) && *value) { 52847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org settings->Add(name + prefix_len, value); 52947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 53047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 53147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_F(LS_WARNING) << "Unparsed pref [" << buffer << "]"; 53247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 53347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 53447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org fs->Close(); 53547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 53647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 53747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 53847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetFirefoxProxySettings(const char* url, ProxyInfo* proxy) { 53947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Url<char> purl(url); 54047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Pathname path; 54147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool success = false; 54247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (GetDefaultFirefoxProfile(&path)) { 54347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org StringMap settings; 54447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org path.SetFilename("prefs.js"); 54547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ReadFirefoxPrefs(path, "network.proxy.", &settings)) { 54647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org success = true; 54747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->bypass_list = 54847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org settings.Get("no_proxies_on", "localhost, 127.0.0.1"); 54947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (settings.Get("type") == "1") { 55047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // User has manually specified a proxy, try to figure out what 55147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // type it is. 55247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ProxyListMatch(purl, proxy->bypass_list.c_str(), ',')) { 55347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Our url is in the list of url's to bypass proxy. 55447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (settings.Get("share_proxy_settings") == "true") { 55547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->type = PROXY_UNKNOWN; 55647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetIP(settings.Get("http")); 55747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetPort(atoi(settings.Get("http_port").c_str())); 55847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (settings.IsSet("socks")) { 55947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->type = PROXY_SOCKS5; 56047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetIP(settings.Get("socks")); 56147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetPort(atoi(settings.Get("socks_port").c_str())); 56247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (settings.IsSet("ssl")) { 56347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->type = PROXY_HTTPS; 56447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetIP(settings.Get("ssl")); 56547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetPort(atoi(settings.Get("ssl_port").c_str())); 56647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (settings.IsSet("http")) { 56747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->type = PROXY_HTTPS; 56847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetIP(settings.Get("http")); 56947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetPort(atoi(settings.Get("http_port").c_str())); 57047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 57147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (settings.Get("type") == "2") { 57247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Browser is configured to get proxy settings from a given url. 57347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->autoconfig_url = settings.Get("autoconfig_url").c_str(); 57447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (settings.Get("type") == "4") { 57547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Browser is configured to auto detect proxy config. 57647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->autodetect = true; 57747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 57847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // No proxy set. 57947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 58047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 58147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 58247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return success; 58347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 58447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 58547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) // Windows specific implementation for reading Internet 58647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Explorer proxy settings. 58747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 58847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid LogGetProxyFault() { 58947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_GLEM(LERROR, WINHTTP) << "WinHttpGetProxyForUrl faulted!!"; 59047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 59147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 59247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgBOOL MyWinHttpGetProxyForUrl(pfnWinHttpGetProxyForUrl pWHGPFU, 59347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org HINTERNET hWinHttp, LPCWSTR url, 59447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WINHTTP_AUTOPROXY_OPTIONS *options, 59547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WINHTTP_PROXY_INFO *info) { 59647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // WinHttpGetProxyForUrl() can call plugins which can crash. 59747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // In the case of McAfee scriptproxy.dll, it does crash in 59847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // older versions. Try to catch crashes here and treat as an 59947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // error. 60047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BOOL success = FALSE; 60147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 60247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if (_HAS_EXCEPTIONS == 0) 60347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org __try { 60447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org success = pWHGPFU(hWinHttp, url, options, info); 60547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } __except(EXCEPTION_EXECUTE_HANDLER) { 60647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // This is a separate function to avoid 60747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Visual C++ error 2712 when compiling with C++ EH 60847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LogGetProxyFault(); 60947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 61047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else 61147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org success = pWHGPFU(hWinHttp, url, options, info); 61247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // (_HAS_EXCEPTIONS == 0) 61347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 61447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return success; 61547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 61647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 61747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool IsDefaultBrowserFirefox() { 61847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org HKEY key; 61947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LONG result = RegOpenKeyEx(HKEY_CLASSES_ROOT, L"http\\shell\\open\\command", 62047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 0, KEY_READ, &key); 62147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ERROR_SUCCESS != result) 62247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 62347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 62447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD size, type; 625b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org bool success = false; 62647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = RegQueryValueEx(key, L"", 0, &type, NULL, &size); 627b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org if (result == ERROR_SUCCESS && type == REG_SZ) { 628b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org wchar_t* value = new wchar_t[size+1]; 62947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BYTE* buffer = reinterpret_cast<BYTE*>(value); 63047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = RegQueryValueEx(key, L"", 0, &type, buffer, &size); 631b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org if (result == ERROR_SUCCESS) { 632b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org // Size returned by RegQueryValueEx is in bytes, convert to number of 633b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org // wchar_t's. 634b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org size /= sizeof(value[0]); 635b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org value[size] = L'\0'; 636b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org for (size_t i = 0; i < size; ++i) { 637b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org value[i] = tolowercase(value[i]); 638b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org } 639b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org success = (NULL != strstr(value, L"firefox.exe")); 64047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 641b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org delete[] value; 64247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 643b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org 644b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org RegCloseKey(key); 64547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return success; 64647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 64747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 64847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetWinHttpProxySettings(const char* url, ProxyInfo* proxy) { 64947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll"); 65047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (winhttp_handle == NULL) { 65147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "Failed to load winhttp.dll."; 65247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 65347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 65447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WINHTTP_CURRENT_USER_IE_PROXY_CONFIG iecfg; 65547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(&iecfg, 0, sizeof(iecfg)); 65647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Url<char> purl(url); 65747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pfnWinHttpGetIEProxyConfig pWHGIEPC = 65847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org reinterpret_cast<pfnWinHttpGetIEProxyConfig>( 65947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GetProcAddress(winhttp_handle, 66047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org "WinHttpGetIEProxyConfigForCurrentUser")); 66147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool success = false; 66247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (pWHGIEPC && pWHGIEPC(&iecfg)) { 66347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // We were read proxy config successfully. 66447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org success = true; 66547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (iecfg.fAutoDetect) { 66647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->autodetect = true; 66747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 66847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (iecfg.lpszAutoConfigUrl) { 66947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->autoconfig_url = ToUtf8(iecfg.lpszAutoConfigUrl); 67047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GlobalFree(iecfg.lpszAutoConfigUrl); 67147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 67247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (iecfg.lpszProxyBypass) { 67347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->bypass_list = ToUtf8(iecfg.lpszProxyBypass); 67447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GlobalFree(iecfg.lpszProxyBypass); 67547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 67647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (iecfg.lpszProxy) { 67747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ProxyListMatch(purl, proxy->bypass_list, ';')) { 67847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ParseProxy(ToUtf8(iecfg.lpszProxy), proxy); 67947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 68047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GlobalFree(iecfg.lpszProxy); 68147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 68247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 68347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FreeLibrary(winhttp_handle); 68447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return success; 68547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 68647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 68747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Uses the WinHTTP API to auto detect proxy for the given url. Firefox and IE 68847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// have slightly different option dialogs for proxy settings. In Firefox, 68947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// either a location of a proxy configuration file can be specified or auto 69047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// detection can be selected. In IE theese two options can be independently 69147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// selected. For the case where both options are selected (only IE) we try to 69247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// fetch the config file first, and if that fails we'll perform an auto 69347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// detection. 69447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 69547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Returns true if we successfully performed an auto detection not depending on 69647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// whether we found a proxy or not. Returns false on error. 69747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool WinHttpAutoDetectProxyForUrl(const char* agent, const char* url, 69847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ProxyInfo* proxy) { 69947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Url<char> purl(url); 70047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool success = true; 70147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll"); 70247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (winhttp_handle == NULL) { 70347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "Failed to load winhttp.dll."; 70447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 70547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 70647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pfnWinHttpOpen pWHO = 70747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org reinterpret_cast<pfnWinHttpOpen>(GetProcAddress(winhttp_handle, 70847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org "WinHttpOpen")); 70947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pfnWinHttpCloseHandle pWHCH = 71047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org reinterpret_cast<pfnWinHttpCloseHandle>( 71147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GetProcAddress(winhttp_handle, "WinHttpCloseHandle")); 71247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pfnWinHttpGetProxyForUrl pWHGPFU = 71347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org reinterpret_cast<pfnWinHttpGetProxyForUrl>( 71447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GetProcAddress(winhttp_handle, "WinHttpGetProxyForUrl")); 71547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (pWHO && pWHCH && pWHGPFU) { 71647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (HINTERNET hWinHttp = pWHO(ToUtf16(agent).c_str(), 71747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WINHTTP_ACCESS_TYPE_NO_PROXY, 71847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WINHTTP_NO_PROXY_NAME, 71947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WINHTTP_NO_PROXY_BYPASS, 72047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 0)) { 72147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BOOL result = FALSE; 72247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WINHTTP_PROXY_INFO info; 72347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(&info, 0, sizeof(info)); 72447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (proxy->autodetect) { 72547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Use DHCP and DNS to try to find any proxy to use. 72647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WINHTTP_AUTOPROXY_OPTIONS options; 72747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(&options, 0, sizeof(options)); 72847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org options.fAutoLogonIfChallenged = TRUE; 72947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 73047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT; 73147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org options.dwAutoDetectFlags |= WINHTTP_AUTO_DETECT_TYPE_DHCP 73247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org | WINHTTP_AUTO_DETECT_TYPE_DNS_A; 73347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = MyWinHttpGetProxyForUrl( 73447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info); 73547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 73647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!result && !proxy->autoconfig_url.empty()) { 73747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // We have the location of a proxy config file. Download it and 73847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // execute it to find proxy settings for our url. 73947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org WINHTTP_AUTOPROXY_OPTIONS options; 74047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(&options, 0, sizeof(options)); 74147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(&info, 0, sizeof(info)); 74247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org options.fAutoLogonIfChallenged = TRUE; 74347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 74447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::wstring autoconfig_url16((ToUtf16)(proxy->autoconfig_url)); 74547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL; 74647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org options.lpszAutoConfigUrl = autoconfig_url16.c_str(); 74747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 74847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = MyWinHttpGetProxyForUrl( 74947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info); 75047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 75147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (result) { 75247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Either the given auto config url was valid or auto 75347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // detection found a proxy on this network. 75447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (info.lpszProxy) { 75547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO: Does this bypass list differ from the list 75647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // retreived from GetWinHttpProxySettings earlier? 75747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (info.lpszProxyBypass) { 75847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->bypass_list = ToUtf8(info.lpszProxyBypass); 75947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GlobalFree(info.lpszProxyBypass); 76047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 76147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->bypass_list.clear(); 76247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 76347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ProxyListMatch(purl, proxy->bypass_list, ';')) { 76447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Found proxy for this URL. If parsing the address turns 76547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // out ok then we are successful. 76647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org success = ParseProxy(ToUtf8(info.lpszProxy), proxy); 76747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 76847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GlobalFree(info.lpszProxy); 76947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 77047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 77147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // We could not find any proxy for this url. 77247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "No proxy detected for " << url; 77347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 77447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pWHCH(hWinHttp); 77547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 77647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 77747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "Failed loading WinHTTP functions."; 77847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org success = false; 77947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 78047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FreeLibrary(winhttp_handle); 78147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return success; 78247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 78347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 78447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if 0 // Below functions currently not used. 78547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 78647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetJsProxySettings(const char* url, ProxyInfo* proxy) { 78747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Url<char> purl(url); 78847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool success = false; 78947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 79047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (HMODULE hModJS = LoadLibrary(_T("jsproxy.dll"))) { 79147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pfnInternetGetProxyInfo pIGPI = 79247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org reinterpret_cast<pfnInternetGetProxyInfo>( 79347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GetProcAddress(hModJS, "InternetGetProxyInfo")); 79447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (pIGPI) { 79547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char proxy[256], host[256]; 79647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(proxy, 0, sizeof(proxy)); 79747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char * ptr = proxy; 79847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD proxylen = sizeof(proxy); 79947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string surl = Utf8String(url); 80047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD hostlen = _snprintf(host, sizeof(host), "http%s://%S", 80147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org purl.secure() ? "s" : "", purl.server()); 80247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (pIGPI(surl.data(), surl.size(), host, hostlen, &ptr, &proxylen)) { 80347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(INFO) << "Proxy: " << proxy; 80447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 80547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG_GLE(INFO) << "InternetGetProxyInfo"; 80647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 80747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 80847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FreeLibrary(hModJS); 80947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 81047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return success; 81147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 81247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 81347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetWmProxySettings(const char* url, ProxyInfo* proxy) { 81447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Url<char> purl(url); 81547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool success = false; 81647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 81747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org INSNetSourceCreator * nsc = 0; 81847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org HRESULT hr = CoCreateInstance(CLSID_ClientNetManager, 0, CLSCTX_ALL, 81947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IID_INSNetSourceCreator, (LPVOID *) &nsc); 82047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (SUCCEEDED(hr)) { 82147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (SUCCEEDED(hr = nsc->Initialize())) { 82247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org VARIANT dispatch; 82347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org VariantInit(&dispatch); 82447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (SUCCEEDED(hr = nsc->GetNetSourceAdminInterface(L"http", &dispatch))) { 82547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IWMSInternalAdminNetSource * ians = 0; 82647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (SUCCEEDED(hr = dispatch.pdispVal->QueryInterface( 82747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org IID_IWMSInternalAdminNetSource, (LPVOID *) &ians))) { 82847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org _bstr_t host(purl.server()); 82947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BSTR proxy = 0; 83047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BOOL bProxyEnabled = FALSE; 83147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD port, context = 0; 83247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (SUCCEEDED(hr = ians->FindProxyForURL( 83347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org L"http", host, &bProxyEnabled, &proxy, &port, &context))) { 83447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org success = true; 83547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (bProxyEnabled) { 83647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org _bstr_t sproxy = proxy; 83747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->ptype = PT_HTTPS; 83847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->host = sproxy; 83947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->port = port; 84047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 84147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 84247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SysFreeString(proxy); 84347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (FAILED(hr = ians->ShutdownProxyContext(context))) { 84447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "IWMSInternalAdminNetSource::ShutdownProxyContext" 84547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << "failed: " << hr; 84647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 84747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ians->Release(); 84847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 84947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 85047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org VariantClear(&dispatch); 85147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (FAILED(hr = nsc->Shutdown())) { 85247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "INSNetSourceCreator::Shutdown failed: " << hr; 85347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 85447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 85547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org nsc->Release(); 85647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 85747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return success; 85847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 85947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 86047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetIePerConnectionProxySettings(const char* url, ProxyInfo* proxy) { 86147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Url<char> purl(url); 86247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool success = false; 86347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 86447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org INTERNET_PER_CONN_OPTION_LIST list; 86547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org INTERNET_PER_CONN_OPTION options[3]; 86647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(&list, 0, sizeof(list)); 86747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(&options, 0, sizeof(options)); 86847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 86947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org list.dwSize = sizeof(list); 87047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org list.dwOptionCount = 3; 87147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org list.pOptions = options; 87247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org options[0].dwOption = INTERNET_PER_CONN_FLAGS; 87347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER; 87447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS; 87547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD dwSize = sizeof(list); 87647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 87747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!InternetQueryOption(0, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, 87847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &dwSize)) { 87947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError(); 88047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if ((options[0].Value.dwValue & PROXY_TYPE_PROXY) != 0) { 88147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org success = true; 88247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ProxyListMatch(purl, nonnull(options[2].Value.pszValue), _T(';'))) { 88347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ParseProxy(nonnull(options[1].Value.pszValue), proxy); 88447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 88547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if ((options[0].Value.dwValue & PROXY_TYPE_DIRECT) != 0) { 88647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org success = true; 88747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 88847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "unknown internet access type: " 88947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << options[0].Value.dwValue; 89047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 89147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (options[1].Value.pszValue) { 89247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GlobalFree(options[1].Value.pszValue); 89347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 89447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (options[2].Value.pszValue) { 89547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org GlobalFree(options[2].Value.pszValue); 89647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 89747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return success; 89847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 89947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 90047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // 0 90147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 90247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Uses the InternetQueryOption function to retrieve proxy settings 90347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// from the registry. This will only give us the 'static' settings, 90447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// ie, not any information about auto config etc. 90547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetIeLanProxySettings(const char* url, ProxyInfo* proxy) { 90647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Url<char> purl(url); 90747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool success = false; 90847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 90947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org wchar_t buffer[1024]; 91047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(buffer, 0, sizeof(buffer)); 91147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org INTERNET_PROXY_INFO * info = reinterpret_cast<INTERNET_PROXY_INFO *>(buffer); 91247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD dwSize = sizeof(buffer); 91347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 91447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!InternetQueryOption(0, INTERNET_OPTION_PROXY, info, &dwSize)) { 91547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError(); 91647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (info->dwAccessType == INTERNET_OPEN_TYPE_DIRECT) { 91747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org success = true; 91847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (info->dwAccessType == INTERNET_OPEN_TYPE_PROXY) { 91947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org success = true; 92047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ProxyListMatch(purl, nonnull(reinterpret_cast<const char*>( 92147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org info->lpszProxyBypass)), ' ')) { 92247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ParseProxy(nonnull(reinterpret_cast<const char*>(info->lpszProxy)), 92347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy); 92447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 92547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 92647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "unknown internet access type: " << info->dwAccessType; 92747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 92847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return success; 92947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 93047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 93147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetIeProxySettings(const char* agent, const char* url, ProxyInfo* proxy) { 93247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool success = GetWinHttpProxySettings(url, proxy); 93347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!success) { 93447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO: Should always call this if no proxy were detected by 93547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // GetWinHttpProxySettings? 93647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // WinHttp failed. Try using the InternetOptionQuery method instead. 93747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return GetIeLanProxySettings(url, proxy); 93847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 93947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 94047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 94147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 94247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_WIN 94347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 94447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) // WEBRTC_MAC && !defined(WEBRTC_IOS) specific implementation for reading system wide 94547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // proxy settings. 94647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 94747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool p_getProxyInfoForTypeFromDictWithKeys(ProxyInfo* proxy, 94847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ProxyType type, 94947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const CFDictionaryRef proxyDict, 95047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const CFStringRef enabledKey, 95147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const CFStringRef hostKey, 95247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const CFStringRef portKey) { 95347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // whether or not we set up the proxy info. 95447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool result = false; 95547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 95647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // we use this as a scratch variable for determining if operations 95747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // succeeded. 95847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool converted = false; 95947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 96047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // the data we need to construct the SocketAddress for the proxy. 96147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string hostname; 96247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int port; 96347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 96447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ((proxyDict != NULL) && 96547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org (CFGetTypeID(proxyDict) == CFDictionaryGetTypeID())) { 96647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // CoreFoundation stuff that we'll have to get from 96747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // the dictionaries and interpret or convert into more usable formats. 96847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CFNumberRef enabledCFNum; 96947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CFNumberRef portCFNum; 97047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CFStringRef hostCFStr; 97147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 97247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org enabledCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, enabledKey); 97347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 97447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (p_isCFNumberTrue(enabledCFNum)) { 97547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // let's see if we can get the address and port. 97647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org hostCFStr = (CFStringRef)CFDictionaryGetValue(proxyDict, hostKey); 97747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org converted = p_convertHostCFStringRefToCPPString(hostCFStr, hostname); 97847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (converted) { 97947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org portCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, portKey); 98047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org converted = p_convertCFNumberToInt(portCFNum, &port); 98147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (converted) { 98247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // we have something enabled, with a hostname and a port. 98347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // That's sufficient to set up the proxy info. 98447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->type = type; 98547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetIP(hostname); 98647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->address.SetPort(port); 98747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = true; 98847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 98947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 99047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 99147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 99247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 99347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return result; 99447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 99547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 99647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Looks for proxy information in the given dictionary, 99747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// return true if it found sufficient information to define one, 99847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// false otherwise. This is guaranteed to not change the values in proxy 99947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// unless a full-fledged proxy description was discovered in the dictionary. 100047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// However, at the present time this does not support username or password. 100147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Checks first for a SOCKS proxy, then for HTTPS, then HTTP. 100247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetMacProxySettingsFromDictionary(ProxyInfo* proxy, 100347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const CFDictionaryRef proxyDict) { 100447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // the function result. 100547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool gotProxy = false; 100647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 100747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 100847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // first we see if there's a SOCKS proxy in place. 100947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy, 101047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org PROXY_SOCKS5, 101147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxyDict, 101247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org kSCPropNetProxiesSOCKSEnable, 101347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org kSCPropNetProxiesSOCKSProxy, 101447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org kSCPropNetProxiesSOCKSPort); 101547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 101647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!gotProxy) { 101747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // okay, no SOCKS proxy, let's look for https. 101847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy, 101947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org PROXY_HTTPS, 102047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxyDict, 102147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org kSCPropNetProxiesHTTPSEnable, 102247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org kSCPropNetProxiesHTTPSProxy, 102347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org kSCPropNetProxiesHTTPSPort); 102447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!gotProxy) { 102547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Finally, try HTTP proxy. Note that flute doesn't 102647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // differentiate between HTTPS and HTTP, hence we are using the 102747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // same flute type here, ie. PROXY_HTTPS. 102847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org gotProxy = p_getProxyInfoForTypeFromDictWithKeys( 102947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy, PROXY_HTTPS, proxyDict, kSCPropNetProxiesHTTPEnable, 103047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort); 103147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 103247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 103347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return gotProxy; 103447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 103547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 103647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// TODO(hughv) Update keychain functions. They work on 10.8, but are depricated. 103747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 103847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool p_putPasswordInProxyInfo(ProxyInfo* proxy) { 103947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool result = true; // by default we assume we're good. 104047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // for all we know there isn't any password. We'll set to false 104147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // if we find a problem. 104247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 104347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Ask the keychain for an internet password search for the given protocol. 104447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org OSStatus oss = 0; 104547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SecKeychainAttributeList attrList; 104647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attrList.count = 3; 104747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SecKeychainAttribute attributes[3]; 104847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attrList.attr = attributes; 104947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 105047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attributes[0].tag = kSecProtocolItemAttr; 105147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attributes[0].length = sizeof(SecProtocolType); 105247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SecProtocolType protocol; 105347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org switch (proxy->type) { 105447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case PROXY_HTTPS : 105547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org protocol = kSecProtocolTypeHTTPS; 105647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 105747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case PROXY_SOCKS5 : 105847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org protocol = kSecProtocolTypeSOCKS; 105947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 106047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org default : 106147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "asked for proxy password for unknown proxy type."; 106247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = false; 106347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 106447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 106547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attributes[0].data = &protocol; 106647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 106747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org UInt32 port = proxy->address.port(); 106847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attributes[1].tag = kSecPortItemAttr; 106947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attributes[1].length = sizeof(UInt32); 107047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attributes[1].data = &port; 107147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 107247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string ip = proxy->address.ipaddr().ToString(); 107347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attributes[2].tag = kSecServerItemAttr; 107447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attributes[2].length = ip.length(); 107547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attributes[2].data = const_cast<char*>(ip.c_str()); 107647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 107747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (result) { 107847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "trying to get proxy username/password"; 107947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SecKeychainSearchRef sref; 108047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org oss = SecKeychainSearchCreateFromAttributes(NULL, 108147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org kSecInternetPasswordItemClass, 108247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &attrList, &sref); 108347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (0 == oss) { 108447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "SecKeychainSearchCreateFromAttributes was good"; 108547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Get the first item, if there is one. 108647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SecKeychainItemRef iref; 108747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org oss = SecKeychainSearchCopyNext(sref, &iref); 108847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (0 == oss) { 108947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "...looks like we have the username/password data"; 109047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // If there is, get the username and the password. 109147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 109247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SecKeychainAttributeInfo attribsToGet; 109347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attribsToGet.count = 1; 109447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org UInt32 tag = kSecAccountItemAttr; 109547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org UInt32 format = CSSM_DB_ATTRIBUTE_FORMAT_STRING; 109647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void *data; 109747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org UInt32 length; 109847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SecKeychainAttributeList *localList; 109947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 110047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attribsToGet.tag = &tag; 110147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org attribsToGet.format = &format; 110247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org OSStatus copyres = SecKeychainItemCopyAttributesAndData(iref, 110347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &attribsToGet, 110447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org NULL, 110547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &localList, 110647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &length, 110747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &data); 110847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (0 == copyres) { 110947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "...and we can pull it out."; 111047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // now, we know from experimentation (sadly not from docs) 111147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // that the username is in the local attribute list, 111247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // and the password in the data, 111347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // both without null termination but with info on their length. 111447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // grab the password from the data. 111547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string password; 111647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org password.append(static_cast<const char*>(data), length); 111747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 111847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // make the password into a CryptString 111947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // huh, at the time of writing, you can't. 112047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // so we'll skip that for now and come back to it later. 112147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 112247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // now put the username in the proxy. 112347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (1 <= localList->attr->length) { 112447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->username.append( 112547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static_cast<const char*>(localList->attr->data), 112647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org localList->attr->length); 112747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "username is " << proxy->username; 112847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 112947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "got keychain entry with no username"; 113047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = false; 113147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 113247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 113347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "couldn't copy info from keychain."; 113447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = false; 113547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 113647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SecKeychainItemFreeAttributesAndData(localList, data); 113747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (errSecItemNotFound == oss) { 113847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "...username/password info not found"; 113947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 114047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // oooh, neither 0 nor itemNotFound. 114147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss; 114247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = false; 114347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 114447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (errSecItemNotFound == oss) { // noop 114547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 114647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // oooh, neither 0 nor itemNotFound. 114747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss; 114847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = false; 114947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 115047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 115147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 115247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return result; 115347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 115447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 115547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetMacProxySettings(ProxyInfo* proxy) { 115647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // based on the Apple Technical Q&A QA1234 115747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // http://developer.apple.com/qa/qa2001/qa1234.html 115847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CFDictionaryRef proxyDict = SCDynamicStoreCopyProxies(NULL); 115947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool result = false; 116047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 116147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (proxyDict != NULL) { 116247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // sending it off to another function makes it easier to unit test 116347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // since we can make our own dictionary to hand to that function. 116447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = GetMacProxySettingsFromDictionary(proxy, proxyDict); 116547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 116647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (result) { 116747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = p_putPasswordInProxyInfo(proxy); 116847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 116947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 117047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // We created the dictionary with something that had the 117147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // word 'copy' in it, so we have to release it, according 117247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // to the Carbon memory management standards. 117347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CFRelease(proxyDict); 117447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 117547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "SCDynamicStoreCopyProxies failed"; 117647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 117747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 117847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return result; 117947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 118047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) 118147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 118247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool AutoDetectProxySettings(const char* agent, const char* url, 118347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ProxyInfo* proxy) { 118447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 118547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return WinHttpAutoDetectProxyForUrl(agent, url, proxy); 118647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else 118747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_WARNING) << "Proxy auto-detection not implemented for this platform"; 118847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 118947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 119047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 119147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 119247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetSystemDefaultProxySettings(const char* agent, const char* url, 119347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ProxyInfo* proxy) { 119447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 119547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return GetIeProxySettings(agent, url, proxy); 119647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) 119747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return GetMacProxySettings(proxy); 119847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else 119947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO: Get System settings if browser is not firefox. 120047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return GetFirefoxProxySettings(url, proxy); 120147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 120247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 120347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 120447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetProxySettingsForUrl(const char* agent, const char* url, 120547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ProxyInfo* proxy, bool long_operation) { 120647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org UserAgent a = GetAgent(agent); 120747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool result; 120847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org switch (a) { 120947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case UA_FIREFOX: { 121047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = GetFirefoxProxySettings(url, proxy); 121147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 121247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 121347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 121447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case UA_INTERNETEXPLORER: 121547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = GetIeProxySettings(agent, url, proxy); 121647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 121747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case UA_UNKNOWN: 121847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Agent not defined, check default browser. 121947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (IsDefaultBrowserFirefox()) { 122047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = GetFirefoxProxySettings(url, proxy); 122147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 122247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = GetIeProxySettings(agent, url, proxy); 122347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 122447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 122547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_WIN 122647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org default: 122747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = GetSystemDefaultProxySettings(agent, url, proxy); 122847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 122947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 123047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 123147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO: Consider using the 'long_operation' parameter to 123247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // decide whether to do the auto detection. 123347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (result && (proxy->autodetect || 123447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org !proxy->autoconfig_url.empty())) { 123547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Use WinHTTP to auto detect proxy for us. 123647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org result = AutoDetectProxySettings(agent, url, proxy); 123747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!result) { 123847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Either auto detection is not supported or we simply didn't 123947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // find any proxy, reset type. 124047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org proxy->type = rtc::PROXY_NONE; 124147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 124247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 124347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return result; 124447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 124547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 124647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // namespace rtc 1247