1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/http/url_security_manager.h"
8 #pragma comment(lib, "urlmon.lib")
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/win/scoped_comptr.h"
13 #include "net/http/http_auth_filter.h"
16 // The Windows implementation of URLSecurityManager uses WinINet/IE's
17 // URL security zone manager. See the MSDN page "URL Security Zones" at
18 // http://msdn.microsoft.com/en-us/library/ms537021(VS.85).aspx for more
19 // info on the Internet Security Manager and Internet Zone Manager objects.
21 // On Windows, we honor the WinINet/IE settings and group policy related to
22 // URL Security Zones. See the Microsoft Knowledge Base article 182569
23 // "Internet Explorer security zones registry entries for advanced users"
24 // (http://support.microsoft.com/kb/182569) for more info on these registry
29 class URLSecurityManagerWin
: public URLSecurityManager
{
31 explicit URLSecurityManagerWin(const HttpAuthFilter
* whitelist_delegate
);
33 // URLSecurityManager methods:
34 virtual bool CanUseDefaultCredentials(const GURL
& auth_origin
) const;
35 virtual bool CanDelegate(const GURL
& auth_origin
) const;
38 bool EnsureSystemSecurityManager();
40 base::win::ScopedComPtr
<IInternetSecurityManager
> security_manager_
;
41 scoped_ptr
<const HttpAuthFilter
> whitelist_delegate_
;
43 DISALLOW_COPY_AND_ASSIGN(URLSecurityManagerWin
);
46 URLSecurityManagerWin::URLSecurityManagerWin(
47 const HttpAuthFilter
* whitelist_delegate
)
48 : whitelist_delegate_(whitelist_delegate
) {
51 bool URLSecurityManagerWin::CanUseDefaultCredentials(
52 const GURL
& auth_origin
) const {
53 if (!const_cast<URLSecurityManagerWin
*>(this)->EnsureSystemSecurityManager())
56 std::wstring url_w
= base::ASCIIToWide(auth_origin
.spec());
59 hr
= security_manager_
->ProcessUrlAction(url_w
.c_str(),
60 URLACTION_CREDENTIALS_USE
,
61 reinterpret_cast<BYTE
*>(&policy
),
62 sizeof(policy
), NULL
, 0,
65 LOG(ERROR
) << "IInternetSecurityManager::ProcessUrlAction failed: " << hr
;
69 // Four possible policies for URLACTION_CREDENTIALS_USE. See the MSDN page
70 // "About URL Security Zones" at
71 // http://msdn.microsoft.com/en-us/library/ms537183(VS.85).aspx
73 case URLPOLICY_CREDENTIALS_SILENT_LOGON_OK
:
75 case URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT
: {
76 // This policy means "prompt the user for permission if the resource is
77 // not located in the Intranet zone". TODO(wtc): Note that it's
78 // prompting for permission (to use the default credentials), as opposed
79 // to prompting the user to enter a user name and password.
81 // URLZONE_LOCAL_MACHINE 0
85 // URLZONE_UNTRUSTED 4
87 hr
= security_manager_
->MapUrlToZone(url_w
.c_str(), &zone
, 0);
89 LOG(ERROR
) << "IInternetSecurityManager::MapUrlToZone failed: " << hr
;
92 return zone
<= URLZONE_INTRANET
;
94 case URLPOLICY_CREDENTIALS_MUST_PROMPT_USER
:
96 case URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY
:
97 // TODO(wtc): we should fail the authentication.
105 bool URLSecurityManagerWin::CanDelegate(const GURL
& auth_origin
) const {
106 // TODO(cbentzel): Could this just use the security zone as well? Apparently
107 // this is what IE does as well.
108 if (whitelist_delegate_
.get())
109 return whitelist_delegate_
->IsValid(auth_origin
, HttpAuth::AUTH_SERVER
);
113 bool URLSecurityManagerWin::EnsureSystemSecurityManager() {
114 if (!security_manager_
) {
115 HRESULT hr
= CoInternetCreateSecurityManager(NULL
,
116 security_manager_
.Receive(),
118 if (FAILED(hr
) || !security_manager_
) {
119 LOG(ERROR
) << "Unable to create the Windows Security Manager instance";
127 URLSecurityManager
* URLSecurityManager::Create(
128 const HttpAuthFilter
* whitelist_default
,
129 const HttpAuthFilter
* whitelist_delegate
) {
130 // If we have a whitelist, just use that.
131 if (whitelist_default
)
132 return new URLSecurityManagerWhitelist(whitelist_default
,
134 return new URLSecurityManagerWin(whitelist_delegate
);