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

Unified Diff: chrome/browser/extensions/api/cast_channel/cast_socket.cc

Issue 35443002: Update CastSocket connection flow to check for receiver credentials. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/cast_channel/cast_socket.cc
===================================================================
--- chrome/browser/extensions/api/cast_channel/cast_socket.cc (revision 230132)
+++ chrome/browser/extensions/api/cast_channel/cast_socket.cc (working copy)
@@ -11,6 +11,7 @@
#include "base/lazy_instance.h"
#include "base/strings/string_number_conversions.h"
#include "base/sys_byteorder.h"
+#include "chrome/browser/extensions/api/cast_channel/cast_auth_util.h"
#include "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h"
#include "chrome/browser/extensions/api/cast_channel/cast_message_util.h"
#include "net/base/address_list.h"
@@ -65,7 +66,8 @@
const uint32 kMaxMessageSize = 65536;
CastSocket::CastSocket(const std::string& owner_extension_id,
- const GURL& url, CastSocket::Delegate* delegate,
+ const GURL& url,
+ CastSocket::Delegate* delegate,
net::NetLog* net_log) :
ApiResource(owner_extension_id),
channel_id_(0),
@@ -97,18 +99,6 @@
return url_;
}
-bool CastSocket::ExtractPeerCert(std::string* cert) {
- CHECK(peer_cert_.empty());
- net::SSLInfo ssl_info;
- if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get())
- return false;
- bool result = net::X509Certificate::GetDEREncoded(
- ssl_info.cert->os_cert_handle(), cert);
- if (result)
- DVLOG(1) << "Successfully extracted peer certificate: " << *cert;
- return result;
-}
-
scoped_ptr<net::TCPClientSocket> CastSocket::CreateTcpSocket() {
net::AddressList addresses(ip_endpoint_);
scoped_ptr<net::TCPClientSocket> tcp_socket(
@@ -146,12 +136,42 @@
connection.Pass(), host_and_port, ssl_config, context);
}
+bool CastSocket::ExtractPeerCert(std::string* cert) {
+ CHECK(peer_cert_.empty());
mark a. foltz 2013/10/23 00:33:41 CHECK(cert)
Munjal (Google) 2013/10/23 03:22:55 Done.
+ net::SSLInfo ssl_info;
+ if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get())
+ return false;
+ bool result = net::X509Certificate::GetDEREncoded(
+ ssl_info.cert->os_cert_handle(), cert);
+ if (result)
+ DVLOG(1) << "Successfully extracted peer certificate: " << *cert;
+ return result;
+}
+
+int CastSocket::SendAuthChallenge() {
+ CastMessage challenge_message;
+ CreateAuthChallengeMessage(&challenge_message);
+ return SendMessageInternal(
+ challenge_message,
+ base::Bind(&CastSocket::OnChallengeEvent, AsWeakPtr()));
+}
+
+int CastSocket::ReadAuthChallengeReply() {
+ return ReadData();
+}
+
void CastSocket::OnConnectComplete(int result) {
int rv = DoConnectLoop(result);
if (rv != net::ERR_IO_PENDING)
DoConnectCallback(rv);
}
+void CastSocket::OnChallengeEvent(int result) {
+ int rv = DoConnectLoop(result);
+ if (rv != net::ERR_IO_PENDING)
+ DoConnectCallback(rv);
+}
+
void CastSocket::Connect(const net::CompletionCallback& callback) {
DCHECK(CalledOnValidThread());
int result = net::ERR_CONNECTION_FAILED;
@@ -205,6 +225,16 @@
case CONN_STATE_SSL_CONNECT_COMPLETE:
rv = DoSslConnectComplete(rv);
break;
+ case CONN_STATE_AUTH_CHALLENGE_SEND:
+ rv = DoAuthChallengeSend();
+ break;
+ case CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE:
+ rv = DoAuthChallengeSendComplete(rv);
+ break;
+ case CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE:
+ rv = DoAuthChallengeReplyComplete(rv);
+ break;
+
default:
NOTREACHED() << "BUG in CastSocket state machine code";
break;
@@ -243,10 +273,38 @@
peer_cert_.empty() &&
ExtractPeerCert(&peer_cert_)) {
next_state_ = CONN_STATE_TCP_CONNECT;
+ } else if (result == net::OK && is_secure_) {
mark a. foltz 2013/10/23 00:33:41 is_secure_ might be better named auth_required_
Munjal (Google) 2013/10/23 03:22:55 Done.
+ next_state_ = CONN_STATE_AUTH_CHALLENGE_SEND;
}
return result;
}
+int CastSocket::DoAuthChallengeSend() {
+ next_state_ = CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE;
+ return SendAuthChallenge();
+}
+
+int CastSocket::DoAuthChallengeSendComplete(int result) {
+ if (result != net::OK)
+ return result;
+
mark a. foltz 2013/10/23 00:33:41 extra newline
Munjal (Google) 2013/10/23 03:22:55 Done.
+ next_state_ = CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE;
+ return ReadAuthChallengeReply();
+}
+
+int CastSocket::DoAuthChallengeReplyComplete(int result) {
+ if (result != net::OK)
+ return result;
+ if (VerifyChallengeReply())
+ return net::OK;
+ else
+ return net::ERR_FAILED;
+}
+
+bool CastSocket::VerifyChallengeReply() {
+ return AuthenticateChallengeReply(*challenge_reply_.get(), peer_cert_);
+}
+
void CastSocket::DoConnectCallback(int result) {
ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED;
error_state_ = (result == net::OK) ?
@@ -276,31 +334,36 @@
callback.Run(result);
return;
}
- WriteRequest write_request(callback);
CastMessage message_proto;
- if (!MessageInfoToCastMessage(message, &message_proto) ||
- !write_request.SetContent(message_proto)) {
+ if (!MessageInfoToCastMessage(message, &message_proto)) {
CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
// TODO(mfoltz): Do a better job of signaling cast_channel errors to the
// caller.
callback.Run(net::OK);
return;
}
+ SendMessageInternal(message_proto, callback);
+}
+
+int CastSocket::SendMessageInternal(const CastMessage& message_proto,
+ const net::CompletionCallback& callback) {
+ WriteRequest write_request(callback);
+ if (!write_request.SetContent(message_proto)) {
+ CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
+ callback.Run(net::OK);
+ return net::ERR_FAILED;
+ }
write_queue_.push(write_request);
- WriteData();
+ return WriteData();
}
-void CastSocket::WriteData() {
+int CastSocket::WriteData() {
DCHECK(CalledOnValidThread());
DVLOG(1) << "WriteData q = " << write_queue_.size();
if (write_queue_.empty() || write_callback_pending_)
- return;
+ return net::ERR_FAILED;
WriteRequest& request = write_queue_.front();
- if (ready_state_ != READY_STATE_OPEN) {
- request.callback.Run(net::ERR_FAILED);
- return;
- }
DVLOG(1) << "WriteData byte_count = " << request.io_buffer->size() <<
" bytes_written " << request.io_buffer->BytesConsumed();
@@ -311,10 +374,10 @@
request.io_buffer->BytesRemaining(),
base::Bind(&CastSocket::OnWriteData, AsWeakPtr()));
- DVLOG(1) << "WriteData result = " << result;
-
if (result != net::ERR_IO_PENDING)
OnWriteData(result);
+
+ return result;
}
void CastSocket::OnWriteData(int result) {
@@ -358,11 +421,10 @@
WriteData();
}
-void CastSocket::ReadData() {
+int CastSocket::ReadData() {
DCHECK(CalledOnValidThread());
- if (!socket_.get() || ready_state_ != READY_STATE_OPEN) {
- return;
- }
+ if (!socket_.get())
+ return net::ERR_FAILED;
DCHECK(!read_callback_pending_);
read_callback_pending_ = true;
// Figure out if we are reading the header or body, and the remaining bytes.
@@ -389,13 +451,14 @@
} else if (result != net::ERR_IO_PENDING) {
CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
}
+ return result;
}
void CastSocket::OnReadData(int result) {
DCHECK(CalledOnValidThread());
- DVLOG(1) << "OnReadData result = " << result <<
- " header offset = " << header_read_buffer_->offset() <<
- " body offset = " << body_read_buffer_->offset();
+ DVLOG(1) << "OnReadData result = " << result
+ << " header offset = " << header_read_buffer_->offset()
+ << " body offset = " << body_read_buffer_->offset();
read_callback_pending_ = false;
if (result <= 0) {
CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
@@ -458,8 +521,12 @@
body_read_buffer_->StartOfBuffer(),
current_message_size_))
return false;
- DVLOG(1) << "Parsed message " << MessageProtoToString(message_proto);
- if (delegate_) {
+ DVLOG(1) << "Parsed message " << CastMessageToString(message_proto);
+ // If the message is an auth message then we handle it internally.
+ if (IsAuthMessage(message_proto)) {
+ challenge_reply_.reset(new CastMessage(message_proto));
+ OnChallengeEvent(net::OK);
+ } else if (delegate_) {
MessageInfo message;
if (!CastMessageToMessageInfo(message_proto, &message))
return false;

Powered by Google App Engine
This is Rietveld 408576698