Merge commit 'c2e0344110c01eef33697c9611c5689e8eee0691' into pullstream

This commit is contained in:
Rebekah 2024-02-14 06:12:23 -05:00
commit c74bca6c28
Signed by: oneechanhax
GPG Key ID: 183EB7902964DAE5
5 changed files with 35 additions and 14 deletions

View File

@ -315,7 +315,7 @@ public:
m_Link = &a_Link; m_Link = &a_Link;
if (m_IsTls) if (m_IsTls)
{ {
m_Link->StartTLSClient(m_ParentRequest.GetOwnCert(), m_ParentRequest.GetOwnPrivKey(), m_ParentRequest.m_UrlHost); m_Link->StartTLSClient(m_ParentRequest.GetOwnCert(), m_ParentRequest.GetOwnPrivKey());
} }
else else
{ {

View File

@ -129,8 +129,7 @@ public:
Returns empty string on success, non-empty error description on failure. */ Returns empty string on success, non-empty error description on failure. */
virtual AString StartTLSClient( virtual AString StartTLSClient(
cX509CertPtr a_OwnCert, cX509CertPtr a_OwnCert,
cCryptoKeyPtr a_OwnPrivKey, cCryptoKeyPtr a_OwnPrivKey
const std::string_view hostname
) = 0; ) = 0;
/** Starts a TLS handshake as a server connection. /** Starts a TLS handshake as a server connection.

View File

@ -33,10 +33,11 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cTCPLinkImpl: // cTCPLinkImpl:
cTCPLinkImpl::cTCPLinkImpl(cTCPLink::cCallbacksPtr a_LinkCallbacks): cTCPLinkImpl::cTCPLinkImpl(const std::string & a_Host, cTCPLink::cCallbacksPtr a_LinkCallbacks):
Super(std::move(a_LinkCallbacks)), Super(std::move(a_LinkCallbacks)),
m_BufferEvent(bufferevent_socket_new(cNetworkSingleton::Get().GetEventBase(), -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE | BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS)), m_BufferEvent(bufferevent_socket_new(cNetworkSingleton::Get().GetEventBase(), -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE | BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS)),
m_LocalPort(0), m_LocalPort(0),
m_RemoteHost(a_Host),
m_RemotePort(0), m_RemotePort(0),
m_ShouldShutdown(false) m_ShouldShutdown(false)
{ {
@ -46,7 +47,13 @@ cTCPLinkImpl::cTCPLinkImpl(cTCPLink::cCallbacksPtr a_LinkCallbacks):
cTCPLinkImpl::cTCPLinkImpl(evutil_socket_t a_Socket, cTCPLink::cCallbacksPtr a_LinkCallbacks, cServerHandleImplPtr a_Server, const sockaddr * a_Address, socklen_t a_AddrLen): cTCPLinkImpl::cTCPLinkImpl(
evutil_socket_t a_Socket,
cTCPLink::cCallbacksPtr a_LinkCallbacks,
cServerHandleImplPtr a_Server,
const sockaddr * a_Address,
socklen_t a_AddrLen
):
Super(std::move(a_LinkCallbacks)), Super(std::move(a_LinkCallbacks)),
m_BufferEvent(bufferevent_socket_new(cNetworkSingleton::Get().GetEventBase(), a_Socket, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE | BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS)), m_BufferEvent(bufferevent_socket_new(cNetworkSingleton::Get().GetEventBase(), a_Socket, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE | BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS)),
m_Server(std::move(a_Server)), m_Server(std::move(a_Server)),
@ -81,7 +88,7 @@ cTCPLinkImplPtr cTCPLinkImpl::Connect(const AString & a_Host, UInt16 a_Port, cTC
ASSERT(a_ConnectCallbacks != nullptr); ASSERT(a_ConnectCallbacks != nullptr);
// Create a new link: // Create a new link:
cTCPLinkImplPtr res{new cTCPLinkImpl(std::move(a_LinkCallbacks))}; // Cannot use std::make_shared here, constructor is not accessible cTCPLinkImplPtr res{new cTCPLinkImpl(a_Host, std::move(a_LinkCallbacks))}; // Cannot use std::make_shared here, constructor is not accessible
res->m_ConnectCallbacks = std::move(a_ConnectCallbacks); res->m_ConnectCallbacks = std::move(a_ConnectCallbacks);
cNetworkSingleton::Get().AddLink(res); cNetworkSingleton::Get().AddLink(res);
res->m_Callbacks->OnLinkCreated(res); res->m_Callbacks->OnLinkCreated(res);
@ -253,8 +260,7 @@ void cTCPLinkImpl::Close(void)
AString cTCPLinkImpl::StartTLSClient( AString cTCPLinkImpl::StartTLSClient(
cX509CertPtr a_OwnCert, cX509CertPtr a_OwnCert,
cCryptoKeyPtr a_OwnPrivKey, cCryptoKeyPtr a_OwnPrivKey
const std::string_view hostname
) )
{ {
// Check preconditions: // Check preconditions:
@ -280,7 +286,11 @@ AString cTCPLinkImpl::StartTLSClient(
m_TlsContext->Initialize(true); m_TlsContext->Initialize(true);
} }
m_TlsContext->SetExpectedPeerName(hostname); // Enable SNI / peer name verification:
if (!m_RemoteHost.empty())
{
m_TlsContext->SetExpectedPeerName(m_RemoteHost);
}
m_TlsContext->SetSelf(cLinkTlsContextWPtr(m_TlsContext)); m_TlsContext->SetSelf(cLinkTlsContextWPtr(m_TlsContext));

View File

@ -56,9 +56,16 @@ public:
/** Creates a new link based on the given socket. /** Creates a new link based on the given socket.
Used for connections accepted in a server using cNetwork::Listen(). Used for connections accepted in a server using cNetwork::Listen().
a_Host is the hostname used for TLS SNI (can be empty in cases TLS is not used).
a_Address and a_AddrLen describe the remote peer that has connected. a_Address and a_AddrLen describe the remote peer that has connected.
The link is created disabled, you need to call Enable() to start the regular communication. */ The link is created disabled, you need to call Enable() to start the regular communication. */
cTCPLinkImpl(evutil_socket_t a_Socket, cCallbacksPtr a_LinkCallbacks, cServerHandleImplPtr a_Server, const sockaddr * a_Address, socklen_t a_AddrLen); cTCPLinkImpl(
evutil_socket_t a_Socket,
cCallbacksPtr a_LinkCallbacks,
cServerHandleImplPtr a_Server,
const sockaddr * a_Address,
socklen_t a_AddrLen
);
/** Destroys the LibEvent handle representing the link. */ /** Destroys the LibEvent handle representing the link. */
virtual ~cTCPLinkImpl() override; virtual ~cTCPLinkImpl() override;
@ -84,8 +91,7 @@ public:
virtual void Close(void) override; virtual void Close(void) override;
virtual AString StartTLSClient( virtual AString StartTLSClient(
cX509CertPtr a_OwnCert, cX509CertPtr a_OwnCert,
cCryptoKeyPtr a_OwnPrivKey, cCryptoKeyPtr a_OwnPrivKey
const std::string_view hostname
) override; ) override;
virtual AString StartTLSServer( virtual AString StartTLSServer(
cX509CertPtr a_OwnCert, cX509CertPtr a_OwnCert,
@ -167,6 +173,10 @@ protected:
/** The port of the local endpoint. Valid only after the socket has been connected. */ /** The port of the local endpoint. Valid only after the socket has been connected. */
UInt16 m_LocalPort; UInt16 m_LocalPort;
/** The original host parameter which was used for creating the link, either hostname or IP address.
Used for TLS SNI. */
AString m_RemoteHost;
/** The IP address of the remote endpoint. Valid only after the socket has been connected. */ /** The IP address of the remote endpoint. Valid only after the socket has been connected. */
AString m_RemoteIP; AString m_RemoteIP;
@ -191,7 +201,7 @@ protected:
Used for outgoing connections created using cNetwork::Connect(). Used for outgoing connections created using cNetwork::Connect().
To be used only by the Connect() factory function. To be used only by the Connect() factory function.
The link is created disabled, you need to call Enable() to start the regular communication. */ The link is created disabled, you need to call Enable() to start the regular communication. */
cTCPLinkImpl(const cCallbacksPtr a_LinkCallbacks); cTCPLinkImpl(const std::string & a_Host, const cCallbacksPtr a_LinkCallbacks);
/** Callback that LibEvent calls when there's data available from the remote peer. */ /** Callback that LibEvent calls when there's data available from the remote peer. */
static void ReadCallback(bufferevent * a_BufferEvent, void * a_Self); static void ReadCallback(bufferevent * a_BufferEvent, void * a_Self);

View File

@ -67,7 +67,9 @@ public:
/** Returns true if the object has been initialized properly. */ /** Returns true if the object has been initialized properly. */
bool IsValid(void) const { return m_IsValid; } bool IsValid(void) const { return m_IsValid; }
/** Sets the SSL peer name expected for this context. Must be called after Initialize(). /** Sets the SSL peer name expected for this context.
This is used both for TLS SNI and for certificate validation.
Must be called after Initialize().
\param a_ExpectedPeerName CommonName that we expect the SSL peer to have in its cert, \param a_ExpectedPeerName CommonName that we expect the SSL peer to have in its cert,
if it is different, the verification will fail. An empty string will disable the CN check. */ if it is different, the verification will fail. An empty string will disable the CN check. */
void SetExpectedPeerName(const std::string_view a_ExpectedPeerName); void SetExpectedPeerName(const std::string_view a_ExpectedPeerName);