This is an automated email from the ASF dual-hosted git repository.

grag pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit e258059d49779a02b6267a9d0829bd244b882ed5
Author: Joseph Wu <jos...@mesosphere.io>
AuthorDate: Wed Feb 26 17:14:50 2020 +0100

    SSL Socket: Moved accept callback logic into protected function.
    
    To support SSL downgrades, this logic will need to be called
    from two potential callsites.
    
    Also fixes a slight typo in a comment within the moved code.
    
    Review: https://reviews.apache.org/r/72014/
---
 3rdparty/libprocess/src/ssl/openssl_socket.cpp | 185 +++++++++++++------------
 3rdparty/libprocess/src/ssl/openssl_socket.hpp |   6 +
 2 files changed, 104 insertions(+), 87 deletions(-)

diff --git a/3rdparty/libprocess/src/ssl/openssl_socket.cpp 
b/3rdparty/libprocess/src/ssl/openssl_socket.cpp
index 74f9fe2..43909f0 100644
--- a/3rdparty/libprocess/src/ssl/openssl_socket.cpp
+++ b/3rdparty/libprocess/src/ssl/openssl_socket.cpp
@@ -573,93 +573,7 @@ Future<std::shared_ptr<SocketImpl>> 
OpenSSLSocketImpl::accept()
             return Break();
           }
 
-          // Wrap this new socket up into our SSL wrapper class by releasing
-          // the FD and creating a new OpenSSLSocketImpl object with the FD.
-          const std::shared_ptr<OpenSSLSocketImpl> ssl_socket =
-            std::make_shared<OpenSSLSocketImpl>(socket->release());
-
-          // Set up SSL object.
-          SSL* accept_ssl = SSL_new(openssl::context());
-          if (accept_ssl == nullptr) {
-            self->accept_queue.put(Failure("Accept failed, SSL_new"));
-            return Continue();
-          }
-
-          Try<Address> peer_address = network::peer(ssl_socket->get());
-          if (!peer_address.isSome()) {
-            SSL_free(accept_ssl);
-            self->accept_queue.put(
-                Failure("Could not determine peer IP for connection"));
-            return Continue();
-          }
-
-          // NOTE: Right now, `openssl::configure_socket` does not do anything
-          // in server mode, but we still pass the correct peer address to
-          // enable modules to implement application-level logic in the future.
-          Try<Nothing> configured = openssl::configure_socket(
-              accept_ssl, Mode::SERVER, peer_address.get(), None());
-
-          if (configured.isError()) {
-            SSL_free(accept_ssl);
-            self->accept_queue.put(
-                Failure("Could not configure socket: " + configured.error()));
-            return Continue();
-          }
-
-          // Set the SSL context in server mode.
-          SSL_set_accept_state(accept_ssl);
-
-          // Pass ownership of `accept_ssl` to the newly accepted socket,
-          // and wtart the SSL handshake. When the SSL handshake completes,
-          // the listening socket will place the result (failure or success)
-          // onto the listening socket's `accept_queue`.
-          //
-          // TODO(josephw): Add a timeout to catch/close incoming sockets which
-          // never finish the SSL handshake.
-          ssl_socket->set_ssl_and_do_handshake(accept_ssl)
-            .onAny([weak_self, ssl_socket](Future<size_t> result) {
-              std::shared_ptr<OpenSSLSocketImpl> self(weak_self.lock());
-
-              if (self == nullptr) {
-                return;
-              }
-
-              if (result.isFailed()) {
-                self->accept_queue.put(Failure(result.failure()));
-                return;
-              }
-
-              // For verification purposes, we need to grab the address 
(again).
-              Try<Address> address = network::address(ssl_socket->get());
-              if (address.isError()) {
-                self->accept_queue.put(
-                    Failure("Failed to get address: " + address.error()));
-                return;
-              }
-
-              Try<inet::Address> inet_address =
-                network::convert<inet::Address>(address.get());
-
-              Try<Nothing> verify = openssl::verify(
-                  ssl_socket->ssl,
-                  Mode::SERVER,
-                  None(),
-                  inet_address.isSome()
-                    ? Some(inet_address->ip)
-                    : Option<net::IP>::none());
-
-              if (verify.isError()) {
-                VLOG(1) << "Failed accept, verification error: "
-                        << verify.error();
-
-                self->accept_queue.put(Failure(verify.error()));
-                return;
-              }
-
-              self->accept_queue.put(ssl_socket);
-            });
-
-          return Continue();
+          return self->handle_accept_callback(socket);
         });
 
     accept_loop_started.done();
@@ -735,6 +649,103 @@ Try<Nothing, SocketError> OpenSSLSocketImpl::shutdown(int 
how)
 }
 
 
+Future<ControlFlow<Nothing>> OpenSSLSocketImpl::handle_accept_callback(
+    const std::shared_ptr<SocketImpl>& socket)
+{
+  // Wrap this new socket up into our SSL wrapper class by releasing
+  // the FD and creating a new OpenSSLSocketImpl object with the FD.
+  const std::shared_ptr<OpenSSLSocketImpl> ssl_socket =
+    std::make_shared<OpenSSLSocketImpl>(socket->release());
+
+  // Set up SSL object.
+  SSL* accept_ssl = SSL_new(openssl::context());
+  if (accept_ssl == nullptr) {
+    accept_queue.put(Failure("Accept failed, SSL_new"));
+    return Continue();
+  }
+
+  Try<Address> peer_address = network::peer(ssl_socket->get());
+  if (!peer_address.isSome()) {
+    SSL_free(accept_ssl);
+    accept_queue.put(
+        Failure("Could not determine peer IP for connection"));
+    return Continue();
+  }
+
+  // NOTE: Right now, `openssl::configure_socket` does not do anything
+  // in server mode, but we still pass the correct peer address to
+  // enable modules to implement application-level logic in the future.
+  Try<Nothing> configured = openssl::configure_socket(
+      accept_ssl, Mode::SERVER, peer_address.get(), None());
+
+  if (configured.isError()) {
+    SSL_free(accept_ssl);
+    accept_queue.put(
+        Failure("Could not configure socket: " + configured.error()));
+    return Continue();
+  }
+
+  // Set the SSL context in server mode.
+  SSL_set_accept_state(accept_ssl);
+
+  // Hold a weak pointer since we do not want this accept function to extend
+  // the lifetime of `this` unnecessarily.
+  std::weak_ptr<OpenSSLSocketImpl> weak_self(shared(this));
+
+  // Pass ownership of `accept_ssl` to the newly accepted socket,
+  // and start the SSL handshake. When the SSL handshake completes,
+  // the listening socket will place the result (failure or success)
+  // onto the listening socket's `accept_queue`.
+  //
+  // TODO(josephw): Add a timeout to catch/close incoming sockets which
+  // never finish the SSL handshake.
+  ssl_socket->set_ssl_and_do_handshake(accept_ssl)
+    .onAny([weak_self, ssl_socket](Future<size_t> result) {
+      std::shared_ptr<OpenSSLSocketImpl> self(weak_self.lock());
+
+      if (self == nullptr) {
+        return;
+      }
+
+      if (result.isFailed()) {
+        self->accept_queue.put(Failure(result.failure()));
+        return;
+      }
+
+      // For verification purposes, we need to grab the address (again).
+      Try<Address> address = network::address(ssl_socket->get());
+      if (address.isError()) {
+        self->accept_queue.put(
+            Failure("Failed to get address: " + address.error()));
+        return;
+      }
+
+      Try<inet::Address> inet_address =
+        network::convert<inet::Address>(address.get());
+
+      Try<Nothing> verify = openssl::verify(
+          ssl_socket->ssl,
+          Mode::SERVER,
+          None(),
+          inet_address.isSome()
+            ? Some(inet_address->ip)
+            : Option<net::IP>::none());
+
+      if (verify.isError()) {
+        VLOG(1) << "Failed accept, verification error: "
+                << verify.error();
+
+        self->accept_queue.put(Failure(verify.error()));
+        return;
+      }
+
+      self->accept_queue.put(ssl_socket);
+    });
+
+  return Continue();
+}
+
+
 Future<size_t> OpenSSLSocketImpl::set_ssl_and_do_handshake(SSL* _ssl)
 {
   // NOTE: We would normally create this UPID in the socket's constructor.
diff --git a/3rdparty/libprocess/src/ssl/openssl_socket.hpp 
b/3rdparty/libprocess/src/ssl/openssl_socket.hpp
index 2d0259d..0528c03 100644
--- a/3rdparty/libprocess/src/ssl/openssl_socket.hpp
+++ b/3rdparty/libprocess/src/ssl/openssl_socket.hpp
@@ -55,6 +55,12 @@ public:
   Try<Nothing, SocketError> shutdown(int how) override;
 
 protected:
+  // Verifies incoming sockets and initiates the SSL handshake.
+  // Upon completion or failure of the SSL handshake, the peer socket
+  // (or Failure object) will be enqueued on the server socket's accept queue.
+  Future<ControlFlow<Nothing>> handle_accept_callback(
+      const std::shared_ptr<SocketImpl>& socket);
+
   // Takes ownership of the given SSL object and performs an SSL handshake
   // with the context of the SSL object. Either `SSL_set_connect_state`
   // or `SSL_set_accept_state` must be called on the context beforehand,

Reply via email to