int CookieManager::SetCookie(const std::string& url, const BrowserCookie& cookie) { std::string full_data = url + "|" + cookie.ToString(); WPARAM set_flags = 0; if (cookie.is_httponly()) { set_flags = INTERNET_COOKIE_HTTPONLY; } HookSettings hook_settings; hook_settings.hook_procedure_name = "CookieWndProc"; hook_settings.hook_procedure_type = WH_CALLWNDPROC; hook_settings.window_handle = this->window_handle_; hook_settings.communication_type = OneWay; HookProcessor hook; if (!hook.CanSetWindowsHook(this->window_handle_)) { LOG(WARN) << "Cannot set cookie because driver and browser are not the " << "same bit-ness."; return EUNHANDLEDERROR; } hook.Initialize(hook_settings); hook.PushData(StringUtilities::ToWString(full_data)); ::SendMessage(this->window_handle_, WD_SET_COOKIE, set_flags, NULL); int status = HookProcessor::GetDataBufferSize(); if (status != 0) { LOG(WARN) << "Setting cookie encountered error " << status; return EINVALIDCOOKIEDOMAIN; } return WD_SUCCESS; }
void ProxyManager::SetPerProcessProxySettings(HWND browser_window_handle) { LOG(TRACE) << "ProxyManager::SetPerProcessProxySettings"; std::wstring proxy = this->BuildProxySettingsString(); HookSettings hook_settings; hook_settings.window_handle = browser_window_handle; hook_settings.hook_procedure_name = "SetProxyWndProc"; hook_settings.hook_procedure_type = WH_CALLWNDPROC; hook_settings.communication_type = OneWay; HookProcessor hook; if (!hook.CanSetWindowsHook(browser_window_handle)) { LOG(WARN) << "Proxy will not be set! There is a mismatch in the " << "bitness between the driver and browser. In particular, " << "be sure you are not attempting to use a 64-bit " << "IEDriverServer.exe against IE 10 or 11, even on 64-bit " << "Windows."; } hook.Initialize(hook_settings); hook.PushData(proxy); LRESULT result = ::SendMessage(browser_window_handle, WD_CHANGE_PROXY, NULL, NULL); if (this->socks_proxy_.size() > 0 && (this->socks_user_name_.size() > 0 || this->socks_password_.size() > 0)) { LOG(WARN) << "Windows APIs provide no way to set proxy user name and " << "password on a per-process basis. Setting global setting."; this->SetProxyAuthentication(StringUtilities::ToWString(this->socks_user_name_), StringUtilities::ToWString(this->socks_password_)); this->is_proxy_authorization_modified_ = true; // Notify WinINet clients that the proxy options have changed. BOOL success = ::InternetSetOption(NULL, INTERNET_OPTION_PROXY_SETTINGS_CHANGED, NULL, 0); if (!success) { LOGERR(WARN) << "InternetSetOption failed setting INTERNET_OPTION_PROXY_SETTINGS_CHANGED"; } } }
int CookieManager::GetCookies(const std::string& url, std::vector<BrowserCookie>* all_cookies) { LOG(TRACE) << "Entering CookieManager::GetCookies"; std::wstring wide_url = StringUtilities::ToWString(url); CComPtr<IUri> parsed_url; ::CreateUri(wide_url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &parsed_url); DWORD url_scheme = 0; parsed_url->GetScheme(&url_scheme); bool is_secure_url = URL_SCHEME_HTTPS == url_scheme; HookSettings hook_settings; hook_settings.hook_procedure_name = "CookieWndProc"; hook_settings.hook_procedure_type = WH_CALLWNDPROC; hook_settings.window_handle = this->window_handle_; hook_settings.communication_type = TwoWay; HookProcessor hook; if (!hook.CanSetWindowsHook(this->window_handle_)) { LOG(WARN) << "Cannot get cookies because driver and browser are not the " << "same bit-ness."; return EUNHANDLEDERROR; } hook.Initialize(hook_settings); bool supports_advanced_api = this->IsAdvancedCookiesApi(); if (supports_advanced_api) { // The version of WinINet installed supports the InternetGetCookieEx2 // API, which gets all cookies (session and persistent) at once. std::wstring raw_cookie_data = this->SendGetCookieMessage(wide_url, WD_GET_ALL_COOKIES, &hook); std::string all_cookies_list = StringUtilities::ToString(raw_cookie_data); std::map<std::string, BrowserCookie> cookies; this->ParseCookieList(all_cookies_list, is_secure_url, &cookies); std::map<std::string, BrowserCookie>::const_iterator cookie_iterator; for (cookie_iterator = cookies.begin(); cookie_iterator != cookies.end(); ++cookie_iterator) { all_cookies->push_back(cookie_iterator->second); } } else { // Get all cookies for the current URL visible to JavaScript. std::wstring scriptable_cookie_string = this->SendGetCookieMessage(wide_url, WD_GET_SCRIPTABLE_COOKIES, &hook); std::map<std::string, std::string> scriptable_cookies; this->ParseCookieString(scriptable_cookie_string, &scriptable_cookies); // Get all cookies for the insecure version of the current URL, // which will include HttpOnly cookies. std::wstring insecure_cookie_string = this->SendGetCookieMessage(wide_url, WD_GET_HTTPONLY_COOKIES, &hook); std::map<std::string, std::string> insecure_cookies; this->ParseCookieString(insecure_cookie_string, &insecure_cookies); // Get all cookies for the current secure URL. This will include // HttpOnly cookies. std::wstring secure_cookie_string = this->SendGetCookieMessage(wide_url, WD_GET_SECURE_COOKIES, &hook); std::map<std::string, std::string> secure_cookies; this->ParseCookieString(secure_cookie_string, &secure_cookies); // Get all of the persistent cookie files in the cache for the // URL currently being browsed. std::wstring file_list = this->SendGetCookieMessage(wide_url, WD_GET_COOKIE_CACHE_FILES, &hook); std::vector<std::wstring> files; StringUtilities::Split(file_list, L"|", &files); // Parse the persistent cookie files to produce a list of // cookies. std::map<std::string, BrowserCookie> persistent_cookies; std::vector<std::wstring>::const_iterator file_iterator; for (file_iterator = files.begin(); file_iterator != files.end(); ++file_iterator) { std::string cookie_file_contents = this->ReadCookieFile(*file_iterator); this->ParseCookieList(cookie_file_contents, is_secure_url, &persistent_cookies); } // Loop through the entire list of cookies, including HttpOnly and secure // cookies. If the cookie exists as a persistent cookie, use its data from // the cache. If the cookie is found in the list of cookies visible to // JavaScript, set the HttpOnly property of the cookie to false. If the // cookie is found in the list of cookies set on the insecure version of // the URL, set the Secure property of the cookie to false. std::map<std::string, std::string>::const_iterator it = secure_cookies.begin(); for (; it != secure_cookies.end(); ++it) { BrowserCookie browser_cookie; if (persistent_cookies.find(it->first) != persistent_cookies.end()) { browser_cookie = persistent_cookies[it->first]; } else { browser_cookie.set_name(it->first); browser_cookie.set_value(it->second); browser_cookie.set_is_httponly(scriptable_cookies.find(it->first) == scriptable_cookies.end()); browser_cookie.set_is_secure(insecure_cookies.find(it->first) == insecure_cookies.end()); } all_cookies->push_back(browser_cookie); } } return WD_SUCCESS; }