Exemple #1
0
LRESULT CALLBACK CookieWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
  CWPSTRUCT* call_window_proc_struct = reinterpret_cast<CWPSTRUCT*>(lParam);
  if (WM_COPYDATA == call_window_proc_struct->message) {
    COPYDATASTRUCT* data = reinterpret_cast<COPYDATASTRUCT*>(call_window_proc_struct->lParam);
    webdriver::HookProcessor::CopyDataToBuffer(data->cbData, data->lpData);
  } else if (WD_GET_ALL_COOKIES == call_window_proc_struct->message) {
    std::wstring url = webdriver::HookProcessor::CopyWStringFromBuffer();
    int driver_process_id = static_cast<int>(call_window_proc_struct->wParam);

    CComPtr<IUri> uri_pointer;
    HRESULT hr = ::CreateUri(url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);
    DWORD scheme = 0;
    uri_pointer->GetScheme(&scheme);
    CComBSTR scheme_bstr;
    uri_pointer->GetSchemeName(&scheme_bstr);
    CComBSTR host_bstr;
    uri_pointer->GetHost(&host_bstr);
    CComBSTR path_bstr;
    uri_pointer->GetPath(&path_bstr);
    
    std::wstring parsed_uri = scheme_bstr;
    parsed_uri.append(L"://");
    parsed_uri.append(host_bstr);
    parsed_uri.append(path_bstr);

    InternetGetCookieEx2Proc get_cookie_proc = NULL;
    InternetFreeCookiesProc free_cookies_proc = NULL;
    HMODULE wininet_handle = ::GetModuleHandle(L"wininet");
    if (wininet_handle) {
      get_cookie_proc = reinterpret_cast<InternetGetCookieEx2Proc>(::GetProcAddress(wininet_handle, "InternetGetCookieEx2"));
      free_cookies_proc = reinterpret_cast<InternetFreeCookiesProc>(::GetProcAddress(wininet_handle, "InternetFreeCookies"));
    }

    DWORD cookie_count = 0;
    INTERNETCOOKIE2* cookie_pointer = NULL;
    DWORD success = 1;
    if (get_cookie_proc) {
      success = get_cookie_proc(parsed_uri.c_str(),
                                NULL,
                                INTERNET_COOKIE_NON_SCRIPT,
                                &cookie_pointer,
                                &cookie_count);
    }

    if (success == 0) {
      // Mimic the format of the old persistent cookie files for ease of
      // transmission back to the driver and parsing.
      std::wstring all_cookies = L"";
      for (DWORD cookie_index = 0; cookie_index < cookie_count; ++cookie_index) {
        if (all_cookies.size() > 0) {
          all_cookies.append(L"\n*\n");
        }
        INTERNETCOOKIE2* current_cookie = cookie_pointer + cookie_index;
        std::wstring cookie_name = current_cookie->pwszName;
        std::wstring cookie_value = current_cookie->pwszValue;
        std::wstring cookie_domain = current_cookie->pwszDomain;
        std::wstring cookie_path = current_cookie->pwszPath;
        DWORD flags = current_cookie->dwFlags;
        FILETIME expires = current_cookie->ftExpires;
        all_cookies.append(cookie_name).append(L"\n");
        all_cookies.append(cookie_value).append(L"\n");
        all_cookies.append(cookie_domain).append(L"/").append(cookie_path).append(L"\n");
        all_cookies.append(std::to_wstring(flags)).append(L"\n");
        // If the expiration time is set, add it to the string for the cookie.
        // If not, append empty fields to the record so subsequent parsing
        // of the string will still work.
        if (current_cookie->fExpiresSet) {
          all_cookies.append(std::to_wstring(expires.dwLowDateTime)).append(L"\n");
          all_cookies.append(std::to_wstring(expires.dwHighDateTime)).append(L"\n");
        } else {
          all_cookies.append(L"\n\n");
        }
      }
      free_cookies_proc(cookie_pointer, cookie_count);
      webdriver::HookProcessor::CopyWStringToBuffer(all_cookies);
    } else {
      webdriver::HookProcessor::SetDataBufferSize(sizeof(wchar_t));
    }
    webdriver::HookProcessor::WriteBufferToPipe(driver_process_id);
  } else if (WD_GET_HTTPONLY_COOKIES == call_window_proc_struct->message ||
             WD_GET_SCRIPTABLE_COOKIES == call_window_proc_struct->message ||
             WD_GET_SECURE_COOKIES == call_window_proc_struct->message) {
    std::wstring url = webdriver::HookProcessor::CopyWStringFromBuffer();
    int driver_process_id = static_cast<int>(call_window_proc_struct->wParam);

    DWORD get_cookie_flags = 0;
    if (WD_GET_HTTPONLY_COOKIES == call_window_proc_struct->message ||
      WD_GET_SECURE_COOKIES == call_window_proc_struct->message) {
      get_cookie_flags = INTERNET_COOKIE_HTTPONLY;
    }

    CComPtr<IUri> uri_pointer;
    HRESULT hr = ::CreateUri(url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);
    DWORD scheme = 0;
    uri_pointer->GetScheme(&scheme);
    CComBSTR scheme_bstr;
    uri_pointer->GetSchemeName(&scheme_bstr);
    CComBSTR host_bstr;
    uri_pointer->GetHost(&host_bstr);
    CComBSTR path_bstr;
    uri_pointer->GetPath(&path_bstr);

    // Get only the cookies for the base URL, omitting port, if there is one.
    // N.B., we only return cookies secure cookies when browsing a site using
    // SSL. The browser won't see cookies with the 'secure' flag for sites
    // visited using plain http.
    std::wstring parsed_uri = L"http";
    if ((WD_GET_SECURE_COOKIES == call_window_proc_struct->message ||
         WD_GET_SCRIPTABLE_COOKIES == call_window_proc_struct->message) &&
        URL_SCHEME_HTTPS == scheme) {
      parsed_uri.append(L"s");
    }
    parsed_uri.append(L"://");
    parsed_uri.append(host_bstr);
    parsed_uri.append(path_bstr);

    // Call InternetGetCookieEx once to get the size of the buffer needed,
    // then call again with the appropriately sized buffer allocated.
    DWORD buffer_size = 0;
    BOOL success = ::InternetGetCookieEx(parsed_uri.c_str(),
                                         NULL,
                                         NULL,
                                         &buffer_size,
                                         get_cookie_flags,
                                         NULL);
    if (success) {
      webdriver::HookProcessor::SetDataBufferSize(buffer_size);
      ::InternetGetCookieEx(parsed_uri.c_str(),
                            NULL,
                            reinterpret_cast<LPTSTR>(webdriver::HookProcessor::GetDataBufferAddress()),
                            &buffer_size,
                            get_cookie_flags,
                            NULL);

      webdriver::HookProcessor::WriteBufferToPipe(driver_process_id);
    } else {
      if (ERROR_NO_MORE_ITEMS == ::GetLastError()) {
        webdriver::HookProcessor::SetDataBufferSize(sizeof(wchar_t));
        webdriver::HookProcessor::WriteBufferToPipe(driver_process_id);
      }
    }
  } else if (WD_GET_COOKIE_CACHE_FILES == call_window_proc_struct->message) {
    int driver_process_id = static_cast<int>(call_window_proc_struct->wParam);
    std::wstring file_list = L"";
    std::wstring url = webdriver::HookProcessor::CopyWStringFromBuffer();

    // We need to remove the port to find the entry in the cache.
    CComPtr<IUri> uri_pointer;
    HRESULT hr = ::CreateUri(url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);
    CComBSTR host_bstr;
    uri_pointer->GetHost(&host_bstr);
    CComBSTR path_bstr;
    uri_pointer->GetPath(&path_bstr);
    std::wstring parsed_uri = host_bstr;
    parsed_uri.append(path_bstr);

    // A 2048-byte buffer should be large enough to handle cookie
    // cache entries in all but the most extreme cases.
    HANDLE cache_enum_handle = NULL;
    DWORD entry_size = 2048;
    LPINTERNET_CACHE_ENTRY_INFO entry = NULL;
    std::vector<char> entry_buffer(entry_size);
    entry = reinterpret_cast<INTERNET_CACHE_ENTRY_INFO*>(&entry_buffer[0]);
    cache_enum_handle = ::FindFirstUrlCacheEntry(L"cookie:",
                                                 entry,
                                                 &entry_size);
    if (cache_enum_handle == NULL &&
        ERROR_INSUFFICIENT_BUFFER == ::GetLastError()) {
      entry_buffer.resize(entry_size);
      entry = reinterpret_cast<INTERNET_CACHE_ENTRY_INFO*>(&entry_buffer[0]);
      cache_enum_handle = ::FindFirstUrlCacheEntry(L"cookie:",
                                                   entry,
                                                   &entry_size);
    }
    while (cache_enum_handle != NULL) {
      if (COOKIE_CACHE_ENTRY == (entry->CacheEntryType & COOKIE_CACHE_ENTRY)) {
        std::wstring name = entry->lpszSourceUrlName;
        size_t name_separator_pos(name.find_first_of(L"@"));
        std::wstring domain = name.substr(name_separator_pos + 1);
        if (parsed_uri.find(domain) != std::wstring::npos) {
          if (file_list.size() > 0) {
            file_list.append(L"|");
          }
          file_list.append(entry->lpszLocalFileName);
        }
      }
      BOOL success = ::FindNextUrlCacheEntry(cache_enum_handle,
                                             entry,
                                             &entry_size);
      if (!success) {
        DWORD error = ::GetLastError();
        if (ERROR_INSUFFICIENT_BUFFER == error) {
          entry_buffer.resize(entry_size);
          BOOL other_success = ::FindNextUrlCacheEntry(cache_enum_handle,
                                                       entry,
                                                       &entry_size);
        } else if (ERROR_NO_MORE_ITEMS == error) {
          ::FindCloseUrlCache(cache_enum_handle);
          cache_enum_handle = NULL;
        }
      }
    }
    webdriver::HookProcessor::CopyWStringToBuffer(file_list);
    webdriver::HookProcessor::WriteBufferToPipe(driver_process_id);
  } else if (WD_SET_COOKIE == call_window_proc_struct->message) {
    DWORD set_cookie_flags = static_cast<DWORD>(call_window_proc_struct->wParam);
    std::wstring cookie_data = webdriver::HookProcessor::CopyWStringFromBuffer();
    size_t url_separator_pos = cookie_data.find_first_of(L"|");
    std::wstring url = cookie_data.substr(0, url_separator_pos);
    std::wstring cookie = cookie_data.substr(url_separator_pos + 1);

    CComPtr<IUri> uri_pointer;
    HRESULT hr = ::CreateUri(url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);
    CComBSTR scheme_bstr;
    uri_pointer->GetSchemeName(&scheme_bstr);
    CComBSTR host_bstr;
    uri_pointer->GetHost(&host_bstr);
    std::wstring parsed_uri = scheme_bstr;
    parsed_uri.append(L"://");
    parsed_uri.append(host_bstr);

    // Leverage the shared data buffer size to return the error code
    // back to the driver, if necessary.
    DWORD cookie_set = ::InternetSetCookieEx(parsed_uri.c_str(),
                                             NULL,
                                             cookie.c_str(),
                                             set_cookie_flags,
                                             NULL);
    if (cookie_set) {
      webdriver::HookProcessor::SetDataBufferSize(0);
    } else {
      DWORD error = ::GetLastError();
      webdriver::HookProcessor::SetDataBufferSize(error);
    }
  }
  return ::CallNextHookEx(NULL, nCode, wParam, lParam);
}
Exemple #2
0
File_List file_list(std::string path)
{
    File_List files;

    auto name_max = pathconf(path.c_str(), _PC_NAME_MAX);
    if (name_max == -1)
        name_max = 255;
    auto len = offsetof(struct dirent, d_name) + name_max + 1;
    std::vector<uint8_t> entry_buffer(len, '\0');
    auto entry = reinterpret_cast<struct dirent*>(entry_buffer.data());
    struct dirent* result;

    std::stack<std::string> directories;
    directories.push(path);

    while (!directories.empty()) {
        path = directories.top();
        directories.pop();

        auto dir = opendir(path.c_str());
        if (dir == nullptr)
            throw os_error::make_os_error(errno);

        do {
            readdir_r(dir, entry, &result);
            if (result == nullptr)
                break;

            // skip 'hidden' files, which includes the pseudo dirs . and ..
            if (result->d_name[0] == '.')
                continue;

            auto new_item = path_get_full_name(path_combine(path, result->d_name));

            if (result->d_type == DT_DIR) {
                // add this directory to our stack
                directories.push(new_item);
            }
            else if (result->d_type == DT_REG) {
                // add this file to our list of results
                files.push_back(new_item);
            }
            else if (result->d_type == DT_LNK) {
                // is it a link to a file or a directory?
                struct stat stat_buf;
                if (stat(new_item.c_str(), &stat_buf) == -1)
                    throw os_error::make_os_error(errno, new_item);
                if (S_ISDIR(stat_buf.st_mode)) {
                    directories.push(new_item);
                }
                else if (S_ISREG(stat_buf.st_mode)) {
                    files.push_back(new_item);
                }
            }
        } while (true);

        closedir(dir);
    }

    return files;
}
Exemple #3
0
LRESULT CALLBACK CookieWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
  CWPSTRUCT* call_window_proc_struct = reinterpret_cast<CWPSTRUCT*>(lParam);
  if (WM_COPYDATA == call_window_proc_struct->message) {
    COPYDATASTRUCT* data = reinterpret_cast<COPYDATASTRUCT*>(call_window_proc_struct->lParam);
    webdriver::HookProcessor::CopyDataToBuffer(data->cbData, data->lpData);
  } else if (WD_GET_HTTPONLY_COOKIES == call_window_proc_struct->message ||
             WD_GET_SCRIPTABLE_COOKIES == call_window_proc_struct->message ||
             WD_GET_SECURE_COOKIES == call_window_proc_struct->message) {
    std::wstring url = webdriver::HookProcessor::CopyWStringFromBuffer();
    int driver_process_id = static_cast<int>(call_window_proc_struct->wParam);

    DWORD get_cookie_flags = 0;
    if (WD_GET_HTTPONLY_COOKIES == call_window_proc_struct->message ||
        WD_GET_SECURE_COOKIES == call_window_proc_struct->message) {
      get_cookie_flags = INTERNET_COOKIE_HTTPONLY;
    }

    CComPtr<IUri> uri_pointer;
    HRESULT hr = ::CreateUri(url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);
    DWORD scheme = 0;
    uri_pointer->GetScheme(&scheme);
    CComBSTR scheme_bstr;
    uri_pointer->GetSchemeName(&scheme_bstr);
    CComBSTR host_bstr;
    uri_pointer->GetHost(&host_bstr);
    CComBSTR path_bstr;
    uri_pointer->GetPath(&path_bstr);
    
    // Get only the cookies for the base URL, omitting port, if there is one.
    // N.B., we only return cookies secure cookies when browsing a site using
    // SSL. The browser won't see cookies with the 'secure' flag for sites
    // visited using plain http.
    std::wstring parsed_uri = L"http";
    if ((WD_GET_SECURE_COOKIES == call_window_proc_struct->message ||
         WD_GET_SCRIPTABLE_COOKIES == call_window_proc_struct->message) && 
        URL_SCHEME_HTTPS == scheme) {
      parsed_uri.append(L"s");
    }
    parsed_uri.append(L"://");
    parsed_uri.append(host_bstr);
    parsed_uri.append(path_bstr);

    // Call InternetGetCookieEx once to get the size of the buffer needed,
    // then call again with the appropriately sized buffer allocated.
    DWORD buffer_size = 0;
    BOOL success = ::InternetGetCookieEx(parsed_uri.c_str(),
                                         NULL,
                                         NULL,
                                         &buffer_size,
                                         get_cookie_flags,
                                         NULL);
    if (success) {
      webdriver::HookProcessor::SetDataBufferSize(buffer_size);
      ::InternetGetCookieEx(parsed_uri.c_str(),
                            NULL,
                            reinterpret_cast<LPTSTR>(webdriver::HookProcessor::GetDataBufferAddress()),
                            &buffer_size,
                            get_cookie_flags,
                            NULL);

      webdriver::HookProcessor::WriteBufferToPipe(driver_process_id);
    } else {
      if (ERROR_NO_MORE_ITEMS == ::GetLastError()) {
        webdriver::HookProcessor::SetDataBufferSize(sizeof(wchar_t));
        webdriver::HookProcessor::WriteBufferToPipe(driver_process_id);
      }
    }
  } else if (WD_GET_COOKIE_CACHE_FILES == call_window_proc_struct->message) {
    int driver_process_id = static_cast<int>(call_window_proc_struct->wParam);
    std::wstring file_list = L"";
    std::wstring url = webdriver::HookProcessor::CopyWStringFromBuffer();

    // We need to remove the port to find the entry in the cache.
    CComPtr<IUri> uri_pointer;
    HRESULT hr = ::CreateUri(url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);
    CComBSTR host_bstr;
    uri_pointer->GetHost(&host_bstr);
    CComBSTR path_bstr;
    uri_pointer->GetPath(&path_bstr);
    std::wstring parsed_uri = host_bstr;
    parsed_uri.append(path_bstr);

    // A 2048-byte buffer should be large enough to handle cookie
    // cache entries in all but the most extreme cases.
    HANDLE cache_enum_handle = NULL;
    DWORD entry_size = 2048;
    LPINTERNET_CACHE_ENTRY_INFO entry = NULL;
    std::vector<char> entry_buffer(entry_size);
    entry = reinterpret_cast<INTERNET_CACHE_ENTRY_INFO*>(&entry_buffer[0]);
    cache_enum_handle = ::FindFirstUrlCacheEntry(L"cookie:",
                                                 entry,
                                                 &entry_size);
    if (cache_enum_handle == NULL &&
        ERROR_INSUFFICIENT_BUFFER == ::GetLastError()) {
      entry_buffer.resize(entry_size);
      entry = reinterpret_cast<INTERNET_CACHE_ENTRY_INFO*>(&entry_buffer[0]);
      cache_enum_handle = ::FindFirstUrlCacheEntry(L"cookie:",
                                                   entry,
                                                   &entry_size);
    }
    while (cache_enum_handle != NULL) {
      if (COOKIE_CACHE_ENTRY == (entry->CacheEntryType & COOKIE_CACHE_ENTRY)) {
        std::wstring name = entry->lpszSourceUrlName;
        size_t name_separator_pos(name.find_first_of(L"@"));
        std::wstring domain = name.substr(name_separator_pos + 1);
        if (parsed_uri.find(domain) != std::wstring::npos) {
          if (file_list.size() > 0) {
            file_list.append(L"|");
          }
          file_list.append(entry->lpszLocalFileName);
        }
      }
      BOOL success = ::FindNextUrlCacheEntry(cache_enum_handle,
                                             entry,
                                             &entry_size);
      if (!success) {
        DWORD error = ::GetLastError();
        if (ERROR_INSUFFICIENT_BUFFER == error) {
          entry_buffer.resize(entry_size);
          BOOL other_success = ::FindNextUrlCacheEntry(cache_enum_handle,
                                                       entry,
                                                       &entry_size);
        } else if (ERROR_NO_MORE_ITEMS == error) {
          ::FindCloseUrlCache(cache_enum_handle);
          cache_enum_handle = NULL;
        }
      }
    }
    webdriver::HookProcessor::CopyWStringToBuffer(file_list);
    webdriver::HookProcessor::WriteBufferToPipe(driver_process_id);
  } else if (WD_SET_COOKIE == call_window_proc_struct->message) {
    DWORD set_cookie_flags = static_cast<DWORD>(call_window_proc_struct->wParam);
    std::wstring cookie_data = webdriver::HookProcessor::CopyWStringFromBuffer();
    size_t url_separator_pos = cookie_data.find_first_of(L"|");
    std::wstring url = cookie_data.substr(0, url_separator_pos);
    std::wstring cookie = cookie_data.substr(url_separator_pos + 1);

    CComPtr<IUri> uri_pointer;
    HRESULT hr = ::CreateUri(url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);
    CComBSTR scheme_bstr;
    uri_pointer->GetSchemeName(&scheme_bstr);
    CComBSTR host_bstr;
    uri_pointer->GetHost(&host_bstr);
    std::wstring parsed_uri = scheme_bstr;
    parsed_uri.append(L"://");
    parsed_uri.append(host_bstr);

    // Leverage the shared data buffer size to return the error code
    // back to the driver, if necessary.
    DWORD cookie_set = ::InternetSetCookieEx(parsed_uri.c_str(),
                                             NULL,
                                             cookie.c_str(),
                                             set_cookie_flags,
                                             NULL);
    if (cookie_set) {
      webdriver::HookProcessor::SetDataBufferSize(0);
    } else {
      DWORD error = ::GetLastError();
      webdriver::HookProcessor::SetDataBufferSize(error);
    }
  }
  return ::CallNextHookEx(NULL, nCode, wParam, lParam);
}