Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/browser/api/cast_channel/cast_socket.h" | 5 #include "extensions/browser/api/cast_channel/cast_socket.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
| 14 #include "base/format_macros.h" | 14 #include "base/format_macros.h" |
| 15 #include "base/guid.h" | |
| 15 #include "base/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
| 16 #include "base/location.h" | 17 #include "base/location.h" |
| 17 #include "base/memory/ptr_util.h" | 18 #include "base/memory/ptr_util.h" |
| 18 #include "base/numerics/safe_conversions.h" | 19 #include "base/numerics/safe_conversions.h" |
| 19 #include "base/single_thread_task_runner.h" | 20 #include "base/single_thread_task_runner.h" |
| 20 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
| 21 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
| 22 #include "base/sys_byteorder.h" | 23 #include "base/sys_byteorder.h" |
| 23 #include "base/threading/thread_task_runner_handle.h" | 24 #include "base/threading/thread_task_runner_handle.h" |
| 24 #include "base/time/time.h" | 25 #include "base/time/time.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 BrowserContextKeyedAPIFactory< | 67 BrowserContextKeyedAPIFactory< |
| 67 ApiResourceManager<api::cast_channel::CastSocket>>* | 68 ApiResourceManager<api::cast_channel::CastSocket>>* |
| 68 ApiResourceManager<api::cast_channel::CastSocket>::GetFactoryInstance() { | 69 ApiResourceManager<api::cast_channel::CastSocket>::GetFactoryInstance() { |
| 69 return g_factory.Pointer(); | 70 return g_factory.Pointer(); |
| 70 } | 71 } |
| 71 | 72 |
| 72 namespace api { | 73 namespace api { |
| 73 namespace cast_channel { | 74 namespace cast_channel { |
| 74 namespace { | 75 namespace { |
| 75 | 76 |
| 77 long kNonceExpirationTimeInHours = 24; | |
| 78 | |
| 76 bool IsTerminalState(proto::ConnectionState state) { | 79 bool IsTerminalState(proto::ConnectionState state) { |
| 77 return state == proto::CONN_STATE_FINISHED || | 80 return state == proto::CONN_STATE_FINISHED || |
| 78 state == proto::CONN_STATE_ERROR || state == proto::CONN_STATE_TIMEOUT; | 81 state == proto::CONN_STATE_ERROR || state == proto::CONN_STATE_TIMEOUT; |
| 79 } | 82 } |
| 80 | 83 |
| 81 // Cert verifier which blindly accepts all certificates, regardless of validity. | 84 // Cert verifier which blindly accepts all certificates, regardless of validity. |
| 82 class FakeCertVerifier : public net::CertVerifier { | 85 class FakeCertVerifier : public net::CertVerifier { |
| 83 public: | 86 public: |
| 84 FakeCertVerifier() {} | 87 FakeCertVerifier() {} |
| 85 ~FakeCertVerifier() override {} | 88 ~FakeCertVerifier() override {} |
| 86 | 89 |
| 87 int Verify(const RequestParams& params, | 90 int Verify(const RequestParams& params, |
| 88 net::CRLSet*, | 91 net::CRLSet*, |
| 89 net::CertVerifyResult* verify_result, | 92 net::CertVerifyResult* verify_result, |
| 90 const net::CompletionCallback&, | 93 const net::CompletionCallback&, |
| 91 std::unique_ptr<Request>*, | 94 std::unique_ptr<Request>*, |
| 92 const net::NetLogWithSource&) override { | 95 const net::NetLogWithSource&) override { |
| 93 verify_result->Reset(); | 96 verify_result->Reset(); |
| 94 verify_result->verified_cert = params.certificate(); | 97 verify_result->verified_cert = params.certificate(); |
| 95 return net::OK; | 98 return net::OK; |
| 96 } | 99 } |
| 97 }; | 100 }; |
| 98 | 101 |
| 99 } // namespace | 102 } // namespace |
| 100 | 103 |
| 104 // static | |
| 105 std::string CastSocketImpl::nonce_ = ""; | |
|
mark a. foltz
2017/03/03 23:25:51
Static variables must be POD (with a few exception
ryanchung
2017/03/06 22:57:46
Done. Thanks.
| |
| 106 // static | |
| 107 base::Time CastSocketImpl::nonce_generation_time_ = base::Time(); | |
| 108 | |
| 109 // static | |
| 110 void CastSocketImpl::EnsureNonceTimely() { | |
| 111 if (nonce_.empty() || | |
| 112 base::Time::Now() > | |
| 113 (nonce_generation_time_ + | |
| 114 base::TimeDelta::FromHours(kNonceExpirationTimeInHours))) { | |
| 115 nonce_ = base::GenerateGUID(); | |
|
mark a. foltz
2017/03/03 23:25:51
I thought there was a different nonce for each att
ryanchung
2017/03/06 22:57:46
Ideally, each connection attempt uses a difference
| |
| 116 nonce_generation_time_ = base::Time::Now(); | |
| 117 } | |
| 118 } | |
| 119 | |
| 101 CastSocket::CastSocket(const std::string& owner_extension_id) | 120 CastSocket::CastSocket(const std::string& owner_extension_id) |
| 102 : ApiResource(owner_extension_id) { | 121 : ApiResource(owner_extension_id) { |
| 103 } | 122 } |
| 104 | 123 |
| 105 bool CastSocket::IsPersistent() const { | 124 bool CastSocket::IsPersistent() const { |
| 106 return true; | 125 return true; |
| 107 } | 126 } |
| 108 | 127 |
| 109 CastSocketImpl::CastSocketImpl(const std::string& owner_extension_id, | 128 CastSocketImpl::CastSocketImpl(const std::string& owner_extension_id, |
| 110 const net::IPEndPoint& ip_endpoint, | 129 const net::IPEndPoint& ip_endpoint, |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 127 is_canceled_(false), | 146 is_canceled_(false), |
| 128 device_capabilities_(device_capabilities), | 147 device_capabilities_(device_capabilities), |
| 129 audio_only_(false), | 148 audio_only_(false), |
| 130 connect_state_(proto::CONN_STATE_START_CONNECT), | 149 connect_state_(proto::CONN_STATE_START_CONNECT), |
| 131 error_state_(CHANNEL_ERROR_NONE), | 150 error_state_(CHANNEL_ERROR_NONE), |
| 132 ready_state_(READY_STATE_NONE), | 151 ready_state_(READY_STATE_NONE), |
| 133 auth_delegate_(nullptr) { | 152 auth_delegate_(nullptr) { |
| 134 DCHECK(net_log_); | 153 DCHECK(net_log_); |
| 135 net_log_source_.type = net::NetLogSourceType::SOCKET; | 154 net_log_source_.type = net::NetLogSourceType::SOCKET; |
| 136 net_log_source_.id = net_log_->NextID(); | 155 net_log_source_.id = net_log_->NextID(); |
| 156 EnsureNonceTimely(); | |
| 137 } | 157 } |
| 138 | 158 |
| 139 CastSocketImpl::~CastSocketImpl() { | 159 CastSocketImpl::~CastSocketImpl() { |
| 140 // Ensure that resources are freed but do not run pending callbacks to avoid | 160 // Ensure that resources are freed but do not run pending callbacks to avoid |
| 141 // any re-entrancy. | 161 // any re-entrancy. |
| 142 CloseInternal(); | 162 CloseInternal(); |
| 143 } | 163 } |
| 144 | 164 |
| 145 ReadyState CastSocketImpl::ready_state() const { | 165 ReadyState CastSocketImpl::ready_state() const { |
| 146 return ready_state_; | 166 return ready_state_; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 logger_->LogSocketEventWithDetails( | 248 logger_->LogSocketEventWithDetails( |
| 229 channel_id_, proto::CHANNEL_POLICY_ENFORCED, std::string()); | 249 channel_id_, proto::CHANNEL_POLICY_ENFORCED, std::string()); |
| 230 return false; | 250 return false; |
| 231 } | 251 } |
| 232 return true; | 252 return true; |
| 233 } | 253 } |
| 234 | 254 |
| 235 bool CastSocketImpl::VerifyChallengeReply() { | 255 bool CastSocketImpl::VerifyChallengeReply() { |
| 236 DCHECK(peer_cert_); | 256 DCHECK(peer_cert_); |
| 237 AuthResult result = | 257 AuthResult result = |
| 238 AuthenticateChallengeReply(*challenge_reply_, *peer_cert_); | 258 AuthenticateChallengeReply(*challenge_reply_, *peer_cert_, nonce_); |
| 239 logger_->LogSocketChallengeReplyEvent(channel_id_, result); | 259 logger_->LogSocketChallengeReplyEvent(channel_id_, result); |
| 240 if (result.success()) { | 260 if (result.success()) { |
| 241 VLOG(1) << result.error_message; | 261 VLOG(1) << result.error_message; |
| 242 if (!VerifyChannelPolicy(result)) { | 262 if (!VerifyChannelPolicy(result)) { |
| 243 return false; | 263 return false; |
| 244 } | 264 } |
| 245 } | 265 } |
| 246 return result.success(); | 266 return result.success(); |
| 247 } | 267 } |
| 248 | 268 |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 443 SetErrorState(CHANNEL_ERROR_AUTHENTICATION_ERROR); | 463 SetErrorState(CHANNEL_ERROR_AUTHENTICATION_ERROR); |
| 444 } | 464 } |
| 445 return result; | 465 return result; |
| 446 } | 466 } |
| 447 | 467 |
| 448 int CastSocketImpl::DoAuthChallengeSend() { | 468 int CastSocketImpl::DoAuthChallengeSend() { |
| 449 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeSend"; | 469 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeSend"; |
| 450 SetConnectState(proto::CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE); | 470 SetConnectState(proto::CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE); |
| 451 | 471 |
| 452 CastMessage challenge_message; | 472 CastMessage challenge_message; |
| 453 CreateAuthChallengeMessage(&challenge_message); | 473 CreateAuthChallengeMessage(&challenge_message, nonce_); |
| 454 VLOG_WITH_CONNECTION(1) << "Sending challenge: " | 474 VLOG_WITH_CONNECTION(1) << "Sending challenge: " |
| 455 << CastMessageToString(challenge_message); | 475 << CastMessageToString(challenge_message); |
| 456 | 476 |
| 457 transport_->SendMessage( | 477 transport_->SendMessage( |
| 458 challenge_message, | 478 challenge_message, |
| 459 base::Bind(&CastSocketImpl::DoConnectLoop, base::Unretained(this))); | 479 base::Bind(&CastSocketImpl::DoConnectLoop, base::Unretained(this))); |
| 460 | 480 |
| 461 // Always return IO_PENDING since the result is always asynchronous. | 481 // Always return IO_PENDING since the result is always asynchronous. |
| 462 return net::ERR_IO_PENDING; | 482 return net::ERR_IO_PENDING; |
| 463 } | 483 } |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 611 } | 631 } |
| 612 } | 632 } |
| 613 | 633 |
| 614 void CastSocketImpl::SetErrorState(ChannelError error_state) { | 634 void CastSocketImpl::SetErrorState(ChannelError error_state) { |
| 615 VLOG_WITH_CONNECTION(1) << "SetErrorState " << error_state; | 635 VLOG_WITH_CONNECTION(1) << "SetErrorState " << error_state; |
| 616 DCHECK_EQ(CHANNEL_ERROR_NONE, error_state_); | 636 DCHECK_EQ(CHANNEL_ERROR_NONE, error_state_); |
| 617 error_state_ = error_state; | 637 error_state_ = error_state; |
| 618 logger_->LogSocketErrorState(channel_id_, ErrorStateToProto(error_state_)); | 638 logger_->LogSocketErrorState(channel_id_, ErrorStateToProto(error_state_)); |
| 619 delegate_->OnError(error_state_); | 639 delegate_->OnError(error_state_); |
| 620 } | 640 } |
| 641 | |
| 621 } // namespace cast_channel | 642 } // namespace cast_channel |
| 622 } // namespace api | 643 } // namespace api |
| 623 } // namespace extensions | 644 } // namespace extensions |
| 624 #undef VLOG_WITH_CONNECTION | 645 #undef VLOG_WITH_CONNECTION |
| OLD | NEW |