Refactored no or wrong ssl certificate error handling #4410
Conflicts: src/lib/net/TCPListenSocket.cpp src/lib/plugin/ns/SecureListenSocket.cpp src/lib/plugin/ns/SecureSocket.cpp src/lib/plugin/ns/SecureSocket.h
This commit is contained in:
parent
dd574c4f2c
commit
916a4c75af
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#include "mt/Thread.h"
|
#include "mt/Thread.h"
|
||||||
|
|
||||||
#include "net/XSocket.h"
|
|
||||||
#include "mt/XMT.h"
|
#include "mt/XMT.h"
|
||||||
#include "mt/XThread.h"
|
#include "mt/XThread.h"
|
||||||
#include "arch/Arch.h"
|
#include "arch/Arch.h"
|
||||||
|
@ -158,10 +157,6 @@ Thread::threadFunc(void* vjob)
|
||||||
job->run();
|
job->run();
|
||||||
LOG((CLOG_DEBUG1 "thread 0x%08x exit", id));
|
LOG((CLOG_DEBUG1 "thread 0x%08x exit", id));
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (XSocket& e) {
|
|
||||||
LOG((CLOG_DEBUG "%s", e.what()));
|
|
||||||
}
|
|
||||||
catch (XThreadCancel&) {
|
catch (XThreadCancel&) {
|
||||||
// client called cancel()
|
// client called cancel()
|
||||||
LOG((CLOG_DEBUG1 "caught cancel on thread 0x%08x", id));
|
LOG((CLOG_DEBUG1 "caught cancel on thread 0x%08x", id));
|
||||||
|
|
|
@ -112,27 +112,35 @@ TCPListenSocket::accept()
|
||||||
try {
|
try {
|
||||||
socket = new TCPSocket(m_events, m_socketMultiplexer, ARCH->acceptSocket(m_socket, NULL));
|
socket = new TCPSocket(m_events, m_socketMultiplexer, ARCH->acceptSocket(m_socket, NULL));
|
||||||
if (socket != NULL) {
|
if (socket != NULL) {
|
||||||
m_socketMultiplexer->addSocket(this,
|
setListeningJob();
|
||||||
new TSocketMultiplexerMethodJob<TCPListenSocket>(
|
|
||||||
this, &TCPListenSocket::serviceListening,
|
|
||||||
m_socket, true, false));
|
|
||||||
}
|
}
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
catch (XArchNetwork&) {
|
catch (XArchNetwork&) {
|
||||||
if (socket != NULL) {
|
if (socket != NULL) {
|
||||||
delete socket;
|
delete socket;
|
||||||
|
setListeningJob();
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
if (socket != NULL) {
|
if (socket != NULL) {
|
||||||
delete socket;
|
delete socket;
|
||||||
|
setListeningJob();
|
||||||
}
|
}
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CTCPListenSocket::setListeningJob()
|
||||||
|
{
|
||||||
|
m_socketMultiplexer->addSocket(this,
|
||||||
|
new TSocketMultiplexerMethodJob<CTCPListenSocket>(
|
||||||
|
this, &CTCPListenSocket::serviceListening,
|
||||||
|
m_socket, true, false));
|
||||||
|
}
|
||||||
|
|
||||||
ISocketMultiplexerJob*
|
ISocketMultiplexerJob*
|
||||||
TCPListenSocket::serviceListening(ISocketMultiplexerJob* job,
|
TCPListenSocket::serviceListening(ISocketMultiplexerJob* job,
|
||||||
bool read, bool, bool error)
|
bool read, bool, bool error)
|
||||||
|
|
|
@ -45,6 +45,9 @@ public:
|
||||||
accept();
|
accept();
|
||||||
virtual void deleteSocket(void*) { }
|
virtual void deleteSocket(void*) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setListeningJob();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ISocketMultiplexerJob*
|
ISocketMultiplexerJob*
|
||||||
serviceListening(ISocketMultiplexerJob*,
|
serviceListening(ISocketMultiplexerJob*,
|
||||||
|
|
|
@ -55,9 +55,16 @@ SecureListenSocket::accept()
|
||||||
m_socketMultiplexer,
|
m_socketMultiplexer,
|
||||||
ARCH->acceptSocket(m_socket, NULL));
|
ARCH->acceptSocket(m_socket, NULL));
|
||||||
|
|
||||||
|
<<<<<<< HEAD:src/lib/plugin/ns/SecureListenSocket.cpp
|
||||||
m_secureSocketSet.insert(socket);
|
m_secureSocketSet.insert(socket);
|
||||||
|
|
||||||
socket->initSsl(true);
|
socket->initSsl(true);
|
||||||
|
=======
|
||||||
|
if (socket != NULL) {
|
||||||
|
setListeningJob();
|
||||||
|
}
|
||||||
|
|
||||||
|
>>>>>>> 79b9c52... Refactored no or wrong ssl certificate error handling #30:src/lib/net/SecureListenSocket.cpp
|
||||||
// TODO: customized certificate path
|
// TODO: customized certificate path
|
||||||
String certificateFilename = ARCH->getProfileDirectory();
|
String certificateFilename = ARCH->getProfileDirectory();
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
|
@ -67,26 +74,36 @@ SecureListenSocket::accept()
|
||||||
#endif
|
#endif
|
||||||
certificateFilename.append(s_certificateFilename);
|
certificateFilename.append(s_certificateFilename);
|
||||||
|
|
||||||
socket->loadCertificates(certificateFilename.c_str());
|
bool loaded = socket->loadCertificates(certificateFilename);
|
||||||
|
if (!loaded) {
|
||||||
|
delete socket;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
socket->secureAccept();
|
socket->secureAccept();
|
||||||
|
|
||||||
|
<<<<<<< HEAD:src/lib/plugin/ns/SecureListenSocket.cpp
|
||||||
if (socket != NULL) {
|
if (socket != NULL) {
|
||||||
m_socketMultiplexer->addSocket(this,
|
m_socketMultiplexer->addSocket(this,
|
||||||
new TSocketMultiplexerMethodJob<TCPListenSocket>(
|
new TSocketMultiplexerMethodJob<TCPListenSocket>(
|
||||||
this, &TCPListenSocket::serviceListening,
|
this, &TCPListenSocket::serviceListening,
|
||||||
m_socket, true, false));
|
m_socket, true, false));
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
>>>>>>> 79b9c52... Refactored no or wrong ssl certificate error handling #30:src/lib/net/SecureListenSocket.cpp
|
||||||
return dynamic_cast<IDataSocket*>(socket);
|
return dynamic_cast<IDataSocket*>(socket);
|
||||||
}
|
}
|
||||||
catch (XArchNetwork&) {
|
catch (XArchNetwork&) {
|
||||||
if (socket != NULL) {
|
if (socket != NULL) {
|
||||||
delete socket;
|
delete socket;
|
||||||
|
setListeningJob();
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
if (socket != NULL) {
|
if (socket != NULL) {
|
||||||
delete socket;
|
delete socket;
|
||||||
|
setListeningJob();
|
||||||
}
|
}
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,24 +151,46 @@ SecureSocket::initSsl(bool server)
|
||||||
initContext(server);
|
initContext(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
SecureSocket::loadCertificates(const char* filename)
|
CSecureSocket::loadCertificates(CString& filename)
|
||||||
{
|
{
|
||||||
int r = 0;
|
if (filename.empty()) {
|
||||||
r = SSL_CTX_use_certificate_file(m_ssl->m_context, filename, SSL_FILETYPE_PEM);
|
showError("ssl certificate is not specified");
|
||||||
if (r <= 0) {
|
return false;
|
||||||
throwError("could not use ssl certificate");
|
}
|
||||||
|
else {
|
||||||
|
std::ifstream file(filename.c_str());
|
||||||
|
bool exist = file.good();
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
if (!exist) {
|
||||||
|
CString errorMsg("ssl certificate doesn't exist: ");
|
||||||
|
errorMsg.append(filename);
|
||||||
|
showError(errorMsg.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = SSL_CTX_use_PrivateKey_file(m_ssl->m_context, filename, SSL_FILETYPE_PEM);
|
int r = 0;
|
||||||
|
r = SSL_CTX_use_certificate_file(m_ssl->m_context, filename.c_str(), SSL_FILETYPE_PEM);
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
throwError("could not use ssl private key");
|
showError("could not use ssl certificate");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = SSL_CTX_use_PrivateKey_file(m_ssl->m_context, filename.c_str(), SSL_FILETYPE_PEM);
|
||||||
|
if (r <= 0) {
|
||||||
|
showError("could not use ssl private key");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = SSL_CTX_check_private_key(m_ssl->m_context);
|
r = SSL_CTX_check_private_key(m_ssl->m_context);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
throwError("could not verify ssl private key");
|
showError("could not verify ssl private key");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -258,7 +280,8 @@ SecureSocket::secureConnect(int socket)
|
||||||
// tell user and sleep so the socket isn't hammered.
|
// tell user and sleep so the socket isn't hammered.
|
||||||
LOG((CLOG_ERR "failed to connect secure socket"));
|
LOG((CLOG_ERR "failed to connect secure socket"));
|
||||||
LOG((CLOG_INFO "server connection may not be secure"));
|
LOG((CLOG_INFO "server connection may not be secure"));
|
||||||
ARCH->sleep(1);
|
disconnect();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_secureReady = !retry;
|
m_secureReady = !retry;
|
||||||
|
@ -266,7 +289,9 @@ SecureSocket::secureConnect(int socket)
|
||||||
if (m_secureReady) {
|
if (m_secureReady) {
|
||||||
if (verifyCertFingerprint()) {
|
if (verifyCertFingerprint()) {
|
||||||
LOG((CLOG_INFO "connected to secure socket"));
|
LOG((CLOG_INFO "connected to secure socket"));
|
||||||
showCertificate();
|
if (!showCertificate()) {
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG((CLOG_ERR "failed to verity server certificate fingerprint"));
|
LOG((CLOG_ERR "failed to verity server certificate fingerprint"));
|
||||||
|
@ -277,8 +302,8 @@ SecureSocket::secureConnect(int socket)
|
||||||
return retry;
|
return retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
SecureSocket::showCertificate()
|
CSecureSocket::showCertificate()
|
||||||
{
|
{
|
||||||
X509* cert;
|
X509* cert;
|
||||||
char* line;
|
char* line;
|
||||||
|
@ -292,8 +317,11 @@ SecureSocket::showCertificate()
|
||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throwError("server has no ssl certificate");
|
showError("server has no ssl certificate");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -359,24 +387,15 @@ SecureSocket::checkResult(int n, bool& fatal, bool& retry)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SecureSocket::showError()
|
CSecureSocket::showError(const char* reason)
|
||||||
{
|
{
|
||||||
String error = getError();
|
if (reason != NULL) {
|
||||||
if (!error.empty()) {
|
LOG((CLOG_ERR "%s", reason));
|
||||||
LOG((CLOG_ERR "secure socket error: %s", error.c_str()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
CString error = getError();
|
||||||
SecureSocket::throwError(const char* reason)
|
|
||||||
{
|
|
||||||
String error = getError();
|
|
||||||
if (!error.empty()) {
|
if (!error.empty()) {
|
||||||
throw XSocket(synergy::string::sprintf(
|
LOG((CLOG_ERR "%s", error.c_str()));
|
||||||
"%s: %s", reason, error.c_str()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw XSocket(reason);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
UInt32 secureRead(void* buffer, UInt32 n);
|
UInt32 secureRead(void* buffer, UInt32 n);
|
||||||
UInt32 secureWrite(const void* buffer, UInt32 n);
|
UInt32 secureWrite(const void* buffer, UInt32 n);
|
||||||
void initSsl(bool server);
|
void initSsl(bool server);
|
||||||
void loadCertificates(const char* CertFile);
|
bool loadCertificates(CString& CertFile);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// SSL
|
// SSL
|
||||||
|
@ -58,10 +58,9 @@ private:
|
||||||
void createSSL();
|
void createSSL();
|
||||||
bool secureAccept(int s);
|
bool secureAccept(int s);
|
||||||
bool secureConnect(int s);
|
bool secureConnect(int s);
|
||||||
void showCertificate();
|
bool showCertificate();
|
||||||
void checkResult(int n, bool& fatal, bool& retry);
|
void checkResult(int n, bool& fatal, bool& retry);
|
||||||
void showError();
|
void showError(const char* reason = NULL);
|
||||||
void throwError(const char* reason);
|
|
||||||
String getError();
|
String getError();
|
||||||
void disconnect();
|
void disconnect();
|
||||||
bool verifyCertFingerprint();
|
bool verifyCertFingerprint();
|
||||||
|
|
Loading…
Reference in New Issue