1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/* 2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle 3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2005, Google Inc. 4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without 6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met: 7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 1. Redistributions of source code must retain the above copyright notice, 9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer. 10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright notice, 11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer in the documentation 12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * and/or other materials provided with the distribution. 13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 3. The name of the author may not be used to endorse or promote products 14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * derived from this software without specific prior written permission. 15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */ 27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/proxydetect.h" 29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32 31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/win32.h" 32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <shlobj.h> 33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // WIN32 34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef HAVE_CONFIG_H 36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "config.h" 37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif 38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef OSX 40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <SystemConfiguration/SystemConfiguration.h> 41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <CoreFoundation/CoreFoundation.h> 42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <CoreServices/CoreServices.h> 43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <Security/Security.h> 44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "macconversion.h" 45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif 46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <map> 48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/fileutils.h" 50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/httpcommon.h" 51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/httpcommon-inl.h" 52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/pathutils.h" 53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/stringutils.h" 54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32 56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define _TRY_WINHTTP 1 57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define _TRY_JSPROXY 0 58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define _TRY_WM_FINDPROXY 0 59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define _TRY_IE_LAN_SETTINGS 1 60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // WIN32 61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// For all platforms try Firefox. 63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define _TRY_FIREFOX 1 64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Use profiles.ini to find the correct profile for this user. 66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// If not set, we'll just look for the default one. 67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define USE_FIREFOX_PROFILES_INI 1 68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstatic const size_t kMaxLineLength = 1024; 70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstatic const char kFirefoxPattern[] = "Firefox"; 71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstatic const char kInternetExplorerPattern[] = "MSIE"; 72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct StringMap { 74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public: 75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch void Add(const char * name, const char * value) { map_[name] = value; } 76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string& Get(const char * name, const char * def = "") const { 77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::map<std::string, std::string>::const_iterator it = 78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch map_.find(name); 79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (it != map_.end()) 80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return it->second; 81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch def_ = def; 82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return def_; 83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool IsSet(const char * name) const { 85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (map_.find(name) != map_.end()); 86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private: 88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::map<std::string, std::string> map_; 89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch mutable std::string def_; 90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}; 91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochenum UserAgent { 93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch UA_FIREFOX, 94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch UA_INTERNETEXPLORER, 95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch UA_OTHER, 96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch UA_UNKNOWN 97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}; 98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if _TRY_WINHTTP 100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch//#include <winhttp.h> 101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Note: From winhttp.h 102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst char WINHTTP[] = "winhttp"; 104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtypedef LPVOID HINTERNET; 106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtypedef struct { 108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD dwAccessType; // see WINHTTP_ACCESS_* types below 109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LPWSTR lpszProxy; // proxy server list 110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LPWSTR lpszProxyBypass; // proxy bypass list 111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} WINHTTP_PROXY_INFO, * LPWINHTTP_PROXY_INFO; 112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtypedef struct { 114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD dwFlags; 115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD dwAutoDetectFlags; 116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LPCWSTR lpszAutoConfigUrl; 117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LPVOID lpvReserved; 118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD dwReserved; 119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch BOOL fAutoLogonIfChallenged; 120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} WINHTTP_AUTOPROXY_OPTIONS; 121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtypedef struct { 123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch BOOL fAutoDetect; 124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LPWSTR lpszAutoConfigUrl; 125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LPWSTR lpszProxy; 126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LPWSTR lpszProxyBypass; 127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG; 128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochextern "C" { 130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch typedef HINTERNET (WINAPI * pfnWinHttpOpen) 131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ( 132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IN LPCWSTR pwszUserAgent, 133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IN DWORD dwAccessType, 134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IN LPCWSTR pwszProxyName OPTIONAL, 135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IN LPCWSTR pwszProxyBypass OPTIONAL, 136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IN DWORD dwFlags 137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ); 138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch typedef BOOL (STDAPICALLTYPE * pfnWinHttpCloseHandle) 139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ( 140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IN HINTERNET hInternet 141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ); 142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetProxyForUrl) 143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ( 144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IN HINTERNET hSession, 145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IN LPCWSTR lpcwszUrl, 146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IN WINHTTP_AUTOPROXY_OPTIONS * pAutoProxyOptions, 147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch OUT WINHTTP_PROXY_INFO * pProxyInfo 148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ); 149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetIEProxyConfig) 150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ( 151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IN OUT WINHTTP_CURRENT_USER_IE_PROXY_CONFIG * pProxyConfig 152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ); 153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} // extern "C" 155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define WINHTTP_AUTOPROXY_AUTO_DETECT 0x00000001 157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define WINHTTP_AUTOPROXY_CONFIG_URL 0x00000002 158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define WINHTTP_AUTOPROXY_RUN_INPROCESS 0x00010000 159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY 0x00020000 160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define WINHTTP_AUTO_DETECT_TYPE_DHCP 0x00000001 161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define WINHTTP_AUTO_DETECT_TYPE_DNS_A 0x00000002 162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0 163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define WINHTTP_ACCESS_TYPE_NO_PROXY 1 164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3 165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define WINHTTP_NO_PROXY_NAME NULL 166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define WINHTTP_NO_PROXY_BYPASS NULL 167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // _TRY_WINHTTP 169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if _TRY_JSPROXY 171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochextern "C" { 172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch typedef BOOL (STDAPICALLTYPE * pfnInternetGetProxyInfo) 173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ( 174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LPCSTR lpszUrl, 175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD dwUrlLength, 176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LPSTR lpszUrlHostName, 177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD dwUrlHostNameLength, 178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LPSTR * lplpszProxyHostName, 179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LPDWORD lpdwProxyHostNameLength 180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ); 181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} // extern "C" 182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // _TRY_JSPROXY 183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if _TRY_WM_FINDPROXY 185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <comutil.h> 186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <wmnetsourcecreator.h> 187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <wmsinternaladminnetsource.h> 188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // _TRY_WM_FINDPROXY 189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if _TRY_IE_LAN_SETTINGS 191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <wininet.h> 192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <string> 193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // _TRY_IE_LAN_SETTINGS 194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace talk_base { 196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch////////////////////////////////////////////////////////////////////// 198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Utility Functions 199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch////////////////////////////////////////////////////////////////////// 200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32 202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef _UNICODE 203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtypedef std::wstring tstring; 205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstd::string Utf8String(const tstring& str) { return ToUtf8(str); } 206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#else // !_UNICODE 208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochtypedef std::string tstring; 210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstd::string Utf8String(const tstring& str) { return str; } 211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // !_UNICODE 213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // WIN32 214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ProxyItemMatch(const Url<char>& url, char * item, size_t len) { 216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // hostname:443 217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (char * port = ::strchr(item, ':')) { 218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *port++ = '\0'; 219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (url.port() != atol(port)) { 220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // A.B.C.D or A.B.C.D/24 225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int a, b, c, d, m; 226f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int match = sscanf(item, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &m); 227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (match >= 4) { 228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch uint32 ip = ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | 229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch (d & 0xFF); 230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((match < 5) || (m > 32)) 231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch m = 32; 232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch else if (m < 0) 233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch m = 0; 234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch uint32 mask = (m == 0) ? 0 : (~0UL) << (32 - m); 235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SocketAddress addr(url.host(), 0); 236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return !addr.IsUnresolved() && ((addr.ip() & mask) == (ip & mask)); 237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // .foo.com 240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (*item == '.') { 241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch size_t hostlen = url.host().length(); 242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (hostlen > len) 243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch && (stricmp(url.host().c_str() + (hostlen - len), item) == 0); 244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 246f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // localhost or www.*.com 247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!string_match(url.host().c_str(), item)) 248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ProxyListMatch(const Url<char>& url, const std::string& proxy_list, 254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char sep) { 255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const size_t BUFSIZE = 256; 256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char buffer[BUFSIZE]; 257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const char* list = proxy_list.c_str(); 258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch while (*list) { 259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Remove leading space 260f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (isspace(*list)) { 261f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ++list; 262f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch continue; 263f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 264f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Break on separator 265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch size_t len; 266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const char * start = list; 267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (const char * end = ::strchr(list, sep)) { 268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch len = (end - list); 269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch list += len + 1; 270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch len = strlen(list); 272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch list += len; 273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Remove trailing space 275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch while ((len > 0) && isspace(start[len-1])) 276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch --len; 277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Check for oversized entry 278f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (len >= BUFSIZE) 279f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch continue; 280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch memcpy(buffer, start, len); 281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buffer[len] = 0; 282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!ProxyItemMatch(url, buffer, len)) 283f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch continue; 284f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 285f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 286f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 287f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 288f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 289f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool Better(ProxyType lhs, const ProxyType rhs) { 290f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // PROXY_NONE, PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN 291f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const int PROXY_VALUE[5] = { 0, 2, 3, 1 }; 292f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (PROXY_VALUE[lhs] > PROXY_VALUE[rhs]); 293f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 294f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 295f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ParseProxy(const std::string& saddress, ProxyInfo* proxy) { 296f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const size_t kMaxAddressLength = 1024; 297f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Allow semicolon, space, or tab as an address separator 298f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const char* const kAddressSeparator = " ;\t"; 299f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 300f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ProxyType ptype; 301f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string host; 302f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch uint16 port; 303f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 304f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const char* address = saddress.c_str(); 305f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch while (*address) { 306f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch size_t len; 307f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const char * start = address; 308f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (const char * sep = strchr(address, kAddressSeparator)) { 309f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch len = (sep - address); 310f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch address += len + 1; 311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick while (*address != '\0' && ::strchr(kAddressSeparator, *address)) { 312f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch address += 1; 313f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 314f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 315f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch len = strlen(address); 316f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch address += len; 317f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 318f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 319f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (len > kMaxAddressLength - 1) { 320f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_WARNING) << "Proxy address too long [" << start << "]"; 321f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch continue; 322f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 323f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 324f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char buffer[kMaxAddressLength]; 325f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch memcpy(buffer, start, len); 326f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buffer[len] = 0; 327f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 328f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char * colon = ::strchr(buffer, ':'); 329f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!colon) { 330f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_WARNING) << "Proxy address without port [" << buffer << "]"; 331f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch continue; 332f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 333f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 334f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *colon = 0; 335f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char * endptr; 336f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch port = static_cast<uint16>(strtol(colon + 1, &endptr, 0)); 337f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (*endptr != 0) { 338f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_WARNING) << "Proxy address with invalid port [" << buffer << "]"; 339f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch continue; 340f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 341f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 342f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (char * equals = ::strchr(buffer, '=')) { 343f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *equals = 0; 344f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch host = equals + 1; 345f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (_stricmp(buffer, "socks") == 0) { 346f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ptype = PROXY_SOCKS5; 347f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (_stricmp(buffer, "https") == 0) { 348f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ptype = PROXY_HTTPS; 349f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 350f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_WARNING) << "Proxy address with unknown protocol [" 351f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch << buffer << "]"; 352f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ptype = PROXY_UNKNOWN; 353f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 354f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 355f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch host = buffer; 356f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ptype = PROXY_UNKNOWN; 357f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 358f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 359f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (Better(ptype, proxy->type)) { 360f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->type = ptype; 361f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetIP(host); 362f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetPort(port); 363f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 364f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 365f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 366f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return proxy->type != PROXY_NONE; 367f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 368f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 369f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochUserAgent GetAgent(const char* agent) { 370f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (agent) { 371f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string agent_str(agent); 372f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (agent_str.find(kFirefoxPattern) != std::string::npos) { 373f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return UA_FIREFOX; 374f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (agent_str.find(kInternetExplorerPattern) != std::string::npos) { 375f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return UA_INTERNETEXPLORER; 376f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (agent_str.empty()) { 377f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return UA_UNKNOWN; 378f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 379f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 380f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return UA_OTHER; 381f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 382f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 383f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool EndsWith(const std::string& a, const std::string& b) { 384f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (b.size() > a.size()) { 385f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 386f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 387f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int result = a.compare(a.size() - b.size(), b.size(), b); 388f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return result == 0; 389f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 390f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 391f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetFirefoxProfilePath(Pathname* path) { 392f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32 393f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch wchar_t w_path[MAX_PATH]; 394f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, w_path) != 395f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch S_OK) { 396f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "SHGetFolderPath failed"; 397f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 398f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 399f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch path->SetFolder(ToUtf8(w_path, wcslen(w_path))); 400f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch path->AppendFolder("Mozilla"); 401f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch path->AppendFolder("Firefox"); 402f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#elif OSX 403f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch FSRef fr; 404f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (0 != FSFindFolder(kUserDomain, kApplicationSupportFolderType, 405f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch kCreateFolder, &fr)) { 406f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "FSFindFolder failed"; 407f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 408f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 409f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char buffer[NAME_MAX + 1]; 410f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (0 != FSRefMakePath(&fr, reinterpret_cast<uint8*>(buffer), 411f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ARRAY_SIZE(buffer))) { 412f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "FSRefMakePath failed"; 413f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 414f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 415f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch path->SetFolder(std::string(buffer)); 416f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch path->AppendFolder("Firefox"); 417f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#else 418f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char* user_home = getenv("HOME"); 419f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (user_home == NULL) { 420f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 421f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 422f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch path->SetFolder(std::string(user_home)); 423f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch path->AppendFolder(".mozilla"); 424f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch path->AppendFolder("firefox"); 425f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // WIN32 426f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 427f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 428f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 429f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetDefaultFirefoxProfile(Pathname* profile_path) { 430f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(NULL != profile_path); 431f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Pathname path; 432f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!GetFirefoxProfilePath(&path)) { 433f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 434f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 435f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 436f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if USE_FIREFOX_PROFILES_INI 437f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // [Profile0] 438f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Name=default 439f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // IsRelative=1 440f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Path=Profiles/2de53ejb.default 441f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Default=1 442f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 443f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Note: we are looking for the first entry with "Default=1", or the last 444f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // entry in the file 445f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch path.SetFilename("profiles.ini"); 446f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch FileStream* fs = Filesystem::OpenFile(path, "r"); 447f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!fs) { 448f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 449f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 450f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Pathname candidate; 451f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool relative = true; 452f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string line; 453f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch while (fs->ReadLine(&line) == SR_SUCCESS) { 454f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (line.length() == 0) { 455f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch continue; 456f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 457f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (line.at(0) == '[') { 458f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch relative = true; 459f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch candidate.clear(); 4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (line.find("IsRelative=") == 0 && 4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick line.length() >= 12) { 462731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO: The initial Linux public launch revealed a fairly 4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // high number of machines where IsRelative= did not have anything after 4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // it. Perhaps that is legal profiles.ini syntax? 465f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch relative = (line.at(11) != '0'); 4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (line.find("Path=") == 0 && 4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick line.length() >= 6) { 468f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (relative) { 469f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch candidate = path; 470f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 471f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch candidate.clear(); 472f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 473f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch candidate.AppendFolder(line.substr(5)); 4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (line.find("Default=") == 0 && 4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick line.length() >= 9) { 476f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((line.at(8) != '0') && !candidate.empty()) { 477f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 478f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 479f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 480f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 481f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch fs->Close(); 482f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (candidate.empty()) { 483f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 484f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 485f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch profile_path->SetPathname(candidate.pathname()); 486f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 487f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#else // !USE_FIREFOX_PROFILES_INI 488f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch path.AppendFolder("Profiles"); 489f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DirectoryIterator* it = Filesystem::IterateDirectory(); 490f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch it->Iterate(path); 491f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string extension(".default"); 492f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch while (!EndsWith(it->Name(), extension)) { 493f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!it->Next()) { 494f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 495f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 496f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 497f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 498f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch profile_path->SetPathname(path); 499f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch profile->AppendFolder("Profiles"); 500f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch profile->AppendFolder(it->Name()); 501f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete it; 502f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 503f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // !USE_FIREFOX_PROFILES_INI 504f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 505f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 506f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 507f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 508f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ReadFirefoxPrefs(const Pathname& filename, 509f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const char * prefix, 510f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StringMap* settings) { 511f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch FileStream* fs = Filesystem::OpenFile(filename, "r"); 512f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!fs) { 513f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "Failed to open file: " << filename.pathname(); 514f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 515f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 516f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 517f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string line; 518f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch while (fs->ReadLine(&line) == SR_SUCCESS) { 519f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch size_t prefix_len = strlen(prefix); 520f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 521f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Skip blank lines and too long lines. 522f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((line.length() == 0) || (line.length() > kMaxLineLength) 523f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch || (line.at(0) == '#') || line.compare(0, 2, "/*") == 0 524f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch || line.compare(0, 2, " *") == 0) { 525f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch continue; 526f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 527f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 528f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char buffer[kMaxLineLength]; 529f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch strcpyn(buffer, sizeof(buffer), line.c_str()); 530f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int nstart = 0, nend = 0, vstart = 0, vend = 0; 531f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch sscanf(buffer, "user_pref(\"%n%*[^\"]%n\", %n%*[^)]%n);", 532f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch &nstart, &nend, &vstart, &vend); 533f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (vend > 0) { 534f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char* name = buffer + nstart; 535f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch name[nend - nstart] = 0; 536f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((vend - vstart >= 2) && (buffer[vstart] == '"')) { 537f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch vstart += 1; 538f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch vend -= 1; 539f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 540f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char* value = buffer + vstart; 541f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch value[vend - vstart] = 0; 542f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((strncmp(name, prefix, prefix_len) == 0) && *value) { 543f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch settings->Add(name + prefix_len, value); 544f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 545f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 546f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG_F(LS_WARNING) << "Unparsed pref [" << buffer << "]"; 547f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 548f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 549f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch fs->Close(); 550f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 551f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 552f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 553f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetFirefoxProxySettings(const char* url, ProxyInfo* proxy) { 554f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Url<char> purl(url); 555f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Pathname path; 556f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool success = false; 557f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (GetDefaultFirefoxProfile(&path)) { 558f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StringMap settings; 559f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch path.SetFilename("prefs.js"); 560f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ReadFirefoxPrefs(path, "network.proxy.", &settings)) { 561f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = true; 562f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->bypass_list = 563f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch settings.Get("no_proxies_on", "localhost, 127.0.0.1"); 564f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (settings.Get("type") == "1") { 565f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // User has manually specified a proxy, try to figure out what 566f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // type it is. 567f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ProxyListMatch(purl, proxy->bypass_list.c_str(), ',')) { 568f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Our url is in the list of url's to bypass proxy. 569f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (settings.Get("share_proxy_settings") == "true") { 570f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->type = PROXY_UNKNOWN; 571f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetIP(settings.Get("http")); 572f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetPort(atoi(settings.Get("http_port").c_str())); 573f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (settings.IsSet("socks")) { 574f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->type = PROXY_SOCKS5; 575f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetIP(settings.Get("socks")); 576f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetPort(atoi(settings.Get("socks_port").c_str())); 577f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (settings.IsSet("ssl")) { 578f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->type = PROXY_HTTPS; 579f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetIP(settings.Get("ssl")); 580f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetPort(atoi(settings.Get("ssl_port").c_str())); 581f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (settings.IsSet("http")) { 582f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->type = PROXY_HTTPS; 583f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetIP(settings.Get("http")); 584f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetPort(atoi(settings.Get("http_port").c_str())); 585f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 586f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (settings.Get("type") == "2") { 587f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Browser is configured to get proxy settings from a given url. 588f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->autoconfig_url = settings.Get("autoconfig_url").c_str(); 589f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (settings.Get("type") == "4") { 590f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Browser is configured to auto detect proxy config. 591f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->autodetect = true; 592f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 593f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // No proxy set. 594f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 595f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 596f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 597f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return success; 598f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 599f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 600f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32 // Windows specific implementation for reading Internet 601f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Explorer proxy settings. 602f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 603f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid LogGetProxyFault() { 604f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG_GLEM(LERROR, WINHTTP) << "WinHttpGetProxyForUrl faulted!!"; 605f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 606f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 607f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochBOOL MyWinHttpGetProxyForUrl(pfnWinHttpGetProxyForUrl pWHGPFU, 608f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch HINTERNET hWinHttp, LPCWSTR url, 609f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch WINHTTP_AUTOPROXY_OPTIONS *options, 610f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch WINHTTP_PROXY_INFO *info) { 611f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // WinHttpGetProxyForUrl() can call plugins which can crash. 612f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // In the case of McAfee scriptproxy.dll, it does crash in 613f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // older versions. Try to catch crashes here and treat as an 614f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // error. 615f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch BOOL success = FALSE; 616f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 617f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if (_HAS_EXCEPTIONS == 0) 618f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch __try { 619f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = pWHGPFU(hWinHttp, url, options, info); 620f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } __except(EXCEPTION_EXECUTE_HANDLER) { 621f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // This is a separate function to avoid 622f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Visual C++ error 2712 when compiling with C++ EH 623f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LogGetProxyFault(); 624f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 625f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#else 626f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = pWHGPFU(hWinHttp, url, options, info); 627f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // (_HAS_EXCEPTIONS == 0) 628f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 629f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return success; 630f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 631f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 632f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool IsDefaultBrowserFirefox() { 633f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch HKEY key; 634f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LONG result = RegOpenKeyEx(HKEY_CLASSES_ROOT, L"http\\shell\\open\\command", 635f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 0, KEY_READ, &key); 636f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ERROR_SUCCESS != result) 637f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 638f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 639f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch wchar_t* value = NULL; 640f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD size, type; 641f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = RegQueryValueEx(key, L"", 0, &type, NULL, &size); 642f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (REG_SZ != type) { 643f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = ERROR_ACCESS_DENIED; // Any error is fine 644f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (ERROR_SUCCESS == result) { 645f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch value = new wchar_t[size+1]; 646f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch BYTE* buffer = reinterpret_cast<BYTE*>(value); 647f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = RegQueryValueEx(key, L"", 0, &type, buffer, &size); 648f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 649f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch RegCloseKey(key); 650f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 651f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool success = false; 652f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ERROR_SUCCESS == result) { 653f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch value[size] = L'\0'; 654f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (size_t i = 0; i < size; ++i) { 655f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch value[i] = tolowercase(value[i]); 656f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 657f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = (NULL != strstr(value, L"firefox.exe")); 658f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 659f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete [] value; 660f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return success; 661f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 662f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 663f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetWinHttpProxySettings(const char* url, ProxyInfo* proxy) { 664f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll"); 665f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (winhttp_handle == NULL) { 666f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "Failed to load winhttp.dll."; 667f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 668f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 669f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch WINHTTP_CURRENT_USER_IE_PROXY_CONFIG iecfg; 670f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch memset(&iecfg, 0, sizeof(iecfg)); 671f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Url<char> purl(url); 672f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch pfnWinHttpGetIEProxyConfig pWHGIEPC = 673f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch reinterpret_cast<pfnWinHttpGetIEProxyConfig>( 674f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetProcAddress(winhttp_handle, 675f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch "WinHttpGetIEProxyConfigForCurrentUser")); 676f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool success = false; 677f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (pWHGIEPC && pWHGIEPC(&iecfg)) { 678f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // We were read proxy config successfully. 679f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = true; 680f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (iecfg.fAutoDetect) { 681f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->autodetect = true; 682f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 683f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (iecfg.lpszAutoConfigUrl) { 684f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->autoconfig_url = ToUtf8(iecfg.lpszAutoConfigUrl); 685f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GlobalFree(iecfg.lpszAutoConfigUrl); 686f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 687f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (iecfg.lpszProxyBypass) { 688f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->bypass_list = ToUtf8(iecfg.lpszProxyBypass); 689f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GlobalFree(iecfg.lpszProxyBypass); 690f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 691f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (iecfg.lpszProxy) { 692f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!ProxyListMatch(purl, proxy->bypass_list, ';')) { 693f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ParseProxy(ToUtf8(iecfg.lpszProxy), proxy); 694f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 695f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GlobalFree(iecfg.lpszProxy); 696f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 697f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 698f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch FreeLibrary(winhttp_handle); 699f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return success; 700f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 701f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 702f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Uses the WinHTTP API to auto detect proxy for the given url. Firefox and IE 703f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// have slightly different option dialogs for proxy settings. In Firefox, 704f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// either a location of a proxy configuration file can be specified or auto 705f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// detection can be selected. In IE theese two options can be independently 706f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// selected. For the case where both options are selected (only IE) we try to 707f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// fetch the config file first, and if that fails we'll perform an auto 708f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// detection. 709f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// 710f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Returns true if we successfully performed an auto detection not depending on 711f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// whether we found a proxy or not. Returns false on error. 712f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool WinHttpAutoDetectProxyForUrl(const char* agent, const char* url, 713f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ProxyInfo* proxy) { 714f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Url<char> purl(url); 715f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool success = true; 716f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll"); 717f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (winhttp_handle == NULL) { 718f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "Failed to load winhttp.dll."; 719f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 720f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 721f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch pfnWinHttpOpen pWHO = 722f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch reinterpret_cast<pfnWinHttpOpen>(GetProcAddress(winhttp_handle, 723f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch "WinHttpOpen")); 724f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch pfnWinHttpCloseHandle pWHCH = 725f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch reinterpret_cast<pfnWinHttpCloseHandle>( 726f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetProcAddress(winhttp_handle, "WinHttpCloseHandle")); 727f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch pfnWinHttpGetProxyForUrl pWHGPFU = 728f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch reinterpret_cast<pfnWinHttpGetProxyForUrl>( 729f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetProcAddress(winhttp_handle, "WinHttpGetProxyForUrl")); 730f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (pWHO && pWHCH && pWHGPFU) { 731f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (HINTERNET hWinHttp = pWHO(ToUtf16(agent).c_str(), 732f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch WINHTTP_ACCESS_TYPE_NO_PROXY, 733f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch WINHTTP_NO_PROXY_NAME, 734f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch WINHTTP_NO_PROXY_BYPASS, 735f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 0)) { 736f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch BOOL result = FALSE; 737f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch WINHTTP_PROXY_INFO info; 738f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch memset(&info, 0, sizeof(info)); 739f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (proxy->autodetect) { 740f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Use DHCP and DNS to try to find any proxy to use. 741f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch WINHTTP_AUTOPROXY_OPTIONS options; 742f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch memset(&options, 0, sizeof(options)); 743f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch options.fAutoLogonIfChallenged = TRUE; 744f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 745f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT; 746f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch options.dwAutoDetectFlags |= WINHTTP_AUTO_DETECT_TYPE_DHCP 747f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch | WINHTTP_AUTO_DETECT_TYPE_DNS_A; 748f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = MyWinHttpGetProxyForUrl( 749f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info); 750f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 751f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!result && !proxy->autoconfig_url.empty()) { 752f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // We have the location of a proxy config file. Download it and 753f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // execute it to find proxy settings for our url. 754f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch WINHTTP_AUTOPROXY_OPTIONS options; 755f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch memset(&options, 0, sizeof(options)); 756f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch memset(&info, 0, sizeof(info)); 757f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch options.fAutoLogonIfChallenged = TRUE; 758f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 759f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::wstring autoconfig_url16((ToUtf16)(proxy->autoconfig_url)); 760f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL; 761f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch options.lpszAutoConfigUrl = autoconfig_url16.c_str(); 762f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 763f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = MyWinHttpGetProxyForUrl( 764f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info); 765f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 766f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (result) { 767f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Either the given auto config url was valid or auto 768f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // detection found a proxy on this network. 769f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (info.lpszProxy) { 770731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO: Does this bypass list differ from the list 771f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // retreived from GetWinHttpProxySettings earlier? 772f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (info.lpszProxyBypass) { 773f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->bypass_list = ToUtf8(info.lpszProxyBypass); 774f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GlobalFree(info.lpszProxyBypass); 775f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 776f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->bypass_list.clear(); 777f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 778f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!ProxyListMatch(purl, proxy->bypass_list, ';')) { 779f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Found proxy for this URL. If parsing the address turns 780f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // out ok then we are successful. 781f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = ParseProxy(ToUtf8(info.lpszProxy), proxy); 782f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 783f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GlobalFree(info.lpszProxy); 784f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 785f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 786f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // We could not find any proxy for this url. 787f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "No proxy detected for " << url; 788f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 789f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch pWHCH(hWinHttp); 790f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 791f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 792f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "Failed loading WinHTTP functions."; 793f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = false; 794f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 795f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch FreeLibrary(winhttp_handle); 796f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return success; 797f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 798f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 799f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if 0 // Below functions currently not used. 800f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 801f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetJsProxySettings(const char* url, ProxyInfo* proxy) { 802f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Url<char> purl(url); 803f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool success = false; 804f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 805f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (HMODULE hModJS = LoadLibrary(_T("jsproxy.dll"))) { 806f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch pfnInternetGetProxyInfo pIGPI = 807f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch reinterpret_cast<pfnInternetGetProxyInfo>( 808f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetProcAddress(hModJS, "InternetGetProxyInfo")); 809f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (pIGPI) { 810f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char proxy[256], host[256]; 811f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch memset(proxy, 0, sizeof(proxy)); 812f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char * ptr = proxy; 813f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD proxylen = sizeof(proxy); 814f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string surl = Utf8String(url); 815f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD hostlen = _snprintf(host, sizeof(host), "http%s://%S", 816f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch purl.secure() ? "s" : "", purl.server()); 817f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (pIGPI(surl.data(), surl.size(), host, hostlen, &ptr, &proxylen)) { 818f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(INFO) << "Proxy: " << proxy; 819f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 820f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG_GLE(INFO) << "InternetGetProxyInfo"; 821f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 822f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 823f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch FreeLibrary(hModJS); 824f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 825f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return success; 826f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 827f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 828f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetWmProxySettings(const char* url, ProxyInfo* proxy) { 829f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Url<char> purl(url); 830f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool success = false; 831f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 832f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch INSNetSourceCreator * nsc = 0; 833f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch HRESULT hr = CoCreateInstance(CLSID_ClientNetManager, 0, CLSCTX_ALL, 834f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IID_INSNetSourceCreator, (LPVOID *) &nsc); 835f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (SUCCEEDED(hr)) { 836f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (SUCCEEDED(hr = nsc->Initialize())) { 837f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch VARIANT dispatch; 838f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch VariantInit(&dispatch); 839f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (SUCCEEDED(hr = nsc->GetNetSourceAdminInterface(L"http", &dispatch))) { 840f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IWMSInternalAdminNetSource * ians = 0; 841f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (SUCCEEDED(hr = dispatch.pdispVal->QueryInterface( 842f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch IID_IWMSInternalAdminNetSource, (LPVOID *) &ians))) { 843f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch _bstr_t host(purl.server()); 844f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch BSTR proxy = 0; 845f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch BOOL bProxyEnabled = FALSE; 846f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD port, context = 0; 847f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (SUCCEEDED(hr = ians->FindProxyForURL( 848f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch L"http", host, &bProxyEnabled, &proxy, &port, &context))) { 849f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = true; 850f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (bProxyEnabled) { 851f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch _bstr_t sproxy = proxy; 852f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->ptype = PT_HTTPS; 853f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->host = sproxy; 854f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->port = port; 855f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 856f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 857f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SysFreeString(proxy); 858f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (FAILED(hr = ians->ShutdownProxyContext(context))) { 859f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "IWMSInternalAdminNetSource::ShutdownProxyContext" 860f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch << "failed: " << hr; 861f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 862f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ians->Release(); 863f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 864f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 865f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch VariantClear(&dispatch); 866f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (FAILED(hr = nsc->Shutdown())) { 867f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "INSNetSourceCreator::Shutdown failed: " << hr; 868f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 869f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 870f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch nsc->Release(); 871f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 872f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return success; 873f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 874f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 875f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetIePerConnectionProxySettings(const char* url, ProxyInfo* proxy) { 876f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Url<char> purl(url); 877f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool success = false; 878f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 879f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch INTERNET_PER_CONN_OPTION_LIST list; 880f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch INTERNET_PER_CONN_OPTION options[3]; 881f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch memset(&list, 0, sizeof(list)); 882f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch memset(&options, 0, sizeof(options)); 883f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 884f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch list.dwSize = sizeof(list); 885f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch list.dwOptionCount = 3; 886f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch list.pOptions = options; 887f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch options[0].dwOption = INTERNET_PER_CONN_FLAGS; 888f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER; 889f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS; 890f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD dwSize = sizeof(list); 891f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 892f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!InternetQueryOption(0, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, 893f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch &dwSize)) { 894f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError(); 895f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if ((options[0].Value.dwValue & PROXY_TYPE_PROXY) != 0) { 896f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = true; 897f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!ProxyListMatch(purl, nonnull(options[2].Value.pszValue), _T(';'))) { 898f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ParseProxy(nonnull(options[1].Value.pszValue), proxy); 899f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 900f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if ((options[0].Value.dwValue & PROXY_TYPE_DIRECT) != 0) { 901f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = true; 902f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 903f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "unknown internet access type: " 904f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch << options[0].Value.dwValue; 905f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 906f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (options[1].Value.pszValue) { 907f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GlobalFree(options[1].Value.pszValue); 908f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 909f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (options[2].Value.pszValue) { 910f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GlobalFree(options[2].Value.pszValue); 911f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 912f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return success; 913f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 914f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 915f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // 0 916f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 917f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Uses the InternetQueryOption function to retrieve proxy settings 918f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// from the registry. This will only give us the 'static' settings, 919f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// ie, not any information about auto config etc. 920f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetIeLanProxySettings(const char* url, ProxyInfo* proxy) { 921f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Url<char> purl(url); 922f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool success = false; 923f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 924f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch wchar_t buffer[1024]; 925f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch memset(buffer, 0, sizeof(buffer)); 926f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch INTERNET_PROXY_INFO * info = reinterpret_cast<INTERNET_PROXY_INFO *>(buffer); 927f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch DWORD dwSize = sizeof(buffer); 928f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 929f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!InternetQueryOption(0, INTERNET_OPTION_PROXY, info, &dwSize)) { 930f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError(); 931f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (info->dwAccessType == INTERNET_OPEN_TYPE_DIRECT) { 932f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = true; 933f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (info->dwAccessType == INTERNET_OPEN_TYPE_PROXY) { 934f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch success = true; 935f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!ProxyListMatch(purl, nonnull(reinterpret_cast<const char*>( 936f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch info->lpszProxyBypass)), ' ')) { 937f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ParseProxy(nonnull(reinterpret_cast<const char*>(info->lpszProxy)), 938f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy); 939f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 940f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 941f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "unknown internet access type: " << info->dwAccessType; 942f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 943f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return success; 944f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 945f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 946f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetIeProxySettings(const char* agent, const char* url, ProxyInfo* proxy) { 947f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool success = GetWinHttpProxySettings(url, proxy); 948f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!success) { 949731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO: Should always call this if no proxy were detected by 950f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // GetWinHttpProxySettings? 951f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // WinHttp failed. Try using the InternetOptionQuery method instead. 952f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return GetIeLanProxySettings(url, proxy); 953f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 954f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 955f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 956f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 957f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // WIN32 958f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 959f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef OSX // OSX specific implementation for reading system wide 960f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // proxy settings. 961f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 962f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool p_getProxyInfoForTypeFromDictWithKeys(ProxyInfo* proxy, 963f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ProxyType type, 964f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const CFDictionaryRef proxyDict, 965f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const CFStringRef enabledKey, 966f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const CFStringRef hostKey, 967f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const CFStringRef portKey) { 968f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // whether or not we set up the proxy info. 969f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool result = false; 970f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 971f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // we use this as a scratch variable for determining if operations 972f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // succeeded. 973f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool converted = false; 974f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 975f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // the data we need to construct the SocketAddress for the proxy. 976f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string hostname; 977f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int port; 978f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 979f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((proxyDict != NULL) && 980f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch (CFGetTypeID(proxyDict) == CFDictionaryGetTypeID())) { 981f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // CoreFoundation stuff that we'll have to get from 982f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // the dictionaries and interpret or convert into more usable formats. 983f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch CFNumberRef enabledCFNum; 984f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch CFNumberRef portCFNum; 985f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch CFStringRef hostCFStr; 986f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 987f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch enabledCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, enabledKey); 988f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 989f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (p_isCFNumberTrue(enabledCFNum)) { 990f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // let's see if we can get the address and port. 991f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch hostCFStr = (CFStringRef)CFDictionaryGetValue(proxyDict, hostKey); 992f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch converted = p_convertHostCFStringRefToCPPString(hostCFStr, hostname); 993f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (converted) { 994f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch portCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, portKey); 995f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch converted = p_convertCFNumberToInt(portCFNum, &port); 996f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (converted) { 997f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // we have something enabled, with a hostname and a port. 998f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // That's sufficient to set up the proxy info. 999f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->type = type; 1000f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetIP(hostname); 1001f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->address.SetPort(port); 1002f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = true; 1003f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1004f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1005f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1006f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1007f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1008f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return result; 1009f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1010f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1011f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Looks for proxy information in the given dictionary, 1012f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// return true if it found sufficient information to define one, 1013f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// false otherwise. This is guaranteed to not change the values in proxy 1014f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// unless a full-fledged proxy description was discovered in the dictionary. 1015f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// However, at the present time this does not support username or password. 1016f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Checks first for a SOCKS proxy, then for HTTPS, then HTTP. 1017f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetMacProxySettingsFromDictionary(ProxyInfo* proxy, 1018f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const CFDictionaryRef proxyDict) { 1019f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // the function result. 1020f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool gotProxy = false; 1021f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1022f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1023f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // first we see if there's a SOCKS proxy in place. 1024f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy, 1025f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch PROXY_SOCKS5, 1026f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxyDict, 1027f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch kSCPropNetProxiesSOCKSEnable, 1028f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch kSCPropNetProxiesSOCKSProxy, 1029f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch kSCPropNetProxiesSOCKSPort); 1030f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1031f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!gotProxy) { 1032f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // okay, no SOCKS proxy, let's look for https. 1033f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy, 1034f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch PROXY_HTTPS, 1035f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxyDict, 1036f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch kSCPropNetProxiesHTTPSEnable, 1037f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch kSCPropNetProxiesHTTPSProxy, 1038f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch kSCPropNetProxiesHTTPSPort); 1039f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!gotProxy) { 1040f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Finally, try HTTP proxy. Note that flute doesn't 1041f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // differentiate between HTTPS and HTTP, hence we are using the 1042f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // same flute type here, ie. PROXY_HTTPS. 1043f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch gotProxy = p_getProxyInfoForTypeFromDictWithKeys( 1044f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy, PROXY_HTTPS, proxyDict, kSCPropNetProxiesHTTPEnable, 1045f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort); 1046f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1047f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1048f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return gotProxy; 1049f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1050f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1051f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool p_putPasswordInProxyInfo(ProxyInfo* proxy) { 1052f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool result = true; // by default we assume we're good. 1053f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // for all we know there isn't any password. We'll set to false 1054f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // if we find a problem. 1055f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1056f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Ask the keychain for an internet password search for the given protocol. 1057f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch OSStatus oss = 0; 1058f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SecKeychainAttributeList attrList; 1059f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attrList.count = 3; 1060f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SecKeychainAttribute attributes[3]; 1061f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attrList.attr = attributes; 1062f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1063f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attributes[0].tag = kSecProtocolItemAttr; 1064f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attributes[0].length = sizeof(SecProtocolType); 1065f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SecProtocolType protocol; 1066f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (proxy->type) { 1067f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case PROXY_HTTPS : 1068f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch protocol = kSecProtocolTypeHTTPS; 1069f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 1070f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case PROXY_SOCKS5 : 1071f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch protocol = kSecProtocolTypeSOCKS; 1072f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 1073f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default : 1074f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "asked for proxy password for unknown proxy type."; 1075f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = false; 1076f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 1077f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1078f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attributes[0].data = &protocol; 1079f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1080f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch UInt32 port = proxy->address.port(); 1081f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attributes[1].tag = kSecPortItemAttr; 1082f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attributes[1].length = sizeof(UInt32); 1083f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attributes[1].data = &port; 1084f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1085f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string ip = proxy->address.IPAsString(); 1086f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attributes[2].tag = kSecServerItemAttr; 1087f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attributes[2].length = ip.length(); 1088f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attributes[2].data = const_cast<char*>(ip.c_str()); 1089f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1090f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (result) { 1091f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "trying to get proxy username/password"; 1092f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SecKeychainSearchRef sref; 1093f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch oss = SecKeychainSearchCreateFromAttributes(NULL, 1094f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch kSecInternetPasswordItemClass, 1095f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch &attrList, &sref); 1096f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (0 == oss) { 1097f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "SecKeychainSearchCreateFromAttributes was good"; 1098f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Get the first item, if there is one. 1099f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SecKeychainItemRef iref; 1100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch oss = SecKeychainSearchCopyNext(sref, &iref); 1101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (0 == oss) { 1102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "...looks like we have the username/password data"; 1103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // If there is, get the username and the password. 1104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SecKeychainAttributeInfo attribsToGet; 1106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attribsToGet.count = 1; 1107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch UInt32 tag = kSecAccountItemAttr; 1108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch UInt32 format = CSSM_DB_ATTRIBUTE_FORMAT_STRING; 1109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch void *data; 1110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch UInt32 length; 1111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SecKeychainAttributeList *localList; 1112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attribsToGet.tag = &tag; 1114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attribsToGet.format = &format; 1115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch OSStatus copyres = SecKeychainItemCopyAttributesAndData(iref, 1116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch &attribsToGet, 1117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch NULL, 1118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch &localList, 1119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch &length, 1120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch &data); 1121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (0 == copyres) { 1122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "...and we can pull it out."; 1123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // now, we know from experimentation (sadly not from docs) 1124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // that the username is in the local attribute list, 1125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // and the password in the data, 1126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // both without null termination but with info on their length. 1127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // grab the password from the data. 1128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string password; 1129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch password.append(static_cast<const char*>(data), length); 1130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // make the password into a CryptString 1132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // huh, at the time of writing, you can't. 1133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // so we'll skip that for now and come back to it later. 1134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // now put the username in the proxy. 1136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (1 <= localList->attr->length) { 1137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy->username.append( 1138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch static_cast<const char*>(localList->attr->data), 1139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch localList->attr->length); 1140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "username is " << proxy->username; 1141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 1142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "got keychain entry with no username"; 1143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = false; 1144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 1146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "couldn't copy info from keychain."; 1147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = false; 1148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SecKeychainItemFreeAttributesAndData(localList, data); 1150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (errSecItemNotFound == oss) { 1151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_INFO) << "...username/password info not found"; 1152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 1153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // oooh, neither 0 nor itemNotFound. 1154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss; 1155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = false; 1156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else if (errSecItemNotFound == oss) { // noop 1158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 1159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // oooh, neither 0 nor itemNotFound. 1160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss; 1161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = false; 1162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return result; 1166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetMacProxySettings(ProxyInfo* proxy) { 1169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // based on the Apple Technical Q&A QA1234 1170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // http://developer.apple.com/qa/qa2001/qa1234.html 1171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch CFDictionaryRef proxyDict = SCDynamicStoreCopyProxies(NULL); 1172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool result = false; 1173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (proxyDict != NULL) { 1175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // sending it off to another function makes it easier to unit test 1176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // since we can make our own dictionary to hand to that function. 1177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = GetMacProxySettingsFromDictionary(proxy, proxyDict); 1178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (result) { 1180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = p_putPasswordInProxyInfo(proxy); 1181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // We created the dictionary with something that had the 1184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // word 'copy' in it, so we have to release it, according 1185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // to the Carbon memory management standards. 1186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch CFRelease(proxyDict); 1187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 1188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_ERROR) << "SCDynamicStoreCopyProxies failed"; 1189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return result; 1192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // OSX 1194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool AutoDetectProxySettings(const char* agent, const char* url, 1196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ProxyInfo* proxy) { 1197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32 1198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return WinHttpAutoDetectProxyForUrl(agent, url, proxy); 1199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#else 1200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_WARNING) << "Proxy auto-detection not implemented for this platform"; 1201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 1202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif 1203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetSystemDefaultProxySettings(const char* agent, const char* url, 1206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ProxyInfo* proxy) { 1207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32 1208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return GetIeProxySettings(agent, url, proxy); 1209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#elif OSX 1210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return GetMacProxySettings(proxy); 1211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#else 1212731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO: Get System settings if browser is not firefox. 1213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return GetFirefoxProxySettings(url, proxy); 1214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif 1215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetProxySettingsForUrl(const char* agent, const char* url, 1218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ProxyInfo& proxy, bool long_operation) { 1219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch UserAgent a = GetAgent(agent); 1220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool result; 1221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (a) { 1222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case UA_FIREFOX: { 1223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = GetFirefoxProxySettings(url, &proxy); 1224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 1225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1226f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32 1227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case UA_INTERNETEXPLORER: 1228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = GetIeProxySettings(agent, url, &proxy); 1229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 1230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case UA_UNKNOWN: 1231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Agent not defined, check default browser. 1232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (IsDefaultBrowserFirefox()) { 1233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = GetFirefoxProxySettings(url, &proxy); 1234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 1235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = GetIeProxySettings(agent, url, &proxy); 1236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 1238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif // WIN32 1239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 1240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = GetSystemDefaultProxySettings(agent, url, &proxy); 1241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 1242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO: Consider using the 'long_operation' parameter to 1245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // decide whether to do the auto detection. 1246f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (result && (proxy.autodetect || 1247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch !proxy.autoconfig_url.empty())) { 1248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Use WinHTTP to auto detect proxy for us. 1249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result = AutoDetectProxySettings(agent, url, &proxy); 1250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!result) { 1251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Either auto detection is not supported or we simply didn't 1252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // find any proxy, reset type. 1253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch proxy.type = talk_base::PROXY_NONE; 1254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 1256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return result; 1257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 1258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} // namespace talk_base 1260