📄 proxydetect.cc
字号:
WIN32_FIND_DATA fdata; HANDLE hFind = FindFirstFile(tmp.c_str(), &fdata); if (hFind == INVALID_HANDLE_VALUE) return false; profile->assign(profile_root); profile->append(L"Profiles\\"); profile->append(fdata.cFileName); profile->append(L"\\"); FindClose(hFind);#endif // !USE_FIREFOX_PROFILES_INI return true;}struct StringMap {public: void Add(const char * name, const char * value) { map_[name] = value; } const std::string& Get(const char * name, const char * def = "") const { std::map<std::string, std::string>::const_iterator it = map_.find(name); if (it != map_.end()) return it->second; def_ = def; return def_; } bool IsSet(const char * name) const { return (map_.find(name) != map_.end()); }private: std::map<std::string, std::string> map_; mutable std::string def_;};bool ReadFirefoxPrefs(const std::wstring& filename, const char * prefix, StringMap& settings) { FILE * fp = _wfopen(filename.c_str(), L"rb"); if (!fp) return false; size_t prefix_len = strlen(prefix); bool overlong_line = false; char buffer[1024]; while (fgets(buffer, sizeof(buffer), fp)) { size_t len = strlen(buffer); bool missing_newline = (len > 0) && (buffer[len-1] != '\n'); if (missing_newline) { overlong_line = true; continue; } else if (overlong_line) { LOG_F(LS_INFO) << "Skipping long line"; overlong_line = false; continue; } while ((len > 0) && isspace(buffer[len-1])) buffer[--len] = 0; // Skip blank lines if ((len == 0) || (buffer[0] == '#') || (strncmp(buffer, "/*", 2) == 0) || (strncmp(buffer, " *", 2) == 0)) continue; int nstart = 0, nend = 0, vstart = 0, vend = 0; sscanf(buffer, "user_pref(\"%n%*[^\"]%n\", %n%*[^)]%n);", &nstart, &nend, &vstart, &vend); if (vend > 0) { char * name = buffer + nstart; name[nend - nstart] = 0; if ((vend - vstart >= 2) && (buffer[vstart] == '"')) { vstart += 1; vend -= 1; } char * value = buffer + vstart; value[vend - vstart] = 0; if ((strncmp(name, prefix, prefix_len) == 0) && *value) { settings.Add(name + prefix_len, value); } } else { LOG_F(LS_WARNING) << "Unparsed pref [" << buffer << "]"; } } fclose(fp); return true;}#endif // _TRY_FIREFOX#ifdef WIN32BOOL MyWinHttpGetProxyForUrl(pfnWinHttpGetProxyForUrl pWHGPFU, HINTERNET hWinHttp, LPCWSTR url, WINHTTP_AUTOPROXY_OPTIONS *options, WINHTTP_PROXY_INFO *info) { // WinHttpGetProxyForUrl() can call plugins which can crash. // In the case of McAfee scriptproxy.dll, it does crash in // older versions. Try to catch crashes here and treat as an // error. BOOL success = FALSE;#if (_HAS_EXCEPTIONS == 0) __try { success = pWHGPFU(hWinHttp, url, options, info); } __except(EXCEPTION_EXECUTE_HANDLER) { LOG_GLEM(LERROR,WINHTTP) << "WinHttpGetProxyForUrl faulted!!"; }#else success = pWHGPFU(hWinHttp, url, options, info);#endif return success;}#endifbool GetProxySettingsForUrl(const char* agent, const char* url, ProxyInfo& proxy, bool long_operation) { bool success = false; Url<char> purl(url);#if 0 assert( WildMatch(_T("A.B.C.D"), _T("a.b.c.d"))); assert( WildMatch(_T("127.0.0.1"), _T("12*.0.*1"))); assert(!WildMatch(_T("127.0.0.0"), _T("12*.0.*1"))); assert(!WildMatch(_T("127.0.0.0"), _T("12*.0.*1"))); assert( WildMatch(_T("127.1.0.21"), _T("12*.0.*1"))); assert(!WildMatch(_T("127.1.1.21"), _T("12*.0.*1"))); purl = PUrl(_T("http://a.b.c:500/")); wchar_t item[256]; _tcscpy(item, _T("a.b.c")); assert( ProxyItemMatch(purl, item, _tcslen(item))); _tcscpy(item, _T("a.x.c")); assert(!ProxyItemMatch(purl, item, _tcslen(item))); _tcscpy(item, _T("a.b.*")); assert( ProxyItemMatch(purl, item, _tcslen(item))); _tcscpy(item, _T("a.x.*")); assert(!ProxyItemMatch(purl, item, _tcslen(item))); _tcscpy(item, _T(".b.c")); assert( ProxyItemMatch(purl, item, _tcslen(item))); _tcscpy(item, _T(".x.c")); assert(!ProxyItemMatch(purl, item, _tcslen(item))); _tcscpy(item, _T("a.b.c:500")); assert( ProxyItemMatch(purl, item, _tcslen(item))); _tcscpy(item, _T("a.b.c:501")); assert(!ProxyItemMatch(purl, item, _tcslen(item))); purl = PUrl(_T("http://1.2.3.4/")); _tcscpy(item, _T("1.2.3.4")); assert( ProxyItemMatch(purl, item, _tcslen(item))); _tcscpy(item, _T("1.2.3.5")); assert(!ProxyItemMatch(purl, item, _tcslen(item))); _tcscpy(item, _T("1.2.3.5/31")); assert( ProxyItemMatch(purl, item, _tcslen(item))); _tcscpy(item, _T("1.2.3.5/32")); assert(!ProxyItemMatch(purl, item, _tcslen(item)));#endif bool autoconfig = false; bool use_firefox = false; std::string autoconfig_url;#if _TRY_FIREFOX use_firefox = IsDefaultBrowserFirefox(); if (use_firefox) { std::wstring tmp; if (GetDefaultFirefoxProfile(&tmp)) { bool complete = true; StringMap settings; tmp.append(L"prefs.js"); if (ReadFirefoxPrefs(tmp, "network.proxy.", settings)) { success = true; if (settings.Get("type") == "1") { if (ProxyListMatch(purl, settings.Get("no_proxies_on", "localhost, 127.0.0.1").c_str(), ',')) { // Bypass proxy } else if (settings.Get("share_proxy_settings") == "true") { proxy.type = PROXY_UNKNOWN; proxy.address.SetIP(settings.Get("http")); proxy.address.SetPort(atoi(settings.Get("http_port").c_str())); } else if (settings.IsSet("socks")) { proxy.type = PROXY_SOCKS5; proxy.address.SetIP(settings.Get("socks")); proxy.address.SetPort(atoi(settings.Get("socks_port").c_str())); } else if (settings.IsSet("ssl")) { proxy.type = PROXY_HTTPS; proxy.address.SetIP(settings.Get("ssl")); proxy.address.SetPort(atoi(settings.Get("ssl_port").c_str())); } else if (settings.IsSet("http")) { proxy.type = PROXY_HTTPS; proxy.address.SetIP(settings.Get("http")); proxy.address.SetPort(atoi(settings.Get("http_port").c_str())); } } else if (settings.Get("type") == "2") { complete = success = false; autoconfig_url = settings.Get("autoconfig_url").c_str(); } else if (settings.Get("type") == "4") { complete = success = false; autoconfig = true; } } if (complete) { // Otherwise fall through to IE autoproxy code return success; } } }#endif // _TRY_FIREFOX#if _TRY_WINHTTP if (!success) { if (HMODULE hModWH = LoadLibrary(L"winhttp.dll")) { pfnWinHttpOpen pWHO = reinterpret_cast<pfnWinHttpOpen>(GetProcAddress(hModWH, "WinHttpOpen")); pfnWinHttpCloseHandle pWHCH = reinterpret_cast<pfnWinHttpCloseHandle>(GetProcAddress(hModWH, "WinHttpCloseHandle")); pfnWinHttpGetProxyForUrl pWHGPFU = reinterpret_cast<pfnWinHttpGetProxyForUrl>(GetProcAddress(hModWH, "WinHttpGetProxyForUrl")); pfnWinHttpGetIEProxyConfig pWHGIEPC = reinterpret_cast<pfnWinHttpGetIEProxyConfig>(GetProcAddress(hModWH, "WinHttpGetIEProxyConfigForCurrentUser")); if (pWHO && pWHCH && pWHGPFU && pWHGIEPC) { WINHTTP_CURRENT_USER_IE_PROXY_CONFIG iecfg; memset(&iecfg, 0, sizeof(iecfg)); if (!use_firefox && !pWHGIEPC(&iecfg)) { LOG_GLEM(LERROR,WINHTTP) << "WinHttpGetIEProxyConfigForCurrentUser"; } else { success = true; if (!use_firefox) { if (iecfg.fAutoDetect) { autoconfig = true; } if (iecfg.lpszAutoConfigUrl) { autoconfig_url = ToUtf8(iecfg.lpszAutoConfigUrl); } } if (!long_operation) { // Unless we perform this operation in the background, don't allow // it to take a long time. autoconfig = false; } if (autoconfig || !autoconfig_url.empty()) { if (HINTERNET hWinHttp = pWHO(ToUtf16(agent).c_str(), WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0)) { WINHTTP_AUTOPROXY_OPTIONS options; memset(&options, 0, sizeof(options)); if (autoconfig) { options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT; options.dwAutoDetectFlags |= WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; } std::wstring autoconfig_url16((ToUtf16)(autoconfig_url)); if (!autoconfig_url.empty()) { options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL; options.lpszAutoConfigUrl = autoconfig_url16.c_str(); } options.fAutoLogonIfChallenged = TRUE; WINHTTP_PROXY_INFO info; memset(&info, 0, sizeof(info)); BOOL success = MyWinHttpGetProxyForUrl(pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info); if (!success) { LOG_GLEM(LERROR,WINHTTP) << "WinHttpGetProxyForUrl"; } else { if (iecfg.lpszProxy) GlobalFree(iecfg.lpszProxy); if (iecfg.lpszProxyBypass) GlobalFree(iecfg.lpszProxyBypass); iecfg.lpszProxy = info.lpszProxy; iecfg.lpszProxyBypass = info.lpszProxyBypass; } pWHCH(hWinHttp); } } if (!ProxyListMatch(purl, ToUtf8(nonnull(iecfg.lpszProxyBypass)), ' ')) { ParseProxy(ToUtf8(nonnull(iecfg.lpszProxy)), proxy); } if (iecfg.lpszAutoConfigUrl) GlobalFree(iecfg.lpszAutoConfigUrl); if (iecfg.lpszProxy) GlobalFree(iecfg.lpszProxy); if (iecfg.lpszProxyBypass) GlobalFree(iecfg.lpszProxyBypass); } } FreeLibrary(hModWH); } }#endif // _TRY_WINHTTP#if _TRY_JSPROXY if (!success) { if (HMODULE hModJS = LoadLibrary(_T("jsproxy.dll"))) { pfnInternetGetProxyInfo pIGPI = reinterpret_cast<pfnInternetGetProxyInfo>(GetProcAddress(hModJS, "InternetGetProxyInfo")); if (pIGPI) { char proxy[256], host[256]; memset(proxy, 0, sizeof(proxy)); char * ptr = proxy; DWORD proxylen = sizeof(proxy); std::string surl = Utf8String(url); DWORD hostlen = _snprintf(host, sizeof(host), "http%s://%S", purl.secure() ? "s" : "", purl.server()); if (pIGPI(surl.data(), surl.size(), host, hostlen, &ptr, &proxylen)) { LOG(INFO) << "Proxy: " << proxy; } else { LOG_GLE(INFO) << "InternetGetProxyInfo"; } } FreeLibrary(hModJS); } }#endif // _TRY_JSPROXY#if _TRY_WM_FINDPROXY if (!success) { INSNetSourceCreator * nsc = 0; HRESULT hr = CoCreateInstance(CLSID_ClientNetManager, 0, CLSCTX_ALL, IID_INSNetSourceCreator, (LPVOID *) &nsc); if (SUCCEEDED(hr)) { if (SUCCEEDED(hr = nsc->Initialize())) { VARIANT dispatch; VariantInit(&dispatch); if (SUCCEEDED(hr = nsc->GetNetSourceAdminInterface(L"http", &dispatch))) { IWMSInternalAdminNetSource * ians = 0; if (SUCCEEDED(hr = dispatch.pdispVal->QueryInterface(IID_IWMSInternalAdminNetSource, (LPVOID *) &ians))) { _bstr_t host(purl.server()); BSTR proxy = 0; BOOL bProxyEnabled = FALSE; DWORD port, context = 0; if (SUCCEEDED(hr = ians->FindProxyForURL(L"http", host, &bProxyEnabled, &proxy, &port, &context))) { success = true; if (bProxyEnabled) { _bstr_t sproxy = proxy; proxy.ptype = PT_HTTPS; proxy.host = sproxy; proxy.port = port; } } SysFreeString(proxy); if (FAILED(hr = ians->ShutdownProxyContext(context))) { LOG(LS_INFO) << "IWMSInternalAdminNetSource::ShutdownProxyContext failed: " << hr; } ians->Release(); } } VariantClear(&dispatch); if (FAILED(hr = nsc->Shutdown())) { LOG(LS_INFO) << "INSNetSourceCreator::Shutdown failed: " << hr; } } nsc->Release(); } }#endif // _TRY_WM_FINDPROXY#if _TRY_IE_LAN_SETTINGS if (!success) { wchar_t buffer[1024]; memset(buffer, 0, sizeof(buffer)); INTERNET_PROXY_INFO * info = reinterpret_cast<INTERNET_PROXY_INFO *>(buffer); DWORD dwSize = sizeof(buffer); if (!InternetQueryOption(0, INTERNET_OPTION_PROXY, info, &dwSize)) { LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError(); } else if (info->dwAccessType == INTERNET_OPEN_TYPE_DIRECT) { success = true; } else if (info->dwAccessType == INTERNET_OPEN_TYPE_PROXY) { success = true; if (!ProxyListMatch(purl, nonnull(reinterpret_cast<const char*>(info->lpszProxyBypass)), ' ')) { ParseProxy(nonnull(reinterpret_cast<const char*>(info->lpszProxy)), proxy); } } else { LOG(LS_INFO) << "unknown internet access type: " << info->dwAccessType; } }#endif // _TRY_IE_LAN_SETTINGS#if 0 if (!success) { INTERNET_PER_CONN_OPTION_LIST list; INTERNET_PER_CONN_OPTION options[3]; memset(&list, 0, sizeof(list)); memset(&options, 0, sizeof(options)); list.dwSize = sizeof(list); list.dwOptionCount = 3; list.pOptions = options; options[0].dwOption = INTERNET_PER_CONN_FLAGS; options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER; options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS; DWORD dwSize = sizeof(list); if (!InternetQueryOption(0, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &dwSize)) { LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError(); } else if ((options[0].Value.dwValue & PROXY_TYPE_PROXY) != 0) { success = true; if (!ProxyListMatch(purl, nonnull(options[2].Value.pszValue), _T(';'))) { ParseProxy(nonnull(options[1].Value.pszValue), proxy); } } else if ((options[0].Value.dwValue & PROXY_TYPE_DIRECT) != 0) { success = true; } else { LOG(LS_INFO) << "unknown internet access type: " << options[0].Value.dwValue; } if (options[1].Value.pszValue) { GlobalFree(options[1].Value.pszValue); } if (options[2].Value.pszValue) { GlobalFree(options[2].Value.pszValue); } }#endif // 0 return success;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -