mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-12-05 03:36:08 +03:00
131 lines
4.5 KiB
C++
131 lines
4.5 KiB
C++
// Copyright 2011 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "net/http/url_security_manager.h"
|
|
|
|
#include <urlmon.h>
|
|
#include <wrl/client.h>
|
|
|
|
#include "base/debug/crash_logging.h"
|
|
#include "base/debug/dump_without_crashing.h"
|
|
#include "base/logging.h"
|
|
#include "base/notreached.h"
|
|
#include "base/strings/string_util.h"
|
|
#include "base/strings/utf_string_conversions.h"
|
|
#include "net/http/http_auth_filter.h"
|
|
#include "url/scheme_host_port.h"
|
|
|
|
// The Windows implementation of URLSecurityManager uses WinINet/IE's
|
|
// URL security zone manager. See the MSDN page "URL Security Zones" at
|
|
// http://msdn.microsoft.com/en-us/library/ms537021(VS.85).aspx for more
|
|
// info on the Internet Security Manager and Internet Zone Manager objects.
|
|
//
|
|
// On Windows, we honor the WinINet/IE settings and group policy related to
|
|
// URL Security Zones. See the Microsoft Knowledge Base article 182569
|
|
// "Internet Explorer security zones registry entries for advanced users"
|
|
// (http://support.microsoft.com/kb/182569) for more info on these registry
|
|
// keys.
|
|
|
|
namespace net {
|
|
|
|
class URLSecurityManagerWin : public URLSecurityManagerAllowlist {
|
|
public:
|
|
URLSecurityManagerWin();
|
|
|
|
URLSecurityManagerWin(const URLSecurityManagerWin&) = delete;
|
|
URLSecurityManagerWin& operator=(const URLSecurityManagerWin&) = delete;
|
|
|
|
~URLSecurityManagerWin() override;
|
|
|
|
// URLSecurityManager methods:
|
|
bool CanUseDefaultCredentials(
|
|
const url::SchemeHostPort& auth_scheme_host_port) const override;
|
|
|
|
private:
|
|
bool EnsureSystemSecurityManager();
|
|
|
|
Microsoft::WRL::ComPtr<IInternetSecurityManager> security_manager_;
|
|
};
|
|
|
|
URLSecurityManagerWin::URLSecurityManagerWin() = default;
|
|
URLSecurityManagerWin::~URLSecurityManagerWin() = default;
|
|
|
|
bool URLSecurityManagerWin::CanUseDefaultCredentials(
|
|
const url::SchemeHostPort& auth_scheme_host_port) const {
|
|
if (HasDefaultAllowlist())
|
|
return URLSecurityManagerAllowlist::CanUseDefaultCredentials(
|
|
auth_scheme_host_port);
|
|
if (!const_cast<URLSecurityManagerWin*>(this)->EnsureSystemSecurityManager())
|
|
return false;
|
|
|
|
std::u16string url16 = base::ASCIIToUTF16(auth_scheme_host_port.Serialize());
|
|
DWORD policy = 0;
|
|
HRESULT hr;
|
|
hr = security_manager_->ProcessUrlAction(
|
|
base::as_wcstr(url16), URLACTION_CREDENTIALS_USE,
|
|
reinterpret_cast<BYTE*>(&policy), sizeof(policy), nullptr, 0, PUAF_NOUI,
|
|
0);
|
|
if (FAILED(hr)) {
|
|
LOG(ERROR) << "IInternetSecurityManager::ProcessUrlAction failed: " << hr;
|
|
return false;
|
|
}
|
|
|
|
// Four possible policies for URLACTION_CREDENTIALS_USE. See the MSDN page
|
|
// "About URL Security Zones" at
|
|
// http://msdn.microsoft.com/en-us/library/ms537183(VS.85).aspx
|
|
switch (policy) {
|
|
case URLPOLICY_CREDENTIALS_SILENT_LOGON_OK:
|
|
return true;
|
|
case URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT: {
|
|
// This policy means "prompt the user for permission if the resource is
|
|
// not located in the Intranet zone". TODO(wtc): Note that it's
|
|
// prompting for permission (to use the default credentials), as opposed
|
|
// to prompting the user to enter a user name and password.
|
|
|
|
// URLZONE_LOCAL_MACHINE 0
|
|
// URLZONE_INTRANET 1
|
|
// URLZONE_TRUSTED 2
|
|
// URLZONE_INTERNET 3
|
|
// URLZONE_UNTRUSTED 4
|
|
DWORD zone = 0;
|
|
hr = security_manager_->MapUrlToZone(base::as_wcstr(url16), &zone, 0);
|
|
if (FAILED(hr)) {
|
|
LOG(ERROR) << "IInternetSecurityManager::MapUrlToZone failed: " << hr;
|
|
return false;
|
|
}
|
|
return zone <= URLZONE_INTRANET;
|
|
}
|
|
case URLPOLICY_CREDENTIALS_MUST_PROMPT_USER:
|
|
return false;
|
|
case URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY:
|
|
// TODO(wtc): we should fail the authentication.
|
|
return false;
|
|
default:
|
|
LOG(ERROR) << "Unexpected policy: " << policy;
|
|
SCOPED_CRASH_KEY_NUMBER("CanUseDefaultCredentials", "policy", policy);
|
|
base::debug::DumpWithoutCrashing();
|
|
return false;
|
|
}
|
|
}
|
|
// TODO(cbentzel): Could CanDelegate use the security zone as well?
|
|
|
|
bool URLSecurityManagerWin::EnsureSystemSecurityManager() {
|
|
if (!security_manager_.Get()) {
|
|
HRESULT hr =
|
|
CoInternetCreateSecurityManager(nullptr, &security_manager_, 0);
|
|
if (FAILED(hr) || !security_manager_.Get()) {
|
|
LOG(ERROR) << "Unable to create the Windows Security Manager instance";
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// static
|
|
std::unique_ptr<URLSecurityManager> URLSecurityManager::Create() {
|
|
return std::make_unique<URLSecurityManagerWin>();
|
|
}
|
|
|
|
} // namespace net
|