This is an automated email from the ASF dual-hosted git repository. mmartell pushed a commit to branch GEODE-8398-sni-support-dotnet in repository https://gitbox.apache.org/repos/asf/geode-native.git
commit 9796ddf72c3ca7bd7351d89005bb4f221a4dc0d8 Author: Blake Bender <[email protected]> AuthorDate: Fri Jul 31 15:29:15 2020 -0700 WIP: Sooooo close! Almost have hostname/port issues worked out for SNI connection --- cppcache/include/geode/PoolFactory.hpp | 5 ++ cppcache/integration/test/SNITest.cpp | 26 ++++---- .../sni-test-config/geode-config/truststore.p12 | Bin 0 -> 8983 bytes .../geode-config/truststore_sni.pem | 68 +++++++++++++++++++++ cppcache/src/PoolAttributes.cpp | 39 +----------- cppcache/src/PoolAttributes.hpp | 14 ++++- cppcache/src/PoolFactory.cpp | 21 +++++-- cppcache/src/TcpSslConn.cpp | 18 ++++-- cppcache/src/TcpSslConn.hpp | 42 ++++++++++--- cppcache/src/ThinClientLocatorHelper.cpp | 28 +++++++-- cppcache/src/ThinClientLocatorHelper.hpp | 5 ++ cppcache/src/ThinClientPoolDM.cpp | 4 +- cryptoimpl/SSLImpl.cpp | 6 +- cryptoimpl/SSLImpl.hpp | 3 +- cryptoimpl/Ssl.hpp | 3 +- ssl_keys/client_keys/truststore_sni.pem | 68 +++++++++++++++++++++ 16 files changed, 270 insertions(+), 80 deletions(-) diff --git a/cppcache/include/geode/PoolFactory.hpp b/cppcache/include/geode/PoolFactory.hpp index 195e28d..d554482 100644 --- a/cppcache/include/geode/PoolFactory.hpp +++ b/cppcache/include/geode/PoolFactory.hpp @@ -427,6 +427,11 @@ class APACHE_GEODE_EXPORT PoolFactory { PoolFactory& addServer(const std::string& host, int port); /** + * Set proxy info for SNI connection. Used for connecting via SNI proxy. + */ + PoolFactory& setSniProxy(const std::string& hostname, const int port); + + /** * If set to <code>true</code> then the created pool will have * server-to-client * subscriptions enabled. diff --git a/cppcache/integration/test/SNITest.cpp b/cppcache/integration/test/SNITest.cpp index 7e70619..ba8b7d0 100644 --- a/cppcache/integration/test/SNITest.cpp +++ b/cppcache/integration/test/SNITest.cpp @@ -28,6 +28,7 @@ #include <geode/RegionShortcut.hpp> #include "framework/Cluster.h" +#include "framework/TestConfig.h" namespace snitest { @@ -41,7 +42,8 @@ class SNITest : public ::testing::Test { protected: SNITest() { certificatePassword = std::string("apachegeode"); - currentWorkingDirectory = boost::filesystem::current_path(); + clientSslKeysDir = boost::filesystem::path( + getFrameworkString(FrameworkVariable::TestClientSslKeysDir)); } ~SNITest() override = default; @@ -108,16 +110,16 @@ class SNITest : public ::testing::Test { } std::string certificatePassword; - boost::filesystem::path currentWorkingDirectory; + boost::filesystem::path clientSslKeysDir; }; -TEST_F(SNITest, DISABLED_connectViaProxyTest) { +TEST_F(SNITest, connectViaProxyTest) { const auto clientTruststore = - (currentWorkingDirectory / - boost::filesystem::path("sni-test-config/geode-config/truststore.jks")); + (clientSslKeysDir / boost::filesystem::path("/truststore_sni.pem")); auto cache = CacheFactory() - .set("log-level", "DEBUG") + .set("log-level", "debug") + .set("log-file", "SNITest.log") .set("ssl-enabled", "true") .set("ssl-truststore", clientTruststore.string()) .create(); @@ -127,7 +129,8 @@ TEST_F(SNITest, DISABLED_connectViaProxyTest) { cache.getPoolManager() .createFactory() - .addLocator("localhost", portNumber) + .setSniProxy("localhost", portNumber) + .addLocator("locator-maeve", 10334) .create("pool"); auto region = cache.createRegionFactory(RegionShortcut::PROXY) @@ -141,8 +144,7 @@ TEST_F(SNITest, DISABLED_connectViaProxyTest) { TEST_F(SNITest, connectionFailsTest) { const auto clientTruststore = - (currentWorkingDirectory / - boost::filesystem::path("sni-test-config/geode-config/truststore.jks")); + (clientSslKeysDir / boost::filesystem::path("/truststore_sni.pem")); auto cache = CacheFactory() .set("log-level", "DEBUG") @@ -152,7 +154,8 @@ TEST_F(SNITest, connectionFailsTest) { cache.getPoolManager() .createFactory() - .addLocator("localhost", 10334) + .setSniProxy("badProxyName", 40000) + .addLocator("locator-maeve", 10334) .create("pool"); auto region = cache.createRegionFactory(RegionShortcut::PROXY) @@ -166,8 +169,7 @@ TEST_F(SNITest, connectionFailsTest) { TEST_F(SNITest, doNothingTest) { const auto clientTruststore = - (currentWorkingDirectory / - boost::filesystem::path("sni-test-config/geode-config/truststore.jks")); + (clientSslKeysDir / boost::filesystem::path("/truststore_sni.pem")); auto cache = CacheFactory() .set("log-level", "DEBUG") diff --git a/cppcache/integration/test/sni-test-config/geode-config/truststore.p12 b/cppcache/integration/test/sni-test-config/geode-config/truststore.p12 new file mode 100644 index 0000000..339d775 Binary files /dev/null and b/cppcache/integration/test/sni-test-config/geode-config/truststore.p12 differ diff --git a/cppcache/integration/test/sni-test-config/geode-config/truststore_sni.pem b/cppcache/integration/test/sni-test-config/geode-config/truststore_sni.pem new file mode 100644 index 0000000..1857ce6 --- /dev/null +++ b/cppcache/integration/test/sni-test-config/geode-config/truststore_sni.pem @@ -0,0 +1,68 @@ +-----BEGIN CERTIFICATE----- +MIICrDCCAZSgAwIBAgIEXozDxjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1s +b2NhdG9yLW1hZXZlMB4XDTIwMDQwNzE4MTc0MloXDTI1MDQwNzE4MTc0MlowGDEW +MBQGA1UEAwwNbG9jYXRvci1tYWV2ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOJ3jM2Rb50L+1fXyhZbaOHMuVUVGJ5jQV9wH3ijjeCEckaF29LbEtG8 +swMaxSoi4Sp/A4dp/7VI9CFZJKOX3zooZcuHyR7GSta4wH3oO55w0AfyTGeG6KF2 +Ekzj8pDPHyn/141rFAUPmMDnCfbF69Uixfi2XPxEJZw2GDN/YIHndY+X1pJ4ZuXS +SmrORSEOSmrN9X7pqbL5D2cy15cmTK5449ZqLEfZS72Mv3gve1Ax2JMWCBEwLdob +xW5utgmEe1/WhlhPzFr5C92znF/5Eucil/Rr+yynp31X+/QYBemYwOxbeZotHBZJ +tMLMzaInydrZ04wgHRftNeN0TIZkPmcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA +Jj1OSCWoILzWLBU1cAiQK8Gt0DVkqcpO4/vc3CoiU2T/em74cBzTwqmgrBvykWgq +f05jWQcod2yNg8trHrgx8F9CfyyvTXRIxttyfmbD7DAQk+qn9QBSbRJFfzo8VfNp +dGcT7KV9UDVyzltiTorqQJHUx3acUgtLYS2XUVlbGclhnNafRO44uobOsteAG01v +YqFa8ZaZM7qcZ88mbbKLXn6lo203JguM+TM0P7wHnzcww9sLmsP8W2cvsvefwCl4 +O7OYcjhcbEph+mIC3/zN8vF6d8xtLiMSGk6BNCHd003MBEhZHizyquGtAFLaEafX +V6sLm65i8uF2glnQfwS5JQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICrDCCAZSgAwIBAgIEXozDxjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1s +b2NhdG9yLW1hZXZlMB4XDTIwMDQwNzE4MTc0MloXDTI1MDQwNzE4MTc0MlowGDEW +MBQGA1UEAwwNbG9jYXRvci1tYWV2ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOJ3jM2Rb50L+1fXyhZbaOHMuVUVGJ5jQV9wH3ijjeCEckaF29LbEtG8 +swMaxSoi4Sp/A4dp/7VI9CFZJKOX3zooZcuHyR7GSta4wH3oO55w0AfyTGeG6KF2 +Ekzj8pDPHyn/141rFAUPmMDnCfbF69Uixfi2XPxEJZw2GDN/YIHndY+X1pJ4ZuXS +SmrORSEOSmrN9X7pqbL5D2cy15cmTK5449ZqLEfZS72Mv3gve1Ax2JMWCBEwLdob +xW5utgmEe1/WhlhPzFr5C92znF/5Eucil/Rr+yynp31X+/QYBemYwOxbeZotHBZJ +tMLMzaInydrZ04wgHRftNeN0TIZkPmcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA +Jj1OSCWoILzWLBU1cAiQK8Gt0DVkqcpO4/vc3CoiU2T/em74cBzTwqmgrBvykWgq +f05jWQcod2yNg8trHrgx8F9CfyyvTXRIxttyfmbD7DAQk+qn9QBSbRJFfzo8VfNp +dGcT7KV9UDVyzltiTorqQJHUx3acUgtLYS2XUVlbGclhnNafRO44uobOsteAG01v +YqFa8ZaZM7qcZ88mbbKLXn6lo203JguM+TM0P7wHnzcww9sLmsP8W2cvsvefwCl4 +O7OYcjhcbEph+mIC3/zN8vF6d8xtLiMSGk6BNCHd003MBEhZHizyquGtAFLaEafX +V6sLm65i8uF2glnQfwS5JQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIEXozGnzANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFz +ZXJ2ZXItY2xlbWVudGluZTAeFw0yMDA0MDcxODI5NTFaFw0yNTA0MDcxODI5NTFa +MBwxGjAYBgNVBAMMEXNlcnZlci1jbGVtZW50aW5lMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA6IzshjujS5c58AH8nJHBhlqjfNpacoNxhxykeCVsExa9 +vi0l8ezi35pte06j7gpMWhDYHokrHaw6ymp9iTi7D91yIPGeMMNUli8DnzgAzpeY +V8SGgkrVBalkVe0GimAHXMrzeZF+8D2BEdvDAsIUbrZRACElPlLUoiO93xZZ8ad+ +fAfLVetH4lDJ54FT7ia+St6L0QxSrDLvrqmc/58ZunkQBnQcd4tMjCD1kX4l+5Q1 +eF+Rc/SbY+/8HfyCZcA98voC3dKF13U+0YAf/0ahin+8Ckm6BL/StUxFNftTtJ7l +iKf56Y3FbSQ84Q9Te8feb05XidkF74Gifa4Q7gOzjwIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQDKvYcnVFryhupo156bB33BU14KN8b5joVyQLeGb2Tx+icZd/jFhqSQ +c3f8VV+aG9+CtRi/6wesdzf9/CVF+J4ARJ7j3i60NlJi4vQJlZnou+JSBgbBiDkW +p12ITsw7l1k2zxH8hoMPNbMK1EC/+uwVRJt92L52uShLw9zKtE4MLZxZVa7Amkf4 +zRc78fHwwPXoMjLcQxw+8JRjlciWr/hZccuppXI4qb17l6HAMvW4vCslao0c9pSp +Opg5Q0PwVXFROIvCANdxNI9ptSrH78Thxh4rggnHs+OZF02D22oTkjquU4Xrar3u +FXlIS8UmdkqAXGIJf0pqa48aXcqeipRe +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICrjCCAZagAwIBAgIEXozE5DANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDDA5z +ZXJ2ZXItZG9sb3JlczAeFw0yMDA0MDcxODIyMjhaFw0yNTA0MDcxODIyMjhaMBkx +FzAVBgNVBAMMDnNlcnZlci1kb2xvcmVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAyRTzsWsih9Boz2/aRFJsgJNDn8/C207kpvJ9lj0uBWNdZGJ86T4i +CwvIyMFvxeYQB0qO0AHf6FvJfMgunRlCj3fD01s7AHj8kCFoM/akgo04M7iJfSkU +dDCVuRbrFtz31akNckyxRw/oORiQ6NYGxnuAvtFdjE8jFc77WVXVU5QuqVEueJXs +HM+t6VGEn+7GwPsSJMIuEERd+05ZlghB1HoQD4Wu4+b/CXU+8aFRad0HRXHInBl0 +0QABETcMtpe3xIotC7H1nsAMipb0jyl3p+1a49FbrAktsiko8Y2iRVv3kZ58xfx9 +2Unmw+ViEb5bVRFytqb5AIgARI/+XX1zBwIDAQABMA0GCSqGSIb3DQEBCwUAA4IB +AQB39QXR3HLEju8B1oNCH1UciZetMxvORC2fwgXhqjbJ2YkHlykaLAAKv6DOSyc2 +HE40F2Q/Y0p0NC41+4YIiujgzKWaDI1Gw22PlceE2B49dO8evmldN2NixkirJbtm +bEtjINAxHXbhXn8GgUKJxSqtFPTX/fG7OCYvkvGItQAhSrGo9r5ACuDYkTZsBAZp +9jHc50TZsQ7od4jsPXrtZ6S2doOA0TdQ/+XzNyoadbG0YZbRtUVmhJN7gQfkBcjH +/AnYeYJL1kg39AuO3PsFhgWCsR2eNizGCh7CnHx7xpJnLYAw/01TGidsku/oYFiI +5SthBjGC992gTekW54hYtMBU +-----END CERTIFICATE----- diff --git a/cppcache/src/PoolAttributes.cpp b/cppcache/src/PoolAttributes.cpp index 2b4230d..206e1a4 100644 --- a/cppcache/src/PoolAttributes.cpp +++ b/cppcache/src/PoolAttributes.cpp @@ -44,46 +44,13 @@ PoolAttributes::PoolAttributes() m_subsEnabled(PoolFactory::DEFAULT_SUBSCRIPTION_ENABLED), m_multiuserSecurityMode(PoolFactory::DEFAULT_MULTIUSER_SECURE_MODE), m_isPRSingleHopEnabled(PoolFactory::DEFAULT_PR_SINGLE_HOP_ENABLED), - m_serverGrp(PoolFactory::DEFAULT_SERVER_GROUP) {} + m_serverGrp(PoolFactory::DEFAULT_SERVER_GROUP), + m_sniProxyPort(0) {} + std::shared_ptr<PoolAttributes> PoolAttributes::clone() { return std::make_shared<PoolAttributes>(*this); } -/** Return true if all the attributes are equal to those of other. */ -bool PoolAttributes::operator==(const PoolAttributes& other) const { - if (m_isThreadLocalConn != other.m_isThreadLocalConn) return false; - if (m_freeConnTimeout != other.m_freeConnTimeout) return false; - if (m_loadCondInterval != other.m_loadCondInterval) return false; - if (m_sockBufferSize != other.m_sockBufferSize) return false; - if (m_readTimeout != other.m_readTimeout) return false; - if (m_minConns != other.m_minConns) return false; - if (m_maxConns != other.m_maxConns) return false; - if (m_retryAttempts != other.m_retryAttempts) return false; - if (m_statsInterval != other.m_statsInterval) return false; - if (m_redundancy != other.m_redundancy) return false; - if (m_msgTrackTimeout != other.m_msgTrackTimeout) return false; - if (m_subsAckInterval != other.m_subsAckInterval) return false; - if (m_idleTimeout != other.m_idleTimeout) return false; - if (m_pingInterval != other.m_pingInterval) return false; - if (m_updateLocatorListInterval != other.m_updateLocatorListInterval) { - return false; - } - if (m_subsEnabled != other.m_subsEnabled) return false; - if (m_multiuserSecurityMode != other.m_multiuserSecurityMode) return false; - if (m_isPRSingleHopEnabled != other.m_isPRSingleHopEnabled) return false; - if (m_serverGrp != other.m_serverGrp) return false; - - if (m_initLocList.size() != other.m_initLocList.size()) return false; - if (m_initServList.size() != other.m_initServList.size()) return false; - - if (!compareVectorOfStrings(m_initLocList, other.m_initLocList)) return false; - if (!compareVectorOfStrings(m_initServList, other.m_initServList)) { - return false; - } - - return true; -} - bool PoolAttributes::compareVectorOfStrings( const std::vector<std::string>& thisVector, const std::vector<std::string>& otherVector) { diff --git a/cppcache/src/PoolAttributes.hpp b/cppcache/src/PoolAttributes.hpp index 3fee900..44d9633 100644 --- a/cppcache/src/PoolAttributes.hpp +++ b/cppcache/src/PoolAttributes.hpp @@ -121,6 +121,14 @@ class PoolAttributes { m_statsInterval = statisticInterval; } + const std::string& getSniProxyHost() const { return m_sniProxyHost; } + + void setSniProxyHost(const std::string& host) { m_sniProxyHost = host; } + + int getSniProxyPort() const { return m_sniProxyPort; } + + void setSniProxyPort(const int port) { m_sniProxyPort = port; } + const std::string& getServerGroup() const { return m_serverGrp; } void setServerGroup(std::string group) { m_serverGrp = group; } @@ -168,9 +176,6 @@ class PoolAttributes { std::shared_ptr<PoolAttributes> clone(); - /** Return true if all the attributes are equal to those of other. */ - bool operator==(const PoolAttributes& other) const; - private: bool m_isThreadLocalConn; std::chrono::milliseconds m_freeConnTimeout; @@ -197,6 +202,9 @@ class PoolAttributes { std::vector<std::string> m_initLocList; std::vector<std::string> m_initServList; + std::string m_sniProxyHost; + int m_sniProxyPort; + static bool compareVectorOfStrings( const std::vector<std::string>& thisVector, const std::vector<std::string>& otherVector); diff --git a/cppcache/src/PoolFactory.cpp b/cppcache/src/PoolFactory.cpp index 0ee2518..9a43f64 100644 --- a/cppcache/src/PoolFactory.cpp +++ b/cppcache/src/PoolFactory.cpp @@ -185,6 +185,13 @@ PoolFactory& PoolFactory::addServer(const std::string& host, int port) { return *this; } +PoolFactory& PoolFactory::setSniProxy(const std::string& hostname, + const int port) { + m_attrs->setSniProxyHost(hostname); + m_attrs->setSniProxyPort(port); + return *this; +} + PoolFactory& PoolFactory::setSubscriptionEnabled(bool enabled) { m_attrs->setSubscriptionEnabled(enabled); return *this; @@ -304,15 +311,17 @@ PoolFactory& PoolFactory::addCheck(const std::string& host, int port) { std::to_string(port)); } - ACE_INET_Addr addr(port, host.c_str()); + if (m_attrs->getSniProxyHost().empty()) { + ACE_INET_Addr addr(port, host.c_str()); #ifdef WITH_IPV6 - // check unknown host - // ACE will not initialize port if hostname is not resolved. - if (port != addr.get_port_number()) { + // check unknown host + // ACE will not initialize port if hostname is not resolved. + if (port != addr.get_port_number()) { #else - if (!(addr.get_ip_address())) { + if (!(addr.get_ip_address())) { #endif - throw IllegalArgumentException("Unknown host " + host); + throw IllegalArgumentException("Unknown host " + host); + } } return *this; } diff --git a/cppcache/src/TcpSslConn.cpp b/cppcache/src/TcpSslConn.cpp index 104b4b4..72cb7e1 100644 --- a/cppcache/src/TcpSslConn.cpp +++ b/cppcache/src/TcpSslConn.cpp @@ -28,6 +28,16 @@ namespace apache { namespace geode { namespace client { +void TcpSslConn::initSsl(const std::string& pubkeyfile, const std::string&, + const std::string& pemPassword, + const std::string& sniHostname, + const uint16_t sniPort) { + LOGDEBUG( + "*** TcpSslConn init, pubkeyfile = %s, pemPassword = %s, sniHostname = " + "%s", + pubkeyfile.c_str(), pemPassword.c_str(), sniHostname.c_str()); + m_sniPort = sniPort; +} Ssl* TcpSslConn::getSSLImpl(ACE_HANDLE sock, const char* pubkeyfile, const char* privkeyfile) { @@ -50,13 +60,13 @@ Ssl* TcpSslConn::getSSLImpl(ACE_HANDLE sock, const char* pubkeyfile, throw IllegalStateException(msg); } return reinterpret_cast<Ssl*>( - func(sock, pubkeyfile, privkeyfile, m_pemPassword)); + func(sock, pubkeyfile, privkeyfile, m_pemPassword.c_str())); } void TcpSslConn::createSocket(ACE_HANDLE sock) { LOGDEBUG("Creating SSL socket stream"); try { - m_ssl = getSSLImpl(sock, m_pubkeyfile, m_privkeyfile); + m_ssl = getSSLImpl(sock, m_pubkeyfile.c_str(), m_privkeyfile.c_str()); } catch (std::exception& e) { throw SslException(e.what()); } @@ -87,15 +97,13 @@ void TcpSslConn::connect() { ACE_OS::signal(SIGPIPE, SIG_IGN); // Ignore broken pipe - // m_ssl->init(); - std::chrono::microseconds waitMicroSeconds = m_waitMilliSeconds; LOGDEBUG("Connecting SSL socket stream to %s:%d waiting %s micro sec", m_addr.get_host_name(), m_addr.get_port_number(), to_string(waitMicroSeconds).c_str()); - int32_t retVal = m_ssl->connect(m_addr, waitMicroSeconds); + int32_t retVal = m_ssl->connect(m_addr, m_sniHostname, waitMicroSeconds); if (retVal == -1) { char msg[256]; diff --git a/cppcache/src/TcpSslConn.hpp b/cppcache/src/TcpSslConn.hpp index c14a5b5..eb6afe0 100644 --- a/cppcache/src/TcpSslConn.hpp +++ b/cppcache/src/TcpSslConn.hpp @@ -33,11 +33,12 @@ class TcpSslConn : public TcpConn { private: Ssl* m_ssl; ACE_DLL m_dll; - const char* m_pubkeyfile; - const char* m_privkeyfile; - const char* m_pemPassword; - // adongre: Added for Ticket #758 - // Pass extra parameter for the password + uint16_t m_sniPort; + std::string m_sniHostname; + std::string m_pubkeyfile; + std::string m_privkeyfile; + std::string m_pemPassword; + typedef void* (*gf_create_SslImpl)(ACE_HANDLE, const char*, const char*, const char*); typedef void (*gf_destroy_SslImpl)(void*); @@ -52,12 +53,27 @@ class TcpSslConn : public TcpConn { void createSocket(ACE_HANDLE sock) override; public: - TcpSslConn(const char* hostname, int32_t port, + TcpSslConn( std::chrono::microseconds waitSeconds, int32_t maxBuffSizePool, - const char* pubkeyfile, const char* privkeyfile, - const char* pemPassword) - : TcpConn(hostname, port, waitSeconds, maxBuffSizePool), + const std::string& sniProxyHostname, uint16_t sniProxyPort, + const std::string& pubkeyfile, const std::string& privkeyfile, + const std::string& pemPassword) + : TcpConn(sniProxyHostname.c_str(), sniProxyPort, waitSeconds, maxBuffSizePool), + m_ssl(nullptr), + m_sniPort(sniProxyPort), + m_sniHostname(sniProxyHostname), + m_pubkeyfile(pubkeyfile), + m_privkeyfile(privkeyfile), + m_pemPassword(pemPassword) {} + + TcpSslConn(const std::string& hostname, uint16_t port, + std::chrono::microseconds connect_timeout, int32_t maxBuffSizePool, + const std::string& pubkeyfile, const std::string& privkeyfile, + const std::string& pemPassword) + : TcpConn(hostname.c_str(), port, connect_timeout, maxBuffSizePool), m_ssl(nullptr), + m_sniPort(0), + m_sniHostname(""), m_pubkeyfile(pubkeyfile), m_privkeyfile(privkeyfile), m_pemPassword(pemPassword) {} @@ -67,14 +83,20 @@ class TcpSslConn : public TcpConn { const char* privkeyfile, const char* pemPassword) : TcpConn(ipaddr, waitSeconds, maxBuffSizePool), m_ssl(nullptr), + m_sniPort(0), + m_sniHostname(""), m_pubkeyfile(pubkeyfile), m_privkeyfile(privkeyfile), m_pemPassword(pemPassword) {} - // TODO: Watch out for virt dtor calling virt methods! + virtual ~TcpSslConn() override {} + private: + void initSsl(const std::string& pubkeyfile, const std::string& privkeyfile, + const std::string& pemPassword, + const std::string& sniHostname = "", const uint16_t sniPort = 0); // Close this tcp connection void close() override; diff --git a/cppcache/src/ThinClientLocatorHelper.cpp b/cppcache/src/ThinClientLocatorHelper.cpp index e7174ce..bbed2a0 100644 --- a/cppcache/src/ThinClientLocatorHelper.cpp +++ b/cppcache/src/ThinClientLocatorHelper.cpp @@ -66,6 +66,18 @@ ThinClientLocatorHelper::ThinClientLocatorHelper( } } +ThinClientLocatorHelper::ThinClientLocatorHelper( + const std::vector<std::string>& locatorAddresses, + const std::string& sniProxyHost, int sniProxyPort, + const ThinClientPoolDM* poolDM) + : m_poolDM(poolDM), + m_sniProxyHost(sniProxyHost), + m_sniProxyPort(sniProxyPort) { + for (auto&& locatorAddress : locatorAddresses) { + m_locHostPort.emplace_back(locatorAddress); + } +} + Connector* ThinClientLocatorHelper::createConnection( Connector*& conn, const char* hostname, int32_t port, std::chrono::microseconds waitSeconds, int32_t maxBuffSizePool) { @@ -75,10 +87,18 @@ Connector* ThinClientLocatorHelper::createConnection( ->getDistributedSystem() .getSystemProperties(); if (systemProperties.sslEnabled()) { - socket = new TcpSslConn(hostname, port, waitSeconds, maxBuffSizePool, - systemProperties.sslTrustStore().c_str(), - systemProperties.sslKeyStore().c_str(), - systemProperties.sslKeystorePassword().c_str()); + if (m_sniProxyHost.empty()) { + socket = new TcpSslConn( + hostname, static_cast<uint16_t>(port), waitSeconds, maxBuffSizePool, + systemProperties.sslTrustStore(), systemProperties.sslKeyStore(), + systemProperties.sslKeystorePassword()); + } else { + socket = new TcpSslConn( + waitSeconds, maxBuffSizePool, m_sniProxyHost, + m_sniProxyPort, systemProperties.sslTrustStore(), + systemProperties.sslKeyStore(), + systemProperties.sslKeystorePassword()); + } } else { socket = new TcpConn(hostname, port, waitSeconds, maxBuffSizePool); } diff --git a/cppcache/src/ThinClientLocatorHelper.hpp b/cppcache/src/ThinClientLocatorHelper.hpp index c72f950..df522a3 100644 --- a/cppcache/src/ThinClientLocatorHelper.hpp +++ b/cppcache/src/ThinClientLocatorHelper.hpp @@ -44,6 +44,9 @@ class ThinClientLocatorHelper { public: ThinClientLocatorHelper(const std::vector<std::string>& locatorAddresses, const ThinClientPoolDM* poolDM); + ThinClientLocatorHelper(const std::vector<std::string>& locatorAddresses, + const std::string& sniProxyHost, int sniProxyPort, + const ThinClientPoolDM* poolDM); GfErrType getEndpointForNewFwdConn( ServerLocation& outEndpoint, std::string& additionalLoc, const std::set<ServerLocation>& exclEndPts, @@ -71,6 +74,8 @@ class ThinClientLocatorHelper { const ThinClientPoolDM* m_poolDM; ThinClientLocatorHelper(const ThinClientLocatorHelper&); ThinClientLocatorHelper& operator=(const ThinClientLocatorHelper&); + std::string m_sniProxyHost; + int m_sniProxyPort; }; } // namespace client } // namespace geode diff --git a/cppcache/src/ThinClientPoolDM.cpp b/cppcache/src/ThinClientPoolDM.cpp index aab3200..8b7022d 100644 --- a/cppcache/src/ThinClientPoolDM.cpp +++ b/cppcache/src/ThinClientPoolDM.cpp @@ -186,7 +186,9 @@ ThinClientPoolDM::ThinClientPoolDM(const char* name, throw IllegalStateException(msg); } reset(); - m_locHelper = new ThinClientLocatorHelper(m_attrs->m_initLocList, this); + m_locHelper = new ThinClientLocatorHelper(m_attrs->m_initLocList, + m_attrs->m_sniProxyHost, + m_attrs->m_sniProxyPort, this); m_stats = new PoolStats( cacheImpl->getStatisticsManager().getStatisticsFactory(), m_poolName); diff --git a/cryptoimpl/SSLImpl.cpp b/cryptoimpl/SSLImpl.cpp index dad15a5..fe98e2e 100644 --- a/cryptoimpl/SSLImpl.cpp +++ b/cryptoimpl/SSLImpl.cpp @@ -18,7 +18,9 @@ #include "SSLImpl.hpp" #include <cstdint> +#include <iostream> #include <stdexcept> +#include <string> #include <ace/Guard_T.h> @@ -116,9 +118,11 @@ int SSLImpl::listen(ACE_INET_Addr addr, std::chrono::microseconds waitSeconds) { } } -int SSLImpl::connect(ACE_INET_Addr ipaddr, +int SSLImpl::connect(ACE_INET_Addr ipaddr, const std::string &proxyHostname, std::chrono::microseconds waitSeconds) { ACE_SSL_SOCK_Connector conn; + + SSL_set_tlsext_host_name(m_io->ssl(), proxyHostname.c_str()); if (waitSeconds > std::chrono::microseconds::zero()) { ACE_Time_Value wtime(waitSeconds); return conn.connect(*m_io, ipaddr, &wtime); diff --git a/cryptoimpl/SSLImpl.hpp b/cryptoimpl/SSLImpl.hpp index a70e965..9e6095b 100644 --- a/cryptoimpl/SSLImpl.hpp +++ b/cryptoimpl/SSLImpl.hpp @@ -66,7 +66,8 @@ class SSLImpl : public apache::geode::client::Ssl { int setOption(int, int, void*, int) override; int listen(ACE_INET_Addr, std::chrono::microseconds) override; - int connect(ACE_INET_Addr, std::chrono::microseconds) override; + int connect(ACE_INET_Addr, const std::string& proxyHostname, + std::chrono::microseconds) override; ssize_t recv(void*, size_t, const ACE_Time_Value*, size_t*) override; ssize_t send(const void*, size_t, const ACE_Time_Value*, size_t*) override; int getLocalAddr(ACE_Addr&) override; diff --git a/cryptoimpl/Ssl.hpp b/cryptoimpl/Ssl.hpp index 45b8da5..16b20ba 100644 --- a/cryptoimpl/Ssl.hpp +++ b/cryptoimpl/Ssl.hpp @@ -33,7 +33,8 @@ class Ssl { virtual ~Ssl() {} virtual int setOption(int, int, void*, int) = 0; virtual int listen(ACE_INET_Addr, std::chrono::microseconds) = 0; - virtual int connect(ACE_INET_Addr, std::chrono::microseconds) = 0; + virtual int connect(ACE_INET_Addr, const std::string& proxyHostname, + std::chrono::microseconds) = 0; virtual ssize_t recv(void*, size_t, const ACE_Time_Value*, size_t*) = 0; virtual ssize_t send(const void*, size_t, const ACE_Time_Value*, size_t*) = 0; virtual int getLocalAddr(ACE_Addr&) = 0; diff --git a/ssl_keys/client_keys/truststore_sni.pem b/ssl_keys/client_keys/truststore_sni.pem new file mode 100644 index 0000000..1857ce6 --- /dev/null +++ b/ssl_keys/client_keys/truststore_sni.pem @@ -0,0 +1,68 @@ +-----BEGIN CERTIFICATE----- +MIICrDCCAZSgAwIBAgIEXozDxjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1s +b2NhdG9yLW1hZXZlMB4XDTIwMDQwNzE4MTc0MloXDTI1MDQwNzE4MTc0MlowGDEW +MBQGA1UEAwwNbG9jYXRvci1tYWV2ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOJ3jM2Rb50L+1fXyhZbaOHMuVUVGJ5jQV9wH3ijjeCEckaF29LbEtG8 +swMaxSoi4Sp/A4dp/7VI9CFZJKOX3zooZcuHyR7GSta4wH3oO55w0AfyTGeG6KF2 +Ekzj8pDPHyn/141rFAUPmMDnCfbF69Uixfi2XPxEJZw2GDN/YIHndY+X1pJ4ZuXS +SmrORSEOSmrN9X7pqbL5D2cy15cmTK5449ZqLEfZS72Mv3gve1Ax2JMWCBEwLdob +xW5utgmEe1/WhlhPzFr5C92znF/5Eucil/Rr+yynp31X+/QYBemYwOxbeZotHBZJ +tMLMzaInydrZ04wgHRftNeN0TIZkPmcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA +Jj1OSCWoILzWLBU1cAiQK8Gt0DVkqcpO4/vc3CoiU2T/em74cBzTwqmgrBvykWgq +f05jWQcod2yNg8trHrgx8F9CfyyvTXRIxttyfmbD7DAQk+qn9QBSbRJFfzo8VfNp +dGcT7KV9UDVyzltiTorqQJHUx3acUgtLYS2XUVlbGclhnNafRO44uobOsteAG01v +YqFa8ZaZM7qcZ88mbbKLXn6lo203JguM+TM0P7wHnzcww9sLmsP8W2cvsvefwCl4 +O7OYcjhcbEph+mIC3/zN8vF6d8xtLiMSGk6BNCHd003MBEhZHizyquGtAFLaEafX +V6sLm65i8uF2glnQfwS5JQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICrDCCAZSgAwIBAgIEXozDxjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1s +b2NhdG9yLW1hZXZlMB4XDTIwMDQwNzE4MTc0MloXDTI1MDQwNzE4MTc0MlowGDEW +MBQGA1UEAwwNbG9jYXRvci1tYWV2ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOJ3jM2Rb50L+1fXyhZbaOHMuVUVGJ5jQV9wH3ijjeCEckaF29LbEtG8 +swMaxSoi4Sp/A4dp/7VI9CFZJKOX3zooZcuHyR7GSta4wH3oO55w0AfyTGeG6KF2 +Ekzj8pDPHyn/141rFAUPmMDnCfbF69Uixfi2XPxEJZw2GDN/YIHndY+X1pJ4ZuXS +SmrORSEOSmrN9X7pqbL5D2cy15cmTK5449ZqLEfZS72Mv3gve1Ax2JMWCBEwLdob +xW5utgmEe1/WhlhPzFr5C92znF/5Eucil/Rr+yynp31X+/QYBemYwOxbeZotHBZJ +tMLMzaInydrZ04wgHRftNeN0TIZkPmcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA +Jj1OSCWoILzWLBU1cAiQK8Gt0DVkqcpO4/vc3CoiU2T/em74cBzTwqmgrBvykWgq +f05jWQcod2yNg8trHrgx8F9CfyyvTXRIxttyfmbD7DAQk+qn9QBSbRJFfzo8VfNp +dGcT7KV9UDVyzltiTorqQJHUx3acUgtLYS2XUVlbGclhnNafRO44uobOsteAG01v +YqFa8ZaZM7qcZ88mbbKLXn6lo203JguM+TM0P7wHnzcww9sLmsP8W2cvsvefwCl4 +O7OYcjhcbEph+mIC3/zN8vF6d8xtLiMSGk6BNCHd003MBEhZHizyquGtAFLaEafX +V6sLm65i8uF2glnQfwS5JQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIEXozGnzANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFz +ZXJ2ZXItY2xlbWVudGluZTAeFw0yMDA0MDcxODI5NTFaFw0yNTA0MDcxODI5NTFa +MBwxGjAYBgNVBAMMEXNlcnZlci1jbGVtZW50aW5lMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA6IzshjujS5c58AH8nJHBhlqjfNpacoNxhxykeCVsExa9 +vi0l8ezi35pte06j7gpMWhDYHokrHaw6ymp9iTi7D91yIPGeMMNUli8DnzgAzpeY +V8SGgkrVBalkVe0GimAHXMrzeZF+8D2BEdvDAsIUbrZRACElPlLUoiO93xZZ8ad+ +fAfLVetH4lDJ54FT7ia+St6L0QxSrDLvrqmc/58ZunkQBnQcd4tMjCD1kX4l+5Q1 +eF+Rc/SbY+/8HfyCZcA98voC3dKF13U+0YAf/0ahin+8Ckm6BL/StUxFNftTtJ7l +iKf56Y3FbSQ84Q9Te8feb05XidkF74Gifa4Q7gOzjwIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQDKvYcnVFryhupo156bB33BU14KN8b5joVyQLeGb2Tx+icZd/jFhqSQ +c3f8VV+aG9+CtRi/6wesdzf9/CVF+J4ARJ7j3i60NlJi4vQJlZnou+JSBgbBiDkW +p12ITsw7l1k2zxH8hoMPNbMK1EC/+uwVRJt92L52uShLw9zKtE4MLZxZVa7Amkf4 +zRc78fHwwPXoMjLcQxw+8JRjlciWr/hZccuppXI4qb17l6HAMvW4vCslao0c9pSp +Opg5Q0PwVXFROIvCANdxNI9ptSrH78Thxh4rggnHs+OZF02D22oTkjquU4Xrar3u +FXlIS8UmdkqAXGIJf0pqa48aXcqeipRe +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICrjCCAZagAwIBAgIEXozE5DANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDDA5z +ZXJ2ZXItZG9sb3JlczAeFw0yMDA0MDcxODIyMjhaFw0yNTA0MDcxODIyMjhaMBkx +FzAVBgNVBAMMDnNlcnZlci1kb2xvcmVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAyRTzsWsih9Boz2/aRFJsgJNDn8/C207kpvJ9lj0uBWNdZGJ86T4i +CwvIyMFvxeYQB0qO0AHf6FvJfMgunRlCj3fD01s7AHj8kCFoM/akgo04M7iJfSkU +dDCVuRbrFtz31akNckyxRw/oORiQ6NYGxnuAvtFdjE8jFc77WVXVU5QuqVEueJXs +HM+t6VGEn+7GwPsSJMIuEERd+05ZlghB1HoQD4Wu4+b/CXU+8aFRad0HRXHInBl0 +0QABETcMtpe3xIotC7H1nsAMipb0jyl3p+1a49FbrAktsiko8Y2iRVv3kZ58xfx9 +2Unmw+ViEb5bVRFytqb5AIgARI/+XX1zBwIDAQABMA0GCSqGSIb3DQEBCwUAA4IB +AQB39QXR3HLEju8B1oNCH1UciZetMxvORC2fwgXhqjbJ2YkHlykaLAAKv6DOSyc2 +HE40F2Q/Y0p0NC41+4YIiujgzKWaDI1Gw22PlceE2B49dO8evmldN2NixkirJbtm +bEtjINAxHXbhXn8GgUKJxSqtFPTX/fG7OCYvkvGItQAhSrGo9r5ACuDYkTZsBAZp +9jHc50TZsQ7od4jsPXrtZ6S2doOA0TdQ/+XzNyoadbG0YZbRtUVmhJN7gQfkBcjH +/AnYeYJL1kg39AuO3PsFhgWCsR2eNizGCh7CnHx7xpJnLYAw/01TGidsku/oYFiI +5SthBjGC992gTekW54hYtMBU +-----END CERTIFICATE-----
