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

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


The following commit(s) were added to refs/heads/master by this push:
     new c46cb22  Allow empty fqdn in ssl_server_name for unsent SNI case.
c46cb22 is described below

commit c46cb2280e503c850db60c2ddabe8b2f5eea9439
Author: Susan Hinrichs <[email protected]>
AuthorDate: Thu Nov 29 19:47:24 2018 +0000

    Allow empty fqdn in ssl_server_name for unsent SNI case.
---
 iocore/net/P_SSLNetVConnection.h                   |  2 +-
 iocore/net/P_SSLSNI.h                              |  6 +-
 iocore/net/SSLNetVConnection.cc                    |  6 --
 iocore/net/SSLSNIConfig.cc                         |  4 +-
 iocore/net/SSLUtils.cc                             | 64 +++++++++++--------
 proxy/http/HttpSM.cc                               |  4 +-
 tests/gold_tests/tls/tls_tunnel.test.py            | 31 +++++++--
 ...el.test.py => tls_tunnel_plugin_rename.test.py} | 71 ++++++++-------------
 tests/tools/plugins/ssl_sni_rename_test.cc         | 73 ++++++++++++++++++++++
 9 files changed, 173 insertions(+), 88 deletions(-)

diff --git a/iocore/net/P_SSLNetVConnection.h b/iocore/net/P_SSLNetVConnection.h
index 163709a..e2b7fdc 100644
--- a/iocore/net/P_SSLNetVConnection.h
+++ b/iocore/net/P_SSLNetVConnection.h
@@ -361,7 +361,7 @@ public:
   ink_hrtime sslHandshakeEndTime   = 0;
   ink_hrtime sslLastWriteTime      = 0;
   int64_t sslTotalBytesSent        = 0;
-  char *serverName                 = nullptr;
+  std::string serverName;
 
   /// Set by asynchronous hooks to request a specific operation.
   SslVConnOp hookOpRequested = SSL_HOOK_OP_DEFAULT;
diff --git a/iocore/net/P_SSLSNI.h b/iocore/net/P_SSLSNI.h
index 781c4da..15580ff 100644
--- a/iocore/net/P_SSLSNI.h
+++ b/iocore/net/P_SSLSNI.h
@@ -76,7 +76,11 @@ public:
   {
     const char *err_ptr;
     int err_offset = 0;
-    match          = pcre_compile(regexName.c_str(), 0, &err_ptr, &err_offset, 
nullptr);
+    if (!regexName.empty()) {
+      match = pcre_compile(regexName.c_str(), 0, &err_ptr, &err_offset, 
nullptr);
+    } else {
+      match = nullptr;
+    }
   }
 
   pcre *match = nullptr;
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index e222d8e..86e150c 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -1709,12 +1709,6 @@ SSLNetVConnection::callHooks(TSEvent eventId)
 
   bool reenabled = true;
 
-  this->serverName = const_cast<char *>(SSL_get_servername(this->ssl, 
TLSEXT_NAMETYPE_host_name));
-  if (this->has_tunnel_destination()) {
-    this->attributes = HttpProxyPort::TRANSPORT_BLIND_TUNNEL;
-    return reenabled;
-  }
-
   if (SSL_HOOK_OP_TUNNEL == hookOpRequested) {
     this->attributes = HttpProxyPort::TRANSPORT_BLIND_TUNNEL;
     // Don't mark the handshake as complete yet,
diff --git a/iocore/net/SSLSNIConfig.cc b/iocore/net/SSLSNIConfig.cc
index ca4f193..21986b7 100644
--- a/iocore/net/SSLSNIConfig.cc
+++ b/iocore/net/SSLSNIConfig.cc
@@ -103,7 +103,9 @@ const actionVector *
 SNIConfigParams::get(const std::string &servername) const
 {
   for (auto retval = sni_action_list.begin(); retval != sni_action_list.end(); 
++retval) {
-    if (pcre_exec(retval->match, nullptr, servername.c_str(), 
servername.length(), 0, 0, nullptr, 0) >= 0) {
+    if (retval->match == nullptr && servername.length() == 0) {
+      return &retval->actions;
+    } else if (pcre_exec(retval->match, nullptr, servername.c_str(), 
servername.length(), 0, 0, nullptr, 0) >= 0) {
       return &retval->actions;
     }
   }
diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc
index 335ae53..f68c522 100644
--- a/iocore/net/SSLUtils.cc
+++ b/iocore/net/SSLUtils.cc
@@ -405,6 +405,24 @@ ssl_verify_client_callback(int preverify_ok, 
X509_STORE_CTX *ctx)
   return preverify_ok;
 }
 
+static int
+PerformAction(Continuation *cont, const char *servername)
+{
+  SNIConfig::scoped_config params;
+  const actionVector *actionvec = params->get(servername);
+  if (!actionvec) {
+    Debug("ssl_sni", "%s not available in the map", servername);
+  } else {
+    for (auto &&item : *actionvec) {
+      auto ret = item->SNIAction(cont);
+      if (ret != SSL_TLSEXT_ERR_OK) {
+        return ret;
+      }
+    }
+  }
+  return SSL_TLSEXT_ERR_OK;
+}
+
 // Use the certificate callback for openssl 1.0.2 and greater
 // otherwise use the SNI callback
 #if TS_USE_CERT_CB
@@ -445,41 +463,25 @@ ssl_cert_callback(SSL *ssl, void * /*arg*/)
   return retval;
 }
 
-static int
-PerformAction(Continuation *cont, const char *servername)
-{
-  SNIConfig::scoped_config params;
-  const actionVector *actionvec = params->get(servername);
-  if (!actionvec) {
-    Debug("ssl_sni", "%s not available in the map", servername);
-  } else {
-    for (auto &&item : *actionvec) {
-      auto ret = item->SNIAction(cont);
-      if (ret != SSL_TLSEXT_ERR_OK) {
-        return ret;
-      }
-    }
-  }
-  return SSL_TLSEXT_ERR_OK;
-}
-
 /*
  * Cannot stop this callback. Always reeneabled
  */
 static int
 ssl_servername_only_callback(SSL *ssl, int * /* ad */, void * /*arg*/)
 {
-  int ret                  = SSL_TLSEXT_ERR_OK;
   SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
-  const char *servername   = SSL_get_servername(ssl, 
TLSEXT_NAMETYPE_host_name);
-  Debug("ssl", "Requested servername is %s", servername);
-  if (servername != nullptr) {
-    ret = PerformAction(netvc, servername);
-  }
-  if (ret != SSL_TLSEXT_ERR_OK)
+  netvc->callHooks(TS_EVENT_SSL_SERVERNAME);
+
+  const char *name  = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+  netvc->serverName = std::string{name ? name : ""};
+  int ret           = PerformAction(netvc, netvc->serverName.c_str());
+  if (ret != SSL_TLSEXT_ERR_OK) {
     return SSL_TLSEXT_ERR_ALERT_FATAL;
+  }
+  if (netvc->has_tunnel_destination()) {
+    netvc->attributes = HttpProxyPort::TRANSPORT_BLIND_TUNNEL;
+  }
 
-  netvc->callHooks(TS_EVENT_SSL_SERVERNAME);
   return SSL_TLSEXT_ERR_OK;
 }
 
@@ -491,6 +493,16 @@ ssl_servername_and_cert_callback(SSL *ssl, int * /* ad */, 
void * /*arg*/)
   bool reenabled;
   int retval = 1;
 
+  const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+  if (servername == nullptr) {
+    servername = "";
+  }
+  Debug("ssl", "Requested servername is %s", servername);
+  int ret = PerformAction(netvc, servername);
+  if (ret != SSL_TLSEXT_ERR_OK) {
+    return SSL_TLSEXT_ERR_ALERT_FATAL;
+  }
+
   // If we are in tunnel mode, don't select a cert.  Pause!
   if (HttpProxyPort::TRANSPORT_BLIND_TUNNEL == netvc->attributes) {
     return -1; // Pause
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 52d4dde..b528932 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -583,7 +583,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->serverName.c_str(), 
ssl_vc->serverName.length());
         
t_state.hdr_info.client_request.url_get()->port_set(t_state.state_machine->ua_txn->get_netvc()->get_local_port());
       }
     }
@@ -1394,7 +1394,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->serverName.data(), 
ssl_vc->serverName.length());
         
t_state.hdr_info.client_request.url_get()->port_set(t_state.state_machine->ua_txn->get_netvc()->get_local_port());
       }
     }
diff --git a/tests/gold_tests/tls/tls_tunnel.test.py 
b/tests/gold_tests/tls/tls_tunnel.test.py
index e92c4a1..2c61a78 100644
--- a/tests/gold_tests/tls/tls_tunnel.test.py
+++ b/tests/gold_tests/tls/tls_tunnel.test.py
@@ -29,13 +29,14 @@ Test.SkipUnless(
 # Define default ATS
 ts = Test.MakeATSProcess("ts", select_ports=False)
 server_foo = Test.MakeOriginServer("server_foo", ssl=True)
-server_bar = Test.MakeOriginServer("server_bar", ssl=False)
+server_bar = Test.MakeOriginServer("server_bar", ssl=True)
 
-request_foo_header = {"headers": "GET / HTTP/1.1\r\nHost: foo.com\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
+request_foo_header = {"headers": "GET / HTTP/1.1\r\nHost: foo.com\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""} 
 request_bar_header = {"headers": "GET / HTTP/1.1\r\nHost: bar.com\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
-response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
-server_foo.addResponse("sessionlog.json", request_foo_header, response_header)
-server_bar.addResponse("sessionlog.json", request_bar_header, response_header)
+response_foo_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: 
close\r\n\r\n", "timestamp": "1469733493.993", "body": "foo ok"}
+response_bar_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: 
close\r\n\r\n", "timestamp": "1469733493.993", "body": "bar ok"}
+server_foo.addResponse("sessionlog.json", request_foo_header, 
response_foo_header)
+server_bar.addResponse("sessionlog.json", request_bar_header, 
response_bar_header)
 
 # add ssl materials like key, certificates for the server
 ts.addSSLfile("ssl/signed-foo.pem")
@@ -73,12 +74,15 @@ ts.Disk.records_config.update({
 })
 
 # foo.com should not terminate.  Just tunnel to server_foo
-# bar.com should terminate.  Forward its tcp stream to server_bar
+# bar.com should terminate.  
+# empty SNI should tunnel to server_bar
 ts.Disk.ssl_server_name_yaml.AddLines([
   '- fqdn: foo.com',
   "  tunnel_route: localhost:{0}".format(server_foo.Variables.Port),
   "- fqdn: bob.*.com",
   "  tunnel_route: localhost:{0}".format(server_foo.Variables.Port),
+  "- fqdn: ''", # No SNI sent
+  "  tunnel_route: localhost:{0}".format(server_bar.Variables.Port)
 ])
 
 tr = Test.AddTestRun("foo.com Tunnel-test")
@@ -95,6 +99,7 @@ tr.Processes.Default.Streams.All += 
Testers.ExcludesExpression("Not Found on Acc
 tr.Processes.Default.Streams.All += Testers.ExcludesExpression("CN=foo.com", 
"Should not TLS terminate on Traffic Server")
 tr.Processes.Default.Streams.All += Testers.ContainsExpression("HTTP/1.1 200 
OK", "Should get a successful response")
 tr.Processes.Default.Streams.All += Testers.ExcludesExpression("ATS", "Do not 
terminate on Traffic Server")
+tr.Processes.Default.Streams.All += Testers.ContainsExpression("foo ok", 
"Should get a response from bar")
 
 tr = Test.AddTestRun("bob.bar.com Tunnel-test")
 tr.Processes.Default.Command = "curl -v --resolve 'bob.bar.com:{0}:127.0.0.1' 
-k  https://bob.bar.com:{0}".format(ts.Variables.ssl_port)
@@ -107,6 +112,7 @@ tr.Processes.Default.Streams.All += 
Testers.ExcludesExpression("Not Found on Acc
 tr.Processes.Default.Streams.All += Testers.ExcludesExpression("CN=foo.com", 
"Should not TLS terminate on Traffic Server")
 tr.Processes.Default.Streams.All += Testers.ContainsExpression("HTTP/1.1 200 
OK", "Should get a successful response")
 tr.Processes.Default.Streams.All += Testers.ExcludesExpression("ATS", "Do not 
terminate on Traffic Server")
+tr.Processes.Default.Streams.All += Testers.ContainsExpression("foo ok", 
"Should get a response from bar")
 
 tr = Test.AddTestRun("bar.com no Tunnel-test")
 tr.Processes.Default.Command = "curl -v --resolve 'bar.com:{0}:127.0.0.1' -k  
https://bar.com:{0}".format(ts.Variables.ssl_port)
@@ -118,5 +124,18 @@ tr.Processes.Default.Streams.All += 
Testers.ExcludesExpression("Could Not Connec
 tr.Processes.Default.Streams.All += Testers.ContainsExpression("Not Found on 
Accelerato", "Terminates on on Traffic Server")
 tr.Processes.Default.Streams.All += Testers.ContainsExpression("ATS", 
"Terminate on Traffic Server")
 
+tr = Test.AddTestRun("no SNI Tunnel-test")
+tr.Processes.Default.Command = "curl -v -k  
https://127.0.0.1:{0}".format(ts.Variables.ssl_port)
+tr.ReturnCode = 0
+tr.StillRunningAfter = ts
+tr.Processes.Default.TimeOut = 5
+tr.TimeOut = 5
+tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not 
Connect", "Curl attempt should have succeeded")
+tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Not Found on 
Accelerato", "Should not try to remap on Traffic Server")
+tr.Processes.Default.Streams.All += Testers.ContainsExpression("HTTP/1.1 200 
OK", "Should get a successful response")
+tr.Processes.Default.Streams.All += Testers.ExcludesExpression("ATS", "Do not 
terminate on Traffic Server")
+tr.Processes.Default.Streams.All += Testers.ContainsExpression("bar ok", 
"Should get a response from bar")
+
+
 
 
diff --git a/tests/gold_tests/tls/tls_tunnel.test.py 
b/tests/gold_tests/tls/tls_tunnel_plugin_rename.test.py
similarity index 56%
copy from tests/gold_tests/tls/tls_tunnel.test.py
copy to tests/gold_tests/tls/tls_tunnel_plugin_rename.test.py
index e92c4a1..920ed9f 100644
--- a/tests/gold_tests/tls/tls_tunnel.test.py
+++ b/tests/gold_tests/tls/tls_tunnel_plugin_rename.test.py
@@ -18,7 +18,7 @@
 
 import os
 Test.Summary = '''
-Test tunneling based on SNI
+Test tunneling based on SNI renaming
 '''
 
 # need Curl
@@ -28,14 +28,17 @@ Test.SkipUnless(
 
 # Define default ATS
 ts = Test.MakeATSProcess("ts", select_ports=False)
-server_foo = Test.MakeOriginServer("server_foo", ssl=True)
-server_bar = Test.MakeOriginServer("server_bar", ssl=False)
+server_bar = Test.MakeOriginServer("server_bar", ssl=True)
+server_random = Test.MakeOriginServer("server_random", ssl=True)
 
-request_foo_header = {"headers": "GET / HTTP/1.1\r\nHost: foo.com\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
 request_bar_header = {"headers": "GET / HTTP/1.1\r\nHost: bar.com\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
-response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
-server_foo.addResponse("sessionlog.json", request_foo_header, response_header)
-server_bar.addResponse("sessionlog.json", request_bar_header, response_header)
+request_random_header = {"headers": "GET / HTTP/1.1\r\nHost: 
random.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""}
+response_bar_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: 
close\r\n\r\n", "timestamp": "1469733493.993", "body": "ok bar"}
+response_random_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: 
close\r\n\r\n", "timestamp": "1469733493.993", "body": "ok random"}
+server_bar.addResponse("sessionlog_bar.json", request_bar_header, 
response_bar_header)
+server_random.addResponse("sessionlog_random.json", request_random_header, 
response_random_header)
+
+Test.PreparePlugin(os.path.join(Test.Variables.AtsTestToolsDir, 'plugins', 
'ssl_sni_rename_test.cc'), ts)
 
 # add ssl materials like key, certificates for the server
 ts.addSSLfile("ssl/signed-foo.pem")
@@ -65,58 +68,36 @@ ts.Disk.records_config.update({
     'proxy.config.ssl.server.private_key.path': 
'{0}'.format(ts.Variables.SSLDir),
     # enable ssl port
     'proxy.config.http.server_ports': '{0} 
{1}:proto=http2;http:ssl'.format(ts.Variables.port, ts.Variables.ssl_port),
-    'proxy.config.http.connect_ports': '{0} {1} 
{2}'.format(ts.Variables.ssl_port,server_foo.Variables.Port,server_bar.Variables.Port),
+    'proxy.config.http.connect_ports': '{0} {1} 
{2}'.format(ts.Variables.ssl_port,server_bar.Variables.Port,server_random.Variables.Port),
     'proxy.config.ssl.server.cipher_suite': 
'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA:RC4-MD5:AES128-SHA:AES256-SHA:DES-CBC3-SHA!SRP:!DSS:!PSK:!aNULL:!eNULL:!SSLv2',
     'proxy.config.ssl.client.CA.cert.path': '{0}'.format(ts.Variables.SSLDir),
     'proxy.config.ssl.client.CA.cert.filename': 'signer.pem',
     'proxy.config.url_remap.pristine_host_hdr': 1
 })
 
-# foo.com should not terminate.  Just tunnel to server_foo
-# bar.com should terminate.  Forward its tcp stream to server_bar
+# bar.com should terminate.  
+# empty should tunnel to server_random (should not happen)
+# newname should tunnel to server_bar
 ts.Disk.ssl_server_name_yaml.AddLines([
-  '- fqdn: foo.com',
-  "  tunnel_route: localhost:{0}".format(server_foo.Variables.Port),
-  "- fqdn: bob.*.com",
-  "  tunnel_route: localhost:{0}".format(server_foo.Variables.Port),
-])
-
-tr = Test.AddTestRun("foo.com Tunnel-test")
-tr.Processes.Default.Command = "curl -v --resolve 'foo.com:{0}:127.0.0.1' -k  
https://foo.com:{0}".format(ts.Variables.ssl_port)
+  "- fqdn: newname",
+  "  tunnel_route: localhost:{0}".format(server_bar.Variables.Port),
+  "- fqdn: ''",  #default case
+  "  tunnel_route: localhost:{0}".format(server_random.Variables.Port),
+  ])
+
+# Plugin should add "newname" to the empty sni and go to _bar instead of 
random.com
+tr = Test.AddTestRun("no-sni-tunnel-test")
+tr.Processes.Default.Command = "curl --http1.1 -v -k 
https://127.0.0.1:{0}".format(ts.Variables.ssl_port)
 tr.ReturnCode = 0
-tr.Processes.Default.StartBefore(server_foo)
 tr.Processes.Default.StartBefore(server_bar)
+tr.Processes.Default.StartBefore(server_random)
 tr.Processes.Default.StartBefore(Test.Processes.ts, 
ready=When.PortOpen(ts.Variables.ssl_port))
-tr.StillRunningAfter = ts
+tr.StillRunningAfter = server_random
 tr.Processes.Default.TimeOut = 5
-tr.TimeOut = 5
-tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not 
Connect", "Curl attempt should have succeeded")
-tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Not Found on 
Accelerato", "Should not try to remap on Traffic Server")
-tr.Processes.Default.Streams.All += Testers.ExcludesExpression("CN=foo.com", 
"Should not TLS terminate on Traffic Server")
-tr.Processes.Default.Streams.All += Testers.ContainsExpression("HTTP/1.1 200 
OK", "Should get a successful response")
-tr.Processes.Default.Streams.All += Testers.ExcludesExpression("ATS", "Do not 
terminate on Traffic Server")
-
-tr = Test.AddTestRun("bob.bar.com Tunnel-test")
-tr.Processes.Default.Command = "curl -v --resolve 'bob.bar.com:{0}:127.0.0.1' 
-k  https://bob.bar.com:{0}".format(ts.Variables.ssl_port)
-tr.ReturnCode = 0
 tr.StillRunningAfter = ts
-tr.Processes.Default.TimeOut = 5
 tr.TimeOut = 5
 tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not 
Connect", "Curl attempt should have succeeded")
 tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Not Found on 
Accelerato", "Should not try to remap on Traffic Server")
-tr.Processes.Default.Streams.All += Testers.ExcludesExpression("CN=foo.com", 
"Should not TLS terminate on Traffic Server")
 tr.Processes.Default.Streams.All += Testers.ContainsExpression("HTTP/1.1 200 
OK", "Should get a successful response")
-tr.Processes.Default.Streams.All += Testers.ExcludesExpression("ATS", "Do not 
terminate on Traffic Server")
-
-tr = Test.AddTestRun("bar.com no Tunnel-test")
-tr.Processes.Default.Command = "curl -v --resolve 'bar.com:{0}:127.0.0.1' -k  
https://bar.com:{0}".format(ts.Variables.ssl_port)
-tr.ReturnCode = 0
-tr.StillRunningAfter = ts
-tr.Processes.Default.TimeOut = 5
-tr.TimeOut = 5
-tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not 
Connect", "Curl attempt should have succeeded")
-tr.Processes.Default.Streams.All += Testers.ContainsExpression("Not Found on 
Accelerato", "Terminates on on Traffic Server")
-tr.Processes.Default.Streams.All += Testers.ContainsExpression("ATS", 
"Terminate on Traffic Server")
-
-
+tr.Processes.Default.Streams.All += Testers.ContainsExpression("ok bar", "Body 
is expected")
 
diff --git a/tests/tools/plugins/ssl_sni_rename_test.cc 
b/tests/tools/plugins/ssl_sni_rename_test.cc
new file mode 100644
index 0000000..99a55ef
--- /dev/null
+++ b/tests/tools/plugins/ssl_sni_rename_test.cc
@@ -0,0 +1,73 @@
+/** @file
+
+  SSL Preaccept test plugin
+  Implements blind tunneling based on the client IP address
+  The client ip addresses are specified in the plugin's
+  config file as an array of IP addresses or IP address ranges under the
+  key "client-blind-tunnel"
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include <ts/ts.h>
+#include <ts/remap.h>
+#include <getopt.h>
+#include <openssl/ssl.h>
+#include <strings.h>
+#include <string>
+#include <map>
+
+#define PN "ssl_rename_test"
+#define PCP "[" PN " Plugin] "
+
+std::map<std::string, int> bad_names;
+
+int
+CB_server_rename(TSCont cont, TSEvent event, void *edata)
+{
+  TSVConn ssl_vc = reinterpret_cast<TSVConn>(edata);
+
+  TSSslConnection sslobj = TSVConnSSLConnectionGet(ssl_vc);
+  SSL *ssl               = (SSL *)sslobj;
+  const char *sni_name   = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+  if (!sni_name) {
+    SSL_set_tlsext_host_name(ssl, "newname");
+  }
+
+  // All done, reactivate things
+  TSVConnReenable(ssl_vc);
+  return TS_SUCCESS;
+}
+
+// Called by ATS as our initialization point
+void
+TSPluginInit(int argc, const char *argv[])
+{
+  TSPluginRegistrationInfo info;
+  info.plugin_name   = const_cast<char *>("SSL rename test");
+  info.vendor_name   = const_cast<char *>("apache");
+  info.support_email = const_cast<char *>("[email protected]");
+  if (TSPluginRegister(&info) != TS_SUCCESS) {
+    TSError("[%s] Plugin registration failed", PN);
+  }
+  TSCont cb = TSContCreate(&CB_server_rename, TSMutexCreate());
+  TSHttpHookAdd(TS_SSL_SERVERNAME_HOOK, cb);
+
+  return;
+}

Reply via email to