http_auth_handler_factory.cc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. // Copyright (c) 2010 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.
  4. #include "net/http/http_auth_handler_factory.h"
  5. #include <set>
  6. #include "base/containers/contains.h"
  7. #include "base/memory/ptr_util.h"
  8. #include "base/strings/string_util.h"
  9. #include "build/build_config.h"
  10. #include "net/base/net_errors.h"
  11. #include "net/dns/host_resolver.h"
  12. #include "net/http/http_auth_challenge_tokenizer.h"
  13. #include "net/http/http_auth_filter.h"
  14. #include "net/http/http_auth_handler_basic.h"
  15. #include "net/http/http_auth_handler_digest.h"
  16. #include "net/http/http_auth_handler_ntlm.h"
  17. #include "net/http/http_auth_preferences.h"
  18. #include "net/http/http_auth_scheme.h"
  19. #include "net/log/net_log_values.h"
  20. #include "net/net_buildflags.h"
  21. #include "net/ssl/ssl_info.h"
  22. #include "third_party/abseil-cpp/absl/types/optional.h"
  23. #include "url/scheme_host_port.h"
  24. #if BUILDFLAG(USE_KERBEROS)
  25. #include "net/http/http_auth_handler_negotiate.h"
  26. #endif
  27. namespace {
  28. base::Value NetLogParamsForCreateAuth(
  29. const std::string& scheme,
  30. const std::string& challenge,
  31. const int net_error,
  32. const url::SchemeHostPort& scheme_host_port,
  33. const absl::optional<bool>& allows_default_credentials,
  34. net::NetLogCaptureMode capture_mode) {
  35. base::Value::Dict dict;
  36. dict.Set("scheme", net::NetLogStringValue(scheme));
  37. if (net::NetLogCaptureIncludesSensitive(capture_mode))
  38. dict.Set("challenge", net::NetLogStringValue(challenge));
  39. dict.Set("origin", scheme_host_port.Serialize());
  40. if (allows_default_credentials)
  41. dict.Set("allows_default_credentials", *allows_default_credentials);
  42. if (net_error < 0)
  43. dict.Set("net_error", net_error);
  44. return base::Value(std::move(dict));
  45. }
  46. } // namespace
  47. namespace net {
  48. int HttpAuthHandlerFactory::CreateAuthHandlerFromString(
  49. const std::string& challenge,
  50. HttpAuth::Target target,
  51. const SSLInfo& ssl_info,
  52. const NetworkIsolationKey& network_isolation_key,
  53. const url::SchemeHostPort& scheme_host_port,
  54. const NetLogWithSource& net_log,
  55. HostResolver* host_resolver,
  56. std::unique_ptr<HttpAuthHandler>* handler) {
  57. HttpAuthChallengeTokenizer props(challenge.begin(), challenge.end());
  58. return CreateAuthHandler(&props, target, ssl_info, network_isolation_key,
  59. scheme_host_port, CREATE_CHALLENGE, 1, net_log,
  60. host_resolver, handler);
  61. }
  62. int HttpAuthHandlerFactory::CreatePreemptiveAuthHandlerFromString(
  63. const std::string& challenge,
  64. HttpAuth::Target target,
  65. const NetworkIsolationKey& network_isolation_key,
  66. const url::SchemeHostPort& scheme_host_port,
  67. int digest_nonce_count,
  68. const NetLogWithSource& net_log,
  69. HostResolver* host_resolver,
  70. std::unique_ptr<HttpAuthHandler>* handler) {
  71. HttpAuthChallengeTokenizer props(challenge.begin(), challenge.end());
  72. SSLInfo null_ssl_info;
  73. return CreateAuthHandler(&props, target, null_ssl_info, network_isolation_key,
  74. scheme_host_port, CREATE_PREEMPTIVE,
  75. digest_nonce_count, net_log, host_resolver, handler);
  76. }
  77. HttpAuthHandlerRegistryFactory::HttpAuthHandlerRegistryFactory(
  78. const HttpAuthPreferences* http_auth_preferences) {
  79. set_http_auth_preferences(http_auth_preferences);
  80. }
  81. HttpAuthHandlerRegistryFactory::~HttpAuthHandlerRegistryFactory() = default;
  82. void HttpAuthHandlerRegistryFactory::SetHttpAuthPreferences(
  83. const std::string& scheme,
  84. const HttpAuthPreferences* prefs) {
  85. HttpAuthHandlerFactory* factory = GetSchemeFactory(scheme);
  86. if (factory)
  87. factory->set_http_auth_preferences(prefs);
  88. }
  89. void HttpAuthHandlerRegistryFactory::RegisterSchemeFactory(
  90. const std::string& scheme,
  91. std::unique_ptr<HttpAuthHandlerFactory> factory) {
  92. std::string lower_scheme = base::ToLowerASCII(scheme);
  93. if (factory) {
  94. factory->set_http_auth_preferences(http_auth_preferences());
  95. factory_map_[lower_scheme] = std::move(factory);
  96. } else {
  97. factory_map_.erase(lower_scheme);
  98. }
  99. }
  100. // static
  101. std::unique_ptr<HttpAuthHandlerRegistryFactory>
  102. HttpAuthHandlerFactory::CreateDefault(
  103. const HttpAuthPreferences* prefs
  104. #if BUILDFLAG(USE_EXTERNAL_GSSAPI)
  105. ,
  106. const std::string& gssapi_library_name
  107. #endif
  108. #if BUILDFLAG(USE_KERBEROS)
  109. ,
  110. HttpAuthMechanismFactory negotiate_auth_system_factory
  111. #endif
  112. ) {
  113. return HttpAuthHandlerRegistryFactory::Create(prefs
  114. #if BUILDFLAG(USE_EXTERNAL_GSSAPI)
  115. ,
  116. gssapi_library_name
  117. #endif
  118. #if BUILDFLAG(USE_KERBEROS)
  119. ,
  120. negotiate_auth_system_factory
  121. #endif
  122. );
  123. }
  124. // static
  125. std::unique_ptr<HttpAuthHandlerRegistryFactory>
  126. HttpAuthHandlerRegistryFactory::Create(
  127. const HttpAuthPreferences* prefs
  128. #if BUILDFLAG(USE_EXTERNAL_GSSAPI)
  129. ,
  130. const std::string& gssapi_library_name
  131. #endif
  132. #if BUILDFLAG(USE_KERBEROS)
  133. ,
  134. HttpAuthMechanismFactory negotiate_auth_system_factory
  135. #endif
  136. ) {
  137. auto registry_factory =
  138. std::make_unique<HttpAuthHandlerRegistryFactory>(prefs);
  139. registry_factory->RegisterSchemeFactory(
  140. kBasicAuthScheme, std::make_unique<HttpAuthHandlerBasic::Factory>());
  141. registry_factory->RegisterSchemeFactory(
  142. kDigestAuthScheme, std::make_unique<HttpAuthHandlerDigest::Factory>());
  143. auto ntlm_factory = std::make_unique<HttpAuthHandlerNTLM::Factory>();
  144. #if BUILDFLAG(IS_WIN)
  145. ntlm_factory->set_sspi_library(
  146. std::make_unique<SSPILibraryDefault>(NTLMSP_NAME));
  147. #endif // BUILDFLAG(IS_WIN)
  148. registry_factory->RegisterSchemeFactory(kNtlmAuthScheme,
  149. std::move(ntlm_factory));
  150. #if BUILDFLAG(USE_KERBEROS)
  151. auto negotiate_factory = std::make_unique<HttpAuthHandlerNegotiate::Factory>(
  152. negotiate_auth_system_factory);
  153. #if BUILDFLAG(IS_WIN)
  154. negotiate_factory->set_library(
  155. std::make_unique<SSPILibraryDefault>(NEGOSSP_NAME));
  156. #elif BUILDFLAG(USE_EXTERNAL_GSSAPI)
  157. negotiate_factory->set_library(
  158. std::make_unique<GSSAPISharedLibrary>(gssapi_library_name));
  159. #endif
  160. registry_factory->RegisterSchemeFactory(kNegotiateAuthScheme,
  161. std::move(negotiate_factory));
  162. #endif // BUILDFLAG(USE_KERBEROS)
  163. if (prefs) {
  164. registry_factory->set_http_auth_preferences(prefs);
  165. for (auto& factory_entry : registry_factory->factory_map_) {
  166. factory_entry.second->set_http_auth_preferences(prefs);
  167. }
  168. }
  169. return registry_factory;
  170. }
  171. int HttpAuthHandlerRegistryFactory::CreateAuthHandler(
  172. HttpAuthChallengeTokenizer* challenge,
  173. HttpAuth::Target target,
  174. const SSLInfo& ssl_info,
  175. const NetworkIsolationKey& network_isolation_key,
  176. const url::SchemeHostPort& scheme_host_port,
  177. CreateReason reason,
  178. int digest_nonce_count,
  179. const NetLogWithSource& net_log,
  180. HostResolver* host_resolver,
  181. std::unique_ptr<HttpAuthHandler>* handler) {
  182. auto scheme = challenge->auth_scheme();
  183. int net_error;
  184. if (scheme.empty()) {
  185. handler->reset();
  186. net_error = ERR_INVALID_RESPONSE;
  187. } else {
  188. bool all_schemes_allowed_for_origin =
  189. http_auth_preferences() &&
  190. http_auth_preferences()->IsAllowedToUseAllHttpAuthSchemes(
  191. scheme_host_port);
  192. auto* factory = all_schemes_allowed_for_origin || IsSchemeAllowed(scheme)
  193. ? GetSchemeFactory(scheme)
  194. : nullptr;
  195. if (!factory) {
  196. handler->reset();
  197. net_error = ERR_UNSUPPORTED_AUTH_SCHEME;
  198. } else {
  199. net_error = factory->CreateAuthHandler(
  200. challenge, target, ssl_info, network_isolation_key, scheme_host_port,
  201. reason, digest_nonce_count, net_log, host_resolver, handler);
  202. }
  203. }
  204. net_log.AddEvent(
  205. NetLogEventType::AUTH_HANDLER_CREATE_RESULT,
  206. [&](NetLogCaptureMode capture_mode) {
  207. return NetLogParamsForCreateAuth(
  208. scheme, challenge->challenge_text(), net_error, scheme_host_port,
  209. *handler
  210. ? absl::make_optional((*handler)->AllowsDefaultCredentials())
  211. : absl::nullopt,
  212. capture_mode);
  213. });
  214. return net_error;
  215. }
  216. bool HttpAuthHandlerRegistryFactory::IsSchemeAllowedForTesting(
  217. const std::string& scheme) const {
  218. return IsSchemeAllowed(scheme);
  219. }
  220. bool HttpAuthHandlerRegistryFactory::IsSchemeAllowed(
  221. const std::string& scheme) const {
  222. const std::set<std::string>& allowed_schemes =
  223. http_auth_preferences() && http_auth_preferences()->allowed_schemes()
  224. ? *http_auth_preferences()->allowed_schemes()
  225. : default_auth_schemes_;
  226. return allowed_schemes.find(scheme) != allowed_schemes.end();
  227. }
  228. #if BUILDFLAG(USE_KERBEROS) && !BUILDFLAG(IS_ANDROID) && BUILDFLAG(IS_POSIX)
  229. absl::optional<std::string>
  230. HttpAuthHandlerRegistryFactory::GetNegotiateLibraryNameForTesting() const {
  231. if (!IsSchemeAllowed(kNegotiateAuthScheme))
  232. return absl::nullopt;
  233. return reinterpret_cast<net::HttpAuthHandlerNegotiate::Factory*>(
  234. GetSchemeFactory(net::kNegotiateAuthScheme))
  235. ->GetLibraryNameForTesting(); // IN-TEST
  236. }
  237. #endif
  238. HttpAuthHandlerFactory* HttpAuthHandlerRegistryFactory::GetSchemeFactory(
  239. const std::string& scheme) const {
  240. std::string lower_scheme = base::ToLowerASCII(scheme);
  241. auto it = factory_map_.find(lower_scheme);
  242. if (it == factory_map_.end()) {
  243. return nullptr; // |scheme| is not registered.
  244. }
  245. return it->second.get();
  246. }
  247. } // namespace net