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 /net/http | |
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
Diffstat (limited to 'net/http')
-rw-r--r-- | net/http/http_auth_gssapi_posix.cc | 33 | ||||
-rw-r--r-- | net/http/http_auth_gssapi_posix.h | 8 | ||||
-rw-r--r-- | net/http/http_auth_gssapi_posix_unittest.cc | 12 | ||||
-rw-r--r-- | net/http/http_auth_handler_factory.cc | 25 | ||||
-rw-r--r-- | net/http/http_auth_handler_factory.h | 4 | ||||
-rw-r--r-- | net/http/http_auth_handler_negotiate.cc | 10 | ||||
-rw-r--r-- | net/http/http_auth_handler_negotiate.h | 12 | ||||
-rw-r--r-- | net/http/http_auth_handler_negotiate_unittest.cc | 9 | ||||
-rw-r--r-- | net/http/http_auth_handler_ntlm_win.cc | 2 | ||||
-rw-r--r-- | net/http/http_auth_sspi_win.cc | 65 | ||||
-rw-r--r-- | net/http/http_auth_sspi_win.h | 59 |
11 files changed, 129 insertions, 110 deletions
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 { |