mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-29 21:30:04 +01:00
fixed a crash on WinCE; code cleanup
This commit is contained in:
parent
ee25a49e9b
commit
0a115be8ac
@ -73,7 +73,7 @@ public:
|
||||
const_cast<AutoSecBufferDesc*>(&desc)->initBuffers();
|
||||
}
|
||||
|
||||
AutoSecBufferDesc& operator=(const AutoSecBufferDesc& desc)
|
||||
AutoSecBufferDesc& operator = (const AutoSecBufferDesc& desc)
|
||||
{
|
||||
if (&desc != this)
|
||||
{
|
||||
@ -96,13 +96,22 @@ public:
|
||||
|
||||
~AutoSecBufferDesc()
|
||||
/// Destroys the AutoSecBufferDesc
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
if (_autoRelease)
|
||||
{
|
||||
for (int i = 0; i < numBufs; ++i)
|
||||
{
|
||||
_pSec->FreeContextBuffer(_buffers[i].pvBuffer);
|
||||
if (_buffers[i].pvBuffer)
|
||||
{
|
||||
_pSec->FreeContextBuffer(_buffers[i].pvBuffer);
|
||||
}
|
||||
}
|
||||
_autoRelease = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,13 @@
|
||||
#include "Poco/Net/InvalidCertificateHandler.h"
|
||||
#include "Poco/BasicEvent.h"
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include <wincrypt.h>
|
||||
#include <schannel.h>
|
||||
#ifndef SECURITY_WIN32
|
||||
#define SECURITY_WIN32
|
||||
#endif
|
||||
#include <security.h>
|
||||
#include <sspi.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -184,6 +191,9 @@ public:
|
||||
static const std::string CFG_SERVER_PREFIX;
|
||||
static const std::string CFG_CLIENT_PREFIX;
|
||||
|
||||
protected:
|
||||
SecurityFunctionTableW& securityFunctions();
|
||||
|
||||
private:
|
||||
SSLManager();
|
||||
/// Creates the SSLManager.
|
||||
@ -200,6 +210,15 @@ private:
|
||||
void initCertificateHandler(bool server);
|
||||
/// Inits the certificate handler.
|
||||
|
||||
void loadSecurityLibrary();
|
||||
/// Loads the Windows security DLL.
|
||||
|
||||
void unloadSecurityLibrary();
|
||||
/// Unloads the Windows security DLL.
|
||||
|
||||
HMODULE _hSecurityModule;
|
||||
SecurityFunctionTableW _securityFunctions;
|
||||
|
||||
CertificateHandlerFactoryMgr _certHandlerFactoryMgr;
|
||||
Context::Ptr _ptrDefaultServerContext;
|
||||
InvalidCertificateHandlerPtr _ptrServerCertificateHandler;
|
||||
@ -232,6 +251,7 @@ private:
|
||||
static const std::string CFG_REQUIRE_TLSV1_2;
|
||||
|
||||
friend class Poco::SingletonHolder<SSLManager>;
|
||||
friend class SecureSocketImpl;
|
||||
};
|
||||
|
||||
|
||||
@ -244,6 +264,12 @@ inline CertificateHandlerFactoryMgr& SSLManager::certificateHandlerFactoryMgr()
|
||||
}
|
||||
|
||||
|
||||
inline SecurityFunctionTableW& SSLManager::securityFunctions()
|
||||
{
|
||||
return _securityFunctions;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
||||
|
||||
|
@ -241,8 +241,7 @@ private:
|
||||
DWORD _clientFlags;
|
||||
DWORD _serverFlags;
|
||||
|
||||
HMODULE _hSecurityModule;
|
||||
SecurityFunctionTableW _securityFunctions;
|
||||
SecurityFunctionTableW& _securityFunctions;
|
||||
|
||||
BYTE* _pReceiveBuffer;
|
||||
DWORD _receiveBufferSize;
|
||||
|
@ -51,19 +51,16 @@ const std::string SSLManager::CFG_REQUIRE_TLSV1_1("requireTLSv1_1");
|
||||
const std::string SSLManager::CFG_REQUIRE_TLSV1_2("requireTLSv1_2");
|
||||
|
||||
|
||||
SSLManager::SSLManager()
|
||||
SSLManager::SSLManager():
|
||||
_hSecurityModule(0)
|
||||
{
|
||||
loadSecurityLibrary();
|
||||
}
|
||||
|
||||
|
||||
SSLManager::~SSLManager()
|
||||
{
|
||||
ClientVerificationError.clear();
|
||||
ServerVerificationError.clear();
|
||||
_ptrServerCertificateHandler = 0;
|
||||
_ptrDefaultServerContext = 0;
|
||||
_ptrClientCertificateHandler = 0;
|
||||
_ptrDefaultClientContext = 0;
|
||||
shutdown();
|
||||
}
|
||||
|
||||
|
||||
@ -237,8 +234,90 @@ void SSLManager::shutdown()
|
||||
{
|
||||
ClientVerificationError.clear();
|
||||
ServerVerificationError.clear();
|
||||
_ptrDefaultServerContext = 0;
|
||||
_ptrDefaultClientContext = 0;
|
||||
_ptrServerCertificateHandler = 0;
|
||||
_ptrDefaultServerContext = 0;
|
||||
_ptrClientCertificateHandler = 0;
|
||||
_ptrDefaultClientContext = 0;
|
||||
|
||||
unloadSecurityLibrary();
|
||||
}
|
||||
|
||||
|
||||
void SSLManager::loadSecurityLibrary()
|
||||
{
|
||||
if (_hSecurityModule) return;
|
||||
|
||||
OSVERSIONINFO VerInfo;
|
||||
std::wstring dllPath;
|
||||
|
||||
// Find out which security DLL to use, depending on
|
||||
// whether we are on Win2k, NT or Win9x
|
||||
|
||||
VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
if (!GetVersionEx(&VerInfo))
|
||||
throw Poco::SystemException("Cannot determine OS version");
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
dllPath = L"Secur32.dll";
|
||||
#else
|
||||
if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT
|
||||
&& VerInfo.dwMajorVersion == 4)
|
||||
{
|
||||
dllPath = L"Security.dll";
|
||||
}
|
||||
else if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ||
|
||||
VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
|
||||
{
|
||||
dllPath = L"Secur32.dll";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Poco::SystemException("Cannot determine which security DLL to use");
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Load Security DLL
|
||||
//
|
||||
|
||||
_hSecurityModule = LoadLibraryW(dllPath.c_str());
|
||||
if(_hSecurityModule == 0)
|
||||
{
|
||||
throw Poco::SystemException("Failed to load security DLL");
|
||||
}
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
INIT_SECURITY_INTERFACE pInitSecurityInterface = (INIT_SECURITY_INTERFACE)GetProcAddressW( _hSecurityModule, L"InitSecurityInterfaceW");
|
||||
#else
|
||||
INIT_SECURITY_INTERFACE pInitSecurityInterface = (INIT_SECURITY_INTERFACE)GetProcAddress( _hSecurityModule, "InitSecurityInterfaceW");
|
||||
#endif
|
||||
|
||||
if (!pInitSecurityInterface)
|
||||
{
|
||||
FreeLibrary(_hSecurityModule);
|
||||
_hSecurityModule = 0;
|
||||
throw Poco::SystemException("Failed to initialize security DLL (no init function)");
|
||||
}
|
||||
|
||||
PSecurityFunctionTable pSecurityFunc = pInitSecurityInterface();
|
||||
if (!pSecurityFunc)
|
||||
{
|
||||
FreeLibrary(_hSecurityModule);
|
||||
_hSecurityModule = 0;
|
||||
throw Poco::SystemException("Failed to initialize security DLL (no function table)");
|
||||
}
|
||||
|
||||
CopyMemory(&_securityFunctions, pSecurityFunc, sizeof(_securityFunctions));
|
||||
}
|
||||
|
||||
|
||||
void SSLManager::unloadSecurityLibrary()
|
||||
{
|
||||
if (_hSecurityModule)
|
||||
{
|
||||
FreeLibrary(_hSecurityModule);
|
||||
_hSecurityModule = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -84,8 +84,7 @@ SecureSocketImpl::SecureSocketImpl(Poco::AutoPtr<SocketImpl> pSocketImpl, Contex
|
||||
_hContext(),
|
||||
_clientFlags(0),
|
||||
_serverFlags(0),
|
||||
_hSecurityModule(0),
|
||||
_securityFunctions(),
|
||||
_securityFunctions(SSLManager::instance().securityFunctions()),
|
||||
_pReceiveBuffer(0),
|
||||
_receiveBufferSize(0),
|
||||
_pIOBuffer(0),
|
||||
@ -122,8 +121,6 @@ SecureSocketImpl::~SecureSocketImpl()
|
||||
|
||||
void SecureSocketImpl::initCommon()
|
||||
{
|
||||
loadSecurityLibrary();
|
||||
|
||||
DWORD commonFlags = ISC_REQ_SEQUENCE_DETECT
|
||||
| ISC_REQ_REPLAY_DETECT
|
||||
| ISC_REQ_CONFIDENTIALITY
|
||||
@ -188,11 +185,9 @@ void SecureSocketImpl::cleanup()
|
||||
_hCertificateStore = 0;
|
||||
}
|
||||
|
||||
if (_hSecurityModule)
|
||||
{
|
||||
FreeLibrary(_hSecurityModule);
|
||||
_hSecurityModule = 0;
|
||||
}
|
||||
// must release buffers before unloading library
|
||||
_outSecBuffer.release();
|
||||
_inSecBuffer.release();
|
||||
|
||||
delete [] _pReceiveBuffer;
|
||||
_pReceiveBuffer = 0;
|
||||
@ -664,6 +659,9 @@ void SecureSocketImpl::setPeerHostName(const std::string& peerHostName)
|
||||
|
||||
PCCERT_CONTEXT SecureSocketImpl::loadCertificate(const std::string& certStore, const std::string& certName, bool useMachineStore, bool mustFindCertificate)
|
||||
{
|
||||
if (mustFindCertificate && certName.empty())
|
||||
throw SSLException("Certificate required, but no certificate name provided");
|
||||
|
||||
PCCERT_CONTEXT pCert = 0;
|
||||
|
||||
std::wstring wcertStore;
|
||||
@ -768,84 +766,11 @@ void SecureSocketImpl::acquireSchannelContext(Mode mode, PCCERT_CONTEXT pCertCon
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
cleanup();
|
||||
throw SSLException("Failed to acquire Schannel credentials", Utility::formatError(status));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SecureSocketImpl::loadSecurityLibrary()
|
||||
{
|
||||
if (_hSecurityModule) return true;
|
||||
|
||||
OSVERSIONINFO VerInfo;
|
||||
std::wstring dllPath;
|
||||
|
||||
// Find out which security DLL to use, depending on
|
||||
// whether we are on Win2k, NT or Win9x
|
||||
|
||||
VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
if (!GetVersionEx(&VerInfo))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
dllPath = L"Secur32.dll";
|
||||
#else
|
||||
if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT
|
||||
&& VerInfo.dwMajorVersion == 4)
|
||||
{
|
||||
dllPath = L"Security.dll";
|
||||
}
|
||||
else if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ||
|
||||
VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
|
||||
{
|
||||
dllPath = L"Secur32.dll";
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Load Security DLL
|
||||
//
|
||||
|
||||
_hSecurityModule = LoadLibraryW(dllPath.c_str());
|
||||
if(_hSecurityModule == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
INIT_SECURITY_INTERFACE pInitSecurityInterface = (INIT_SECURITY_INTERFACE)GetProcAddressW( _hSecurityModule, L"InitSecurityInterfaceW");
|
||||
#else
|
||||
INIT_SECURITY_INTERFACE pInitSecurityInterface = (INIT_SECURITY_INTERFACE)GetProcAddress( _hSecurityModule, "InitSecurityInterfaceW");
|
||||
#endif
|
||||
|
||||
if (!pInitSecurityInterface)
|
||||
{
|
||||
FreeLibrary(_hSecurityModule);
|
||||
_hSecurityModule = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
PSecurityFunctionTable pSecurityFunc = pInitSecurityInterface();
|
||||
if (!pSecurityFunc)
|
||||
{
|
||||
FreeLibrary(_hSecurityModule);
|
||||
_hSecurityModule = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CopyMemory(&_securityFunctions, pSecurityFunc, sizeof(_securityFunctions));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::connectSSL(bool completeHandshake)
|
||||
{
|
||||
poco_assert_dbg(_pPeerCertificate == 0);
|
||||
@ -1012,7 +937,6 @@ SECURITY_STATUS SecureSocketImpl::performClientHandshakeLoop()
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SecureSocketImpl::performClientHandshakeLoopExtError()
|
||||
{
|
||||
poco_assert_dbg (FAILED(_securityStatus));
|
||||
@ -1030,6 +954,7 @@ void SecureSocketImpl::performClientHandshakeLoopError()
|
||||
throw SSLException("Error during handshake", Utility::formatError(_securityStatus));
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::performClientHandshakeSendOutBuffer()
|
||||
{
|
||||
if (_outSecBuffer[0].cbBuffer != 0 && _outSecBuffer[0].pvBuffer != NULL)
|
||||
@ -1038,7 +963,6 @@ void SecureSocketImpl::performClientHandshakeSendOutBuffer()
|
||||
|
||||
if (numBytes != _outSecBuffer[0].cbBuffer)
|
||||
{
|
||||
cleanup();
|
||||
throw SSLException("Socket error during handshake");
|
||||
}
|
||||
_bytesReadSum = 0;
|
||||
@ -1349,7 +1273,6 @@ void SecureSocketImpl::clientVerifyCertificate(PCCERT_CONTEXT pServerCert, const
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SecureSocketImpl::verifyCertificateChainClient(PCCERT_CONTEXT pServerCert, PCCERT_CHAIN_CONTEXT pChainContext)
|
||||
{
|
||||
X509Certificate cert(pServerCert, true);
|
||||
|
@ -19,9 +19,8 @@
|
||||
|
||||
CppUnit::Test* NetSSLTestSuite::suite()
|
||||
{
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("OpenSSLTestSuite");
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("NetSSLTestSuite");
|
||||
|
||||
|
||||
pSuite->addTest(HTTPSClientTestSuite::suite());
|
||||
pSuite->addTest(TCPServerTestSuite::suite());
|
||||
pSuite->addTest(HTTPSServerTestSuite::suite());
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "Poco/Net/HTTPStreamFactory.h"
|
||||
#include "Poco/Net/HTTPSStreamFactory.h"
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
class NetSSLApp: public Poco::Util::Application
|
||||
|
Loading…
x
Reference in New Issue
Block a user