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;
+}