# include "sslserver.hh" // Qt specific libraries # include # include # include # include // External libraries # include # include # include "../base/settings.hh" # define FileName "SSLServer" SslServer::SslServer ( void ) : QObject () , mLastPendingConnection ( 1 ) { } void SslServer::listenForConnections ( void ) { mSslServer->listen ( ServiceSettings::SSL::Address ); return; } quint16 SslServer::serverPort ( void ) { return ( mSslServer->serverPort () ); } void SslServer::prepareCertificates ( void ) { mConfiguration = QSslConfiguration::defaultConfiguration (); QFile file1 ( ":/SSL/MacCertificate" ); debug ( FileName , "LOG Loading certificate file 1" ); if ( file1.open ( QIODevice::ReadOnly ) ) { mSslCertificate = QSslCertificate ( file1.readAll () , QSsl::Pem ); if ( !mSslCertificate.isNull () ) { mConfiguration.setLocalCertificate ( mSslCertificate ); } else { debug ( FileName , QSTRING_OBFUSCATED ( "ERR: Unable to use CFile" ) ); } file1.close (); } else { debug ( FileName , QSTRING_OBFUSCATED ( "ERR: Unable to load CFile: " ) + file1.errorString () ); } debug ( FileName , "LOG Loading key file 1" ); QFile file2 = QFile ( ":/SSL/MacKey" ); if ( file2.open ( QIODevice::ReadOnly ) ) { mSslKey = QSslKey ( file2.readAll () , QSsl::Rsa , QSsl::Pem , QSsl::PrivateKey , "" ); if ( !mSslKey.isNull () ) { mConfiguration.setPrivateKey ( mSslKey ); } else { debug ( FileName , QSTRING_OBFUSCATED ( "ERR: PK of CFile is null." ) ); } file2.close (); } else { debug ( FileName , QSTRING_OBFUSCATED ( "ERR: Can't open PK of CFile." ) ); } debug ( FileName , "LOG Creating SSL Server" ); mSslServer = new QSslServer ( this ); debug ( FileName , "LOG Connecting SSL Server" ); connect ( mSslServer , &QSslServer::alertReceived , this , &SslServer::onSocketAlertReceived ); connect ( mSslServer , &QSslServer::alertSent , this , &SslServer::onSocketAlertSent ); connect ( mSslServer , &QSslServer::errorOccurred , this , &SslServer::onSocketConnectionError ); connect ( mSslServer , &QSslServer::handshakeInterruptedOnError , this , &SslServer::onSocketHandshakeInterruptedOnError ); connect ( mSslServer , &QSslServer::peerVerifyError , this , &SslServer::onSocketPeerVerifyError ); connect ( mSslServer , &QSslServer::preSharedKeyAuthenticationRequired , this , &SslServer::onSocketPreSharedKeyAuthenticationRequired ); connect ( mSslServer , &QSslServer::sslErrors , this , &SslServer::onSocketSslErrors ); connect ( mSslServer , &QSslServer::startedEncryptionHandshake , this , &SslServer::onSocketStartedEncryptionHandshake ); connect ( mSslServer , &QSslServer::acceptError , this , &SslServer::onServerAcceptError ); connect ( mSslServer , &QSslServer::newConnection , this , &SslServer::onServerNewConnection ); connect ( mSslServer , &QSslServer::pendingConnectionAvailable , this , &SslServer::onServerPendingConnectionAvailable ); debug ( FileName , "LOG Setting up SSL configuration" ); mSslServer->setSslConfiguration ( mConfiguration ); return; } void SslServer::onServerPendingConnectionAvailable ( void ) { using namespace SharedComponents::Functions; debug ( FileName , "LOG onServerPendingConnectionAvailable Pending connection available" ); while ( mSslServer->hasPendingConnections () ) { debug ( FileName , "LOG onServerPendingConnectionAvailable Checking for pending connection" ); QSslSocket* new_raw_socket = qobject_cast< QSslSocket* > ( mSslServer->nextPendingConnection () ); // Create Socket QSharedPointer< QSslSocket > new_socket = QSharedPointer< QSslSocket > ( new_raw_socket , NativeQObjectRemover ); debug ( FileName , "LOG onServerPendingConnectionAvailable Creating PendingConnection instance" ); QSharedPointer< ClientConnection > new_pending_connection = QSharedPointer< ClientConnection > ( new ClientConnection () , CustomQObjectRemover ); debug ( FileName , "LOG onServerPendingConnectionAvailable Setting ID: " + QString::number ( mLastPendingConnection ) ); new_pending_connection->setID ( mLastPendingConnection ); debug ( FileName , "LOG onServerPendingConnectionAvailable Setting QSslSocket" ); new_pending_connection->setConnectionSocket ( new_socket ); ++mLastPendingConnection; if ( mLastPendingConnection == 0 ) { // Overflow detected, reset to 1 mLastPendingConnection = 1; } new_socket->ignoreSslErrors (); debug ( FileName , "LOG onServerPendingConnectionAvailable Notifying about new client" ); emit newClientDetected ( new_pending_connection ); debug ( FileName , "LOG onServerPendingConnectionAvailable Notified about client, starting encryption (disabled)" ); //new_socket->startServerEncryption (); debug ( FileName , "LOG onServerPendingConnectionAvailable Started encryption, finish reception of new client" ); } debug ( FileName , "LOG onServerPendingConnectionAvailable Finished checking for connections" ); return; } void SslServer::onServerNewConnection ( void ) { debug ( FileName , "LOG onServerNewConnection New connection" ); return; } void SslServer::onServerAcceptError ( QAbstractSocket::SocketError pSocketError ) { debug ( FileName , "LOG onServerAcceptError Accept error: " + QString::number ( (int)pSocketError ) ); return; } void SslServer::onSocketAlertReceived ( QSslSocket* pSocket , QSsl::AlertLevel pLevel , QSsl::AlertType pType , const QString& pDescription ) { using namespace SharedComponents::Functions; Q_UNUSED ( pSocket ) Q_UNUSED ( pLevel ) Q_UNUSED ( pType ) Q_UNUSED ( pDescription ) QString level; QString type; level = SocketAlertLevelToString ( pLevel ); type = SocketAlertTypeToString ( pType ); debug ( FileName , "LOG onSocketAlertReceived Type=" + type + ", Level=" + level + ", Description=" + pDescription ); return; } void SslServer::onSocketAlertSent ( QSslSocket* pSocket , QSsl::AlertLevel pLevel , QSsl::AlertType pType , const QString& pDescription ) { using namespace SharedComponents::Functions; Q_UNUSED ( pSocket ) Q_UNUSED ( pLevel ) Q_UNUSED ( pType ) Q_UNUSED ( pDescription ) QString level; QString type; level = SocketAlertLevelToString ( pLevel ); type = SocketAlertTypeToString ( pType ); debug ( FileName , "LOG onSocketAlertSent Type=" + type + ", Level=" + level + ", Description=" + pDescription ); return; } void SslServer::onSocketConnectionError ( QSslSocket* pSocket , QAbstractSocket::SocketError pSocketError ) { Q_UNUSED ( pSocket ) using namespace SharedComponents::Functions; debug ( FileName , QSTRING_OBFUSCATED ( "LOG onSocketConnectionError Connection problem found." ) ); QString problem = SocketErrorToString ( pSocketError ); debug ( FileName , QSTRING_OBFUSCATED ( "LOG onSocketConnectionError Problem=%1" ).arg ( problem ) ); return; } void SslServer::onSocketHandshakeInterruptedOnError ( QSslSocket* pSocket , const QSslError& pError ) { debug ( FileName , QSTRING_OBFUSCATED ( "LOG onSocketHandshakeInterruptedOnError HS error identified: %1" ).arg ( pError.errorString () ) ); debug ( FileName , "LOG onSocketHandshakeInterruptedOnError Error=" + pError.errorString () ); pSocket->continueInterruptedHandshake (); debug ( FileName , "LOG onSocketHandshakeInterruptedOnError Asked socket to continue handshake" ); return; } void SslServer::onSocketPeerVerifyError ( QSslSocket* pSocket , const QSslError& pError ) { Q_UNUSED ( pSocket ) debug ( FileName , QSTRING_OBFUSCATED ( "LOG onSocketPeerVerifyError Client PV error: %1" ).arg ( pError.errorString () ) ); debug ( FileName , "LOG onSocketPeerVerifyError Error=" + pError.errorString () ); return; } void SslServer::onSocketPreSharedKeyAuthenticationRequired ( QSslSocket* pSocket , QSslPreSharedKeyAuthenticator* pAuthenticator ) { Q_UNUSED ( pSocket ) Q_UNUSED ( pAuthenticator ) debug ( FileName , "LOG preSharedKeyAuthenticationRequired" ); return; } void SslServer::onSocketSslErrors ( QSslSocket* pSocket , const QList< QSslError >& pSslErrors ) { Q_UNUSED ( pSocket ) debug ( FileName , "LOG onSocketSslErrors Total=" + QString::number ( pSslErrors.size () ) ); for ( auto x : pSslErrors ) { debug ( FileName , "LOG onSocketSslErrors Error: " + x.errorString () ); } pSocket->ignoreSslErrors ( pSslErrors ); return; } void SslServer::onSocketStartedEncryptionHandshake ( QSslSocket* pSocket ) { Q_UNUSED ( pSocket ) debug ( FileName , "LOG onSocketStartedEncryptionHandshake Started encryption" ); return; }