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:
XinyuHou 2015-04-10 14:07:53 +01:00
parent dd574c4f2c
commit 916a4c75af
6 changed files with 83 additions and 42 deletions

View File

@ -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));

View File

@ -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)

View File

@ -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*,

View File

@ -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;
} }

View File

@ -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);
} }
} }

View File

@ -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();