diff options
Diffstat (limited to 'src/server/net')
-rw-r--r-- | src/server/net/certmanager.cpp | 43 | ||||
-rw-r--r-- | src/server/net/client.cpp | 52 | ||||
-rw-r--r-- | src/server/net/client.h | 64 | ||||
-rw-r--r-- | src/server/net/discoverylistener.cpp | 23 | ||||
-rw-r--r-- | src/server/net/discoverylistener.h | 14 | ||||
-rw-r--r-- | src/server/net/filedownloader.cpp | 41 | ||||
-rw-r--r-- | src/server/net/filedownloader.h | 44 | ||||
-rw-r--r-- | src/server/net/listenserver.cpp | 10 | ||||
-rw-r--r-- | src/server/net/listenserver.h | 4 | ||||
-rw-r--r-- | src/server/net/sslserver.cpp | 14 | ||||
-rw-r--r-- | src/server/net/sslserver.h | 6 |
11 files changed, 122 insertions, 193 deletions
diff --git a/src/server/net/certmanager.cpp b/src/server/net/certmanager.cpp index 5d8d824..968535a 100644 --- a/src/server/net/certmanager.cpp +++ b/src/server/net/certmanager.cpp @@ -18,19 +18,20 @@ #define CERTSTORAGE ".config/openslx/pvs2/" #include "certmanager.h" -#include <QMap> +#include "../../shared/util.h" + +#include <QHash> #include <QDir> #include <QDebug> #include <QFileInfo> -#include <QSettings> #include <QMessageBox> -#include <QApplication> -#include <cstdlib> +#include <QProcess> +#include <QCoreApplication> namespace CertManager { -static QMap<QString, QSslCertificate> _certs; -static QMap<QString, QSslKey> _keys; +static QHash<QString, QSslCertificate> _certs; +static QHash<QString, QSslKey> _keys; static void generateFiles(QString& key, QString& cert); static bool loadFiles(QString& keyFile, QString& certFile, QSslKey &key, QSslCertificate &cert); @@ -44,7 +45,7 @@ bool getPrivateKeyAndCert(const QString &name, QSslKey &key, QSslCertificate &ce } QString certDir = QDir::homePath().append("/").append(CERTSTORAGE); if (!QDir::root().mkpath(certDir)) { - certDir = QString("/tmp/") + QString::number(qrand()) + "-" + QString::number(qrand()) + "/"; + certDir = QString("/tmp/") + QString::number(slxrand()) + "-" + QString::number(slxrand()) + "/"; QDir::root().mkpath(certDir); } QString certFile = certDir.append(name); @@ -66,11 +67,11 @@ bool getPrivateKeyAndCert(const QString &name, QSslKey &key, QSslCertificate &ce void fatal() { - QMessageBox::critical(nullptr, QCoreApplication::trUtf8("OpenSSL error", "CertManager"), - QCoreApplication::trUtf8("Could not generate certificates for secure connections.\n" + QMessageBox::critical(nullptr, QObject::tr("OpenSSL error", "CertManager"), + QObject::tr("Could not generate certificates for secure connections.\n" "PVS will not work.\n\n" "Press OK to quit.", "CertManager")); - qApp->exit(1); + QCoreApplication::exit(1); } static bool loadFiles(QString& keyFile, QString& certFile, QSslKey &key, QSslCertificate &cert) @@ -95,14 +96,18 @@ static bool loadFiles(QString& keyFile, QString& certFile, QSslKey &key, QSslCer static void generateFiles(QString& key, QString& cert) { - char tmp[1000]; - remove(key.toLocal8Bit().data()); - remove(cert.toLocal8Bit().data()); - snprintf(tmp, 1000, - "openssl req -x509 -nodes -days 5000 -newkey rsa:4096 -subj '/C=DE/ST=BaWue/L=Freiburg/CN=openslx.org' -keyout \"%s\" -out \"%s\"", - key.toLocal8Bit().data(), cert.toLocal8Bit().data()); - system(tmp); - snprintf(tmp, 1000, "chmod 0600 \"%s\" \"%s\"", key.toLocal8Bit().data(), cert.toLocal8Bit().data()); - system(tmp); + QProcess p; + QFile::remove(key); + QFile::remove(cert); + p.setProcessChannelMode(QProcess::ForwardedChannels); + p.start(QStringLiteral("openssl"), { + "req", "-x509", "-nodes", "-days", "5000", "-newkey", "rsa:4096", + "-subj", "'/C=DE/ST=BaWue/L=Freiburg/CN=openslx.org'", + "-keyout", key, "-out", cert + }); + p.waitForFinished(); + p.start(QStringLiteral("chmod"), { "0600", key, cert }); + p.waitForFinished(500); } + } diff --git a/src/server/net/client.cpp b/src/server/net/client.cpp index 977eb84..08dfc9a 100644 --- a/src/server/net/client.cpp +++ b/src/server/net/client.cpp @@ -9,46 +9,46 @@ #include "../serverapp/serverapp.h" #include "../../shared/settings.h" #include "../../shared/util.h" + #include <QPixmap> #include <cassert> #include <QNetworkInterface> +#include <QTcpSocket> +#include <QSslSocket> #define CHALLENGE_LEN 20 int Client::_clientIdCounter = 0; -Client::Client(QTcpSocket* socket) : _socket(socket) +Client::Client(QTcpSocket* socket) + : _socket(socket) { assert(socket != nullptr); - _authed = 0; - _projectionSource = 0; _desiredSource = NO_SOURCE; - _isActiveVncClient = false; - _vncPort = 0; - _isTutor = false; - _locked = false; - _wantsAttention = false; - + _socket->setParent(this); _id = ++_clientIdCounter; //_ip = _socket->peerAddress().toString(); qDebug("*** Client %s created.", qPrintable(_socket->peerAddress().toString())); // Connect important signals - connect(_socket, SIGNAL(disconnected()), - this, SLOT(disconnect())); - connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(disconnect())); - connect(_socket, SIGNAL(sslErrors(const QList<QSslError> &)), - this, SLOT(disconnect())); - connect(_socket, SIGNAL(readyRead()), - this, SLOT(onDataArrival())); + connect(_socket, &QTcpSocket::disconnected, + this, &Client::disconnect); + connect(_socket, &QTcpSocket::errorOccurred, + this, &Client::disconnect); + auto *ssl = qobject_cast<QSslSocket*>(_socket); + if (ssl != nullptr) { + connect(ssl, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), + this, &Client::disconnect); + } + connect(_socket, &QTcpSocket::readyRead, + this, &Client::onDataArrival); // Send challenge _challenge.resize(CHALLENGE_LEN); for (int i = 0; i < CHALLENGE_LEN; ++i) { - _challenge[i] = char(qrand() & 0xff); + _challenge[i] = char(slxrand() & 0xff); } - NetworkMessage msgChlng; - msgChlng.setField(_ID, _CHALLENGE); - msgChlng.setField(_CHALLENGE, _challenge); - msgChlng.writeMessage(_socket); + NetworkMessage msgChallenge; + msgChallenge.setField(_ID, _CHALLENGE); + msgChallenge.setField(_CHALLENGE, _challenge); + msgChallenge.writeMessage(_socket); // give client 3 seconds to complete handshake _timerIdAuthTimeout = startTimer(3000); _timerPingTimeout = startTimer(3000); @@ -58,7 +58,6 @@ Client::Client(QTcpSocket* socket) : _socket(socket) Client::~Client() { qDebug() << "*** Client" << _host << " destroyed."; - _socket->deleteLater(); } void Client::timerEvent(QTimerEvent* event) @@ -302,7 +301,7 @@ void Client::stopVncClient() * Checks if client and manager runs on same machine. * @return Return true, if pvsmanager is running on client. */ -bool Client::isManagerMachine() +bool Client::isManagerMachine() const { foreach (const QHostAddress & address, QNetworkInterface::allAddresses()) if (address != QHostAddress(QHostAddress::LocalHost) @@ -334,3 +333,8 @@ void Client::disconnect() this->deleteLater(); emit disconnected(); } + +QString Client::ip() const +{ + return _socket->peerAddress().toString(); +} diff --git a/src/server/net/client.h b/src/server/net/client.h index 3d5158b..3b95321 100644 --- a/src/server/net/client.h +++ b/src/server/net/client.h @@ -1,13 +1,13 @@ #ifndef CLIENT_H_ #define CLIENT_H_ -#include <QtCore> -#include <QHostAddress> -#include <QAbstractSocket> -#include <QTcpSocket> #include "../../shared/networkmessage.h" +#include <QByteArray> + //class QSslSocket; +class QTcpSocket; +class Client; #define NO_SOURCE 0 @@ -26,32 +26,32 @@ class Client : public QObject public: explicit Client(QTcpSocket* socket); - ~Client(); + ~Client() override; // Getters - inline bool isAuthed() const { return _authed == 2; } - inline const QString& name() const { return _name; } - inline const QString& host() const { return _host; } - inline const QString ip() const { return _socket->peerAddress().toString(); } - inline int id() const { return _id; } - inline bool isActiveVncClient() const { return _isActiveVncClient; } - inline bool isActiveVncServer() const { return _vncPort > 0; } - inline bool isLocked() const { return _locked; } - inline int desiredProjectionSource() const { return _desiredSource; } - inline int projectionSource() const { return _projectionSource; } - inline int isExamMode() const { return _isExamMode; } - inline bool wantsAttention() const { return _wantsAttention; } - inline void removeAttention() { if (!_wantsAttention) return; removeAttentionInternal(); } + bool isAuthed() const { return _authed == 2; } + const QString& name() const { return _name; } + const QString& host() const { return _host; } + QString ip() const; + int id() const { return _id; } + bool isActiveVncClient() const { return _isActiveVncClient; } + bool isActiveVncServer() const { return _vncPort > 0; } + bool isLocked() const { return _locked; } + int desiredProjectionSource() const { return _desiredSource; } + int projectionSource() const { return _projectionSource; } + int isExamMode() const { return _isExamMode; } + bool wantsAttention() const { return _wantsAttention; } + void removeAttention() { if (!_wantsAttention) return; removeAttentionInternal(); } // Setters - inline void setTutor(bool enable) { _isTutor = enable; } - inline void setDesiredProjectionSource(int id) {_desiredSource = id;} - inline void setExamMode(bool mode) { _isExamMode = mode; } + void setTutor(bool enable) { _isTutor = enable; } + void setDesiredProjectionSource(int id) { _desiredSource = id; } + void setExamMode(bool mode) { _isExamMode = mode; } //Send message stuff void startVncServer(); void stopVncServer(); - void startVncClient(Client const * const to ); + void startVncClient(const Client * to); void stopVncClient(); void lockScreen(bool); void requestThumb(const QSize& size); @@ -59,8 +59,8 @@ public: private: QTcpSocket * const _socket; - bool _locked; - int _authed; // 0 = challenge sent, awaiting reply 1 = challenge ok, client challenge replied, awaiting login, 2 = ESTABLISHED + bool _locked{}; + int _authed{}; // 0 = challenge sent, awaiting reply 1 = challenge ok, client challenge replied, awaiting login, 2 = ESTABLISHED QString _name; QString _host; QByteArray _challenge; @@ -69,26 +69,26 @@ private: int _timerIdAuthTimeout, _timerPingTimeout; int _id; // this client's unique id QString _vncRwPass, _vncRoPass; - int _vncPort; // VNCserver state. Greater 0 -> active on this port. Equals 0 -> no server. + int _vncPort{}; // VNCserver state. Greater 0 -> active on this port. Equals 0 -> no server. int _desiredSource; // The source the client shall be connected to - int _projectionSource; // The source the client was or is connected to (depends on _isActiveVncClient) - bool _isActiveVncClient; // VNCclient state. indicating that the client is displaying a remote screen via VNC - bool _isTutor; // Flag indicating that the client has been set as a tutor - bool _isExamMode; - bool _wantsAttention; // Flag telling whether the client activated the "i want attention" button + int _projectionSource{}; // The source the client was or is connected to (depends on _isActiveVncClient) + bool _isActiveVncClient{}; // VNCclient state. indicating that the client is displaying a remote screen via VNC + bool _isTutor{}; // Flag indicating that the client has been set as a tutor + bool _isExamMode{}; + bool _wantsAttention{}; // Flag telling whether the client activated the "i want attention" button QByteArray _rawRemoteScreen; static int _clientIdCounter; - bool isManagerMachine(); + bool isManagerMachine() const; void handleMsg(); void sendMessage(NetworkMessage& message); void removeAttentionInternal(); protected: - void timerEvent(QTimerEvent* event); + void timerEvent(QTimerEvent* event) override; signals: void authenticating(Client* client, ClientLogin* request); diff --git a/src/server/net/discoverylistener.cpp b/src/server/net/discoverylistener.cpp index b0f0df4..d644259 100644 --- a/src/server/net/discoverylistener.cpp +++ b/src/server/net/discoverylistener.cpp @@ -29,23 +29,20 @@ /** * @brief DiscoveryListener::DiscoveryListener */ -DiscoveryListener::DiscoveryListener() : - _socket(this), _counterResetPos(0) +DiscoveryListener::DiscoveryListener(QObject *parent) + : _socket(this) { - if (!_socket.bind(QHostAddress::AnyIPv4, SERVICE_DISCOVERY_PORT)) + if (!_socket.bind(QHostAddress::AnyIPv4, SERVICE_DISCOVERY_PORT)) { qFatal("Could not bind to service discovery port %d", int(SERVICE_DISCOVERY_PORT)); - connect(&_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead())); - for (int i = 0; i < SD_PACKET_TABLE_SIZE; ++i) - _packetCounter[i] = 0; + } + connect(&_socket, &QUdpSocket::readyRead, this, &DiscoveryListener::onReadyRead); startTimer((SPAM_MODERATE_AT_ONCE * SPAM_MODERATE_INTERVAL) / SD_PACKET_TABLE_SIZE + 1); } /** * @brief DiscoveryListener::~DiscoveryListener */ -DiscoveryListener::~DiscoveryListener() -{ -} +DiscoveryListener::~DiscoveryListener() = default; /** * @brief hash @@ -57,8 +54,8 @@ static quint16 hash(const QHostAddress& host) static quint16 seed1 = 0, seed2 = 0; while (seed1 == 0) { // Make sure the algorithm uses different seeds each time the program is // run to prevent hash collision attacks - seed1 = quint16(qrand() & 0xffff); - seed2 = quint16(qrand() & 0xffff); + seed1 = quint16(slxrand() & 0xffff); + seed2 = quint16(slxrand() & 0xffff); } quint8 data[16], len; if (host.protocol() == QAbstractSocket::IPv4Protocol) { @@ -79,8 +76,8 @@ static quint16 hash(const QHostAddress& host) } else { // Durr? len = 2; - data[0] = quint8(qrand()); - data[1] = quint8(qrand()); + data[0] = quint8(slxrand()); + data[1] = quint8(slxrand()); } quint16 result = 0; quint16 mod = seed1; diff --git a/src/server/net/discoverylistener.h b/src/server/net/discoverylistener.h index 64d4351..47a4295 100644 --- a/src/server/net/discoverylistener.h +++ b/src/server/net/discoverylistener.h @@ -8,12 +8,14 @@ #ifndef DISCOVERYLISTENER_H_ #define DISCOVERYLISTENER_H_ -#include <QtCore> +#include <QObject> #include <QUdpSocket> #include "../../shared/networkmessage.h" #define SD_PACKET_TABLE_SIZE 20000 +class QTimerEvent; + class DiscoveryListener : public QObject { Q_OBJECT @@ -21,16 +23,16 @@ class DiscoveryListener : public QObject private: QUdpSocket _socket; NetworkMessage _packet; - int _counterResetPos; + int _counterResetPos{}; - quint8 _packetCounter[SD_PACKET_TABLE_SIZE]; // count packets per source address to ignore spammers + quint8 _packetCounter[SD_PACKET_TABLE_SIZE]{}; // count packets per source address to ignore spammers protected: - void timerEvent(QTimerEvent* event); + void timerEvent(QTimerEvent* event) override; public: - DiscoveryListener(); - virtual ~DiscoveryListener(); + explicit DiscoveryListener(QObject *parent); + ~DiscoveryListener() override; private slots: void onReadyRead(); diff --git a/src/server/net/filedownloader.cpp b/src/server/net/filedownloader.cpp deleted file mode 100644 index b930869..0000000 --- a/src/server/net/filedownloader.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * FileDownloader.cpp - * - * Created on: Mar 7, 2014 - * Author: nils - */ - -#include <QFileInfo> - -#include "filedownloader.h" - -FileDownloader::FileDownloader(QObject *parent) : - QObject(parent) -{ - connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)), - SLOT(fileDownloaded(QNetworkReply*))); -} - -FileDownloader::~FileDownloader() -{ - -} - -void FileDownloader::connectSlot(QObject* obj, const char* slot) -{ - QObject::connect(this, SIGNAL(downloaded(QByteArray&)), - obj, slot); -} - -void FileDownloader::fileDownloaded(QNetworkReply* pReply) -{ - QByteArray downloadedData = pReply->readAll(); - //emit a signal - pReply->deleteLater(); - emit downloaded(downloadedData); -} - -void FileDownloader::downloadFile(const QUrl& fileUrl) -{ - m_WebCtrl.get(QNetworkRequest(fileUrl)); -} diff --git a/src/server/net/filedownloader.h b/src/server/net/filedownloader.h deleted file mode 100644 index 227af50..0000000 --- a/src/server/net/filedownloader.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * filedownloader.h - * - * Created on: Mar 7, 2014 - * Author: nils - */ - -#ifndef FILEDOWNLOADER_H_ -#define FILEDOWNLOADER_H_ - -#include <QObject> -#include <QByteArray> -#include <QNetworkAccessManager> -#include <QNetworkRequest> -#include <QNetworkReply> - -class FileDownloader : public QObject -{ - Q_OBJECT -public: - explicit FileDownloader(QObject *parent = 0); - - virtual ~FileDownloader(); - - void downloadFile(const QUrl& fileUrl); - - void connectSlot(QObject* obj, const char* slot); - - QByteArray downloadedData() const; - -signals: - void downloaded(QByteArray& downloadedData); - -private slots: - - void fileDownloaded(QNetworkReply* pReply); - -private: - - QNetworkAccessManager m_WebCtrl; - -}; - -#endif /* FILEDOWNLOADER_H_ */ diff --git a/src/server/net/listenserver.cpp b/src/server/net/listenserver.cpp index 0438fb4..27a1412 100644 --- a/src/server/net/listenserver.cpp +++ b/src/server/net/listenserver.cpp @@ -1,18 +1,20 @@ #include "listenserver.h" #include "client.h" + #include <QSslSocket> -#define MAX_CLIENTS 50 /** * Initialize listenServer to listen on specific port. * And connect Signal newConnection() with Slot newClientConnection(). * @param port */ -ListenServer::ListenServer(quint16 port) +ListenServer::ListenServer(quint16 port, QObject *parent) + : QObject(parent) + , _server(this) { 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())); + connect(&_server, &SslServer::newConnection, this, &ListenServer::newClientConnection); } ListenServer::~ListenServer() @@ -32,7 +34,7 @@ void ListenServer::newClientConnection() { QTcpSocket* sock; while ((sock = _server.nextPendingConnection()) != nullptr) { - Client* client = new Client(sock); // TODO: what happens with disconnected clients + auto* client = new Client(sock); // TODO: what happens with disconnected clients emit newClient(client); } } diff --git a/src/server/net/listenserver.h b/src/server/net/listenserver.h index 640da23..4ad363d 100644 --- a/src/server/net/listenserver.h +++ b/src/server/net/listenserver.h @@ -18,8 +18,8 @@ private: SslServer _server; public: - explicit ListenServer(quint16 port); - virtual ~ListenServer(); + explicit ListenServer(quint16 port, QObject *parent); + ~ListenServer() override; private slots: void newClientConnection(); diff --git a/src/server/net/sslserver.cpp b/src/server/net/sslserver.cpp index b2da034..2dfa84c 100644 --- a/src/server/net/sslserver.cpp +++ b/src/server/net/sslserver.cpp @@ -21,7 +21,9 @@ #include "certmanager.h" #include <unistd.h> -SslServer::SslServer() : QTcpServer(nullptr), _timer(new QTimer(this)) +SslServer::SslServer(QObject *parent) + : QTcpServer(parent) + , _timer(new QTimer(this)) { connect(_timer, &QTimer::timeout, [=]() { if (_pending.empty()) @@ -43,9 +45,11 @@ SslServer::SslServer() : QTcpServer(nullptr), _timer(new QTimer(this)) SslServer::~SslServer() { _timer->stop(); - for (QSslSocket *sock : _pending.keys()) { + auto keys = _pending.keys(); + for (QSslSocket *sock : keys) { sock->deleteLater(); } + _pending.clear(); } /** @@ -64,7 +68,7 @@ void SslServer::incomingConnection(qintptr socketDescriptor) ::close(int(socketDescriptor)); return; } - QSslSocket *serverSocket = new QSslSocket(nullptr); + auto *serverSocket = new QSslSocket(nullptr); connect(serverSocket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), this, &SslServer::sslErrors); serverSocket->setPrivateKey(key); serverSocket->setLocalCertificate(cert); @@ -93,8 +97,8 @@ void SslServer::incomingConnection(qintptr socketDescriptor) void SslServer::sslErrors(const QList<QSslError>& errors) { qDebug() << "Client caused sslErrors before connection:"; - for (QList<QSslError>::const_iterator it = errors.begin(); it != errors.end(); it++) { - qDebug() << it->errorString(); + for (const auto & error : errors) { + qDebug() << error.errorString(); } } diff --git a/src/server/net/sslserver.h b/src/server/net/sslserver.h index 03d947a..c74e56c 100644 --- a/src/server/net/sslserver.h +++ b/src/server/net/sslserver.h @@ -35,11 +35,11 @@ private slots: void sslErrors ( const QList<QSslError> & errors ); public: - explicit SslServer(); - virtual ~SslServer(); + explicit SslServer(QObject *parent); + ~SslServer() override; protected: - void incomingConnection(qintptr handle); + void incomingConnection(qintptr handle) override; QHash<QSslSocket*, qint64> _pending; // Queue for connected but unencrypted connections QTimer* _timer; }; |