Pool Video Switch v2
Software video switch for distributed remote display in a lecture environment
sslserver.cpp
Go to the documentation of this file.
1 /*
2  # Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg
3  #
4  # This program is free software distributed under the GPL version 2.
5  # See http://openslx.org/COPYING
6  #
7  # If you have any feedback please consult http://openslx.org/feedback and
8  # send your suggestions, praise, or complaints to feedback@openslx.org
9  #
10  # General information about OpenSLX can be found at http://openslx.org/
11  # -----------------------------------------------------------------------------
12  # src/net/SslServer.cpp
13  # - provide QTcpServer-like behaviour for SSL
14  # -----------------------------------------------------------------------------
15  */
16 
17 #include "sslserver.h"
18 #include <QtNetwork/QSslCipher>
19 #include <QtNetwork/QSslSocket>
20 #include <QTimer>
21 #include "certmanager.h"
22 #include <unistd.h>
23 
25  : QTcpServer(parent)
26  , _timer(new QTimer(this))
27 {
28  connect(_timer, &QTimer::timeout, [=]() {
29  if (_pending.empty())
30  return;
31  const qint64 deadline = QDateTime::currentMSecsSinceEpoch() - 10000;
32  QMutableHashIterator<QSslSocket*, qint64> it(_pending);
33  while (it.hasNext()) { // Remove lingering connections after 10s
34  it.next();
35  if (it.value() < deadline) {
36  it.key()->blockSignals(true);
37  it.key()->deleteLater();
38  it.remove();
39  }
40  }
41  });
42  _timer->start(10000);
43 }
44 
46 {
47  _timer->stop();
48  auto keys = _pending.keys();
49  for (QSslSocket *sock : keys) {
50  sock->deleteLater();
51  }
52  _pending.clear();
53 }
54 
59 void SslServer::incomingConnection(qintptr socketDescriptor)
60 {
61  static int certFails = 0;
62  QSslKey key;
63  QSslCertificate cert;
64  if (!CertManager::getPrivateKeyAndCert("manager2", key, cert)) {
65  if (++certFails > 5) {
67  }
68  ::close(int(socketDescriptor));
69  return;
70  }
71  auto *serverSocket = new QSslSocket(nullptr);
72  connect(serverSocket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), this, &SslServer::sslErrors);
73  serverSocket->setPrivateKey(key);
74  serverSocket->setLocalCertificate(cert);
75  serverSocket->setPeerVerifyMode(QSslSocket::VerifyNone);
76  serverSocket->setProtocol(QSsl::SecureProtocols);
77  if (serverSocket->setSocketDescriptor(socketDescriptor)) {
78  _pending.insert(serverSocket, QDateTime::currentMSecsSinceEpoch());
79  // Once the connection is successfully encrypted, raise our newConnection event
80  connect(serverSocket, &QSslSocket::encrypted, [=]() {
81  serverSocket->disconnect(this);
82  if (_pending.remove(serverSocket) == 0) {
83  // Should never happen, so better log...
84  qDebug() << "Encryption event for socket that is not pending!?";
85  } else {
86  this->addPendingConnection(serverSocket);
87  emit newConnection();
88  }
89  });
90  serverSocket->startServerEncryption();
91  } else {
92  qDebug() << "Failed to setSocketDescriptor on new SSL Socket";
93  serverSocket->deleteLater();
94  }
95 }
96 
97 void SslServer::sslErrors(const QList<QSslError>& errors)
98 {
99  qDebug() << "Client caused sslErrors before connection:";
100  for (const auto & error : errors) {
101  qDebug() << error.errorString();
102  }
103 
104 }
105 
void fatal()
Definition: certmanager.cpp:70
void incomingConnection(qintptr handle) override
Handle incomming connection.
Definition: sslserver.cpp:59
void sslErrors(const QList< QSslError > &errors)
Definition: sslserver.cpp:97
QTimer * _timer
Definition: sslserver.h:44
SslServer(QObject *parent)
Definition: sslserver.cpp:24
QHash< QSslSocket *, qint64 > _pending
Definition: sslserver.h:43
bool getPrivateKeyAndCert(const QString &name, QSslKey &key, QSslCertificate &cert)
Definition: certmanager.cpp:41
~SslServer() override
Definition: sslserver.cpp:45