From 9f1bfd08c47de2a1f59b406ae57e5a90d2670ea6 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Fri, 8 Nov 2019 14:55:54 +0100 Subject: Use the new functions/signals introduced in QSslSocket Task-number: QTBUG-68419 Change-Id: Icdc41079cb946d4316cc0ec2ae40522e6de52725 Reviewed-by: Timur Pocheptsov --- src/websockets/qsslserver.cpp | 6 +++ src/websockets/qsslserver_p.h | 3 ++ src/websockets/qwebsocket.cpp | 77 +++++++++++++++++++++++++++++++++++ src/websockets/qwebsocket.h | 6 +++ src/websockets/qwebsocket_p.cpp | 20 +++++++++ src/websockets/qwebsocket_p.h | 1 + src/websockets/qwebsocketserver.h | 3 ++ src/websockets/qwebsocketserver_p.cpp | 6 +++ 8 files changed, 122 insertions(+) diff --git a/src/websockets/qsslserver.cpp b/src/websockets/qsslserver.cpp index ec645c9..7f33a9d 100644 --- a/src/websockets/qsslserver.cpp +++ b/src/websockets/qsslserver.cpp @@ -121,6 +121,12 @@ void QSslServer::incomingConnection(qintptr socket) this, &QSslServer::socketEncrypted); connect(pSslSocket, &QSslSocket::preSharedKeyAuthenticationRequired, this, &QSslServer::preSharedKeyAuthenticationRequired); + connect(pSslSocket, &QSslSocket::alertSent, + this, &QSslServer::alertSent); + connect(pSslSocket, &QSslSocket::alertReceived, + this, &QSslServer::alertReceived); + connect(pSslSocket, &QSslSocket::handshakeInterruptedOnError, + this, &QSslServer::handshakeInterruptedOnError); Q_EMIT startedEncryptionHandshake(pSslSocket); diff --git a/src/websockets/qsslserver_p.h b/src/websockets/qsslserver_p.h index 6283058..e0c77fa 100644 --- a/src/websockets/qsslserver_p.h +++ b/src/websockets/qsslserver_p.h @@ -78,6 +78,9 @@ Q_SIGNALS: void peerVerifyError(const QSslError &error); void newEncryptedConnection(); void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator); + void alertSent(QAlertLevel level, QAlertType type, const QString &description); + void alertReceived(QAlertLevel level, QAlertType type, const QString &description); + void handshakeInterruptedOnError(const QSslError &error); void startedEncryptionHandshake(QSslSocket *socket); protected: diff --git a/src/websockets/qwebsocket.cpp b/src/websockets/qwebsocket.cpp index ade1eb4..e9bba37 100644 --- a/src/websockets/qwebsocket.cpp +++ b/src/websockets/qwebsocket.cpp @@ -260,6 +260,67 @@ not been filled in with new information when the signal returns. \sa QSslPreSharedKeyAuthenticator \sa QSslSocket::preSharedKeyAuthenticationRequired() */ +/*! + \fn void QWebSocket::peerVerifyError(const QSslError &error) + \since 6.0 + + QWebSocket can emit this signal several times during the SSL handshake, + before encryption has been established, to indicate that an error has + occurred while establishing the identity of the peer. The \a error is + usually an indication that QWebSocket is unable to securely identify the + peer. + + This signal provides you with an early indication when something's wrong. + By connecting to this signal, you can manually choose to tear down the + connection from inside the connected slot before the handshake has + completed. If no action is taken, QWebSocket will proceed to emitting + QWebSocket::sslErrors(). + + \sa sslErrors() +*/ +/*! + \fn void QWebSocket::alertSent(QAlertLevel level, QAlertType type, const QString &description) + \since 6.0 + + QWebSocket emits this signal if an alert message was sent to a peer. \a level + describes if it was a warning or a fatal error. \a type gives the code + of the alert message. When a textual description of the alert message is + available, it is supplied in \a description. + + \note This signal is mostly informational and can be used for debugging + purposes, normally it does not require any actions from the application. + \note Not all backends support this functionality. + + \sa alertReceived(), QSslSocket::QAlertLevel, QSslSocket::QAlertType +*/ +/*! + \fn void QWebSocket::alertReceived(QAlertLevel level, QAlertType type, const QString &description) + \since 6.0 + + QWebSocket emits this signal if an alert message was received from a peer. + \a level tells if the alert was fatal or it was a warning. \a type is the + code explaining why the alert was sent. When a textual description of + the alert message is available, it is supplied in \a description. + + \note The signal is mostly for informational and debugging purposes and does not + require any handling in the application. If the alert was fatal, underlying + backend will handle it and close the connection. + \note Not all backends support this functionality. + + \sa alertSent(), QSslSocket::QAlertLevel, QSslSocket::QAlertType +*/ +/*! + \fn void QWebSocket::handshakeInterruptedOnError(const QSslError &error) + \since 6.0 + + QWebSocket emits this signal if a certificate verification error was + found and if early error reporting was enabled in QSslConfiguration. + An application is expected to inspect the \a error and decide if + it wants to continue the handshake, or abort it and send an alert message + to the peer. The signal-slot connection must be direct. + + \sa continueInterruptedHandshake(), sslErrors(), QSslConfiguration::setHandshakeMustInterruptOnError() +*/ /*! \fn void QWebSocket::pong(quint64 elapsedTime, const QByteArray &payload) @@ -482,6 +543,22 @@ void QWebSocket::ignoreSslErrors() d->ignoreSslErrors(); } +/*! + \since 6.0 + + If an application wants to conclude a handshake even after receiving + handshakeInterruptedOnError() signal, it must call this function. + This call must be done from a slot function attached to the signal. + The signal-slot connection must be direct. + + \sa handshakeInterruptedOnError(), QSslConfiguration::setHandshakeMustInterruptOnError() +*/ +void QWebSocket::continueInterruptedHandshake() +{ + Q_D(QWebSocket); + d->continueInterruptedHandshake(); +} + /*! \overload diff --git a/src/websockets/qwebsocket.h b/src/websockets/qwebsocket.h index 4944689..530127f 100644 --- a/src/websockets/qwebsocket.h +++ b/src/websockets/qwebsocket.h @@ -109,6 +109,8 @@ public: #ifndef QT_NO_SSL void ignoreSslErrors(const QList &errors); + void continueInterruptedHandshake(); + void setSslConfiguration(const QSslConfiguration &sslConfiguration); QSslConfiguration sslConfiguration() const; #endif @@ -143,8 +145,12 @@ Q_SIGNALS: void bytesWritten(qint64 bytes); #ifndef QT_NO_SSL + void peerVerifyError(const QSslError &error); void sslErrors(const QList &errors); void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator); + void alertSent(QAlertLevel level, QAlertType type, const QString &description); + void alertReceived(QAlertLevel level, QAlertType type, const QString &description); + void handshakeInterruptedOnError(const QSslError &error); #endif private: diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp index 17f0224..01b58b5 100644 --- a/src/websockets/qwebsocket_p.cpp +++ b/src/websockets/qwebsocket_p.cpp @@ -284,6 +284,18 @@ void QWebSocketPrivate::ignoreSslErrors() } } +/*! + * \internal + */ +void QWebSocketPrivate::continueInterruptedHandshake() +{ + if (Q_LIKELY(m_pSocket)) { + QSslSocket *pSslSocket = qobject_cast(m_pSocket); + if (Q_LIKELY(pSslSocket)) + pSslSocket->continueInterruptedHandshake(); + } +} + /*! * \internal */ @@ -612,6 +624,14 @@ void QWebSocketPrivate::makeConnections(QTcpSocket *pTcpSocket) q, &QWebSocket::sslErrors); QObjectPrivate::connect(sslSocket, &QSslSocket::encrypted, this, &QWebSocketPrivate::_q_updateSslConfiguration); + QObject::connect(sslSocket, &QSslSocket::peerVerifyError, + q, &QWebSocket::peerVerifyError); + QObject::connect(sslSocket, &QSslSocket::alertSent, + q, &QWebSocket::alertSent); + QObject::connect(sslSocket, &QSslSocket::alertReceived, + q, &QWebSocket::alertReceived); + QObject::connect(sslSocket, &QSslSocket::handshakeInterruptedOnError, + q, &QWebSocket::handshakeInterruptedOnError); } else #endif // QT_NO_SSL { diff --git a/src/websockets/qwebsocket_p.h b/src/websockets/qwebsocket_p.h index 1db1077..e7c11f3 100644 --- a/src/websockets/qwebsocket_p.h +++ b/src/websockets/qwebsocket_p.h @@ -149,6 +149,7 @@ public: #ifndef QT_NO_SSL void ignoreSslErrors(const QList &errors); void ignoreSslErrors(); + void continueInterruptedHandshake(); void setSslConfiguration(const QSslConfiguration &sslConfiguration); QSslConfiguration sslConfiguration() const; void _q_updateSslConfiguration(); diff --git a/src/websockets/qwebsocketserver.h b/src/websockets/qwebsocketserver.h index ceb9106..478b35e 100644 --- a/src/websockets/qwebsocketserver.h +++ b/src/websockets/qwebsocketserver.h @@ -158,6 +158,9 @@ Q_SIGNALS: void peerVerifyError(const QSslError &error); void sslErrors(const QList &errors); void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator); + void alertSent(QAlertLevel level, QAlertType type, const QString &description); + void alertReceived(QAlertLevel level, QAlertType type, const QString &description); + void handshakeInterruptedOnError(const QSslError &error); #endif void closed(); }; diff --git a/src/websockets/qwebsocketserver_p.cpp b/src/websockets/qwebsocketserver_p.cpp index 8c75721..d139f4b 100644 --- a/src/websockets/qwebsocketserver_p.cpp +++ b/src/websockets/qwebsocketserver_p.cpp @@ -107,6 +107,12 @@ void QWebSocketServerPrivate::init() q, &QWebSocketServer::sslErrors); QObject::connect(pSslServer, &QSslServer::preSharedKeyAuthenticationRequired, q, &QWebSocketServer::preSharedKeyAuthenticationRequired); + QObject::connect(pSslServer, &QSslServer::alertSent, + q, &QWebSocketServer::alertSent); + QObject::connect(pSslServer, &QSslServer::alertReceived, + q, &QWebSocketServer::alertReceived); + QObject::connect(pSslServer, &QSslServer::handshakeInterruptedOnError, + q, &QWebSocketServer::handshakeInterruptedOnError); } #else qFatal("SSL not supported on this platform."); -- cgit v1.2.1