From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jeremy Apthorp Date: Tue, 12 Nov 2019 11:50:16 -0800 Subject: add TrustedAuthClient to URLLoaderFactory This allows intercepting authentication requests for the 'net' module. Without this, the 'login' event for electron.net.ClientRequest can't be implemented, because the existing path checks for the presence of a WebContents, and cancels the authentication if there's no WebContents available, which there isn't in the case of the 'net' module. diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index b98cb1c863c72f631adad78dcb4c6412b42e8680..2d964693da7f9f2ea351f24c28ba04953988f9b1 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom @@ -193,6 +193,25 @@ struct HttpAuthStaticNetworkContextParams { = DefaultCredentials.ALLOW_DEFAULT_CREDENTIALS; }; +interface TrustedAuthClient { + OnAuthRequired( + mojo_base.mojom.UnguessableToken? window_id, + uint32 process_id, + uint32 routing_id, + uint32 request_id, + url.mojom.Url url, + bool first_auth_attempt, + AuthChallengeInfo auth_info, + URLResponseHead? head, + pending_remote auth_challenge_responder); +}; +interface TrustedURLLoaderAuthClient { + // When a new URLLoader is created, this will be called to pass a + // corresponding |auth_client|. + OnLoaderCreated(int32 request_id, + pending_receiver auth_client); +}; + interface CertVerifierClient { Verify( int32 default_error, @@ -633,6 +652,8 @@ struct URLLoaderFactoryParams { // interface. This still respects the per-context block lists. CorsOriginAccessPatterns? factory_bound_access_patterns; + pending_remote? auth_client; + // Key used to isolate shared network resources like the cache. NetworkIsolationKey? network_isolation_key; diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index e8c902a95d23d785dad4d5920831337ad24c359c..dcb1421169062978b28ac0ea40f1fd63cc26c889 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc @@ -483,6 +483,7 @@ URLLoader::URLLoader( base::WeakPtr keepalive_statistics_recorder, base::WeakPtr network_usage_accumulator, mojom::TrustedURLLoaderHeaderClient* url_loader_header_client, + mojom::TrustedURLLoaderAuthClient* url_loader_auth_client, mojom::OriginPolicyManager* origin_policy_manager) : url_request_context_(url_request_context), network_service_client_(network_service_client), @@ -545,6 +546,11 @@ URLLoader::URLLoader( header_client_.set_disconnect_handler( base::BindOnce(&URLLoader::OnMojoDisconnect, base::Unretained(this))); } + if (url_loader_auth_client) { + url_loader_auth_client->OnLoaderCreated(request_id_, auth_client_.BindNewPipeAndPassReceiver()); + auth_client_.set_disconnect_handler( + base::BindOnce(&URLLoader::OnMojoDisconnect, base::Unretained(this))); + } if (want_raw_headers_) { options_ |= mojom::kURLLoadOptionSendSSLInfoWithResponse | mojom::kURLLoadOptionSendSSLInfoForCertificateError; @@ -980,7 +986,7 @@ void URLLoader::OnReceivedRedirect(net::URLRequest* url_request, void URLLoader::OnAuthRequired(net::URLRequest* url_request, const net::AuthChallengeInfo& auth_info) { - if (!network_context_client_) { + if (!network_context_client_ && !auth_client_) { OnAuthCredentials(base::nullopt); return; } @@ -996,11 +1002,20 @@ void URLLoader::OnAuthRequired(net::URLRequest* url_request, if (url_request->response_headers()) head->headers = url_request->response_headers(); head->auth_challenge_info = auth_info; - network_context_client_->OnAuthRequired( - fetch_window_id_, factory_params_->process_id, render_frame_id_, - request_id_, url_request_->url(), first_auth_attempt_, auth_info, - std::move(head), - auth_challenge_responder_receiver_.BindNewPipeAndPassRemote()); + + if (auth_client_) { + auth_client_->OnAuthRequired( + fetch_window_id_, factory_params_->process_id, render_frame_id_, + request_id_, url_request_->url(), first_auth_attempt_, auth_info, + std::move(head), + auth_challenge_responder_receiver_.BindNewPipeAndPassRemote()); + } else { + network_context_client_->OnAuthRequired( + fetch_window_id_, factory_params_->process_id, render_frame_id_, + request_id_, url_request_->url(), first_auth_attempt_, auth_info, + std::move(head), + auth_challenge_responder_receiver_.BindNewPipeAndPassRemote()); + } auth_challenge_responder_receiver_.set_disconnect_handler( base::BindOnce(&URLLoader::DeleteSelf, base::Unretained(this))); diff --git a/services/network/url_loader.h b/services/network/url_loader.h index d2ebc94fdc3a6a7b73b89894427fa30ca6f45a20..5c39949e945b245becc1879b18123ee5628c299b 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h @@ -104,6 +104,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoader base::WeakPtr keepalive_statistics_recorder, base::WeakPtr network_usage_accumulator, mojom::TrustedURLLoaderHeaderClient* url_loader_header_client, + mojom::TrustedURLLoaderAuthClient* url_loader_auth_client, mojom::OriginPolicyManager* origin_policy_manager); ~URLLoader() override; @@ -412,6 +413,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoader base::Optional fetch_window_id_; mojo::Remote header_client_; + mojo::Remote auth_client_; std::unique_ptr file_opener_for_upload_; diff --git a/services/network/url_loader_factory.cc b/services/network/url_loader_factory.cc index 9e9baaf8ecd33e6416027014361edc332ab71e3c..cc2c59828f56988d43b680588d4625d9864aa9b6 100644 --- a/services/network/url_loader_factory.cc +++ b/services/network/url_loader_factory.cc @@ -65,6 +65,7 @@ URLLoaderFactory::URLLoaderFactory( params_(std::move(params)), resource_scheduler_client_(std::move(resource_scheduler_client)), header_client_(std::move(params_->header_client)), + auth_client_(std::move(params_->auth_client)), cors_url_loader_factory_(cors_url_loader_factory) { DCHECK(context); DCHECK_NE(mojom::kInvalidProcessId, params_->process_id); @@ -207,6 +208,7 @@ void URLLoaderFactory::CreateLoaderAndStart( resource_scheduler_client_, std::move(keepalive_statistics_recorder), std::move(network_usage_accumulator), header_client_.is_bound() ? header_client_.get() : nullptr, + auth_client_.is_bound() ? auth_client_.get() : nullptr, context_->origin_policy_manager()); cors_url_loader_factory_->OnLoaderCreated(std::move(loader)); } diff --git a/services/network/url_loader_factory.h b/services/network/url_loader_factory.h index 7d13494649c43be52b06774f2cf5763ebe9129c0..d4b19342c44f86c685f700e4260475ff2235b298 100644 --- a/services/network/url_loader_factory.h +++ b/services/network/url_loader_factory.h @@ -72,6 +72,7 @@ class URLLoaderFactory : public mojom::URLLoaderFactory { mojom::URLLoaderFactoryParamsPtr params_; scoped_refptr resource_scheduler_client_; mojo::Remote header_client_; + mojo::Remote auth_client_; // |cors_url_loader_factory_| owns this. cors::CorsURLLoaderFactory* cors_url_loader_factory_;