Skip to content

Commit

Permalink
fix(NetSSL_Win): shutdown behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
obiltschnig committed Nov 23, 2024
1 parent 25ce194 commit e911884
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 24 deletions.
11 changes: 9 additions & 2 deletions NetSSL_Win/include/Poco/Net/SecureSocketImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,12 @@ class NetSSL_Win_API SecureSocketImpl
ST_ERROR
};

enum TLSShutdown
{
TLS_SHUTDOWN_SENT = 1,
TLS_SHUTDOWN_RECEIVED = 2
};

int sendRawBytes(const void* buffer, int length, int flags = 0);
int receiveRawBytes(void* buffer, int length, int flags = 0);
void clientConnectVerify();
Expand All @@ -245,8 +251,8 @@ class NetSSL_Win_API SecureSocketImpl
void clientVerifyCertificate(const std::string& hostName);
void verifyCertificateChainClient(PCCERT_CONTEXT pServerCert);
void serverVerifyCertificate();
LONG serverDisconnect(PCredHandle phCreds, CtxtHandle* phContext);
LONG clientDisconnect(PCredHandle phCreds, CtxtHandle* phContext);
int serverShutdown(PCredHandle phCreds, CtxtHandle* phContext);
int clientShutdown(PCredHandle phCreds, CtxtHandle* phContext);
bool loadSecurityLibrary();
void initClientContext();
void initServerContext();
Expand Down Expand Up @@ -286,6 +292,7 @@ class NetSSL_Win_API SecureSocketImpl
Poco::AutoPtr<SocketImpl> _pSocket;
Context::Ptr _pContext;
Mode _mode;
int _shutdownFlags;
std::string _peerHostName;
bool _useMachineStore;
bool _clientAuthRequired;
Expand Down
2 changes: 1 addition & 1 deletion NetSSL_Win/src/HTTPSStreamFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ std::istream* HTTPSStreamFactory::open(const URI& uri)
{
return new HTTPResponseStream(rs, pSession);
}
else if (res.getStatus() == HTTPResponse::HTTP_USEPROXY && !retry)
else if (res.getStatus() == HTTPResponse::HTTP_USE_PROXY && !retry)
{
// The requested resource MUST be accessed through the proxy
// given by the Location field. The Location field gives the
Expand Down
55 changes: 36 additions & 19 deletions NetSSL_Win/src/SecureSocketImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ SecureSocketImpl::SecureSocketImpl(Poco::AutoPtr<SocketImpl> pSocketImpl, Contex
_pSocket(pSocketImpl),
_pContext(pContext),
_mode(pContext->isForServerUse() ? MODE_SERVER : MODE_CLIENT),
_shutdownFlags(0),
_clientAuthRequired(pContext->verificationMode() >= Context::VERIFY_STRICT),
_securityFunctions(SSLManager::instance().securityFunctions()),
_pOwnCertificate(0),
Expand Down Expand Up @@ -267,24 +268,32 @@ void SecureSocketImpl::listen(int backlog)

int SecureSocketImpl::shutdown()
{
if (_mode == MODE_SERVER)
serverDisconnect(&_hCreds, &_hContext);
else
clientDisconnect(&_hCreds, &_hContext);

_pSocket->shutdown();
return 0;
int rc = 0;
if ((_shutdownFlags & TLS_SHUTDOWN_SENT) == 0)
{
if (_mode == MODE_SERVER)
{
rc = serverShutdown(&_hCreds, &_hContext);
}
else
{
rc = clientShutdown(&_hCreds, &_hContext);
}
if (rc >= 0)
{
_pSocket->shutdownSend();
_shutdownFlags |= TLS_SHUTDOWN_SENT;
}
}
return (_shutdownFlags & TLS_SHUTDOWN_RECEIVED) ? 1 : 0;
}


void SecureSocketImpl::close()
{
try
{
if (_mode == MODE_SERVER)
serverDisconnect(&_hCreds, &_hContext);
else
clientDisconnect(&_hCreds, &_hContext);
shutdown();
}
catch (Poco::Exception&)
{
Expand Down Expand Up @@ -577,13 +586,12 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)

if (securityStatus == SEC_I_CONTEXT_EXPIRED)
{
SetLastError(securityStatus);
_shutdownFlags |= TLS_SHUTDOWN_RECEIVED;
break;
}

if (securityStatus != SEC_E_OK && securityStatus != SEC_I_RENEGOTIATE && securityStatus != SEC_I_CONTEXT_EXPIRED)
if (securityStatus != SEC_E_OK && securityStatus != SEC_I_RENEGOTIATE)
{
SetLastError(securityStatus);
break;
}

Expand Down Expand Up @@ -626,6 +634,7 @@ SECURITY_STATUS SecureSocketImpl::decodeMessage(BYTE* pBuffer, DWORD bufSize, Au
pExtraBuffer = 0;

SECURITY_STATUS securityStatus = _securityFunctions.DecryptMessage(&_hContext, &msg, 0, 0);
// TODO: when decrypting the close_notify alert, returns SEC_E_DECRYPT_FAILURE

if (securityStatus == SEC_E_OK || securityStatus == SEC_I_RENEGOTIATE)
{
Expand Down Expand Up @@ -1493,11 +1502,11 @@ void SecureSocketImpl::serverVerifyCertificate()
}


LONG SecureSocketImpl::clientDisconnect(PCredHandle phCreds, CtxtHandle* phContext)
int SecureSocketImpl::clientShutdown(PCredHandle phCreds, CtxtHandle* phContext)
{
if (phContext->dwLower == 0 && phContext->dwUpper == 0)
{
return SEC_E_OK;
return 0;
}

AutoSecBufferDesc<1> tokBuffer(&_securityFunctions, false);
Expand All @@ -1506,7 +1515,7 @@ LONG SecureSocketImpl::clientDisconnect(PCredHandle phCreds, CtxtHandle* phConte
tokBuffer.setSecBufferToken(0, &tokenType, sizeof(tokenType));
DWORD status = _securityFunctions.ApplyControlToken(phContext, &tokBuffer);

if (FAILED(status)) return status;
if (FAILED(status)) throw SSLException(Utility::formatError(status));

DWORD sspiFlags = ISC_REQ_SEQUENCE_DETECT
| ISC_REQ_REPLAY_DETECT
Expand Down Expand Up @@ -1534,11 +1543,19 @@ LONG SecureSocketImpl::clientDisconnect(PCredHandle phCreds, CtxtHandle* phConte
&sspiOutFlags,
&expiry);

return status;
if (FAILED(status)) throw SSLException(Utility::formatError(status));

if (outBuffer[0].pvBuffer && outBuffer[0].cbBuffer)
{
int sent = sendRawBytes(outBuffer[0].pvBuffer, outBuffer[0].cbBuffer);
return sent;
}

return 0;
}


LONG SecureSocketImpl::serverDisconnect(PCredHandle phCreds, CtxtHandle* phContext)
int SecureSocketImpl::serverShutdown(PCredHandle phCreds, CtxtHandle* phContext)
{
if (phContext->dwLower == 0 && phContext->dwUpper == 0)
{
Expand Down
4 changes: 2 additions & 2 deletions NetSSL_Win/src/SecureStreamSocketImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,13 @@ void SecureStreamSocketImpl::shutdownReceive()
}


void SecureStreamSocketImpl::shutdownSend()
int SecureStreamSocketImpl::shutdownSend()
{
return _impl.shutdown();
}


void SecureStreamSocketImpl::shutdown()
int SecureStreamSocketImpl::shutdown()
{
return _impl.shutdown();
}
Expand Down

0 comments on commit e911884

Please sign in to comment.