From 0d3d853f8414bd383fa1caea8a9322cb7854e5f3 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 16 Nov 2017 14:21:23 +0100 Subject: Fix SSL on Qt5 --- src/client/net/serverconnection.cpp | 9 +++++++-- src/server/mainwindow/mainwindow.h | 5 +++-- src/server/net/client.cpp | 2 +- src/server/net/client.h | 7 +++---- src/server/net/listenserver.cpp | 6 +++--- src/server/net/sslserver.cpp | 39 +++++++++++++++++++++++++++++-------- src/server/net/sslserver.h | 6 ++++-- 7 files changed, 52 insertions(+), 22 deletions(-) diff --git a/src/client/net/serverconnection.cpp b/src/client/net/serverconnection.cpp index e9cc72c..d79c7c3 100644 --- a/src/client/net/serverconnection.cpp +++ b/src/client/net/serverconnection.cpp @@ -33,7 +33,9 @@ ServerConnection::ServerConnection(const QString& host, const quint16 port, cons this, SLOT(sslErrors(const QList &)) ); + connect(_socket, &QSslSocket::peerVerifyError, [=](const QSslError &error) { qDebug() << "PVE:" << error.errorString(); }); qDebug("Connecting to %s on port %d", host.toUtf8().data(), (int)port); + _socket->ignoreSslErrors(); _socket->connectToHostEncrypted(host, port); _timerId = startTimer(4000); _lastData = QDateTime::currentMSecsSinceEpoch() + PING_TIMEOUT_MS; @@ -294,10 +296,12 @@ void ServerConnection::timerEvent(QTimerEvent *event) { if (event->timerId() == _timerConnectionCheck) { if (_lastData < QDateTime::currentMSecsSinceEpoch()) { + qDebug() << "Ping timeout"; this->disconnectFromServer(); killTimer(_timerConnectionCheck); } } else if (event->timerId() == _timerId) { + qDebug() << "Connect timeout"; killTimer(_timerId); _timerId = 0; this->disconnectFromServer(); @@ -362,7 +366,7 @@ void ServerConnection::onVncViewerStartStop(const bool started, const int client void ServerConnection::sslErrors(const QList & errors) { for (QList::const_iterator it = errors.begin(); it != errors.end(); it++) { - QSslError err = *it; + const QSslError &err = *it; qDebug("Connect SSL: %s", qPrintable(err.errorString())); if (err.error() == QSslError::HostNameMismatch) continue; // We don't pay attention to hostnames for validation @@ -371,9 +375,9 @@ void ServerConnection::sslErrors(const QList & errors) if (err.error() == QSslError::CertificateNotYetValid || err.error() == QSslError::CertificateExpired) continue; // Some other SSL error - do not ignore + _socket->ignoreSslErrors(QList()); return; } - _socket->ignoreSslErrors(); } void ServerConnection::sock_dataArrival() @@ -416,6 +420,7 @@ void ServerConnection::sock_error(QAbstractSocket::SocketError errcode) void ServerConnection::sock_connected() { + qDebug() << "Connection to server established and encrypted"; QByteArray cert(_socket->peerCertificate().digest(QCryptographicHash::Sha1)); if (_certHash != cert) { emit stateChange(ConnectWindow::InvalidCert); diff --git a/src/server/mainwindow/mainwindow.h b/src/server/mainwindow/mainwindow.h index ac59481..6a0db89 100644 --- a/src/server/mainwindow/mainwindow.h +++ b/src/server/mainwindow/mainwindow.h @@ -103,11 +103,12 @@ private: void reloadCurrentRoom(); - void DisableButtons(); - void EnableButtons(); void clientCountChanged(); protected slots: + void DisableButtons(); + void EnableButtons(); + void onSessionNameClick(); void onSessionNameUpdate(); diff --git a/src/server/net/client.cpp b/src/server/net/client.cpp index 1b0bbdb..82ebf26 100644 --- a/src/server/net/client.cpp +++ b/src/server/net/client.cpp @@ -17,7 +17,7 @@ int Client::_clientIdCounter = 0; /******************************************************************************/ -Client::Client(QSslSocket* socket) : _socket(socket) +Client::Client(QTcpSocket* socket) : _socket(socket) { assert(socket != NULL); _authed = 0; diff --git a/src/server/net/client.h b/src/server/net/client.h index 9bbc23f..885d4fc 100644 --- a/src/server/net/client.h +++ b/src/server/net/client.h @@ -4,8 +4,7 @@ #include #include #include -#include -#include +#include #include "../../shared/networkmessage.h" //class QSslSocket; @@ -26,7 +25,7 @@ class Client : public QObject Q_OBJECT public: - explicit Client(QSslSocket* socket); + explicit Client(QTcpSocket* socket); ~Client(); // Getters @@ -59,7 +58,7 @@ public: private: - QSslSocket * const _socket; + QTcpSocket * const _socket; bool _locked; int _authed; // 0 = challenge sent, awaiting reply 1 = challenge ok, client challenge replied, awaiting login, 2 = ESTABLISHED QString _name; diff --git a/src/server/net/listenserver.cpp b/src/server/net/listenserver.cpp index 1ce5016..0a585c7 100644 --- a/src/server/net/listenserver.cpp +++ b/src/server/net/listenserver.cpp @@ -10,7 +10,7 @@ */ ListenServer::ListenServer(quint16 port) { - if (!_server.listen(QHostAddress::Any, port) || !_server.isListening()) + if (!_server.listen(QHostAddress::AnyIPv4, port) || !_server.isListening()) qFatal("Cannot bind to TCP port %d (incoming SSL clients)", (int)port); connect(&_server, SIGNAL(newConnection()), this, SLOT(newClientConnection())); } @@ -30,8 +30,8 @@ ListenServer::~ListenServer() */ void ListenServer::newClientConnection() { - QSslSocket* sock; - while ((sock = (QSslSocket*)_server.nextPendingConnection()) != NULL) { + QTcpSocket* sock; + while ((sock = _server.nextPendingConnection()) != NULL) { Client* client = new Client(sock); // TODO: what happens with disconnected clients emit newClient(client); } diff --git a/src/server/net/sslserver.cpp b/src/server/net/sslserver.cpp index 6aefae9..0e0639e 100644 --- a/src/server/net/sslserver.cpp +++ b/src/server/net/sslserver.cpp @@ -20,22 +20,21 @@ #include "certmanager.h" #include -SslServer::SslServer() +SslServer::SslServer() : QTcpServer(NULL) { _tmr = startTimer(5123); - //QSslSocket::setDefaultCiphers(QSslSocket::supportedCiphers()); } SslServer::~SslServer() { - killTimer((_tmr)); + killTimer(_tmr); } /** * Handle incomming connection. * @param socketDescriptor */ -void SslServer::incomingConnection(int socketDescriptor) +void SslServer::incomingConnection(qintptr socketDescriptor) { static int certFails = 0; QSslKey key; @@ -49,24 +48,48 @@ void SslServer::incomingConnection(int socketDescriptor) } QSslSocket *serverSocket = new QSslSocket(NULL); connect(serverSocket, SIGNAL(sslErrors(const QList &)), this, SLOT(sslErrors(const QList &))); + connect(serverSocket, SIGNAL(disconnected()), this, SLOT(sock_closed())); + connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(sock_error(QAbstractSocket::SocketError))); serverSocket->setPrivateKey(key); serverSocket->setLocalCertificate(cert); serverSocket->setPeerVerifyMode(QSslSocket::VerifyNone); - serverSocket->setProtocol(QSsl::TlsV1SslV3); - //printf("Keylen %d\n", serverSocket->privateKey().length()); + serverSocket->setProtocol(QSsl::SecureProtocols); if (serverSocket->setSocketDescriptor(socketDescriptor)) { // Once the connection is successfully encrypted, raise our newConnection event + connect(serverSocket, &QSslSocket::encrypted, [=]() { + disconnect(serverSocket, SIGNAL(sslErrors(const QList &)), this, SLOT(sslErrors(const QList &))); + disconnect(serverSocket, SIGNAL(disconnected()), this, SLOT(sock_closed())); + disconnect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(sock_error(QAbstractSocket::SocketError))); + }); connect(serverSocket, SIGNAL(encrypted()), this, SIGNAL(newConnection())); serverSocket->startServerEncryption(); _pending.push_back(serverSocket); } else { + qDebug() << "Failed to setSocketDescriptor on new SSL Socket"; serverSocket->deleteLater(); } } -void SslServer::sslErrors(const QList & /* errors */ ) +void SslServer::sslErrors(const QList &errors) { - //qDebug("FIXME: SSL ERRORS on SERVER: %s", qPrintable(errors.begin()->errorString())); + /* + qDebug() << "Client caused sslErrors before connection:"; + for (QList::const_iterator it = errors.begin(); it != errors.end(); it++) { + qDebug() << it->errorString(); + } + */ +} + +void SslServer::sock_closed() +{ + qDebug() << "Client closed connection before SSL handshake completed."; + sender()->deleteLater(); +} + +void SslServer::sock_error(QAbstractSocket::SocketError err) +{ + qDebug() << "Client error before SSL handshake completed: " << err; + sender()->deleteLater(); } void SslServer::timerEvent(QTimerEvent* /* event */ ) diff --git a/src/server/net/sslserver.h b/src/server/net/sslserver.h index 7b727aa..6e8f26e 100644 --- a/src/server/net/sslserver.h +++ b/src/server/net/sslserver.h @@ -32,6 +32,8 @@ class SslServer : public QTcpServer private Q_SLOTS: void sslErrors ( const QList & errors ); + void sock_closed(); + void sock_error(QAbstractSocket::SocketError err); public: SslServer(); @@ -43,8 +45,8 @@ public: virtual QTcpSocket* nextPendingConnection(); protected: - void incomingConnection(int socketDescriptor); - void timerEvent (QTimerEvent* event); + void incomingConnection(qintptr handle); + void timerEvent(QTimerEvent* event); QList _pending; QList _delete; int _tmr; -- cgit v1.2.3-55-g7522