You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2020/01/14 21:45:31 UTC

[trafficserver] 01/03: Copy the Client SNI Server Name out of the openssl SSL object and ensure it is null-terminated.

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

zwoop pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 0fade4485a139abff4346b40c40db30bdb314ef6
Author: Walter Karas <wk...@verizonmedia.com>
AuthorDate: Wed Dec 4 18:32:45 2019 -0600

    Copy the Client SNI Server Name out of the openssl SSL object and ensure it is null-terminated.
    
    (cherry picked from commit 770f9d4f5a6825465f2ae5a681c5f3896479f635)
---
 iocore/net/P_SSLNetVConnection.h | 19 ++++++++++++++-----
 iocore/net/SSLNetVConnection.cc  | 14 ++++++++++++++
 iocore/net/SSLUtils.cc           | 15 ++++++++-------
 proxy/http/HttpSM.cc             |  4 ++--
 4 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/iocore/net/P_SSLNetVConnection.h b/iocore/net/P_SSLNetVConnection.h
index 609d6f1..60ce374 100644
--- a/iocore/net/P_SSLNetVConnection.h
+++ b/iocore/net/P_SSLNetVConnection.h
@@ -31,6 +31,8 @@
  ****************************************************************************/
 #pragma once
 
+#include <memory>
+
 #include "tscore/ink_platform.h"
 #include "ts/apidefs.h"
 #include <string_view>
@@ -393,11 +395,16 @@ public:
   ink_hrtime sslHandshakeEndTime   = 0;
   ink_hrtime sslLastWriteTime      = 0;
   int64_t sslTotalBytesSent        = 0;
-  // The serverName is either a pointer to the name fetched from the
-  // SSL object or the empty string.  Therefore, we do not allocate
-  // extra memory for this value.  If plugins in the future can set the
-  // serverName value, this strategy will have to change.
-  const char *serverName = nullptr;
+
+  // The serverName is either a pointer to the (null-terminated) name fetched from the
+  // SSL object or the empty string.
+  const char *
+  get_server_name() const
+  {
+    return _serverName.get() ? _serverName.get() : "";
+  }
+
+  void set_server_name(std::string_view name);
 
   /// Set by asynchronous hooks to request a specific operation.
   SslVConnOp hookOpRequested = SSL_HOOK_OP_DEFAULT;
@@ -472,6 +479,8 @@ private:
   in_port_t tunnel_port       = 0;
   bool tunnel_decrypt         = false;
   X509_STORE_CTX *verify_cert = nullptr;
+
+  std::unique_ptr<char[]> _serverName;
 };
 
 typedef int (SSLNetVConnection::*SSLNetVConnHandler)(int, void *);
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index fa59bb4..02618d4 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -45,6 +45,7 @@
 
 #include <climits>
 #include <string>
+#include <cstring>
 
 using namespace std::literals;
 
@@ -922,6 +923,8 @@ SSLNetVConnection::do_io_close(int lerrno)
 void
 SSLNetVConnection::clear()
 {
+  _serverName.reset();
+
   if (ssl != nullptr) {
     SSL_free(ssl);
     ssl = nullptr;
@@ -1921,3 +1924,14 @@ SSLNetVConnection::protocol_contains(std::string_view prefix) const
   }
   return retval;
 }
+
+void
+SSLNetVConnection::set_server_name(std::string_view name)
+{
+  if (name.size()) {
+    char *n = new char[name.size() + 1];
+    std::memcpy(n, name.data(), name.size());
+    n[name.size()] = '\0';
+    _serverName.reset(n);
+  }
+}
diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc
index eb28242..8255221 100644
--- a/iocore/net/SSLUtils.cc
+++ b/iocore/net/SSLUtils.cc
@@ -416,15 +416,16 @@ ssl_client_hello_callback(SSL *s, int *al, void *arg)
           len = *(p++) << 8;
           len += *(p++);
           if (len + 2 <= remaining) {
-            remaining  = len;
             servername = reinterpret_cast<const char *>(p);
           }
         }
       }
     }
   }
-  netvc->serverName = servername ? servername : "";
-  int ret           = PerformAction(netvc, netvc->serverName);
+  if (servername) {
+    netvc->set_server_name(std::string_view(servername, len));
+  }
+  int ret = PerformAction(netvc, netvc->get_server_name());
   if (ret != SSL_TLSEXT_ERR_OK) {
     return SSL_CLIENT_HELLO_ERROR;
   }
@@ -490,14 +491,14 @@ ssl_servername_callback(SSL *ssl, int * /* ad */, void * /*arg*/)
   SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
   netvc->callHooks(TS_EVENT_SSL_SERVERNAME);
 
-  netvc->serverName = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
-  if (nullptr == netvc->serverName) {
-    netvc->serverName = "";
+  const char *name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+  if (name) {
+    netvc->set_server_name(name);
   }
 
 #if !TS_USE_HELLO_CB
   // Only call the SNI actions here if not already performed in the HELLO_CB
-  int ret = PerformAction(netvc, netvc->serverName);
+  int ret = PerformAction(netvc, netvc->get_server_name());
   if (ret != SSL_TLSEXT_ERR_OK) {
     return SSL_TLSEXT_ERR_ALERT_FATAL;
   }
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 540b94c..c4e850b 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -581,7 +581,7 @@ HttpSM::setup_blind_tunnel_port()
           t_state.hdr_info.client_request.url_get()->port_set(t_state.state_machine->ua_txn->get_netvc()->get_local_port());
         }
       } else {
-        t_state.hdr_info.client_request.url_get()->host_set(ssl_vc->serverName, strlen(ssl_vc->serverName));
+        t_state.hdr_info.client_request.url_get()->host_set(ssl_vc->get_server_name(), strlen(ssl_vc->get_server_name()));
         t_state.hdr_info.client_request.url_get()->port_set(t_state.state_machine->ua_txn->get_netvc()->get_local_port());
       }
     }
@@ -1411,7 +1411,7 @@ plugins required to work with sni_routing.
           t_state.hdr_info.client_request.url_get()->port_set(t_state.state_machine->ua_txn->get_netvc()->get_local_port());
         }
       } else if (ssl_vc) {
-        t_state.hdr_info.client_request.url_get()->host_set(ssl_vc->serverName, strlen(ssl_vc->serverName));
+        t_state.hdr_info.client_request.url_get()->host_set(ssl_vc->get_server_name(), strlen(ssl_vc->get_server_name()));
         t_state.hdr_info.client_request.url_get()->port_set(t_state.state_machine->ua_txn->get_netvc()->get_local_port());
       }
     }