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 b4d200164829d0d34c2511a07eb0cc3d046d6fa3..e15635d66859211ac91b5beff36beffd4dfe4807 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom @@ -214,6 +214,25 @@ struct CTPolicy { array excluded_legacy_spkis; }; +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, @@ -652,6 +671,8 @@ struct URLLoaderFactoryParams { // impact because of the extra process hops, so use should be minimized. pending_remote? header_client; + pending_remote? auth_client; + // |factory_bound_access_patterns| are used for CORS checks in addition to // the per-context allow patterns that is managed via NetworkContext // interface. This still respects the per-context block lists. diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 5f05f9a5385f5b424b2d66a5ac19e878f09f24f4..f5ce4de54b0c71f2099753198794503c8ee10013 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, std::unique_ptr trust_token_helper_factory, mojo::PendingRemote cookie_observer) @@ -546,6 +547,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; @@ -1119,7 +1125,7 @@ void URLLoader::OnAuthRequired(net::URLRequest* url_request, // |this| may have been deleted. return; } - if (!network_context_client_) { + if (!network_context_client_ && !auth_client_) { OnAuthCredentials(base::nullopt); return; } @@ -1135,11 +1141,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 a624b8c43f49a7db975d8deda753b18583db5d72..cce8d7e0b8847528715aca4704db5194829c5bbc 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h @@ -118,6 +118,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, std::unique_ptr trust_token_helper_factory, @@ -481,6 +482,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 75ae8488efa7e5acfda0b21029657b525fa95f86..5dce71ee5efc97f9f63d0b5f236dccdfb05cfc79 100644 --- a/services/network/url_loader_factory.cc +++ b/services/network/url_loader_factory.cc @@ -75,6 +75,7 @@ URLLoaderFactory::URLLoaderFactory( resource_scheduler_client_(std::move(resource_scheduler_client)), header_client_(std::move(params_->header_client)), coep_reporter_(std::move(params_->coep_reporter)), + auth_client_(std::move(params_->auth_client)), cors_url_loader_factory_(cors_url_loader_factory), cookie_observer_(std::move(params_->cookie_observer)) { DCHECK(context); @@ -254,6 +255,7 @@ void URLLoaderFactory::CreateLoaderAndStart( 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(), std::move(trust_token_factory), std::move(cookie_observer)); diff --git a/services/network/url_loader_factory.h b/services/network/url_loader_factory.h index 182b26816da9e82d83c47c3c73ecfdcf3003b967..903a3ad083201ed85e82169698041152278697fa 100644 --- a/services/network/url_loader_factory.h +++ b/services/network/url_loader_factory.h @@ -74,6 +74,7 @@ class URLLoaderFactory : public mojom::URLLoaderFactory { scoped_refptr resource_scheduler_client_; mojo::Remote header_client_; mojo::Remote coep_reporter_; + mojo::Remote auth_client_; // |cors_url_loader_factory_| owns this. cors::CorsURLLoaderFactory* cors_url_loader_factory_;