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

Unified Diff: chrome/browser/extensions/api/cast_channel/cast_socket_unittest.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_unittest.cc
===================================================================
--- chrome/browser/extensions/api/cast_channel/cast_socket_unittest.cc (revision 230522)
+++ chrome/browser/extensions/api/cast_channel/cast_socket_unittest.cc (working copy)
@@ -80,14 +80,30 @@
class TestCastSocket : public CastSocket {
public:
- explicit TestCastSocket(MockCastSocketDelegate* delegate) :
- CastSocket("abcdefg", GURL("cast://192.0.0.1:8009"), delegate,
+ static scoped_ptr<TestCastSocket> Create(
+ MockCastSocketDelegate* delegate) {
+ return scoped_ptr<TestCastSocket>(
+ new TestCastSocket(delegate, "cast://192.0.0.1:8009"));
+ }
+
+ static scoped_ptr<TestCastSocket> CreateSecure(
+ MockCastSocketDelegate* delegate) {
+ return scoped_ptr<TestCastSocket>(
+ new TestCastSocket(delegate, "casts://192.0.0.1:8009"));
+ }
+
+ explicit TestCastSocket(MockCastSocketDelegate* delegate,
+ const std::string& url) :
+ CastSocket("abcdefg", GURL(url), delegate,
&capturing_net_log_),
mock_tcp_socket_(new MockTCPClientSocket()),
mock_ssl_socket_(new MockSSLClientSocket()),
owns_tcp_socket_(true),
owns_ssl_socket_(true),
- extract_cert_result_(true) {
+ extract_cert_result_(true),
+ send_auth_challenge_result_(net::ERR_IO_PENDING),
+ read_auth_challenge_reply_result_(net::ERR_IO_PENDING),
+ challenge_reply_result_(true) {
}
virtual ~TestCastSocket() {
@@ -120,6 +136,18 @@
extract_cert_result_ = value;
}
+ void SetSendAuthChallengeResult(int result) {
+ send_auth_challenge_result_ = result;
+ }
+
+ void SetReadAuthChallengeReplyResult(int result) {
+ read_auth_challenge_reply_result_ = result;
+ }
+
+ void SetChallengeReplyResult(bool value) {
+ challenge_reply_result_ = value;
+ }
+
MockTCPClientSocket* mock_tcp_socket_;
MockSSLClientSocket* mock_ssl_socket_;
@@ -140,6 +168,18 @@
return extract_cert_result_;
}
+ virtual int SendAuthChallenge() OVERRIDE {
+ return send_auth_challenge_result_;
+ }
+
+ virtual int ReadAuthChallengeReply() OVERRIDE {
+ return read_auth_challenge_reply_result_;
+ }
+
+ virtual bool VerifyChallengeReply() OVERRIDE {
+ return challenge_reply_result_;
+ }
+
private:
net::CapturingNetLog capturing_net_log_;
// Whether this object or the parent owns |mock_tcp_socket_|.
@@ -148,6 +188,12 @@
bool owns_ssl_socket_;
// Simulated result of peer cert extraction.
bool extract_cert_result_;
+ // Simulated result to be returned by SendAuthChallenge.
+ int send_auth_challenge_result_;
+ // Simulated result to be returned by ReadAuthChallengeReply.
+ int read_auth_challenge_reply_result_;
+ // Simulated result of verifying challenge reply.
+ bool challenge_reply_result_;
};
class CastSocketTest : public testing::Test {
@@ -156,7 +202,6 @@
virtual ~CastSocketTest() {}
virtual void SetUp() OVERRIDE {
- socket_.reset(new TestCastSocket(&mock_delegate_));
test_message_.namespace_ = "urn:test";
test_message_.source_id = "1";
test_message_.destination_id = "2";
@@ -170,27 +215,43 @@
base::Unretained(&handler_)));
}
- // Sets an expectation on the TCP socket Connect method. Connect method is
- // setup to return net::ERR_IO_PENDING and store the callback passed to it
- // in |callback|.
- void ExpectTCPConnect(net::CompletionCallback* callback) {
+ void CreateCastSocket() {
+ socket_ = TestCastSocket::Create(&mock_delegate_);
+ }
+
+ void CreateCastSocketSecure() {
+ socket_ = TestCastSocket::CreateSecure(&mock_delegate_);
+ }
+
+ // Sets an expectation that TCPClientSocket::Connect is called and
+ // returns |result| and stores the callback passed to it in |callback|.
+ void ExpectTcpConnect(net::CompletionCallback* callback, int result) {
EXPECT_CALL(mock_tcp_socket(), Connect(A<const net::CompletionCallback&>()))
.Times(1)
- .WillOnce(DoAll(SaveArg<0>(callback), Return(net::ERR_IO_PENDING)));
+ .WillOnce(DoAll(SaveArg<0>(callback), Return(result)));
}
- // Sets an expectation on the SSL socket Connect method. Connect method is
- // setup to return net::ERR_IO_PENDING and store the callback passed to it
- // in |callback|.
- void ExpectSSLConnect(net::CompletionCallback* callback) {
+ // Same as ExpectTcpConnect but to return net::ERR_IO_PENDING.
+ void ExpectTcpConnectPending(net::CompletionCallback* callback) {
+ ExpectTcpConnect(callback, net::ERR_IO_PENDING);
+ }
+
+ // Sets an expectation that SSLClientSocket::Connect is called and
+ // returns |result| and stores the callback passed to it in |callback|.
+ void ExpectSslConnect(net::CompletionCallback* callback, int result) {
EXPECT_CALL(mock_ssl_socket(), Connect(A<const net::CompletionCallback&>()))
.Times(1)
- .WillOnce(DoAll(SaveArg<0>(callback), Return(net::ERR_IO_PENDING)));
+ .WillOnce(DoAll(SaveArg<0>(callback), Return(result)));
}
- // Sets an expectation on the SSL socket Read method. Read method is setup
- // to return net::ERR_IO_PENDING and to be called |times| number of times.
- void ExpectSSLRead(int times) {
+ // Same as ExpectSslConnect but to return net::ERR_IO_PENDING.
+ void ExpectSslConnectPending(net::CompletionCallback* callback) {
+ ExpectSslConnect(callback, net::ERR_IO_PENDING);
+ }
+
+ // Sets an expectation that SSLClientSocket::Read is called |times| number
+ // of times and returns net::ERR_IO_PENDING.
+ void ExpectSslRead(int times) {
EXPECT_CALL(mock_ssl_socket(), Read(A<net::IOBuffer*>(),
A<int>(),
A<const net::CompletionCallback&>()))
@@ -198,22 +259,20 @@
.WillOnce(Return(net::ERR_IO_PENDING));
}
- // Sets expectations when the socket is connected. Connecting the socket also
- // starts the read loop; we expect the call to Read(), but never fire the read
- // callback.
+ // Sets up CastSocket::Connect to succeed.
+ // Connecting the socket also starts the read loop; we expect the call to
+ // Read(), but never fire the read callback.
void ConnectHelper() {
net::CompletionCallback connect_callback1;
net::CompletionCallback connect_callback2;
- ExpectTCPConnect(&connect_callback1);
- ExpectSSLConnect(&connect_callback2);
+ ExpectTcpConnect(&connect_callback1, net::OK);
+ ExpectSslConnect(&connect_callback2, net::OK);
EXPECT_CALL(handler_, OnConnectComplete(net::OK));
- ExpectSSLRead(1);
+ ExpectSslRead(1);
socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete,
base::Unretained(&handler_)));
- connect_callback1.Run(net::OK);
- connect_callback2.Run(net::OK);
EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state());
EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state());
@@ -232,6 +291,10 @@
return *mock_socket;
}
+ void CallOnChallengeEvent(int result) {
+ socket_->OnChallengeEvent(result);
+ }
+
MockCastSocketDelegate mock_delegate_;
scoped_ptr<TestCastSocket> socket_;
CompleteHandler handler_;
@@ -241,12 +304,13 @@
// Tests URL parsing and validation.
TEST_F(CastSocketTest, TestCastURLs) {
+ CreateCastSocket();
EXPECT_TRUE(socket_->ParseChannelUrl(GURL("cast://192.0.0.1:8009")));
- EXPECT_FALSE(socket_->is_secure_);
+ EXPECT_FALSE(socket_->auth_required());
EXPECT_EQ(socket_->ip_endpoint_.ToString(), "192.0.0.1:8009");
EXPECT_TRUE(socket_->ParseChannelUrl(GURL("casts://192.0.0.1:12345")));
- EXPECT_TRUE(socket_->is_secure_);
+ EXPECT_TRUE(socket_->auth_required());
EXPECT_EQ(socket_->ip_endpoint_.ToString(), "192.0.0.1:12345");
EXPECT_FALSE(socket_->ParseChannelUrl(GURL("http://192.0.0.1:12345")));
@@ -266,6 +330,7 @@
// Tests connecting and closing the socket.
TEST_F(CastSocketTest, TestConnectAndClose) {
+ CreateCastSocket();
ConnectHelper();
EXPECT_CALL(handler_, OnCloseComplete(net::OK));
@@ -275,16 +340,44 @@
EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state());
}
-// Test that when first connection attempt fails with certificate authority
-// invalid error, a second connection attempt is made with peer cert
-// whitelisted.
+// Tests that the following connection flow works:
+// - TCP connection succeeds (async)
+// - SSL connection succeeds (async)
+TEST_F(CastSocketTest, TestConnect) {
+ CreateCastSocket();
+
+ net::CompletionCallback connect_callback1;
+ net::CompletionCallback connect_callback2;
+
+ ExpectTcpConnectPending(&connect_callback1);
+ ExpectSslConnectPending(&connect_callback2);
+ EXPECT_CALL(handler_, OnConnectComplete(net::OK));
+ ExpectSslRead(1);
+
+ socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ connect_callback1.Run(net::OK);
+ connect_callback2.Run(net::OK);
+
+ EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state());
+ EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state());
+}
+
+// Test that the following connection flow works:
+// - TCP connection succeeds (async)
+// - SSL connection fails with cert error (async)
+// - Cert is extracted successfully
+// - Second TCP connection succeeds (async)
+// - Second SSL connection succeeds (async)
TEST_F(CastSocketTest, TestTwoStepConnect) {
+ CreateCastSocket();
+
// Expectations for the initial connect call
net::CompletionCallback tcp_connect_callback1;
net::CompletionCallback ssl_connect_callback1;
- ExpectTCPConnect(&tcp_connect_callback1);
- ExpectSSLConnect(&ssl_connect_callback1);
+ ExpectTcpConnectPending(&tcp_connect_callback1);
+ ExpectSslConnectPending(&ssl_connect_callback1);
// Start connect flow
socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete,
@@ -295,10 +388,10 @@
socket_->CreateNewSockets();
net::CompletionCallback tcp_connect_callback2;
net::CompletionCallback ssl_connect_callback2;
- ExpectTCPConnect(&tcp_connect_callback2);
- ExpectSSLConnect(&ssl_connect_callback2);
+ ExpectTcpConnectPending(&tcp_connect_callback2);
+ ExpectSslConnectPending(&ssl_connect_callback2);
EXPECT_CALL(handler_, OnConnectComplete(net::OK));
- ExpectSSLRead(1);
+ ExpectSslRead(1);
// Trigger callbacks for the first connect
ssl_connect_callback1.Run(net::ERR_CERT_AUTHORITY_INVALID);
@@ -311,15 +404,22 @@
EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state());
}
-// Test that connection will be attempted a maximum of 2 times even if the
-// second attempt also returns certificate authority invalid error.
+// Test that the following connection flow works:
+// - TCP connection succeeds (async)
+// - SSL connection fails with cert error (async)
+// - Cert is extracted successfully
+// - Second TCP connection succeeds (async)
+// - Second SSL connection fails (async)
+// - The flow should NOT be tried again
TEST_F(CastSocketTest, TestMaxTwoConnectAttempts) {
+ CreateCastSocket();
+
net::CompletionCallback tcp_connect_callback1;
net::CompletionCallback ssl_connect_callback1;
// Expectations for the initial connect call
- ExpectTCPConnect(&tcp_connect_callback1);
- ExpectSSLConnect(&ssl_connect_callback1);
+ ExpectTcpConnectPending(&tcp_connect_callback1);
+ ExpectSslConnectPending(&ssl_connect_callback1);
// Start connect flow
socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete,
@@ -331,8 +431,8 @@
net::CompletionCallback ssl_connect_callback2;
// Expectations for the second connect call
- ExpectTCPConnect(&tcp_connect_callback2);
- ExpectSSLConnect(&ssl_connect_callback2);
+ ExpectTcpConnectPending(&tcp_connect_callback2);
+ ExpectSslConnectPending(&ssl_connect_callback2);
EXPECT_CALL(handler_, OnConnectComplete(net::ERR_CERT_AUTHORITY_INVALID));
// Trigger callbacks for the first connect
@@ -346,12 +446,15 @@
EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state());
}
+// Test that when cert extraction fails the connection flow stops.
TEST_F(CastSocketTest, TestCertExtractionFailure) {
+ CreateCastSocket();
+
net::CompletionCallback connect_callback1;
net::CompletionCallback connect_callback2;
- ExpectTCPConnect(&connect_callback1);
- ExpectSSLConnect(&connect_callback2);
+ ExpectTcpConnectPending(&connect_callback1);
+ ExpectSslConnectPending(&connect_callback2);
socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete,
base::Unretained(&handler_)));
@@ -368,10 +471,85 @@
EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state());
}
+// Tests that the following connection flow works:
+// - TCP connection succeeds (async)
+// - SSL connection fails with cert error (async)
+// - Cert is extracted successfully
+// - Second TCP connection succeeds (async)
+// - Second SSL connection succeeds (async)
+// - Challenge request is sent (async)
+// - Challenge response is received (async)
+// - Credentials are verified successfuly
+TEST_F(CastSocketTest, TestFullSecureConnectionFlowAsync) {
+ CreateCastSocketSecure();
+
+ net::CompletionCallback tcp_connect_callback1;
+ net::CompletionCallback ssl_connect_callback1;
+
+ // Expectations for the initial connect call
+ ExpectTcpConnectPending(&tcp_connect_callback1);
+ ExpectSslConnectPending(&ssl_connect_callback1);
+
+ // Start connect flow
+ socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ tcp_connect_callback1.Run(net::OK);
+
+ socket_->CreateNewSockets();
+ net::CompletionCallback tcp_connect_callback2;
+ net::CompletionCallback ssl_connect_callback2;
+
+ // Expectations for the second connect call
+ ExpectTcpConnectPending(&tcp_connect_callback2);
+ ExpectSslConnectPending(&ssl_connect_callback2);
+ EXPECT_CALL(handler_, OnConnectComplete(net::OK));
+ ExpectSslRead(1);
+
+ // Trigger callbacks for the first connect
+ ssl_connect_callback1.Run(net::ERR_CERT_AUTHORITY_INVALID);
+
+ // Trigger callbacks for the second connect
+ tcp_connect_callback2.Run(net::OK);
+ ssl_connect_callback2.Run(net::OK);
+
+ // Trigger callbacks for auth events.
+ CallOnChallengeEvent(net::OK); // Sent challenge
+ CallOnChallengeEvent(net::OK); // Received reply
+
+ EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state());
+ EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state());
+}
+
+// Same as TestFullSecureConnectionFlowAsync, but operations are synchronous.
+TEST_F(CastSocketTest, TestFullSecureConnectionFlowSync) {
+ CreateCastSocketSecure();
+
+ net::CompletionCallback tcp_connect_callback;
+ net::CompletionCallback ssl_connect_callback;
+
+ // Expectations for the connect calls
+ ExpectTcpConnect(&tcp_connect_callback, net::OK);
+ ExpectSslConnect(&ssl_connect_callback, net::OK);
+ EXPECT_CALL(handler_, OnConnectComplete(net::OK));
+ ExpectSslRead(1);
+
+ socket_->SetSendAuthChallengeResult(net::OK);
+ socket_->SetReadAuthChallengeReplyResult(net::OK);
+
+ // Start connect flow
+ socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+
+ EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state());
+ EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state());
+}
+
// Tests writing a single message where the completion is signaled via
// callback.
TEST_F(CastSocketTest, TestWriteViaCallback) {
+ CreateCastSocket();
ConnectHelper();
+
net::CompletionCallback write_callback;
EXPECT_CALL(mock_ssl_socket(),
@@ -392,6 +570,7 @@
// Tests writing a single message where the Write() returns directly.
TEST_F(CastSocketTest, TestWrite) {
+ CreateCastSocket();
ConnectHelper();
EXPECT_CALL(mock_ssl_socket(),
@@ -410,6 +589,7 @@
// Tests writing multiple messages.
TEST_F(CastSocketTest, TestWriteMany) {
+ CreateCastSocket();
ConnectHelper();
std::string messages[4];
messages[0] = "Hello, World!";
@@ -448,6 +628,7 @@
// Tests error on writing.
TEST_F(CastSocketTest, TestWriteError) {
+ CreateCastSocket();
ConnectHelper();
net::CompletionCallback write_callback;
@@ -470,6 +651,8 @@
// Tests reading a single message.
TEST_F(CastSocketTest, TestRead) {
+ CreateCastSocket();
+
net::CompletionCallback connect_callback1;
net::CompletionCallback connect_callback2;
net::CompletionCallback read_callback;
@@ -518,6 +701,8 @@
// Tests reading multiple messages.
TEST_F(CastSocketTest, TestReadMany) {
+ CreateCastSocket();
+
net::CompletionCallback connect_callback1;
net::CompletionCallback connect_callback2;
net::CompletionCallback read_callback;
@@ -580,6 +765,8 @@
// Tests error on reading.
TEST_F(CastSocketTest, TestReadError) {
+ CreateCastSocket();
+
net::CompletionCallback connect_callback1;
net::CompletionCallback connect_callback2;
net::CompletionCallback read_callback;

Powered by Google App Engine
This is Rietveld 408576698