AsyncSSLSocket connect without SSL
authorAaron Balsara <abalsara@fb.com>
Thu, 22 Jun 2017 18:26:36 +0000 (11:26 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Thu, 22 Jun 2017 18:37:59 +0000 (11:37 -0700)
Summary:
Currently when calling connect with AsyncSSLSocket in unencrypted
mode it still attempts to perform a SSL handshake. Add check to not
do SSL. Calling sslConnect will always run the SSL handshake

Reviewed By: jrahman

Differential Revision: D5153456

fbshipit-source-id: 4d9164115be72c8ee76e383535561e3083a327e3

folly/io/async/AsyncSSLSocket.cpp
folly/io/async/test/AsyncSSLSocketTest.cpp

index 5c9ee683205b2d75da3d295fd505ce56588931d6..bb2452e6cbcdce95b9ca1300bcf6053f200ae4c2 100644 (file)
@@ -454,8 +454,8 @@ void AsyncSSLSocket::sslAccept(
   verifyPeer_ = verifyPeer;
 
   // Make sure we're in the uninitialized state
-  if (!server_ || (sslState_ != STATE_UNINIT &&
-                   sslState_ != STATE_UNENCRYPTED) ||
+  if (!server_ ||
+      (sslState_ != STATE_UNINIT && sslState_ != STATE_UNENCRYPTED) ||
       handshakeCallback_ != nullptr) {
     return invalidState(callback);
   }
@@ -697,13 +697,15 @@ void AsyncSSLSocket::connect(
     const folly::SocketAddress& bindAddr) noexcept {
   assert(!server_);
   assert(state_ == StateEnum::UNINIT);
-  assert(sslState_ == STATE_UNINIT);
+  assert(sslState_ == STATE_UNINIT || sslState_ == STATE_UNENCRYPTED);
   noTransparentTls_ = true;
   totalConnectTimeout_ = totalConnectTimeout;
-  AsyncSSLSocketConnector* connector = new AsyncSSLSocketConnector(
-      this, callback, int(totalConnectTimeout.count()));
+  if (sslState_ != STATE_UNENCRYPTED) {
+    callback = new AsyncSSLSocketConnector(
+        this, callback, int(totalConnectTimeout.count()));
+  }
   AsyncSocket::connect(
-      connector, address, int(connectTimeout.count()), options, bindAddr);
+      callback, address, int(connectTimeout.count()), options, bindAddr);
 }
 
 bool AsyncSSLSocket::needsPeerVerification() const {
index 1ad8caa6afb4db8026854c3bd7742af1106a5b10..47e0902496687e77f13a5d06dfb4b2eb77a3f149 100644 (file)
@@ -1633,6 +1633,37 @@ TEST(AsyncSSLSocketTest, UnencryptedTest) {
   EXPECT_EQ(AsyncSSLSocket::STATE_ESTABLISHED, client->getSSLState());
 }
 
+TEST(AsyncSSLSocketTest, ConnectUnencryptedTest) {
+  auto clientCtx = std::make_shared<folly::SSLContext>();
+  auto serverCtx = std::make_shared<folly::SSLContext>();
+  getctx(clientCtx, serverCtx);
+
+  WriteCallbackBase writeCallback;
+  ReadCallback readCallback(&writeCallback);
+  HandshakeCallback handshakeCallback(&readCallback);
+  SSLServerAcceptCallback acceptCallback(&handshakeCallback);
+  TestSSLServer server(&acceptCallback);
+
+  EventBase evb;
+  std::shared_ptr<AsyncSSLSocket> socket =
+      AsyncSSLSocket::newSocket(clientCtx, &evb, true);
+  socket->connect(nullptr, server.getAddress(), 0);
+
+  evb.loop();
+
+  EXPECT_EQ(AsyncSSLSocket::STATE_UNENCRYPTED, socket->getSSLState());
+  socket->sslConn(nullptr);
+  evb.loop();
+  EXPECT_EQ(AsyncSSLSocket::STATE_ESTABLISHED, socket->getSSLState());
+
+  // write()
+  std::array<uint8_t, 128> buf;
+  memset(buf.data(), 'a', buf.size());
+  socket->write(nullptr, buf.data(), buf.size());
+
+  socket->close();
+}
+
 TEST(AsyncSSLSocketTest, ConnResetErrorString) {
   // Start listening on a local port
   WriteCallbackBase writeCallback;