diff options
author | danno@chromium.org <danno@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-12 12:47:05 +0000 |
---|---|---|
committer | danno@chromium.org <danno@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-12 12:47:05 +0000 |
commit | ac7f3fdb4987d7f44c1612d55437cfcb3eb263f6 (patch) | |
tree | c017e812bb298f7f2c7341372ab62021df3c8a29 | |
parent | bb33eb1e2468eacb996e19493a36c3f6e4625b12 (diff) | |
download | chromium_src-ac7f3fdb4987d7f44c1612d55437cfcb3eb263f6.zip chromium_src-ac7f3fdb4987d7f44c1612d55437cfcb3eb263f6.tar.gz chromium_src-ac7f3fdb4987d7f44c1612d55437cfcb3eb263f6.tar.bz2 |
Support specifying the GSSAPI library that will be used.
This preference can be set either via command-line or via group policy.
BUG=53625
TEST=unittests: ConfigurationPolicyPrefStore*; net_unittests: HttpAuthHandlerNegotiateTest.*:HttpAuthGSSAPIPOSIXTest.*; manually: start Chrome with command-line switch --gssapi-library-name=XYZ and see if this results in the Chrome process loading /usr/lib/whatever/XYZ as soon as an authenticated HTTP site is encountered.
Review URL: http://codereview.chromium.org/4560001
Patch from Jakob Kummerow <jkummerow@google.com>.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65939 0039d316-1c4b-4281-b951-d872f2087c98
26 files changed, 173 insertions, 115 deletions
diff --git a/chrome/app/policy/policy_templates.grd b/chrome/app/policy/policy_templates.grd index 2448267..08cd727 100644 --- a/chrome/app/policy/policy_templates.grd +++ b/chrome/app/policy/policy_templates.grd @@ -401,6 +401,12 @@ templates and will be translated for each locale. --> <message name="IDS_POLICY_AUTHNEGOTIATEDELEGATEWHITELIST_DESC" desc="Description of the 'auth negotiate delegate whitelist' policy."> Servers that <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> may delegate to. </message> + <message name="IDS_POLICY_GSSAPILIBRARYNAME_CAPTION" desc="Caption of the 'GSSAPI library name' policy"> + GSSAPI library name + </message> + <message name="IDS_POLICY_GSSAPILIBRARYNAME_DESC" desc="Description of the 'GSSAPI library name' policy"> + Specifies which GSSAPI library to use for HTTP Authentication. You can set either just a library name, or a full path. If no setting is provided, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will fall back to using a default library name. + </message> <!-- End HTTP Authentication Policy messages --> <message name="IDS_POLICY_METRICSREPORTINGENABLED_CAPTION" desc="Caption of the 'crash reporting' policy."> diff --git a/chrome/app/policy/policy_templates.json b/chrome/app/policy/policy_templates.json index fa31823..7d06fbd 100644 --- a/chrome/app/policy/policy_templates.json +++ b/chrome/app/policy/policy_templates.json @@ -358,6 +358,16 @@ 'example_value': 'foobar.example.com', } }, + { + 'name': 'GSSAPILibraryName', + 'type': 'string', + 'annotations': { + 'platforms': ['linux', 'mac'], + 'products': ['chrome'], + 'features': {'dynamic_refresh': 0}, + 'example_value': 'libgssapi_krb5.so.2', + } + }, ] }, { diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 9b7f718..65be41e 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -229,6 +229,7 @@ IOThread::IOThread(PrefService* local_state) auth_server_whitelist_ = local_state->GetString(prefs::kAuthServerWhitelist); auth_delegate_whitelist_ = local_state->GetString( prefs::kAuthNegotiateDelegateWhitelist); + gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName); } IOThread::~IOThread() { @@ -428,6 +429,7 @@ void IOThread::RegisterPrefs(PrefService* local_state) { local_state->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort, false); local_state->RegisterStringPref(prefs::kAuthServerWhitelist, ""); local_state->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist, ""); + local_state->RegisterStringPref(prefs::kGSSAPILibraryName, ""); } net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory( @@ -447,6 +449,7 @@ net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory( supported_schemes, globals_->url_security_manager.get(), resolver, + gssapi_library_name_, negotiate_disable_cname_lookup_, negotiate_enable_port_); } diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h index 4bc63cda..d7ba9db 100644 --- a/chrome/browser/io_thread.h +++ b/chrome/browser/io_thread.h @@ -144,6 +144,7 @@ class IOThread : public BrowserProcessSubThread { bool negotiate_enable_port_; std::string auth_server_whitelist_; std::string auth_delegate_whitelist_; + std::string gssapi_library_name_; // These member variables are initialized by a task posted to the IO thread, // which gets posted by calling certain member functions of IOThread. diff --git a/chrome/browser/policy/configuration_policy_pref_store.cc b/chrome/browser/policy/configuration_policy_pref_store.cc index 3d73182..e83887f 100644 --- a/chrome/browser/policy/configuration_policy_pref_store.cc +++ b/chrome/browser/policy/configuration_policy_pref_store.cc @@ -165,6 +165,8 @@ const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry prefs::kAuthServerWhitelist }, { Value::TYPE_STRING, kPolicyAuthNegotiateDelegateWhitelist, prefs::kAuthNegotiateDelegateWhitelist }, + { Value::TYPE_STRING, kPolicyGSSAPILibraryName, + prefs::kGSSAPILibraryName }, #if defined(OS_CHROMEOS) { Value::TYPE_BOOLEAN, kPolicyChromeOsLockOnIdleSuspend, @@ -269,6 +271,9 @@ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() { key::kAuthServerWhitelist }, { kPolicyAuthNegotiateDelegateWhitelist, Value::TYPE_STRING, key::kAuthNegotiateDelegateWhitelist }, + { kPolicyGSSAPILibraryName, Value::TYPE_STRING, + key::kGSSAPILibraryName }, + #if defined(OS_CHROMEOS) { kPolicyChromeOsLockOnIdleSuspend, Value::TYPE_BOOLEAN, diff --git a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc index 1940b73..2595f83 100644 --- a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc +++ b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc @@ -114,7 +114,9 @@ INSTANTIATE_TEST_CASE_P( TypeAndName(kPolicyAuthServerWhitelist, prefs::kAuthServerWhitelist), TypeAndName(kPolicyAuthNegotiateDelegateWhitelist, - prefs::kAuthNegotiateDelegateWhitelist))); + prefs::kAuthNegotiateDelegateWhitelist), + TypeAndName(kPolicyGSSAPILibraryName, + prefs::kGSSAPILibraryName))); // Test cases for boolean-valued policy settings. class ConfigurationPolicyPrefStoreBooleanTest diff --git a/chrome/browser/policy/configuration_policy_store_interface.h b/chrome/browser/policy/configuration_policy_store_interface.h index cd28771..646430b 100644 --- a/chrome/browser/policy/configuration_policy_store_interface.h +++ b/chrome/browser/policy/configuration_policy_store_interface.h @@ -58,7 +58,7 @@ enum ConfigurationPolicyType { kPolicyEnableAuthNegotiatePort, kPolicyAuthServerWhitelist, kPolicyAuthNegotiateDelegateWhitelist, - + kPolicyGSSAPILibraryName, }; static const int kPolicyNoProxyServerMode = 0; diff --git a/chrome/browser/prefs/command_line_pref_store.cc b/chrome/browser/prefs/command_line_pref_store.cc index f5c146d..2bebe5b 100644 --- a/chrome/browser/prefs/command_line_pref_store.cc +++ b/chrome/browser/prefs/command_line_pref_store.cc @@ -20,6 +20,7 @@ const CommandLinePrefStore::StringSwitchToPreferenceMapEntry { switches::kAuthServerWhitelist, prefs::kAuthServerWhitelist }, { switches::kAuthNegotiateDelegateWhitelist, prefs::kAuthNegotiateDelegateWhitelist }, + { switches::kGSSAPILibraryName, prefs::kGSSAPILibraryName }, }; const CommandLinePrefStore::BooleanSwitchToPreferenceMapEntry diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 91d82105..592bcd9 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -639,6 +639,9 @@ const char kGpuProcess[] = "gpu-process"; // Causes the GPU process to display a dialog on launch. const char kGpuStartupDialog[] = "gpu-startup-dialog"; +// Specifies a custom name for the GSSAPI library to load. +const char kGSSAPILibraryName[] = "gssapi-library-name"; + // These flags show the man page on Linux. They are equivalent to each // other. const char kHelp[] = "help"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 34a1986..16e1223 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -188,6 +188,7 @@ extern const char kForceRendererAccessibility[]; extern const char kGpuLauncher[]; extern const char kGpuProcess[]; extern const char kGpuStartupDialog[]; +extern const char kGSSAPILibraryName[]; extern const char kHelp[]; extern const char kHelpShort[]; extern const char kHideIcons[]; diff --git a/chrome/common/policy_constants.cc b/chrome/common/policy_constants.cc index 5eb5998..31b61b2 100644 --- a/chrome/common/policy_constants.cc +++ b/chrome/common/policy_constants.cc @@ -63,6 +63,7 @@ const char kDisableAuthNegotiateCnameLookup[] = const char kEnableAuthNegotiatePort[] = "EnableAuthNegotiatePort"; const char kAuthServerWhitelist[] = "AuthServerWhitelist"; const char kAuthNegotiateDelegateWhitelist[] = "AuthNegotiateDelegateWhitelist"; +const char kGSSAPILibraryName[] = "GSSAPILibraryName"; // Chrome Frame specific policy constants const char kChromeFrameRendererSettings[] = "ChromeFrameRendererSettings"; diff --git a/chrome/common/policy_constants.h b/chrome/common/policy_constants.h index e0244e0..be82cbd 100644 --- a/chrome/common/policy_constants.h +++ b/chrome/common/policy_constants.h @@ -59,6 +59,7 @@ extern const char kDisableAuthNegotiateCnameLookup[]; extern const char kEnableAuthNegotiatePort[]; extern const char kAuthServerWhitelist[]; extern const char kAuthNegotiateDelegateWhitelist[]; +extern const char kGSSAPILibraryName[]; // Chrome Frame specific policy constants extern const char kChromeFrameRendererSettings[]; diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index d809dfd..575b311 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -1041,6 +1041,8 @@ const char kAuthServerWhitelist[] = "auth.server_whitelist"; // with. const char kAuthNegotiateDelegateWhitelist[] = "auth.negotiate_delegate_whitelist"; +// String that specifies the name of a custom GSSAPI library to load. +const char kGSSAPILibraryName[] = "auth.gssapi_library_name"; #if defined(OS_CHROMEOS) // Dictionary for transient storage of settings that should go into signed diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 6200467..190178d 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -405,6 +405,7 @@ extern const char kDisableAuthNegotiateCnameLookup[]; extern const char kEnableAuthNegotiatePort[]; extern const char kAuthServerWhitelist[]; extern const char kAuthNegotiateDelegateWhitelist[]; +extern const char kGSSAPILibraryName[]; } // namespace prefs diff --git a/chrome_frame/metrics_service.cc b/chrome_frame/metrics_service.cc index fd52b8a..eecf468 100644 --- a/chrome_frame/metrics_service.cc +++ b/chrome_frame/metrics_service.cc @@ -42,8 +42,10 @@ #include <atlbase.h> #include <atlwin.h> -#include <windows.h> #include <objbase.h> +#include <windows.h> + +#include <vector> #if defined(USE_SYSTEM_LIBBZ2) #include <bzlib.h> @@ -168,8 +170,8 @@ class ChromeFrameUploadRequestContext : public URLRequestContext { base::SplitString(csv_auth_schemes, ',', &supported_schemes); http_auth_handler_factory_ = net::HttpAuthHandlerRegistryFactory::Create( - supported_schemes, url_security_manager_.get(), host_resolver_, false, - false); + supported_schemes, url_security_manager_.get(), host_resolver_, + std::string(), false, false); http_transaction_factory_ = new net::HttpCache( net::HttpNetworkLayer::CreateFactory(host_resolver_, diff --git a/net/http/http_auth_gssapi_posix.cc b/net/http/http_auth_gssapi_posix.cc index b20ef50..bd2734f 100644 --- a/net/http/http_auth_gssapi_posix.cc +++ b/net/http/http_auth_gssapi_posix.cc @@ -11,7 +11,6 @@ #include "base/file_path.h" #include "base/format_macros.h" #include "base/logging.h" -#include "base/singleton.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "net/base/net_errors.h" @@ -385,8 +384,9 @@ std::string DescribeContext(GSSAPILibrary* gssapi_lib, } // namespace -GSSAPISharedLibrary::GSSAPISharedLibrary() +GSSAPISharedLibrary::GSSAPISharedLibrary(const std::string& gssapi_library_name) : initialized_(false), + gssapi_library_name_(gssapi_library_name), gssapi_library_(NULL), import_name_(NULL), release_name_(NULL), @@ -422,19 +422,29 @@ bool GSSAPISharedLibrary::InitImpl() { } base::NativeLibrary GSSAPISharedLibrary::LoadSharedLibrary() { - static const char* kLibraryNames[] = { + const char** library_names; + size_t num_lib_names; + const char* user_specified_library[1]; + if (!gssapi_library_name_.empty()) { + user_specified_library[0] = gssapi_library_name_.c_str(); + library_names = user_specified_library; + num_lib_names = 1; + } else { + static const char* kDefaultLibraryNames[] = { #if defined(OS_MACOSX) - "libgssapi_krb5.dylib" // MIT Kerberos + "libgssapi_krb5.dylib" // MIT Kerberos #else - "libgssapi_krb5.so.2", // MIT Kerberos - FC, Suse10, Debian - "libgssapi.so.4", // Heimdal - Suse10, MDK - "libgssapi.so.1" // Heimdal - Suse9, CITI - FC, MDK, Suse10 + "libgssapi_krb5.so.2", // MIT Kerberos - FC, Suse10, Debian + "libgssapi.so.4", // Heimdal - Suse10, MDK + "libgssapi.so.1" // Heimdal - Suse9, CITI - FC, MDK, Suse10 #endif - }; - static size_t num_lib_names = arraysize(kLibraryNames); + }; + library_names = kDefaultLibraryNames; + num_lib_names = arraysize(kDefaultLibraryNames); + } for (size_t i = 0; i < num_lib_names; ++i) { - const char* library_name = kLibraryNames[i]; + const char* library_name = library_names[i]; FilePath file_path(library_name); base::NativeLibrary lib = base::LoadNativeLibrary(file_path); if (lib) { @@ -613,9 +623,6 @@ OM_uint32 GSSAPISharedLibrary::inquire_context( locally_initiated, open); } -GSSAPILibrary* GSSAPILibrary::GetDefault() { - return Singleton<GSSAPISharedLibrary>::get(); -} ScopedSecurityContext::ScopedSecurityContext(GSSAPILibrary* gssapi_lib) : security_context_(GSS_C_NO_CONTEXT), diff --git a/net/http/http_auth_gssapi_posix.h b/net/http/http_auth_gssapi_posix.h index 3ea1131..9b1d0ed 100644 --- a/net/http/http_auth_gssapi_posix.h +++ b/net/http/http_auth_gssapi_posix.h @@ -95,15 +95,14 @@ class GSSAPILibrary { int* locally_initiated, int* open) = 0; - // Get the default GSSPILibrary instance. The object returned is a singleton - // instance, and the caller should not delete it. - static GSSAPILibrary* GetDefault(); }; // GSSAPISharedLibrary class is defined here so that unit tests can access it. class GSSAPISharedLibrary : public GSSAPILibrary { public: - GSSAPISharedLibrary(); + // If |gssapi_library_name| is empty, hard-coded default library names are + // used. + explicit GSSAPISharedLibrary(const std::string& gssapi_library_name); virtual ~GSSAPISharedLibrary(); // GSSAPILibrary methods: @@ -179,6 +178,7 @@ class GSSAPISharedLibrary : public GSSAPILibrary { bool initialized_; + std::string gssapi_library_name_; // Need some way to invalidate the library. base::NativeLibrary gssapi_library_; diff --git a/net/http/http_auth_gssapi_posix_unittest.cc b/net/http/http_auth_gssapi_posix_unittest.cc index 62bae71..f83acb4 100644 --- a/net/http/http_auth_gssapi_posix_unittest.cc +++ b/net/http/http_auth_gssapi_posix_unittest.cc @@ -76,9 +76,15 @@ TEST(HttpAuthGSSAPIPOSIXTest, GSSAPIStartup) { // TODO(ahendrickson): Manipulate the libraries and paths to test each of the // libraries we expect, and also whether or not they have the interface // functions we want. - GSSAPILibrary* gssapi = GSSAPILibrary::GetDefault(); - DCHECK(gssapi); - gssapi->Init(); + scoped_ptr<GSSAPILibrary> gssapi(new GSSAPISharedLibrary("")); + DCHECK(gssapi.get()); + DCHECK(gssapi.get()->Init()); +} + +TEST(HttpAuthGSSAPIPOSIXTest, GSSAPILoadCustomLibrary) { + scoped_ptr<GSSAPILibrary> gssapi( + new GSSAPISharedLibrary("/this/library/does/not/exist")); + DCHECK(!gssapi.get()->Init()); } TEST(HttpAuthGSSAPIPOSIXTest, GSSAPICycle) { diff --git a/net/http/http_auth_handler_factory.cc b/net/http/http_auth_handler_factory.cc index d001fd4..7d34cff 100644 --- a/net/http/http_auth_handler_factory.cc +++ b/net/http/http_auth_handler_factory.cc @@ -48,12 +48,23 @@ HttpAuthHandlerRegistryFactory* HttpAuthHandlerFactory::CreateDefault( "basic", new HttpAuthHandlerBasic::Factory()); registry_factory->RegisterSchemeFactory( "digest", new HttpAuthHandlerDigest::Factory()); + HttpAuthHandlerNegotiate::Factory* negotiate_factory = new HttpAuthHandlerNegotiate::Factory(); +#if defined(OS_POSIX) + negotiate_factory->set_library(new GSSAPISharedLibrary(std::string())); +#elif defined(OS_WIN) + negotiate_factory->set_library(new SSPILibraryDefault()); +#endif negotiate_factory->set_host_resolver(host_resolver); registry_factory->RegisterSchemeFactory("negotiate", negotiate_factory); - registry_factory->RegisterSchemeFactory( - "ntlm", new HttpAuthHandlerNTLM::Factory()); + + HttpAuthHandlerNTLM::Factory* ntlm_factory = + new HttpAuthHandlerNTLM::Factory(); +#if defined(OS_WIN) + ntlm_factory->set_sspi_library(new SSPILibraryDefault()); +#endif + registry_factory->RegisterSchemeFactory("ntlm", ntlm_factory); return registry_factory; } @@ -73,6 +84,7 @@ HttpAuthHandlerRegistryFactory* HttpAuthHandlerRegistryFactory::Create( const std::vector<std::string>& supported_schemes, URLSecurityManager* security_manager, HostResolver* host_resolver, + const std::string& gssapi_library_name, bool negotiate_disable_cname_lookup, bool negotiate_enable_port) { HttpAuthHandlerRegistryFactory* registry_factory = @@ -87,11 +99,20 @@ HttpAuthHandlerRegistryFactory* HttpAuthHandlerRegistryFactory::Create( HttpAuthHandlerNTLM::Factory* ntlm_factory = new HttpAuthHandlerNTLM::Factory(); ntlm_factory->set_url_security_manager(security_manager); +#if defined(OS_WIN) + ntlm_factory->set_sspi_library(new SSPILibraryDefault()); +#endif registry_factory->RegisterSchemeFactory("ntlm", ntlm_factory); } if (IsSupportedScheme(supported_schemes, "negotiate")) { HttpAuthHandlerNegotiate::Factory* negotiate_factory = new HttpAuthHandlerNegotiate::Factory(); +#if defined(OS_POSIX) + negotiate_factory->set_library( + new GSSAPISharedLibrary(gssapi_library_name)); +#elif defined(OS_WIN) + negotiate_factory->set_library(new SSPILibraryDefault()); +#endif negotiate_factory->set_url_security_manager(security_manager); DCHECK(host_resolver || negotiate_disable_cname_lookup); negotiate_factory->set_host_resolver(host_resolver); diff --git a/net/http/http_auth_handler_factory.h b/net/http/http_auth_handler_factory.h index da6bad8..16e60c4 100644 --- a/net/http/http_auth_handler_factory.h +++ b/net/http/http_auth_handler_factory.h @@ -174,12 +174,16 @@ class HttpAuthHandlerRegistryFactory : public HttpAuthHandlerFactory { // scheme is used and |negotiate_disable_cname_lookup| is false, // |host_resolver| must not be NULL. // + // |gssapi_library_name| specifies the name of the GSSAPI library that will + // be loaded on all platforms except Windows. + // // |negotiate_disable_cname_lookup| and |negotiate_enable_port| both control // how Negotiate does SPN generation, by default these should be false. static HttpAuthHandlerRegistryFactory* Create( const std::vector<std::string>& supported_schemes, URLSecurityManager* security_manager, HostResolver* host_resolver, + const std::string& gssapi_library_name, bool negotiate_disable_cname_lookup, bool negotiate_enable_port); diff --git a/net/http/http_auth_handler_negotiate.cc b/net/http/http_auth_handler_negotiate.cc index 99abdf6..0fce354 100644 --- a/net/http/http_auth_handler_negotiate.cc +++ b/net/http/http_auth_handler_negotiate.cc @@ -274,10 +274,8 @@ HttpAuthHandlerNegotiate::Factory::Factory() max_token_length_(0), first_creation_(true), is_unsupported_(false), - auth_library_(SSPILibrary::GetDefault()) { -#elif defined(OS_POSIX) - auth_library_(GSSAPILibrary::GetDefault()) { #endif + auth_library_(NULL) { } HttpAuthHandlerNegotiate::Factory::~Factory() { @@ -300,7 +298,7 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( if (is_unsupported_ || reason == CREATE_PREEMPTIVE) return ERR_UNSUPPORTED_AUTH_SCHEME; if (max_token_length_ == 0) { - int rv = DetermineMaxTokenLength(auth_library_, NEGOSSP_NAME, + int rv = DetermineMaxTokenLength(auth_library_.get(), NEGOSSP_NAME, &max_token_length_); if (rv == ERR_UNSUPPORTED_AUTH_SCHEME) is_unsupported_ = true; @@ -310,7 +308,7 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( // TODO(cbentzel): Move towards model of parsing in the factory // method and only constructing when valid. scoped_ptr<HttpAuthHandler> tmp_handler( - new HttpAuthHandlerNegotiate(auth_library_, max_token_length_, + new HttpAuthHandlerNegotiate(auth_library_.get(), max_token_length_, url_security_manager(), resolver_, disable_cname_lookup_, use_port_)); if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) @@ -321,7 +319,7 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( // TODO(ahendrickson): Move towards model of parsing in the factory // method and only constructing when valid. scoped_ptr<HttpAuthHandler> tmp_handler( - new HttpAuthHandlerNegotiate(auth_library_, url_security_manager(), + new HttpAuthHandlerNegotiate(auth_library_.get(), url_security_manager(), resolver_, disable_cname_lookup_, use_port_)); if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) diff --git a/net/http/http_auth_handler_negotiate.h b/net/http/http_auth_handler_negotiate.h index 5f46ab1..a19d182 100644 --- a/net/http/http_auth_handler_negotiate.h +++ b/net/http/http_auth_handler_negotiate.h @@ -72,14 +72,10 @@ class HttpAuthHandlerNegotiate : public HttpAuthHandler { const BoundNetLog& net_log, scoped_ptr<HttpAuthHandler>* handler); - // Set the system library to use. Typically the only callers which need to - // use this are unit tests which pass in a mocked-out version of the - // system library. - // The caller is responsible for managing the lifetime of |*auth_library|, - // and the lifetime must exceed that of this Factory object and all - // HttpAuthHandler's that this Factory object creates. + // Sets the system library to use, thereby assuming ownership of + // |auth_library|. void set_library(AuthLibrary* auth_library) { - auth_library_ = auth_library; + auth_library_.reset(auth_library); } private: @@ -91,7 +87,7 @@ class HttpAuthHandlerNegotiate : public HttpAuthHandler { bool first_creation_; bool is_unsupported_; #endif - AuthLibrary* auth_library_; + scoped_ptr<AuthLibrary> auth_library_; }; HttpAuthHandlerNegotiate(AuthLibrary* sspi_library, diff --git a/net/http/http_auth_handler_negotiate_unittest.cc b/net/http/http_auth_handler_negotiate_unittest.cc index 9f87f78..684ff55 100644 --- a/net/http/http_auth_handler_negotiate_unittest.cc +++ b/net/http/http_auth_handler_negotiate_unittest.cc @@ -31,7 +31,7 @@ namespace net { class HttpAuthHandlerNegotiateTest : public PlatformTest { public: virtual void SetUp() { - auth_library_.reset(new MockAuthLibrary()); + auth_library_ = new MockAuthLibrary(); resolver_.reset(new MockHostResolver()); resolver_->rules()->AddIPLiteralRule("alias", "10.0.0.2", "canonical.example.com"); @@ -39,7 +39,7 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest { url_security_manager_.reset(new URLSecurityManagerAllow()); factory_.reset(new HttpAuthHandlerNegotiate::Factory()); factory_->set_url_security_manager(url_security_manager_.get()); - factory_->set_library(auth_library_.get()); + factory_->set_library(auth_library_); factory_->set_host_resolver(resolver_.get()); } @@ -205,13 +205,14 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest { return rv; } - MockAuthLibrary* AuthLibrary() { return auth_library_.get(); } + MockAuthLibrary* AuthLibrary() { return auth_library_; } private: #if defined(OS_WIN) scoped_ptr<SecPkgInfoW> security_package_; #endif - scoped_ptr<MockAuthLibrary> auth_library_; + // |auth_library_| is passed to |factory_|, which assumes ownership of it. + MockAuthLibrary* auth_library_; scoped_ptr<MockHostResolver> resolver_; scoped_ptr<URLSecurityManager> url_security_manager_; scoped_ptr<HttpAuthHandlerNegotiate::Factory> factory_; diff --git a/net/http/http_auth_handler_ntlm_win.cc b/net/http/http_auth_handler_ntlm_win.cc index 1b7d1ac..684f29d 100644 --- a/net/http/http_auth_handler_ntlm_win.cc +++ b/net/http/http_auth_handler_ntlm_win.cc @@ -46,7 +46,7 @@ HttpAuthHandlerNTLM::Factory::Factory() : max_token_length_(0), first_creation_(true), is_unsupported_(false), - sspi_library_(SSPILibrary::GetDefault()) { + sspi_library_(NULL) { } HttpAuthHandlerNTLM::Factory::~Factory() { diff --git a/net/http/http_auth_sspi_win.cc b/net/http/http_auth_sspi_win.cc index d6fedf9..c5264cd 100644 --- a/net/http/http_auth_sspi_win.cc +++ b/net/http/http_auth_sspi_win.cc @@ -9,7 +9,6 @@ #include "base/base64.h" #include "base/logging.h" -#include "base/singleton.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "net/base/net_errors.h" @@ -425,68 +424,4 @@ int DetermineMaxTokenLength(SSPILibrary* library, return OK; } -class SSPILibraryDefault : public SSPILibrary { - public: - SSPILibraryDefault() {} - virtual ~SSPILibraryDefault() {} - - virtual SECURITY_STATUS AcquireCredentialsHandle(LPWSTR pszPrincipal, - LPWSTR pszPackage, - unsigned long fCredentialUse, - void* pvLogonId, - void* pvAuthData, - SEC_GET_KEY_FN pGetKeyFn, - void* pvGetKeyArgument, - PCredHandle phCredential, - PTimeStamp ptsExpiry) { - return ::AcquireCredentialsHandle(pszPrincipal, pszPackage, fCredentialUse, - pvLogonId, pvAuthData, pGetKeyFn, - pvGetKeyArgument, phCredential, - ptsExpiry); - } - - virtual SECURITY_STATUS InitializeSecurityContext(PCredHandle phCredential, - PCtxtHandle phContext, - SEC_WCHAR* pszTargetName, - unsigned long fContextReq, - unsigned long Reserved1, - unsigned long TargetDataRep, - PSecBufferDesc pInput, - unsigned long Reserved2, - PCtxtHandle phNewContext, - PSecBufferDesc pOutput, - unsigned long* contextAttr, - PTimeStamp ptsExpiry) { - return ::InitializeSecurityContext(phCredential, phContext, pszTargetName, - fContextReq, Reserved1, TargetDataRep, - pInput, Reserved2, phNewContext, pOutput, - contextAttr, ptsExpiry); - } - - virtual SECURITY_STATUS QuerySecurityPackageInfo(LPWSTR pszPackageName, - PSecPkgInfoW *pkgInfo) { - return ::QuerySecurityPackageInfo(pszPackageName, pkgInfo); - } - - virtual SECURITY_STATUS FreeCredentialsHandle(PCredHandle phCredential) { - return ::FreeCredentialsHandle(phCredential); - } - - virtual SECURITY_STATUS DeleteSecurityContext(PCtxtHandle phContext) { - return ::DeleteSecurityContext(phContext); - } - - virtual SECURITY_STATUS FreeContextBuffer(PVOID pvContextBuffer) { - return ::FreeContextBuffer(pvContextBuffer); - } - - private: - friend struct DefaultSingletonTraits<SSPILibraryDefault>; -}; - -// static -SSPILibrary* SSPILibrary::GetDefault() { - return Singleton<SSPILibraryDefault>::get(); -} - } // namespace net diff --git a/net/http/http_auth_sspi_win.h b/net/http/http_auth_sspi_win.h index c4df58e..f56df8e 100644 --- a/net/http/http_auth_sspi_win.h +++ b/net/http/http_auth_sspi_win.h @@ -63,11 +63,62 @@ class SSPILibrary { virtual SECURITY_STATUS DeleteSecurityContext(PCtxtHandle phContext) = 0; virtual SECURITY_STATUS FreeContextBuffer(PVOID pvContextBuffer) = 0; +}; + +class SSPILibraryDefault : public SSPILibrary { + public: + SSPILibraryDefault() {} + virtual ~SSPILibraryDefault() {} + + virtual SECURITY_STATUS AcquireCredentialsHandle(LPWSTR pszPrincipal, + LPWSTR pszPackage, + unsigned long fCredentialUse, + void* pvLogonId, + void* pvAuthData, + SEC_GET_KEY_FN pGetKeyFn, + void* pvGetKeyArgument, + PCredHandle phCredential, + PTimeStamp ptsExpiry) { + return ::AcquireCredentialsHandle(pszPrincipal, pszPackage, fCredentialUse, + pvLogonId, pvAuthData, pGetKeyFn, + pvGetKeyArgument, phCredential, + ptsExpiry); + } + + virtual SECURITY_STATUS InitializeSecurityContext(PCredHandle phCredential, + PCtxtHandle phContext, + SEC_WCHAR* pszTargetName, + unsigned long fContextReq, + unsigned long Reserved1, + unsigned long TargetDataRep, + PSecBufferDesc pInput, + unsigned long Reserved2, + PCtxtHandle phNewContext, + PSecBufferDesc pOutput, + unsigned long* contextAttr, + PTimeStamp ptsExpiry) { + return ::InitializeSecurityContext(phCredential, phContext, pszTargetName, + fContextReq, Reserved1, TargetDataRep, + pInput, Reserved2, phNewContext, pOutput, + contextAttr, ptsExpiry); + } + + virtual SECURITY_STATUS QuerySecurityPackageInfo(LPWSTR pszPackageName, + PSecPkgInfoW *pkgInfo) { + return ::QuerySecurityPackageInfo(pszPackageName, pkgInfo); + } + + virtual SECURITY_STATUS FreeCredentialsHandle(PCredHandle phCredential) { + return ::FreeCredentialsHandle(phCredential); + } + + virtual SECURITY_STATUS DeleteSecurityContext(PCtxtHandle phContext) { + return ::DeleteSecurityContext(phContext); + } - // Get the default SSPILibrary instance, which simply acts as a passthrough - // to the Windows SSPI implementation. The object returned is a singleton - // instance, and the caller should not delete it. - static SSPILibrary* GetDefault(); + virtual SECURITY_STATUS FreeContextBuffer(PVOID pvContextBuffer) { + return ::FreeContextBuffer(pvContextBuffer); + } }; class HttpAuthSSPI { |