diff --git a/src/XrdCl/XrdClAsyncSocketHandler.cc b/src/XrdCl/XrdClAsyncSocketHandler.cc index 63110295590..3b65f2a5a00 100644 --- a/src/XrdCl/XrdClAsyncSocketHandler.cc +++ b/src/XrdCl/XrdClAsyncSocketHandler.cc @@ -25,94 +25,8 @@ #include "XrdCl/XrdClXRootDMsgHandler.hh" #include "XrdCl/XrdClOptimizers.hh" #include "XrdSys/XrdSysE2T.hh" -#include "XrdTls/XrdTlsContext.hh" - #include -#include -#include - -namespace -{ - //--------------------------------------------------------------------------- - // Multitone providing an unique instance of XrdTlsContext for every - // event-loop thread. - //--------------------------------------------------------------------------- - struct TlsContextProvider - { - //------------------------------------------------------------------------- - // Singleton access - //------------------------------------------------------------------------- - static TlsContextProvider& Instance() - { - static TlsContextProvider instance; - return instance; - } - - //------------------------------------------------------------------------- - // Get the TLS context unique to the calling thread - //------------------------------------------------------------------------- - XrdTlsContext& Get() - { - std::unique_lock lck( mtx ); - //----------------------------------------------------------------------- - // Each event-loop thread has its own SSL context - //----------------------------------------------------------------------- - std::thread::id this_id = std::this_thread::get_id(); - auto itr = instances.find( this_id ); - if( itr == instances.end() ) - { - std::string emsg; - auto p = instances.emplace( std::piecewise_construct, std::forward_as_tuple( this_id ), - std::forward_as_tuple( nullptr, nullptr, GetCaDir(), nullptr, 0, &emsg ) ); - itr = p.first; - //--------------------------------------------------------------------- - // If the context is not valid throw an exception! We throw generic - // exception as this will be translated to TlsError anyway. - //--------------------------------------------------------------------- - if( !itr->second.isOK() ) throw std::runtime_error( emsg ); - } - return itr->second; - } - - private: - - //----------------------------------------------------------------------- - // Default constructor - //----------------------------------------------------------------------- - TlsContextProvider(){ } - - //----------------------------------------------------------------------- - // Copy and move constructors, deleted! - //----------------------------------------------------------------------- - TlsContextProvider( const TlsContextProvider& ) = delete; - TlsContextProvider( TlsContextProvider&& ) = delete; - - //----------------------------------------------------------------------- - // Copy and move assignment operator, deleted! - //----------------------------------------------------------------------- - TlsContextProvider& operator=( const TlsContextProvider& ) = delete; - TlsContextProvider& operator=( TlsContextProvider&& ) = delete; - - //------------------------------------------------------------------------ - // Helper function for setting the CA directory in TLS context - //------------------------------------------------------------------------ - static const char* GetCaDir() - { - static const char *envval = getenv("X509_CERT_DIR"); - static const std::string cadir = envval ? envval : - "/etc/grid-security/certificates"; - return cadir.c_str(); - } - - //------------------------------------------------------------------------ - // TLS contexts for every event-loop thread - //------------------------------------------------------------------------ - std::unordered_map instances; - std::mutex mtx; - }; -} - namespace XrdCl { //---------------------------------------------------------------------------- @@ -850,17 +764,7 @@ namespace XrdCl if( !pSocket->IsEncrypted() && pTransport->NeedEncryption( pHandShakeData, *pChannelData ) ) { - //------------------------------------------------------------------------ - // - //------------------------------------------------------------------------ - XRootDStatus st = pSocket->CreateTLS( TlsContextProvider::Instance().Get(), - this ); - if( !st.IsOK() ) - { - OnFaultWhileHandshaking( st ); - return; - } - st = DoTlsHandShake(); + XRootDStatus st = DoTlsHandShake(); if( !st.IsOK() || st.code == suRetry ) return; } diff --git a/src/XrdCl/XrdClSocket.cc b/src/XrdCl/XrdClSocket.cc index ef300123cc9..fe00599a777 100644 --- a/src/XrdCl/XrdClSocket.cc +++ b/src/XrdCl/XrdClSocket.cc @@ -780,9 +780,20 @@ namespace XrdCl XRootDStatus Socket::TlsHandShake( AsyncSocketHandler *socketHandler, const std::string &thehost ) { - if( !pServerAddr ) return XRootDStatus( stError, errInvalidOp ); - if( !pTls ) XRootDStatus( stFatal, errTlsError, 0, "TLS context missing." ); - return pTls->Connect( thehost, pServerAddr.get() ); + try + { + if( !pServerAddr ) return XRootDStatus( stError, errInvalidOp ); + if( !pTls ) pTls.reset( new Tls( this, socketHandler ) ); + return pTls->Connect( thehost, pServerAddr.get() ); + } + catch( std::exception& ex ) + { + // the exception has been thrown when we tried to create + // the TLS context + return XRootDStatus( stFatal, errTlsError, 0, ex.what() ); + } + + return XRootDStatus(); } //------------------------------------------------------------------------ @@ -794,24 +805,6 @@ namespace XrdCl return bool( pTls.get() ); } - //------------------------------------------------------------------------ - // Create the TLS context for the Socket object - //------------------------------------------------------------------------ - XRootDStatus Socket::CreateTLS( XrdTlsContext &tlsContext, - AsyncSocketHandler *socketHandler) - { - try - { - pTls.reset( new Tls( tlsContext, this, socketHandler ) ); - } - catch( std::exception &ex ) - { - // the exception has been thrown when we tried to create - // the TLS context - return XRootDStatus( stFatal, errTlsError, 0, ex.what() ); - } - return XRootDStatus(); - } } diff --git a/src/XrdCl/XrdClSocket.hh b/src/XrdCl/XrdClSocket.hh index 5c25196447e..86b85212c9b 100644 --- a/src/XrdCl/XrdClSocket.hh +++ b/src/XrdCl/XrdClSocket.hh @@ -28,13 +28,12 @@ #include "XrdNet/XrdNetAddr.hh" #include "XrdSys/XrdSysKernelBuffer.hh" -class XrdTlsContext; namespace XrdCl { class AnyObject; - class AsyncSocketHandler; class Tls; + class AsyncSocketHandler; //---------------------------------------------------------------------------- //! A network socket @@ -287,12 +286,6 @@ namespace XrdCl //------------------------------------------------------------------------ bool IsEncrypted(); - //------------------------------------------------------------------------ - // Create the TLS context for the Socket object - //------------------------------------------------------------------------ - XRootDStatus CreateTLS( XrdTlsContext &tlsContext, - AsyncSocketHandler *socketHandler); - protected: //------------------------------------------------------------------------ //! Poll the socket to see whether it is ready for IO diff --git a/src/XrdCl/XrdClTls.cc b/src/XrdCl/XrdClTls.cc index a381acdc2c0..32b27e56c08 100644 --- a/src/XrdCl/XrdClTls.cc +++ b/src/XrdCl/XrdClTls.cc @@ -85,6 +85,17 @@ namespace return XrdTls::dbgOFF; } }; + + //------------------------------------------------------------------------ + // Helper function for setting the CA directory in TLS context + //------------------------------------------------------------------------ + static const char* GetCaDir() + { + static const char *envval = getenv("X509_CERT_DIR"); + static const std::string cadir = envval ? envval : + "/etc/grid-security/certificates"; + return cadir.c_str(); + } } namespace XrdCl @@ -92,15 +103,24 @@ namespace XrdCl //------------------------------------------------------------------------ // Constructor //------------------------------------------------------------------------ - Tls::Tls( XrdTlsContext &tlsContext, - Socket *socket, - AsyncSocketHandler *socketHandler ) : pSocket( socket ), - pTlsHSRevert( None ), - pSocketHandler( socketHandler ) + Tls::Tls( Socket *socket, AsyncSocketHandler *socketHandler ) : pSocket( socket ), pTlsHSRevert( None ), pSocketHandler( socketHandler ) { //---------------------------------------------------------------------- // Set the message callback for TLS layer //---------------------------------------------------------------------- + SetTlsMsgCB::Once(); + //---------------------------------------------------------------------- + // we only need one instance of TLS + //---------------------------------------------------------------------- + std::string emsg; + static XrdTlsContext tlsContext( 0, 0, GetCaDir(), 0, 0, &emsg ); + + //---------------------------------------------------------------------- + // If the context is not valid throw an exception! We throw generic + // exception as this will be translated to TlsError anyway. + //---------------------------------------------------------------------- + if( !tlsContext.isOK() ) throw std::runtime_error( emsg ); + pTls.reset( new XrdTlsSocket( tlsContext, pSocket->GetFD(), XrdTlsSocket::TLS_RNB_WNB, XrdTlsSocket::TLS_HS_NOBLK, true ) ); diff --git a/src/XrdCl/XrdClTls.hh b/src/XrdCl/XrdClTls.hh index e69511e1836..32ca6f8f1aa 100644 --- a/src/XrdCl/XrdClTls.hh +++ b/src/XrdCl/XrdClTls.hh @@ -40,7 +40,7 @@ namespace XrdCl //------------------------------------------------------------------------ //! Constructor - creates async TLS layer for given socker file descriptor //------------------------------------------------------------------------ - Tls( XrdTlsContext &tlsContext, Socket *socket, AsyncSocketHandler *socketHandler ); + Tls( Socket *socket, AsyncSocketHandler *socketHandler ); //------------------------------------------------------------------------ //! Destructor