mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-22 16:02:29 +02:00
4435 secure sock thread (#4512)
* fix(SecureSocket): Refactor detection of timeout when reading, writing or handshaking. (#3725) * enh(SecureSocket): some trivial C++17 modernisation changes. * chore: indentation and compiler warning * fix(SecureSocketImpl): not thread-safe (1st attempt) #4435 * fix(SecureSocketImpl): silence CodeQL cpp/certificate-not-checked --------- Co-authored-by: Matej Kenda <matejken@gmail.com>
This commit is contained in:

committed by
GitHub

parent
8d3de8a5ed
commit
ece360393f
@@ -284,16 +284,21 @@ protected:
|
|||||||
/// Callback to handle new session data sent by server.
|
/// Callback to handle new session data sent by server.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using MutexT = Poco::FastMutex;
|
||||||
|
using LockT = MutexT::ScopedLock;
|
||||||
|
using UnLockT = Poco::ScopedLockWithUnlock<MutexT>;
|
||||||
|
|
||||||
SecureSocketImpl(const SecureSocketImpl&);
|
SecureSocketImpl(const SecureSocketImpl&);
|
||||||
SecureSocketImpl& operator = (const SecureSocketImpl&);
|
SecureSocketImpl& operator = (const SecureSocketImpl&);
|
||||||
|
|
||||||
SSL* _pSSL;
|
std::atomic<SSL*> _pSSL;
|
||||||
Poco::AutoPtr<SocketImpl> _pSocket;
|
Poco::AutoPtr<SocketImpl> _pSocket;
|
||||||
Context::Ptr _pContext;
|
Context::Ptr _pContext;
|
||||||
bool _needHandshake;
|
bool _needHandshake;
|
||||||
std::string _peerHostName;
|
std::string _peerHostName;
|
||||||
Session::Ptr _pSession;
|
Session::Ptr _pSession;
|
||||||
bool _bidirectShutdown = true;
|
bool _bidirectShutdown = true;
|
||||||
|
mutable MutexT _mutex;
|
||||||
|
|
||||||
friend class SecureStreamSocketImpl;
|
friend class SecureStreamSocketImpl;
|
||||||
friend class Context;
|
friend class Context;
|
||||||
|
@@ -80,6 +80,8 @@ void SecureSocketImpl::acceptSSL()
|
|||||||
{
|
{
|
||||||
poco_assert (!_pSSL);
|
poco_assert (!_pSSL);
|
||||||
|
|
||||||
|
LockT l(_mutex);
|
||||||
|
|
||||||
BIO* pBIO = ::BIO_new(BIO_s_socket());
|
BIO* pBIO = ::BIO_new(BIO_s_socket());
|
||||||
if (!pBIO) throw SSLException("Cannot create BIO object");
|
if (!pBIO) throw SSLException("Cannot create BIO object");
|
||||||
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
|
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
|
||||||
@@ -156,6 +158,8 @@ void SecureSocketImpl::connectSSL(bool performHandshake)
|
|||||||
poco_assert (!_pSSL);
|
poco_assert (!_pSSL);
|
||||||
poco_assert (_pSocket->initialized());
|
poco_assert (_pSocket->initialized());
|
||||||
|
|
||||||
|
LockT l(_mutex);
|
||||||
|
|
||||||
::BIO* pBIO = ::BIO_new(BIO_s_socket());
|
::BIO* pBIO = ::BIO_new(BIO_s_socket());
|
||||||
if (!pBIO) throw SSLException("Cannot create SSL BIO object");
|
if (!pBIO) throw SSLException("Cannot create SSL BIO object");
|
||||||
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
|
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
|
||||||
@@ -253,6 +257,8 @@ void SecureSocketImpl::shutdown()
|
|||||||
{
|
{
|
||||||
if (_pSSL)
|
if (_pSSL)
|
||||||
{
|
{
|
||||||
|
UnLockT l(_mutex);
|
||||||
|
|
||||||
// Don't shut down the socket more than once.
|
// Don't shut down the socket more than once.
|
||||||
int shutdownState = ::SSL_get_shutdown(_pSSL);
|
int shutdownState = ::SSL_get_shutdown(_pSSL);
|
||||||
bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN;
|
bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN;
|
||||||
@@ -301,6 +307,9 @@ void SecureSocketImpl::shutdown()
|
|||||||
int rc = ::SSL_shutdown(_pSSL);
|
int rc = ::SSL_shutdown(_pSSL);
|
||||||
#endif
|
#endif
|
||||||
if (rc < 0) handleError(rc);
|
if (rc < 0) handleError(rc);
|
||||||
|
|
||||||
|
l.unlock();
|
||||||
|
|
||||||
if (_pSocket->getBlocking())
|
if (_pSocket->getBlocking())
|
||||||
{
|
{
|
||||||
_pSocket->shutdown();
|
_pSocket->shutdown();
|
||||||
@@ -345,6 +354,9 @@ int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags)
|
|||||||
poco_check_ptr (_pSSL);
|
poco_check_ptr (_pSSL);
|
||||||
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
LockT l(_mutex);
|
||||||
|
|
||||||
if (_needHandshake)
|
if (_needHandshake)
|
||||||
{
|
{
|
||||||
rc = completeHandshake();
|
rc = completeHandshake();
|
||||||
@@ -381,6 +393,9 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
|
|||||||
poco_check_ptr (_pSSL);
|
poco_check_ptr (_pSSL);
|
||||||
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
LockT l(_mutex);
|
||||||
|
|
||||||
if (_needHandshake)
|
if (_needHandshake)
|
||||||
{
|
{
|
||||||
rc = completeHandshake();
|
rc = completeHandshake();
|
||||||
@@ -414,6 +429,8 @@ int SecureSocketImpl::available() const
|
|||||||
{
|
{
|
||||||
poco_check_ptr (_pSSL);
|
poco_check_ptr (_pSSL);
|
||||||
|
|
||||||
|
LockT l(_mutex);
|
||||||
|
|
||||||
return ::SSL_pending(_pSSL);
|
return ::SSL_pending(_pSSL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,7 +485,7 @@ long SecureSocketImpl::verifyPeerCertificateImpl(const std::string& hostName)
|
|||||||
{
|
{
|
||||||
Context::VerificationMode mode = _pContext->verificationMode();
|
Context::VerificationMode mode = _pContext->verificationMode();
|
||||||
if (mode == Context::VERIFY_NONE || !_pContext->extendedCertificateVerificationEnabled() ||
|
if (mode == Context::VERIFY_NONE || !_pContext->extendedCertificateVerificationEnabled() ||
|
||||||
(mode != Context::VERIFY_STRICT && isLocalHost(hostName)))
|
(mode != Context::VERIFY_STRICT && isLocalHost(hostName)))
|
||||||
{
|
{
|
||||||
return X509_V_OK;
|
return X509_V_OK;
|
||||||
}
|
}
|
||||||
@@ -499,10 +516,19 @@ bool SecureSocketImpl::isLocalHost(const std::string& hostName)
|
|||||||
|
|
||||||
X509* SecureSocketImpl::peerCertificate() const
|
X509* SecureSocketImpl::peerCertificate() const
|
||||||
{
|
{
|
||||||
|
LockT l(_mutex);
|
||||||
|
|
||||||
|
X509* pCert = nullptr;
|
||||||
|
|
||||||
if (_pSSL)
|
if (_pSSL)
|
||||||
return ::SSL_get_peer_certificate(_pSSL);
|
{
|
||||||
else
|
pCert = ::SSL_get_peer_certificate(_pSSL);
|
||||||
return nullptr;
|
if (X509_V_OK != SSL_get_verify_result(_pSSL))
|
||||||
|
throw CertificateValidationException("SecureSocketImpl::peerCertificate(): "
|
||||||
|
"Certificate verification error " + Utility::getLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return pCert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -637,6 +663,8 @@ void SecureSocketImpl::reset()
|
|||||||
{
|
{
|
||||||
if (_pSSL)
|
if (_pSSL)
|
||||||
{
|
{
|
||||||
|
LockT l(_mutex);
|
||||||
|
|
||||||
::SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), nullptr);
|
::SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), nullptr);
|
||||||
::SSL_free(_pSSL);
|
::SSL_free(_pSSL);
|
||||||
_pSSL = nullptr;
|
_pSSL = nullptr;
|
||||||
@@ -665,9 +693,12 @@ void SecureSocketImpl::useSession(Session::Ptr pSession)
|
|||||||
bool SecureSocketImpl::sessionWasReused()
|
bool SecureSocketImpl::sessionWasReused()
|
||||||
{
|
{
|
||||||
if (_pSSL)
|
if (_pSSL)
|
||||||
|
{
|
||||||
|
LockT l(_mutex);
|
||||||
return ::SSL_session_reused(_pSSL) != 0;
|
return ::SSL_session_reused(_pSSL) != 0;
|
||||||
else
|
}
|
||||||
return false;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user