Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to handle TLS handshake timeout in QTcpServer?
Forum Updated to NodeBB v4.3 + New Features

How to handle TLS handshake timeout in QTcpServer?

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 3 Posters 687 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    RandomGuy
    wrote on last edited by RandomGuy
    #1

    I'm trying to figure out how to create a timeout for the handshake process in a TLS connection in a
    QTcpServer I tried something like this in the overriden incomingConnection function:

    QSslSocket * const tlsSocket = static_cast<QSslSocket*>(socket);
        connect(tlsSocket, &QSslSocket::encrypted, this, [this, tlsSocket](){ addPendingConnection(tlsSocket); });
        tlsSocket->setLocalCertificate(m_serverCertificate);
        tlsSocket->setPrivateKey(m_serverPrivateKey);
        tlsSocket->setProtocol(QSsl::SecureProtocols);
        tlsSocket->startServerEncryption();
    
        // We will have a handshake timeout of 30 seconds
        QTimer::singleShot(30*1000, this, [this, tlsSocket]() {
            if(!tlsSocket->isEncrypted()) {
                // If no handshake initialized from the client close the connection
                delete tlsSocket;
            }
        });
    

    But this doesn't seem to work because I am not calling directly addPendingConnection function (it get's called in a slot/lamdba which seems to break the pendingConnection chain.

    Does anybody know how can I achieve this timeout in Qt? The problem at the moment is that a client can open a connection with the server and it never answers the TLS handshake which leads to an useless open connection (that is never closed).

    Pablo J. RoginaP kshegunovK 2 Replies Last reply
    0
    • R RandomGuy

      I'm trying to figure out how to create a timeout for the handshake process in a TLS connection in a
      QTcpServer I tried something like this in the overriden incomingConnection function:

      QSslSocket * const tlsSocket = static_cast<QSslSocket*>(socket);
          connect(tlsSocket, &QSslSocket::encrypted, this, [this, tlsSocket](){ addPendingConnection(tlsSocket); });
          tlsSocket->setLocalCertificate(m_serverCertificate);
          tlsSocket->setPrivateKey(m_serverPrivateKey);
          tlsSocket->setProtocol(QSsl::SecureProtocols);
          tlsSocket->startServerEncryption();
      
          // We will have a handshake timeout of 30 seconds
          QTimer::singleShot(30*1000, this, [this, tlsSocket]() {
              if(!tlsSocket->isEncrypted()) {
                  // If no handshake initialized from the client close the connection
                  delete tlsSocket;
              }
          });
      

      But this doesn't seem to work because I am not calling directly addPendingConnection function (it get's called in a slot/lamdba which seems to break the pendingConnection chain.

      Does anybody know how can I achieve this timeout in Qt? The problem at the moment is that a client can open a connection with the server and it never answers the TLS handshake which leads to an useless open connection (that is never closed).

      Pablo J. RoginaP Offline
      Pablo J. RoginaP Offline
      Pablo J. Rogina
      wrote on last edited by
      #2

      @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

      QSslSocket

      Instead of worrying about getting a timeout, I'd check for any SSL errors, so you may want to listen to the sslErrors signal.

      I expect that any handshake timeout happening between your clients and your server will fire up such signal.

      Upvote the answer(s) that helped you solve the issue
      Use "Topic Tools" button to mark your post as Solved
      Add screenshots via postimage.org
      Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

      R 1 Reply Last reply
      0
      • Pablo J. RoginaP Pablo J. Rogina

        @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

        QSslSocket

        Instead of worrying about getting a timeout, I'd check for any SSL errors, so you may want to listen to the sslErrors signal.

        I expect that any handshake timeout happening between your clients and your server will fire up such signal.

        R Offline
        R Offline
        RandomGuy
        wrote on last edited by
        #3

        @Pablo-J-Rogina said in How to handle TLS handshake timeout in QTcpServer?:

        @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

        QSslSocket

        Instead of worrying about getting a timeout, I'd check for any SSL errors, so you may want to listen to the sslErrors signal.

        I expect that any handshake timeout happening between your clients and your server will fire up such signal.

        Thanks I tried that. I added this in the server:

        connect(tlsSocket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), 
                        [](const QList<QSslError> &errors)
                {
                    for(const QSslError &error:errors)
                        qWarning() << error.errorString();
                });
        

        But I don't see any error after some minutes, after the connection has been opened by the client. Also if the client sends invalid bytes to start the handshake, the server automatically closes the connection (which is good) but I also don't get an error for that.

        The client is not a Qt program. I am using putty directly through a raw connection to test this.

        Pablo J. RoginaP 1 Reply Last reply
        0
        • R RandomGuy

          I'm trying to figure out how to create a timeout for the handshake process in a TLS connection in a
          QTcpServer I tried something like this in the overriden incomingConnection function:

          QSslSocket * const tlsSocket = static_cast<QSslSocket*>(socket);
              connect(tlsSocket, &QSslSocket::encrypted, this, [this, tlsSocket](){ addPendingConnection(tlsSocket); });
              tlsSocket->setLocalCertificate(m_serverCertificate);
              tlsSocket->setPrivateKey(m_serverPrivateKey);
              tlsSocket->setProtocol(QSsl::SecureProtocols);
              tlsSocket->startServerEncryption();
          
              // We will have a handshake timeout of 30 seconds
              QTimer::singleShot(30*1000, this, [this, tlsSocket]() {
                  if(!tlsSocket->isEncrypted()) {
                      // If no handshake initialized from the client close the connection
                      delete tlsSocket;
                  }
              });
          

          But this doesn't seem to work because I am not calling directly addPendingConnection function (it get's called in a slot/lamdba which seems to break the pendingConnection chain.

          Does anybody know how can I achieve this timeout in Qt? The problem at the moment is that a client can open a connection with the server and it never answers the TLS handshake which leads to an useless open connection (that is never closed).

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

          QSslSocket * const tlsSocket = static_cast<QSslSocket*>(socket);

          What is this supposed to do? What is socket? The incomingConnection gives you a socket descriptor, a.k.a. a handle - and opaque pointer, if socket is the descriptor you can't just arbitrarily cast it, instead attach it with QTcpSocket::setSocketDescriptor.

          Read and abide by the Qt Code of Conduct

          R 1 Reply Last reply
          0
          • R RandomGuy

            @Pablo-J-Rogina said in How to handle TLS handshake timeout in QTcpServer?:

            @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

            QSslSocket

            Instead of worrying about getting a timeout, I'd check for any SSL errors, so you may want to listen to the sslErrors signal.

            I expect that any handshake timeout happening between your clients and your server will fire up such signal.

            Thanks I tried that. I added this in the server:

            connect(tlsSocket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), 
                            [](const QList<QSslError> &errors)
                    {
                        for(const QSslError &error:errors)
                            qWarning() << error.errorString();
                    });
            

            But I don't see any error after some minutes, after the connection has been opened by the client. Also if the client sends invalid bytes to start the handshake, the server automatically closes the connection (which is good) but I also don't get an error for that.

            The client is not a Qt program. I am using putty directly through a raw connection to test this.

            Pablo J. RoginaP Offline
            Pablo J. RoginaP Offline
            Pablo J. Rogina
            wrote on last edited by
            #5

            @RandomGuy you may want to check this project, especially the Tcp Server class with SSL support using QTcpServer and QSslSocket

            Upvote the answer(s) that helped you solve the issue
            Use "Topic Tools" button to mark your post as Solved
            Add screenshots via postimage.org
            Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

            1 Reply Last reply
            0
            • kshegunovK kshegunov

              @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

              QSslSocket * const tlsSocket = static_cast<QSslSocket*>(socket);

              What is this supposed to do? What is socket? The incomingConnection gives you a socket descriptor, a.k.a. a handle - and opaque pointer, if socket is the descriptor you can't just arbitrarily cast it, instead attach it with QTcpSocket::setSocketDescriptor.

              R Offline
              R Offline
              RandomGuy
              wrote on last edited by
              #6

              @kshegunov said in How to handle TLS handshake timeout in QTcpServer?:

              @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

              QSslSocket * const tlsSocket = static_cast<QSslSocket*>(socket);

              What is this supposed to do? What is socket? The incomingConnection gives you a socket descriptor, a.k.a. a handle - and opaque pointer, if socket is the descriptor you can't just arbitrarily cast it, instead attach it with QTcpSocket::setSocketDescriptor.

              socket, is simply the QTcpSocket that I created:

                  // Create socket
                  QTcpSocket *socket = nullptr;
              
                  if(!m_tlsEnabled) {
                      socket = new QTcpSocket(this);
                  } else {
                      socket = new QSslSocket(this);
                  }
              
                  if(!socket->setSocketDescriptor(socketDescriptor)) {
                      return;
                  }
              

              As my code can work with TLS or without.

              @Pablo-J-Rogina said in How to handle TLS handshake timeout in QTcpServer?:

              @RandomGuy you may want to check this project, especially the Tcp Server class with SSL support using QTcpServer and QSslSocket

              Thanks I will have a look for handshake timeout handling.

              kshegunovK 1 Reply Last reply
              0
              • R RandomGuy

                @kshegunov said in How to handle TLS handshake timeout in QTcpServer?:

                @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

                QSslSocket * const tlsSocket = static_cast<QSslSocket*>(socket);

                What is this supposed to do? What is socket? The incomingConnection gives you a socket descriptor, a.k.a. a handle - and opaque pointer, if socket is the descriptor you can't just arbitrarily cast it, instead attach it with QTcpSocket::setSocketDescriptor.

                socket, is simply the QTcpSocket that I created:

                    // Create socket
                    QTcpSocket *socket = nullptr;
                
                    if(!m_tlsEnabled) {
                        socket = new QTcpSocket(this);
                    } else {
                        socket = new QSslSocket(this);
                    }
                
                    if(!socket->setSocketDescriptor(socketDescriptor)) {
                        return;
                    }
                

                As my code can work with TLS or without.

                @Pablo-J-Rogina said in How to handle TLS handshake timeout in QTcpServer?:

                @RandomGuy you may want to check this project, especially the Tcp Server class with SSL support using QTcpServer and QSslSocket

                Thanks I will have a look for handshake timeout handling.

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by
                #7

                @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

                socket, is simply the QTcpSocket that I created:

                Then I don't understand the need for a static cast, but anyway.
                Do you listen to the state changes? Do you listen to peer verification errors?

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  RandomGuy
                  wrote on last edited by RandomGuy
                  #8

                  Hi @Pablo-J-Rogina and @kshegunov ,

                  Thanks for your help. The project https://github.com/GuiTeK/Qt-SslServer didn't solve my issue but it gave me some ideas.

                  I ended implementing the TLS handshake timeout this way:

                      // We will have a handshake timeout of 30 seconds (same as firefox today)
                      QTimer::singleShot(30*1000, this, [this]() {
                  
                          // we use dynamic_cast because this may be or not an encrypted socket
                          QSslSocket * const tlsSocket = dynamic_cast<QSslSocket*>(m_socket);
                  
                          if(tlsSocket != nullptr && !tlsSocket->isEncrypted()) {
                              qWarning() << "TLS Handshake timeout for connection from " <<
                                            tlsSocket->peerAddress().toString() << ":" << tlsSocket->peerPort();
                              tlsSocket->close();
                          }
                      });
                  

                  This code can be added anywhere where is more practical for your project. I added it in a session class that we have (which owns the created socket), this class is created in the end of newConnection slot. I have tested it and works perfectly.

                  kshegunovK 1 Reply Last reply
                  0
                  • R RandomGuy

                    Hi @Pablo-J-Rogina and @kshegunov ,

                    Thanks for your help. The project https://github.com/GuiTeK/Qt-SslServer didn't solve my issue but it gave me some ideas.

                    I ended implementing the TLS handshake timeout this way:

                        // We will have a handshake timeout of 30 seconds (same as firefox today)
                        QTimer::singleShot(30*1000, this, [this]() {
                    
                            // we use dynamic_cast because this may be or not an encrypted socket
                            QSslSocket * const tlsSocket = dynamic_cast<QSslSocket*>(m_socket);
                    
                            if(tlsSocket != nullptr && !tlsSocket->isEncrypted()) {
                                qWarning() << "TLS Handshake timeout for connection from " <<
                                              tlsSocket->peerAddress().toString() << ":" << tlsSocket->peerPort();
                                tlsSocket->close();
                            }
                        });
                    

                    This code can be added anywhere where is more practical for your project. I added it in a session class that we have (which owns the created socket), this class is created in the end of newConnection slot. I have tested it and works perfectly.

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by
                    #9

                    @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

                    I have tested it and works perfectly.

                    Calling close() whenever SSL has raised an error is ill advised[1].

                    [1]: https://bugreports.qt.io/browse/QTBUG-72024

                    Read and abide by the Qt Code of Conduct

                    R 1 Reply Last reply
                    1
                    • kshegunovK kshegunov

                      @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

                      I have tested it and works perfectly.

                      Calling close() whenever SSL has raised an error is ill advised[1].

                      [1]: https://bugreports.qt.io/browse/QTBUG-72024

                      R Offline
                      R Offline
                      RandomGuy
                      wrote on last edited by
                      #10

                      @kshegunov said in How to handle TLS handshake timeout in QTcpServer?:

                      @RandomGuy said in How to handle TLS handshake timeout in QTcpServer?:

                      I have tested it and works perfectly.

                      Calling close() whenever SSL has raised an error is ill advised[1].

                      [1]: https://bugreports.qt.io/browse/QTBUG-72024

                      Thanks for the information. I will keep this in mind in case problems arise.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved