0

Make the AuthSchemes policy support dynamic refresh

This is in preparation for the new policy that allows some domains to
use any http authentication scheme regardless of the AuthSchemes  policy

Bug: 549273,1198536
Change-Id: Icc904b884f847f9c0cee777fbe14550c92af2196
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3370428
Reviewed-by: Matt Menke <mmenke@chromium.org>
Reviewed-by: Rohit Rao <rohitrao@chromium.org>
Reviewed-by: Owen Min <zmin@chromium.org>
Reviewed-by: Nasko Oskov <nasko@chromium.org>
Reviewed-by: Nate Fischer <ntfschr@chromium.org>
Reviewed-by: Alex Ilin <alexilin@chromium.org>
Commit-Queue: Yann Dago <ydago@chromium.org>
Cr-Commit-Position: refs/heads/main@{#961187}
This commit is contained in:
Yann Dago
2022-01-19 23:48:50 +00:00
committed by Chromium LUCI CQ
parent 30af706d4f
commit a2fee34ed3
16 changed files with 234 additions and 127 deletions

@ -191,6 +191,7 @@ AwBrowserProcess::CreateHttpAuthDynamicParams() {
network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params =
network::mojom::HttpAuthDynamicParams::New();
auth_dynamic_params->allowed_schemes = AwBrowserContext::GetAuthSchemes();
auth_dynamic_params->server_allowlist =
local_state()->GetString(prefs::kAuthServerAllowlist);
auth_dynamic_params->android_negotiate_account_type =

@ -258,10 +258,8 @@ AwContentBrowserClient::~AwContentBrowserClient() {}
void AwContentBrowserClient::OnNetworkServiceCreated(
network::mojom::NetworkService* network_service) {
network::mojom::HttpAuthStaticParamsPtr auth_static_params =
network::mojom::HttpAuthStaticParams::New();
auth_static_params->supported_schemes = AwBrowserContext::GetAuthSchemes();
content::GetNetworkService()->SetUpHttpAuth(std::move(auth_static_params));
content::GetNetworkService()->SetUpHttpAuth(
network::mojom::HttpAuthStaticParams::New());
}
void AwContentBrowserClient::ConfigureNetworkContextParams(

@ -109,11 +109,6 @@ network::mojom::HttpAuthStaticParamsPtr CreateHttpAuthStaticParams(
network::mojom::HttpAuthStaticParamsPtr auth_static_params =
network::mojom::HttpAuthStaticParams::New();
// TODO(https://crbug/549273): Allow this to change after startup.
auth_static_params->supported_schemes =
base::SplitString(local_state->GetString(prefs::kAuthSchemes), ",",
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
auth_static_params->gssapi_library_name =
local_state->GetString(prefs::kGSSAPILibraryName);
@ -128,6 +123,9 @@ network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams(
network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params =
network::mojom::HttpAuthDynamicParams::New();
auth_dynamic_params->allowed_schemes =
base::SplitString(local_state->GetString(prefs::kAuthSchemes), ",",
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
auth_dynamic_params->server_allowlist =
local_state->GetString(prefs::kAuthServerAllowlist);
auth_dynamic_params->delegate_allowlist =
@ -360,6 +358,7 @@ SystemNetworkContextManager::SystemNetworkContextManager(
PrefChangeRegistrar::NamedChangeCallback auth_pref_callback =
base::BindRepeating(&OnAuthPrefsChanged, base::Unretained(local_state_));
pref_change_registrar_.Add(prefs::kAuthSchemes, auth_pref_callback);
pref_change_registrar_.Add(prefs::kAuthServerAllowlist, auth_pref_callback);
pref_change_registrar_.Add(prefs::kAuthNegotiateDelegateAllowlist,
auth_pref_callback);

@ -87,20 +87,11 @@ IN_PROC_BROWSER_TEST_F(SystemNetworkContextManagerBrowsertest,
// Test defaults.
network::mojom::HttpAuthStaticParamsPtr static_params =
SystemNetworkContextManager::GetHttpAuthStaticParamsForTesting();
EXPECT_THAT(static_params->supported_schemes,
testing::ElementsAre("basic", "digest", "ntlm", "negotiate"));
EXPECT_EQ("", static_params->gssapi_library_name);
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
// Test that prefs are reflected in params.
PrefService* local_state = g_browser_process->local_state();
local_state->SetString(prefs::kAuthSchemes, "basic");
static_params =
SystemNetworkContextManager::GetHttpAuthStaticParamsForTesting();
EXPECT_THAT(static_params->supported_schemes, testing::ElementsAre("basic"));
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
const char dev_null[] = "/dev/null";
local_state->SetString(prefs::kGSSAPILibraryName, dev_null);
static_params =
@ -113,6 +104,8 @@ IN_PROC_BROWSER_TEST_F(SystemNetworkContextManagerBrowsertest, AuthParams) {
// Test defaults.
network::mojom::HttpAuthDynamicParamsPtr dynamic_params =
SystemNetworkContextManager::GetHttpAuthDynamicParamsForTesting();
EXPECT_THAT(*dynamic_params->allowed_schemes,
testing::ElementsAre("basic", "digest", "ntlm", "negotiate"));
EXPECT_FALSE(dynamic_params->negotiate_disable_cname_lookup);
EXPECT_FALSE(dynamic_params->enable_negotiate_port);
EXPECT_TRUE(dynamic_params->basic_over_http_enabled);
@ -125,6 +118,8 @@ IN_PROC_BROWSER_TEST_F(SystemNetworkContextManagerBrowsertest, AuthParams) {
local_state->SetBoolean(prefs::kDisableAuthNegotiateCnameLookup, true);
dynamic_params =
SystemNetworkContextManager::GetHttpAuthDynamicParamsForTesting();
EXPECT_THAT(*dynamic_params->allowed_schemes,
testing::ElementsAre("basic", "digest", "ntlm", "negotiate"));
EXPECT_TRUE(dynamic_params->negotiate_disable_cname_lookup);
EXPECT_FALSE(dynamic_params->enable_negotiate_port);
EXPECT_TRUE(dynamic_params->basic_over_http_enabled);
@ -135,6 +130,8 @@ IN_PROC_BROWSER_TEST_F(SystemNetworkContextManagerBrowsertest, AuthParams) {
local_state->SetBoolean(prefs::kEnableAuthNegotiatePort, true);
dynamic_params =
SystemNetworkContextManager::GetHttpAuthDynamicParamsForTesting();
EXPECT_THAT(*dynamic_params->allowed_schemes,
testing::ElementsAre("basic", "digest", "ntlm", "negotiate"));
EXPECT_TRUE(dynamic_params->negotiate_disable_cname_lookup);
EXPECT_TRUE(dynamic_params->enable_negotiate_port);
EXPECT_TRUE(dynamic_params->basic_over_http_enabled);
@ -145,6 +142,8 @@ IN_PROC_BROWSER_TEST_F(SystemNetworkContextManagerBrowsertest, AuthParams) {
local_state->SetBoolean(prefs::kBasicAuthOverHttpEnabled, false);
dynamic_params =
SystemNetworkContextManager::GetHttpAuthDynamicParamsForTesting();
EXPECT_THAT(*dynamic_params->allowed_schemes,
testing::ElementsAre("basic", "digest", "ntlm", "negotiate"));
EXPECT_TRUE(dynamic_params->negotiate_disable_cname_lookup);
EXPECT_TRUE(dynamic_params->enable_negotiate_port);
EXPECT_FALSE(dynamic_params->basic_over_http_enabled);
@ -156,6 +155,8 @@ IN_PROC_BROWSER_TEST_F(SystemNetworkContextManagerBrowsertest, AuthParams) {
local_state->SetString(prefs::kAuthServerAllowlist, kServerAllowList);
dynamic_params =
SystemNetworkContextManager::GetHttpAuthDynamicParamsForTesting();
EXPECT_THAT(*dynamic_params->allowed_schemes,
testing::ElementsAre("basic", "digest", "ntlm", "negotiate"));
EXPECT_TRUE(dynamic_params->negotiate_disable_cname_lookup);
EXPECT_TRUE(dynamic_params->enable_negotiate_port);
EXPECT_FALSE(dynamic_params->basic_over_http_enabled);
@ -167,6 +168,8 @@ IN_PROC_BROWSER_TEST_F(SystemNetworkContextManagerBrowsertest, AuthParams) {
kDelegateAllowList);
dynamic_params =
SystemNetworkContextManager::GetHttpAuthDynamicParamsForTesting();
EXPECT_THAT(*dynamic_params->allowed_schemes,
testing::ElementsAre("basic", "digest", "ntlm", "negotiate"));
EXPECT_TRUE(dynamic_params->negotiate_disable_cname_lookup);
EXPECT_TRUE(dynamic_params->enable_negotiate_port);
EXPECT_EQ(kServerAllowList, dynamic_params->server_allowlist);
@ -174,10 +177,23 @@ IN_PROC_BROWSER_TEST_F(SystemNetworkContextManagerBrowsertest, AuthParams) {
EXPECT_EQ(kDelegateAllowList, dynamic_params->delegate_allowlist);
EXPECT_FALSE(dynamic_params->delegate_by_kdc_policy);
local_state->SetString(prefs::kAuthSchemes, "basic");
dynamic_params =
SystemNetworkContextManager::GetHttpAuthDynamicParamsForTesting();
EXPECT_THAT(*dynamic_params->allowed_schemes, testing::ElementsAre("basic"));
EXPECT_TRUE(dynamic_params->negotiate_disable_cname_lookup);
EXPECT_TRUE(dynamic_params->enable_negotiate_port);
EXPECT_FALSE(dynamic_params->basic_over_http_enabled);
EXPECT_EQ(kServerAllowList, dynamic_params->server_allowlist);
EXPECT_EQ(kDelegateAllowList, dynamic_params->delegate_allowlist);
EXPECT_FALSE(dynamic_params->delegate_by_kdc_policy);
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
local_state->SetString(prefs::kAuthSchemes, "basic");
local_state->SetBoolean(prefs::kAuthNegotiateDelegateByKdcPolicy, true);
dynamic_params =
SystemNetworkContextManager::GetHttpAuthDynamicParamsForTesting();
EXPECT_THAT(*dynamic_params->allowed_schemes, testing::ElementsAre("basic"));
EXPECT_TRUE(dynamic_params->negotiate_disable_cname_lookup);
EXPECT_TRUE(dynamic_params->enable_negotiate_port);
EXPECT_FALSE(dynamic_params->basic_over_http_enabled);

@ -4991,7 +4991,7 @@
'schema': { 'type': 'string' },
'supported_on': ['chrome.*:9-','android:46-','chrome_os:62-'],
'features': {
'dynamic_refresh': False,
'dynamic_refresh': True,
'per_profile': False,
},
'example_value': 'basic,digest,ntlm,negotiate',

@ -10,6 +10,7 @@
#include <cstddef>
#include <cstdio>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
@ -351,9 +352,10 @@ void MCSProbe::InitializeNetworkState() {
builder.set_net_log(net_log_);
builder.set_host_resolver(
net::HostResolver::CreateStandaloneResolver(net_log_));
builder.SetHttpAuthHandlerFactory(net::HttpAuthHandlerRegistryFactory::Create(
&http_auth_preferences_,
std::vector<std::string>{net::kBasicAuthScheme}));
http_auth_preferences_.set_allowed_schemes(
std::set<std::string>{net::kBasicAuthScheme});
builder.SetHttpAuthHandlerFactory(
net::HttpAuthHandlerRegistryFactory::Create(&http_auth_preferences_));
builder.set_proxy_resolution_service(
net::ConfiguredProxyResolutionService::CreateDirect());

@ -313,9 +313,11 @@ void IOSIOThread::CreateDefaultAuthHandlerFactory() {
base::SPLIT_WANT_NONEMPTY);
globals_->http_auth_preferences =
std::make_unique<net::HttpAuthPreferences>();
globals_->http_auth_preferences->set_allowed_schemes(std::set<std::string>(
supported_schemes.begin(), supported_schemes.end()));
globals_->http_auth_handler_factory =
net::HttpAuthHandlerRegistryFactory::Create(
globals_->http_auth_preferences.get(), supported_schemes);
globals_->http_auth_preferences.get());
}
void IOSIOThread::ClearHostCache() {

@ -84,24 +84,17 @@ int HttpAuthHandlerFactory::CreatePreemptiveAuthHandlerFromString(
digest_nonce_count, net_log, host_resolver, handler);
}
namespace {
const char* const kDefaultAuthSchemes[] = {kBasicAuthScheme, kDigestAuthScheme,
#if BUILDFLAG(USE_KERBEROS) && !BUILDFLAG(IS_ANDROID)
kNegotiateAuthScheme,
#endif
kNtlmAuthScheme};
} // namespace
HttpAuthHandlerRegistryFactory::HttpAuthHandlerRegistryFactory() = default;
HttpAuthHandlerRegistryFactory::HttpAuthHandlerRegistryFactory(
const HttpAuthPreferences* http_auth_preferences) {
set_http_auth_preferences(http_auth_preferences);
}
HttpAuthHandlerRegistryFactory::~HttpAuthHandlerRegistryFactory() = default;
void HttpAuthHandlerRegistryFactory::SetHttpAuthPreferences(
const std::string& scheme,
const HttpAuthPreferences* prefs) {
HttpAuthHandlerFactory* factory = GetSchemeFactory(scheme);
HttpAuthHandlerFactory* factory = GetRegisteredSchemeFactory(scheme);
if (factory)
factory->set_http_auth_preferences(prefs);
}
@ -121,11 +114,11 @@ void HttpAuthHandlerRegistryFactory::RegisterSchemeFactory(
HttpAuthHandlerFactory* HttpAuthHandlerRegistryFactory::GetSchemeFactory(
const std::string& scheme) const {
std::string lower_scheme = base::ToLowerASCII(scheme);
auto it = factory_map_.find(lower_scheme);
if (it == factory_map_.end()) {
return nullptr; // |scheme| is not registered.
const auto& allowed_schemes = GetAllowedAuthSchemes();
if (allowed_schemes.find(lower_scheme) == allowed_schemes.end()) {
return nullptr;
}
return it->second.get();
return GetRegisteredSchemeFactory(scheme);
}
// static
@ -141,9 +134,7 @@ HttpAuthHandlerFactory::CreateDefault(
HttpAuthMechanismFactory negotiate_auth_system_factory
#endif
) {
std::vector<std::string> auth_types(std::begin(kDefaultAuthSchemes),
std::end(kDefaultAuthSchemes));
return HttpAuthHandlerRegistryFactory::Create(prefs, auth_types
return HttpAuthHandlerRegistryFactory::Create(prefs
#if BUILDFLAG(USE_EXTERNAL_GSSAPI)
,
gssapi_library_name
@ -158,8 +149,7 @@ HttpAuthHandlerFactory::CreateDefault(
// static
std::unique_ptr<HttpAuthHandlerRegistryFactory>
HttpAuthHandlerRegistryFactory::Create(
const HttpAuthPreferences* prefs,
const std::vector<std::string>& auth_schemes
const HttpAuthPreferences* prefs
#if BUILDFLAG(USE_EXTERNAL_GSSAPI)
,
const std::string& gssapi_library_name
@ -169,45 +159,35 @@ HttpAuthHandlerRegistryFactory::Create(
HttpAuthMechanismFactory negotiate_auth_system_factory
#endif
) {
std::set<std::string> auth_schemes_set(auth_schemes.begin(),
auth_schemes.end());
std::unique_ptr<HttpAuthHandlerRegistryFactory> registry_factory(
new HttpAuthHandlerRegistryFactory());
if (base::Contains(auth_schemes_set, kBasicAuthScheme)) {
registry_factory->RegisterSchemeFactory(
kBasicAuthScheme, new HttpAuthHandlerBasic::Factory());
}
new HttpAuthHandlerRegistryFactory(prefs));
if (base::Contains(auth_schemes_set, kDigestAuthScheme)) {
registry_factory->RegisterSchemeFactory(
kDigestAuthScheme, new HttpAuthHandlerDigest::Factory());
}
registry_factory->RegisterSchemeFactory(kBasicAuthScheme,
new HttpAuthHandlerBasic::Factory());
if (base::Contains(auth_schemes_set, kNtlmAuthScheme)) {
HttpAuthHandlerNTLM::Factory* ntlm_factory =
new HttpAuthHandlerNTLM::Factory();
registry_factory->RegisterSchemeFactory(kDigestAuthScheme,
new HttpAuthHandlerDigest::Factory());
HttpAuthHandlerNTLM::Factory* ntlm_factory =
new HttpAuthHandlerNTLM::Factory();
#if BUILDFLAG(IS_WIN)
ntlm_factory->set_sspi_library(
std::make_unique<SSPILibraryDefault>(NTLMSP_NAME));
ntlm_factory->set_sspi_library(
std::make_unique<SSPILibraryDefault>(NTLMSP_NAME));
#endif // BUILDFLAG(IS_WIN)
registry_factory->RegisterSchemeFactory(kNtlmAuthScheme, ntlm_factory);
}
registry_factory->RegisterSchemeFactory(kNtlmAuthScheme, ntlm_factory);
#if BUILDFLAG(USE_KERBEROS)
if (base::Contains(auth_schemes_set, kNegotiateAuthScheme)) {
HttpAuthHandlerNegotiate::Factory* negotiate_factory =
new HttpAuthHandlerNegotiate::Factory(negotiate_auth_system_factory);
HttpAuthHandlerNegotiate::Factory* negotiate_factory =
new HttpAuthHandlerNegotiate::Factory(negotiate_auth_system_factory);
#if BUILDFLAG(IS_WIN)
negotiate_factory->set_library(
std::make_unique<SSPILibraryDefault>(NEGOSSP_NAME));
negotiate_factory->set_library(
std::make_unique<SSPILibraryDefault>(NEGOSSP_NAME));
#elif BUILDFLAG(USE_EXTERNAL_GSSAPI)
negotiate_factory->set_library(
std::make_unique<GSSAPISharedLibrary>(gssapi_library_name));
negotiate_factory->set_library(
std::make_unique<GSSAPISharedLibrary>(gssapi_library_name));
#endif
registry_factory->RegisterSchemeFactory(kNegotiateAuthScheme,
negotiate_factory);
}
registry_factory->RegisterSchemeFactory(kNegotiateAuthScheme,
negotiate_factory);
#endif // BUILDFLAG(USE_KERBEROS)
if (prefs) {
@ -238,13 +218,12 @@ int HttpAuthHandlerRegistryFactory::CreateAuthHandler(
handler->reset();
net_error = ERR_INVALID_RESPONSE;
} else {
auto it = factory_map_.find(scheme);
if (it == factory_map_.end()) {
auto* factory = GetSchemeFactory(scheme);
if (!factory) {
handler->reset();
net_error = ERR_UNSUPPORTED_AUTH_SCHEME;
} else {
DCHECK(it->second);
net_error = it->second->CreateAuthHandler(
net_error = factory->CreateAuthHandler(
challenge, target, ssl_info, network_isolation_key, scheme_host_port,
reason, digest_nonce_count, net_log, host_resolver, handler);
}
@ -263,4 +242,24 @@ int HttpAuthHandlerRegistryFactory::CreateAuthHandler(
return net_error;
}
const std::set<std::string>&
HttpAuthHandlerRegistryFactory::GetAllowedAuthSchemes() const {
if (http_auth_preferences() &&
http_auth_preferences()->allowed_schemes().has_value()) {
return *http_auth_preferences()->allowed_schemes();
}
return default_auth_schemes_;
}
HttpAuthHandlerFactory*
HttpAuthHandlerRegistryFactory::GetRegisteredSchemeFactory(
const std::string& scheme) const {
std::string lower_scheme = base::ToLowerASCII(scheme);
auto it = factory_map_.find(lower_scheme);
if (it == factory_map_.end()) {
return nullptr; // |scheme| is not registered.
}
return it->second.get();
}
} // namespace net

@ -7,6 +7,7 @@
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
@ -15,6 +16,7 @@
#include "net/base/net_export.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_mechanism.h"
#include "net/http/http_auth_scheme.h"
#include "net/http/url_security_manager.h"
#include "net/net_buildflags.h"
@ -59,7 +61,7 @@ class NET_EXPORT HttpAuthHandlerFactory {
}
// Retrieves the associated URL security manager.
const HttpAuthPreferences* http_auth_preferences() {
const HttpAuthPreferences* http_auth_preferences() const {
return http_auth_preferences_;
}
@ -168,7 +170,8 @@ class NET_EXPORT HttpAuthHandlerFactory {
class NET_EXPORT HttpAuthHandlerRegistryFactory
: public HttpAuthHandlerFactory {
public:
HttpAuthHandlerRegistryFactory();
explicit HttpAuthHandlerRegistryFactory(
const HttpAuthPreferences* http_auth_preferences);
HttpAuthHandlerRegistryFactory(const HttpAuthHandlerRegistryFactory&) =
delete;
@ -205,14 +208,10 @@ class NET_EXPORT HttpAuthHandlerRegistryFactory
// That object tracks preference, and hence policy, updates relevant to HTTP
// authentication, and provides the current values of the preferences.
//
// |auth_schemes| is a list of authentication schemes to support. Unknown
// schemes are ignored.
//
// |negotiate_auth_system_factory| is used to override the default auth system
// used by the Negotiate authentication handler.
static std::unique_ptr<HttpAuthHandlerRegistryFactory> Create(
const HttpAuthPreferences* prefs,
const std::vector<std::string>& auth_schemes
const HttpAuthPreferences* prefs
#if BUILDFLAG(USE_EXTERNAL_GSSAPI)
,
const std::string& gssapi_library_name = ""
@ -242,11 +241,26 @@ class NET_EXPORT HttpAuthHandlerRegistryFactory
const NetLogWithSource& net_log,
HostResolver* host_resolver,
std::unique_ptr<HttpAuthHandler>* handler) override;
const std::set<std::string>& GetAllowedAuthSchemes() const;
private:
// Retrieve the factory for the specified |scheme|. If no factory exists
// for the |scheme|, nullptr is returned. The returned factory must not be
// deleted by the caller, and it is guaranteed to be valid until either
// a new factory is registered for the same scheme, or until this
// registry factory is destroyed.
HttpAuthHandlerFactory* GetRegisteredSchemeFactory(
const std::string& scheme) const;
using FactoryMap =
std::map<std::string, std::unique_ptr<HttpAuthHandlerFactory>>;
std::set<std::string> default_auth_schemes_ {
kBasicAuthScheme, kDigestAuthScheme,
#if BUILDFLAG(USE_KERBEROS) && !BUILDFLAG(IS_ANDROID)
kNegotiateAuthScheme,
#endif
kNtlmAuthScheme
};
FactoryMap factory_map_;
};

@ -61,7 +61,8 @@ class MockHttpAuthHandlerFactory : public HttpAuthHandlerFactory {
TEST(HttpAuthHandlerFactoryTest, RegistryFactory) {
SSLInfo null_ssl_info;
HttpAuthHandlerRegistryFactory registry_factory;
HttpAuthHandlerRegistryFactory registry_factory(
/*http_auth_preferences=*/nullptr);
url::SchemeHostPort scheme_host_port(GURL("https://www.google.com"));
const int kBasicReturnCode = -1;
MockHttpAuthHandlerFactory* mock_factory_basic =

@ -8,12 +8,12 @@
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "net/base/net_export.h"
#include "net/http/http_auth.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace url {
class SchemeHostPort;
@ -91,6 +91,15 @@ class NET_EXPORT HttpAuthPreferences {
}
#endif
const absl::optional<std::set<std::string>>& allowed_schemes() const {
return allowed_schemes_;
}
void set_allowed_schemes(
const absl::optional<std::set<std::string>>& allowed_schemes) {
allowed_schemes_ = allowed_schemes;
}
void SetServerAllowlist(const std::string& server_allowlist);
void SetDelegateAllowlist(const std::string& delegate_allowlist);
@ -124,6 +133,7 @@ class NET_EXPORT HttpAuthPreferences {
bool allow_gssapi_library_load_ = true;
#endif
absl::optional<std::set<std::string>> allowed_schemes_;
std::unique_ptr<URLSecurityManager> security_manager_;
};

@ -23,6 +23,7 @@
#include "net/http/http_auth_handler_basic.h"
#include "net/http/http_auth_handler_digest.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_preferences.h"
#include "net/http/http_auth_scheme.h"
#include "net/log/net_log.h"
#include "net/log/test_net_log.h"
@ -50,11 +51,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// make system calls, which doesn't seem like a great idea.
net::HttpAuthCache auth_cache(
false /* key_server_entries_by_network_isolation_key */);
net::HttpAuthHandlerRegistryFactory auth_handler_factory;
auth_handler_factory.RegisterSchemeFactory(
net::kBasicAuthScheme, new net::HttpAuthHandlerBasic::Factory());
auth_handler_factory.RegisterSchemeFactory(
net::kDigestAuthScheme, new net::HttpAuthHandlerDigest::Factory());
net::HttpAuthPreferences http_auth_preferences;
http_auth_preferences.set_allowed_schemes(
std::set<std::string>{net::kBasicAuthScheme, net::kDigestAuthScheme});
net::HttpAuthHandlerRegistryFactory auth_handler_factory(
&http_auth_preferences);
scoped_refptr<net::HttpAuthController> auth_controller(
base::MakeRefCounted<net::HttpAuthController>(

@ -62,11 +62,13 @@
#include "net/http/http_auth.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_preferences.h"
#include "net/http/http_auth_scheme.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_server_properties.h"
#include "net/http/http_transaction_factory.h"
#include "net/net_buildflags.h"
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
@ -2086,6 +2088,13 @@ void NetworkContext::OnHttpAuthDynamicParamsChanged(
http_auth_merged_preferences_.set_allow_gssapi_library_load(
http_auth_dynamic_network_service_params->allow_gssapi_library_load);
#endif
if (http_auth_dynamic_network_service_params->allowed_schemes.has_value()) {
http_auth_merged_preferences_.set_allowed_schemes(std::set<std::string>(
http_auth_dynamic_network_service_params->allowed_schemes->begin(),
http_auth_dynamic_network_service_params->allowed_schemes->end()));
} else {
http_auth_merged_preferences_.set_allowed_schemes(absl::nullopt);
}
}
URLRequestContextOwner NetworkContext::MakeURLRequestContext(

@ -784,10 +784,9 @@ NetworkService::CreateHttpAuthHandlerFactory(NetworkContext* network_context) {
}
return net::HttpAuthHandlerRegistryFactory::Create(
network_context->GetHttpAuthPreferences(),
http_auth_static_network_service_params_->supported_schemes
network_context->GetHttpAuthPreferences()
#if BUILDFLAG(USE_EXTERNAL_GSSAPI)
,
,
http_auth_static_network_service_params_->gssapi_library_name
#endif
#if BUILDFLAG(IS_ANDROID) && BUILDFLAG(USE_KERBEROS)

@ -205,31 +205,7 @@ TEST_F(NetworkServiceTest, AuthDefaultParams) {
#endif // BUILDFLAG(IS_ANDROID)
}
TEST_F(NetworkServiceTest, AuthSchemesDigestAndNtlmOnly) {
mojom::HttpAuthStaticParamsPtr auth_params =
mojom::HttpAuthStaticParams::New();
auth_params->supported_schemes.push_back("digest");
auth_params->supported_schemes.push_back("ntlm");
service()->SetUpHttpAuth(std::move(auth_params));
mojo::Remote<mojom::NetworkContext> network_context_remote;
NetworkContext network_context(
service(), network_context_remote.BindNewPipeAndPassReceiver(),
CreateContextParams());
net::HttpAuthHandlerRegistryFactory* auth_handler_factory =
reinterpret_cast<net::HttpAuthHandlerRegistryFactory*>(
network_context.url_request_context()->http_auth_handler_factory());
ASSERT_TRUE(auth_handler_factory);
EXPECT_FALSE(auth_handler_factory->GetSchemeFactory(net::kBasicAuthScheme));
EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kDigestAuthScheme));
EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kNtlmAuthScheme));
EXPECT_FALSE(
auth_handler_factory->GetSchemeFactory(net::kNegotiateAuthScheme));
}
TEST_F(NetworkServiceTest, AuthSchemesNone) {
// An empty list means to support no schemes.
TEST_F(NetworkServiceTest, AuthSchemesDynamicallyChanging) {
service()->SetUpHttpAuth(mojom::HttpAuthStaticParams::New());
mojo::Remote<mojom::NetworkContext> network_context_remote;
@ -241,6 +217,78 @@ TEST_F(NetworkServiceTest, AuthSchemesNone) {
network_context.url_request_context()->http_auth_handler_factory());
ASSERT_TRUE(auth_handler_factory);
EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kBasicAuthScheme));
EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kDigestAuthScheme));
EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kNtlmAuthScheme));
#if BUILDFLAG(USE_KERBEROS) && !defined(OS_ANDROID)
EXPECT_TRUE(
auth_handler_factory->GetSchemeFactory(net::kNegotiateAuthScheme));
#else
EXPECT_FALSE(
auth_handler_factory->GetSchemeFactory(net::kNegotiateAuthScheme));
#endif
{
mojom::HttpAuthDynamicParamsPtr auth_params =
mojom::HttpAuthDynamicParams::New();
auth_params->allowed_schemes = std::vector<std::string>{};
service()->ConfigureHttpAuthPrefs(std::move(auth_params));
EXPECT_FALSE(auth_handler_factory->GetSchemeFactory(net::kBasicAuthScheme));
EXPECT_FALSE(
auth_handler_factory->GetSchemeFactory(net::kDigestAuthScheme));
EXPECT_FALSE(auth_handler_factory->GetSchemeFactory(net::kNtlmAuthScheme));
EXPECT_FALSE(
auth_handler_factory->GetSchemeFactory(net::kNegotiateAuthScheme));
}
{
mojom::HttpAuthDynamicParamsPtr auth_params =
mojom::HttpAuthDynamicParams::New();
auth_params->allowed_schemes =
std::vector<std::string>{net::kDigestAuthScheme, net::kNtlmAuthScheme};
service()->ConfigureHttpAuthPrefs(std::move(auth_params));
EXPECT_FALSE(auth_handler_factory->GetSchemeFactory(net::kBasicAuthScheme));
EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kDigestAuthScheme));
EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kNtlmAuthScheme));
EXPECT_FALSE(
auth_handler_factory->GetSchemeFactory(net::kNegotiateAuthScheme));
}
{
mojom::HttpAuthDynamicParamsPtr auth_params =
mojom::HttpAuthDynamicParams::New();
service()->ConfigureHttpAuthPrefs(std::move(auth_params));
EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kBasicAuthScheme));
EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kDigestAuthScheme));
EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kNtlmAuthScheme));
#if BUILDFLAG(USE_KERBEROS) && !defined(OS_ANDROID)
EXPECT_TRUE(
auth_handler_factory->GetSchemeFactory(net::kNegotiateAuthScheme));
#else
EXPECT_FALSE(
auth_handler_factory->GetSchemeFactory(net::kNegotiateAuthScheme));
#endif
}
}
TEST_F(NetworkServiceTest, AuthSchemesNone) {
service()->SetUpHttpAuth(mojom::HttpAuthStaticParams::New());
mojo::Remote<mojom::NetworkContext> network_context_remote;
NetworkContext network_context(
service(), network_context_remote.BindNewPipeAndPassReceiver(),
CreateContextParams());
net::HttpAuthHandlerRegistryFactory* auth_handler_factory =
reinterpret_cast<net::HttpAuthHandlerRegistryFactory*>(
network_context.url_request_context()->http_auth_handler_factory());
ASSERT_TRUE(auth_handler_factory);
// An empty list means to support no schemes.
mojom::HttpAuthDynamicParamsPtr auth_params =
mojom::HttpAuthDynamicParams::New();
auth_params->allowed_schemes = std::vector<std::string>{};
service()->ConfigureHttpAuthPrefs(std::move(auth_params));
EXPECT_FALSE(auth_handler_factory->GetSchemeFactory(net::kBasicAuthScheme));
EXPECT_FALSE(auth_handler_factory->GetSchemeFactory(net::kDigestAuthScheme));
EXPECT_FALSE(auth_handler_factory->GetSchemeFactory(net::kNtlmAuthScheme));
@ -249,11 +297,16 @@ TEST_F(NetworkServiceTest, AuthSchemesNone) {
#if BUILDFLAG(USE_EXTERNAL_GSSAPI)
TEST_F(NetworkServiceTest, AuthGssapiLibraryName) {
const std::string kGssapiLibraryName = "Jim";
mojom::HttpAuthStaticParamsPtr auth_params =
mojom::HttpAuthStaticParamsPtr static_auth_params =
mojom::HttpAuthStaticParams::New();
auth_params->supported_schemes.push_back("negotiate");
auth_params->gssapi_library_name = kGssapiLibraryName;
service()->SetUpHttpAuth(std::move(auth_params));
static_auth_params->gssapi_library_name = kGssapiLibraryName;
service()->SetUpHttpAuth(std::move(static_auth_params));
mojom::HttpAuthDynamicParamsPtr dynamic_auth_params =
mojom::HttpAuthDynamicParams::New();
dynamic_auth_params->allowed_schemes =
std::vector<std::string>{net::kNegotiateAuthScheme};
service()->ConfigureHttpAuthPrefs(std::move(dynamic_auth_params));
mojo::Remote<mojom::NetworkContext> network_context_remote;
NetworkContext network_context(

@ -43,10 +43,10 @@ import "services/network/public/mojom/ct_log_info.mojom";
// Values for configuring HTTP authentication that can only be set once.
struct HttpAuthStaticParams {
// List of supported auth schemes. Unrecognized schemes are ignored.
// List of allowed auth schemes. Unrecognized schemes are ignored.
// The default value of this field (an empty list) does not match default
// behavior of NetworkService when no HttpAuthStaticParams is specified.
array<string> supported_schemes;
array<string> allowed_schemes;
// File name the GSSAPI library to load. Only supported on platforms where an
// external GSSAPI library is necessary for Kerberos/SPNEGO support. See the
@ -57,6 +57,9 @@ struct HttpAuthStaticParams {
// Values for configurating HTTP authentication that can be changed as needed.
struct HttpAuthDynamicParams {
// List of allowed auth schemes. Unrecognized schemes are ignored.
array<string>? allowed_schemes;
// Comma / semi-colon delimited allowlist of server origins which the network
// service may send the default credentials for NTLM or Negotiate
// authentication.