From fd9dc32a3d80888b1f3edd1f2bb88768d10c9001 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 5 Mar 2015 14:15:42 +0100 Subject: [PATCH] Implement SNI support for the TlsStream class fixes #8610 --- lib/base/tlsstream.cpp | 10 ++++++++-- lib/base/tlsstream.hpp | 2 +- lib/cli/pkiutility.cpp | 4 ++-- lib/remote/apilistener.cpp | 8 ++++---- lib/remote/apilistener.hpp | 2 +- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/base/tlsstream.cpp b/lib/base/tlsstream.cpp index f9bbb6de2..6f6ab788b 100644 --- a/lib/base/tlsstream.cpp +++ b/lib/base/tlsstream.cpp @@ -39,7 +39,7 @@ bool I2_EXPORT TlsStream::m_SSLIndexInitialized = false; * @param role The role of the client. * @param sslContext The SSL context for the client. */ -TlsStream::TlsStream(const Socket::Ptr& socket, ConnectionRole role, const boost::shared_ptr& sslContext) +TlsStream::TlsStream(const Socket::Ptr& socket, const String& hostname, ConnectionRole role, const boost::shared_ptr& sslContext) : SocketEvents(socket, this), m_Eof(false), m_HandshakeOK(false), m_VerifyOK(true), m_ErrorCode(0), m_ErrorOccurred(false), m_Socket(socket), m_Role(role), m_SendQ(new FIFO()), m_RecvQ(new FIFO()), m_CurrentAction(TlsActionNone), m_Retry(false) @@ -73,8 +73,14 @@ TlsStream::TlsStream(const Socket::Ptr& socket, ConnectionRole role, const boost if (m_Role == RoleServer) SSL_set_accept_state(m_SSL.get()); - else + else { +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + if (!hostname.IsEmpty()) + SSL_set_tlsext_host_name(m_SSL.get(), hostname.CStr()); +#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */ + SSL_set_connect_state(m_SSL.get()); + } } TlsStream::~TlsStream(void) diff --git a/lib/base/tlsstream.hpp b/lib/base/tlsstream.hpp index c0c6907d3..cc627b1b5 100644 --- a/lib/base/tlsstream.hpp +++ b/lib/base/tlsstream.hpp @@ -48,7 +48,7 @@ class I2_BASE_API TlsStream : public Stream, private SocketEvents public: DECLARE_PTR_TYPEDEFS(TlsStream); - TlsStream(const Socket::Ptr& socket, ConnectionRole role, const boost::shared_ptr& sslContext); + TlsStream(const Socket::Ptr& socket, const String& hostname, ConnectionRole role, const boost::shared_ptr& sslContext); ~TlsStream(void); boost::shared_ptr GetClientCertificate(void) const; diff --git a/lib/cli/pkiutility.cpp b/lib/cli/pkiutility.cpp index ab8f7b04e..9a1c11ef0 100644 --- a/lib/cli/pkiutility.cpp +++ b/lib/cli/pkiutility.cpp @@ -153,7 +153,7 @@ int PkiUtility::SaveCert(const String& host, const String& port, const String& k return 1; } - TlsStream::Ptr stream = new TlsStream(client, RoleClient, sslContext); + TlsStream::Ptr stream = new TlsStream(client, String(), RoleClient, sslContext); try { stream->Handshake(); @@ -219,7 +219,7 @@ int PkiUtility::RequestCertificate(const String& host, const String& port, const return 1; } - TlsStream::Ptr stream = new TlsStream(client, RoleClient, sslContext); + TlsStream::Ptr stream = new TlsStream(client, String(), RoleClient, sslContext); try { stream->Handshake(); diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index cda6ccd75..7fe35b5c9 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -210,7 +210,7 @@ void ApiListener::ListenerThreadProc(const Socket::Ptr& server) for (;;) { try { Socket::Ptr client = server->Accept(); - Utility::QueueAsyncCallback(boost::bind(&ApiListener::NewClientHandler, this, client, RoleServer), LowLatencyScheduler); + Utility::QueueAsyncCallback(boost::bind(&ApiListener::NewClientHandler, this, client, String(), RoleServer), LowLatencyScheduler); } catch (const std::exception&) { Log(LogCritical, "ApiListener", "Cannot accept new connection."); } @@ -246,7 +246,7 @@ void ApiListener::AddConnection(const Endpoint::Ptr& endpoint) try { endpoint->SetConnecting(true); client->Connect(host, port); - NewClientHandler(client, RoleClient); + NewClientHandler(client, endpoint->GetName(), RoleClient); endpoint->SetConnecting(false); } catch (const std::exception& ex) { endpoint->SetConnecting(false); @@ -265,7 +265,7 @@ void ApiListener::AddConnection(const Endpoint::Ptr& endpoint) * * @param client The new client. */ -void ApiListener::NewClientHandler(const Socket::Ptr& client, ConnectionRole role) +void ApiListener::NewClientHandler(const Socket::Ptr& client, const String& hostname, ConnectionRole role) { CONTEXT("Handling new API client connection"); @@ -274,7 +274,7 @@ void ApiListener::NewClientHandler(const Socket::Ptr& client, ConnectionRole rol { ObjectLock olock(this); try { - tlsStream = new TlsStream(client, role, m_SSLContext); + tlsStream = new TlsStream(client, hostname, role, m_SSLContext); } catch (const std::exception&) { Log(LogCritical, "ApiListener", "Cannot create TLS stream from client connection."); return; diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp index 642db025e..7f3cc5057 100644 --- a/lib/remote/apilistener.hpp +++ b/lib/remote/apilistener.hpp @@ -86,7 +86,7 @@ private: bool AddListener(const String& node, const String& service); void AddConnection(const Endpoint::Ptr& endpoint); - void NewClientHandler(const Socket::Ptr& client, ConnectionRole role); + void NewClientHandler(const Socket::Ptr& client, const String& hostname, ConnectionRole role); void ListenerThreadProc(const Socket::Ptr& server); WorkQueue m_RelayQueue; -- 2.40.0