Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Side by Side Diff: net/http/http_stream_factory_impl_job.cc

Issue 1074193003: Verify alternative server certificate validity for origin. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nit. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_stream_factory_impl_job.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_stream_factory_impl_job.h" 5 #include "net/http/http_stream_factory_impl_job.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 ptr_factory_.GetWeakPtr())); 532 ptr_factory_.GetWeakPtr()));
533 } else { 533 } else {
534 DCHECK(stream_.get()); 534 DCHECK(stream_.get());
535 base::MessageLoop::current()->PostTask( 535 base::MessageLoop::current()->PostTask(
536 FROM_HERE, 536 FROM_HERE,
537 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); 537 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr()));
538 } 538 }
539 return ERR_IO_PENDING; 539 return ERR_IO_PENDING;
540 540
541 default: 541 default:
542 DCHECK(result != ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN ||
543 IsSpdyAlternate());
542 if (job_status_ != STATUS_BROKEN) { 544 if (job_status_ != STATUS_BROKEN) {
543 DCHECK_EQ(STATUS_RUNNING, job_status_); 545 DCHECK_EQ(STATUS_RUNNING, job_status_);
544 job_status_ = STATUS_FAILED; 546 job_status_ = STATUS_FAILED;
547 // TODO(bnc): If (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN),
548 // then instead of marking alternative service broken, mark (origin,
549 // alternative service) couple as invalid.
545 MaybeMarkAlternativeServiceBroken(); 550 MaybeMarkAlternativeServiceBroken();
546 } 551 }
547 base::MessageLoop::current()->PostTask( 552 base::MessageLoop::current()->PostTask(
548 FROM_HERE, 553 FROM_HERE,
549 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), 554 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(),
550 result)); 555 result));
551 return ERR_IO_PENDING; 556 return ERR_IO_PENDING;
552 } 557 }
553 } 558 }
554 559
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 } 624 }
620 625
621 int HttpStreamFactoryImpl::Job::DoStart() { 626 int HttpStreamFactoryImpl::Job::DoStart() {
622 if (IsAlternate()) { 627 if (IsAlternate()) {
623 server_ = alternative_service_.host_port_pair(); 628 server_ = alternative_service_.host_port_pair();
624 } else { 629 } else {
625 server_ = HostPortPair::FromURL(request_info_.url); 630 server_ = HostPortPair::FromURL(request_info_.url);
626 } 631 }
627 origin_url_ = 632 origin_url_ =
628 stream_factory_->ApplyHostMappingRules(request_info_.url, &server_); 633 stream_factory_->ApplyHostMappingRules(request_info_.url, &server_);
634 valid_spdy_session_pool_.reset(new ValidSpdySessionPool(
635 session_->spdy_session_pool(), origin_url_, IsSpdyAlternate()));
629 636
630 net_log_.BeginEvent( 637 net_log_.BeginEvent(
631 NetLog::TYPE_HTTP_STREAM_JOB, 638 NetLog::TYPE_HTTP_STREAM_JOB,
632 base::Bind(&NetLogHttpStreamJobCallback, &request_info_.url, &origin_url_, 639 base::Bind(&NetLogHttpStreamJobCallback, &request_info_.url, &origin_url_,
633 &alternative_service_, priority_)); 640 &alternative_service_, priority_));
634 641
635 // Don't connect to restricted ports. 642 // Don't connect to restricted ports.
636 bool is_port_allowed = IsPortAllowedByDefault(server_.port()); 643 bool is_port_allowed = IsPortAllowedByDefault(server_.port());
637 if (request_info_.url.SchemeIs("ftp")) { 644 if (request_info_.url.SchemeIs("ftp")) {
638 // Never share connection with other jobs for FTP requests. 645 // Never share connection with other jobs for FTP requests.
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 } 805 }
799 } 806 }
800 return rv; 807 return rv;
801 } 808 }
802 809
803 SpdySessionKey spdy_session_key = GetSpdySessionKey(); 810 SpdySessionKey spdy_session_key = GetSpdySessionKey();
804 811
805 // Check first if we have a spdy session for this group. If so, then go 812 // Check first if we have a spdy session for this group. If so, then go
806 // straight to using that. 813 // straight to using that.
807 if (CanUseExistingSpdySession()) { 814 if (CanUseExistingSpdySession()) {
808 base::WeakPtr<SpdySession> spdy_session = 815 base::WeakPtr<SpdySession> spdy_session;
809 session_->spdy_session_pool()->FindAvailableSession(spdy_session_key, 816 int result = valid_spdy_session_pool_->FindAvailableSession(
810 net_log_); 817 spdy_session_key, net_log_, &spdy_session);
818 if (result != OK)
819 return result;
811 if (spdy_session) { 820 if (spdy_session) {
812 // If we're preconnecting, but we already have a SpdySession, we don't 821 // If we're preconnecting, but we already have a SpdySession, we don't
813 // actually need to preconnect any sockets, so we're done. 822 // actually need to preconnect any sockets, so we're done.
814 if (IsPreconnecting()) 823 if (IsPreconnecting())
815 return OK; 824 return OK;
816 using_spdy_ = true; 825 using_spdy_ = true;
817 next_state_ = STATE_CREATE_STREAM; 826 next_state_ = STATE_CREATE_STREAM;
818 existing_spdy_session_ = spdy_session; 827 existing_spdy_session_ = spdy_session;
819 return OK; 828 return OK;
820 } 829 }
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 // puts the in progress HttpProxy socket into |connection_| in order to 998 // puts the in progress HttpProxy socket into |connection_| in order to
990 // complete the auth (or read the response body). The tunnel restart code 999 // complete the auth (or read the response body). The tunnel restart code
991 // is careful to remove it before returning control to the rest of this 1000 // is careful to remove it before returning control to the rest of this
992 // class. 1001 // class.
993 connection_.reset(connection_->release_pending_http_proxy_connection()); 1002 connection_.reset(connection_->release_pending_http_proxy_connection());
994 return result; 1003 return result;
995 } 1004 }
996 1005
997 if (!ssl_started && result < 0 && IsAlternate()) { 1006 if (!ssl_started && result < 0 && IsAlternate()) {
998 job_status_ = STATUS_BROKEN; 1007 job_status_ = STATUS_BROKEN;
1008 // TODO(bnc): if (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN), then
1009 // instead of marking alternative service broken, mark (origin, alternative
1010 // service) couple as invalid.
999 MaybeMarkAlternativeServiceBroken(); 1011 MaybeMarkAlternativeServiceBroken();
1000 return result; 1012 return result;
1001 } 1013 }
1002 1014
1003 if (using_quic_) { 1015 if (using_quic_) {
1004 if (result < 0) { 1016 if (result < 0) {
1005 job_status_ = STATUS_BROKEN; 1017 job_status_ = STATUS_BROKEN;
1006 MaybeMarkAlternativeServiceBroken(); 1018 MaybeMarkAlternativeServiceBroken();
1007 return result; 1019 return result;
1008 } 1020 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 // We picked up an existing session, so we don't need our socket. 1123 // We picked up an existing session, so we don't need our socket.
1112 if (connection_->socket()) 1124 if (connection_->socket())
1113 connection_->socket()->Disconnect(); 1125 connection_->socket()->Disconnect();
1114 connection_->Reset(); 1126 connection_->Reset();
1115 1127
1116 int set_result = SetSpdyHttpStream(existing_spdy_session_, direct); 1128 int set_result = SetSpdyHttpStream(existing_spdy_session_, direct);
1117 existing_spdy_session_.reset(); 1129 existing_spdy_session_.reset();
1118 return set_result; 1130 return set_result;
1119 } 1131 }
1120 1132
1121 SpdySessionPool* spdy_pool = session_->spdy_session_pool();
1122 SpdySessionKey spdy_session_key = GetSpdySessionKey(); 1133 SpdySessionKey spdy_session_key = GetSpdySessionKey();
1123 base::WeakPtr<SpdySession> spdy_session = 1134 base::WeakPtr<SpdySession> spdy_session;
1124 spdy_pool->FindAvailableSession(spdy_session_key, net_log_); 1135 int result = valid_spdy_session_pool_->FindAvailableSession(
1125 1136 spdy_session_key, net_log_, &spdy_session);
1137 if (result != OK) {
1138 return result;
1139 }
1126 if (spdy_session) { 1140 if (spdy_session) {
1127 return SetSpdyHttpStream(spdy_session, direct); 1141 return SetSpdyHttpStream(spdy_session, direct);
1128 } 1142 }
1129 1143
1130 spdy_session = 1144 result = valid_spdy_session_pool_->CreateAvailableSessionFromSocket(
1131 spdy_pool->CreateAvailableSessionFromSocket(spdy_session_key, 1145 spdy_session_key, connection_.Pass(), net_log_, spdy_certificate_error_,
1132 connection_.Pass(), 1146 using_ssl_, &spdy_session);
1133 net_log_, 1147 if (result != OK) {
1134 spdy_certificate_error_, 1148 return result;
1135 using_ssl_); 1149 }
1150
1136 if (!spdy_session->HasAcceptableTransportSecurity()) { 1151 if (!spdy_session->HasAcceptableTransportSecurity()) {
1137 spdy_session->CloseSessionOnError( 1152 spdy_session->CloseSessionOnError(
1138 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, ""); 1153 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, "");
1139 return ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY; 1154 return ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY;
1140 } 1155 }
1141 1156
1142 new_spdy_session_ = spdy_session; 1157 new_spdy_session_ = spdy_session;
1143 spdy_session_direct_ = direct; 1158 spdy_session_direct_ = direct;
1144 const HostPortPair& host_port_pair = spdy_session_key.host_port_pair(); 1159 const HostPortPair& host_port_pair = spdy_session_key.host_port_pair();
1145 base::WeakPtr<HttpServerProperties> http_server_properties = 1160 base::WeakPtr<HttpServerProperties> http_server_properties =
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
1461 } 1476 }
1462 1477
1463 if (job_status_ == STATUS_SUCCEEDED && other_job_status_ == STATUS_BROKEN) { 1478 if (job_status_ == STATUS_SUCCEEDED && other_job_status_ == STATUS_BROKEN) {
1464 HistogramBrokenAlternateProtocolLocation( 1479 HistogramBrokenAlternateProtocolLocation(
1465 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_MAIN); 1480 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_MAIN);
1466 session_->http_server_properties()->MarkAlternativeServiceBroken( 1481 session_->http_server_properties()->MarkAlternativeServiceBroken(
1467 other_job_alternative_service_); 1482 other_job_alternative_service_);
1468 } 1483 }
1469 } 1484 }
1470 1485
1486 HttpStreamFactoryImpl::Job::ValidSpdySessionPool::ValidSpdySessionPool(
1487 SpdySessionPool* spdy_session_pool,
1488 GURL& origin_url,
1489 bool is_spdy_alternate)
1490 : spdy_session_pool_(spdy_session_pool),
1491 origin_url_(origin_url),
1492 is_spdy_alternate_(is_spdy_alternate) {
1493 }
1494
1495 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool::FindAvailableSession(
1496 const SpdySessionKey& key,
1497 const BoundNetLog& net_log,
1498 base::WeakPtr<SpdySession>* spdy_session) {
1499 *spdy_session = spdy_session_pool_->FindAvailableSession(key, net_log);
1500 return CheckAlternativeServiceValidityForOrigin(*spdy_session);
1501 }
1502
1503 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool::
1504 CreateAvailableSessionFromSocket(const SpdySessionKey& key,
1505 scoped_ptr<ClientSocketHandle> connection,
1506 const BoundNetLog& net_log,
1507 int certificate_error_code,
1508 bool is_secure,
1509 base::WeakPtr<SpdySession>* spdy_session) {
1510 *spdy_session = spdy_session_pool_->CreateAvailableSessionFromSocket(
1511 key, connection.Pass(), net_log, certificate_error_code, is_secure);
1512 return CheckAlternativeServiceValidityForOrigin(*spdy_session);
1513 }
1514
1515 int HttpStreamFactoryImpl::Job::ValidSpdySessionPool::
1516 CheckAlternativeServiceValidityForOrigin(
1517 base::WeakPtr<SpdySession> spdy_session) {
1518 // For a SPDY alternate Job, server_.host() might be different than
1519 // origin_url_.host(), therefore it needs to be verified that the former
1520 // provides a certificate that is valid for the latter.
1521 if (!is_spdy_alternate_ || !spdy_session ||
1522 spdy_session->VerifyDomainAuthentication(origin_url_.host())) {
1523 return OK;
1524 }
1525 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN;
1526 }
1527
1471 ClientSocketPoolManager::SocketGroupType 1528 ClientSocketPoolManager::SocketGroupType
1472 HttpStreamFactoryImpl::Job::GetSocketGroup() const { 1529 HttpStreamFactoryImpl::Job::GetSocketGroup() const {
1473 std::string scheme = origin_url_.scheme(); 1530 std::string scheme = origin_url_.scheme();
1474 if (scheme == "https" || scheme == "wss" || IsSpdyAlternate()) 1531 if (scheme == "https" || scheme == "wss" || IsSpdyAlternate())
1475 return ClientSocketPoolManager::SSL_GROUP; 1532 return ClientSocketPoolManager::SSL_GROUP;
1476 1533
1477 if (scheme == "ftp") 1534 if (scheme == "ftp")
1478 return ClientSocketPoolManager::FTP_GROUP; 1535 return ClientSocketPoolManager::FTP_GROUP;
1479 1536
1480 return ClientSocketPoolManager::NORMAL_GROUP; 1537 return ClientSocketPoolManager::NORMAL_GROUP;
1481 } 1538 }
1482 1539
1483 } // namespace net 1540 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_stream_factory_impl_job.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698