diff options
Diffstat (limited to 'src/client/net')
-rw-r--r-- | src/client/net/serverconnection.cpp | 171 | ||||
-rw-r--r-- | src/client/net/serverconnection.h | 2 | ||||
-rw-r--r-- | src/client/net/serverdiscovery.cpp | 35 | ||||
-rw-r--r-- | src/client/net/serverdiscovery.h | 81 |
4 files changed, 117 insertions, 172 deletions
diff --git a/src/client/net/serverconnection.cpp b/src/client/net/serverconnection.cpp index f4a6fd6..5c812d5 100644 --- a/src/client/net/serverconnection.cpp +++ b/src/client/net/serverconnection.cpp @@ -24,17 +24,17 @@ ServerConnection::ServerConnection(const QString& host, const quint16 port, cons { _socket = new QSslSocket(); _blank = new BlankScreen(); - connect(_socket, SIGNAL(encrypted()), this, SLOT(sock_connected())); - connect(_socket, SIGNAL(readyRead()), this, SLOT(sock_dataArrival())); - connect(_socket, SIGNAL(disconnected()), this, SLOT(sock_closed())); - connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(sock_error(QAbstractSocket::SocketError))); - connect(_socket, - SIGNAL(sslErrors(const QList<QSslError> &)), - this, - SLOT(sslErrors(const QList<QSslError> &)) - ); - qDebug("Connecting to %s on port %d", host.toUtf8().data(), (int)port); - _socket->connectToHostEncrypted(host, port); + connect(_socket, SIGNAL(encrypted()), this, SLOT(sock_connected())); + connect(_socket, SIGNAL(readyRead()), this, SLOT(sock_dataArrival())); + connect(_socket, SIGNAL(disconnected()), this, SLOT(sock_closed())); + connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(sock_error(QAbstractSocket::SocketError))); + connect(_socket, + SIGNAL(sslErrors(const QList<QSslError> &)), + this, + SLOT(sslErrors(const QList<QSslError> &)) + ); + qDebug("Connecting to %s on port %d", host.toUtf8().data(), (int)port); + _socket->connectToHostEncrypted(host, port); _timerId = startTimer(4000); _lastData = QDateTime::currentMSecsSinceEpoch() + PING_TIMEOUT_MS; _timerConnectionCheck = startTimer(5000); @@ -44,8 +44,7 @@ ServerConnection::ServerConnection(const QString& host, const quint16 port, cons ServerConnection::~ServerConnection() { - if (_socket != NULL) - { + if (_socket != NULL) { qCritical("**** SOCKET DELETE IN DESTRUCTOR"); _socket->deleteLater(); } @@ -62,8 +61,7 @@ void ServerConnection::sendMessage(NetworkMessage& message) if (_socket == NULL || _socket->state() != QAbstractSocket::ConnectedState) return; message.writeMessage(_socket); - if (!message.writeComplete()) - { + if (!message.writeComplete()) { qCritical() << "SendMessage to server failed!"; } } @@ -75,15 +73,13 @@ void ServerConnection::sendMessage(NetworkMessage& message) */ void ServerConnection::disconnectFromServer() { - if (_timerDelete == 0) - { + if (_timerDelete == 0) { VncServer::instance()->stop(); emit closeVnc(); emit disconnected(); _timerDelete = startTimer(500); qDebug("Closing connection to server"); - if (_socket != NULL) - { + if (_socket != NULL) { _socket->blockSignals(true); _socket->abort(); } @@ -100,10 +96,8 @@ void ServerConnection::handleMsg() _lastData = QDateTime::currentMSecsSinceEpoch() + PING_TIMEOUT_MS; const QString &id = _fromServer.getFieldString(_ID); - if (_authed == 0) - { - if (id == _CHALLENGE) - { + if (_authed == 0) { + if (id == _CHALLENGE) { // Initial challenge request by server emit stateChange(ConnectWindow::AwaitingChallengeResponse); _myChallenge.resize(CHALLENGE_LEN); @@ -121,21 +115,17 @@ void ServerConnection::handleMsg() return; } - if (_authed == 1) - { - if (id == _CHALLENGE) - { + if (_authed == 1) { + if (id == _CHALLENGE) { qDebug("Received challenge reply"); - if (_timerId != 0) - { + if (_timerId != 0) { killTimer(_timerId); _timerId = 0; } // Check challenge response QByteArray serverhash(_fromServer.getFieldBytes(_HASH)); if (serverhash != genSha1(&_sessionName, &_myChallenge) - && !_autoConnect) - { + && !_autoConnect) { qDebug("invalid. STOP."); emit stateChange(ConnectWindow::InvalidSslHash); this->disconnectFromServer(); @@ -157,23 +147,18 @@ void ServerConnection::handleMsg() _toServer.setField(_EXAMMODE, clientApp->isExamMode() ? __TRUE : __FALSE); /* TODO: (Question) Why is this here not using sendMessage() ? */ qDebug("Sending login request!"); - if (_toServer.writeMessage(_socket)) - { + if (_toServer.writeMessage(_socket)) { _authed = 2; qDebug("valid, step <- 2"); - } - else - { + } else { this->disconnectFromServer(); } } return; } - if (_authed == 2) - { - if (id == _LOGIN) - { + if (_authed == 2) { + if (id == _LOGIN) { qDebug("login accepted, step <- 3"); _authed = 3; emit stateChange(ConnectWindow::Connected); @@ -182,8 +167,7 @@ void ServerConnection::handleMsg() } // message THUMB - server requests screenshot as thumbnail - if (id == _THUMB) - { + if (id == _THUMB) { if (clientApp->isExamMode()) { QByteArray emptyArray; _toServer.setField(_ID, _THUMB); @@ -207,34 +191,31 @@ void ServerConnection::handleMsg() const QRect primaryRect = primary.screenGeometry(); QPixmap desktop( - QPixmap::grabWindow( - QApplication::desktop()->winId(), - primaryRect.x(), - primaryRect.y(), - primaryRect.width(), - primaryRect.height() - ).scaled( - x, y, - Qt::KeepAspectRatio, - Qt::SmoothTransformation)); + QPixmap::grabWindow( + QApplication::desktop()->winId(), + primaryRect.x(), + primaryRect.y(), + primaryRect.width(), + primaryRect.height() + ).scaled( + x, y, + Qt::KeepAspectRatio, + Qt::SmoothTransformation)); QByteArray bytes; QBuffer jpgBuffer(&bytes); jpgBuffer.open(QIODevice::WriteOnly); - if (desktop.save(&jpgBuffer, "JPG", _jpegQuality)) // writes pixmap into bytes in JPG format - { + if (desktop.save(&jpgBuffer, "JPG", _jpegQuality)) { // writes pixmap into bytes in JPG format // Try to adjust quality so we stay between 3 and 4.5 KB if (_jpegQuality < 90 && bytes.size() < 3000) _jpegQuality += 7; else if (_jpegQuality > 40 && bytes.size() > 4500) _jpegQuality -= 7; - } - else - { // FALLBACK + } else { + // FALLBACK bytes.clear(); QBuffer pngBuffer(&bytes); pngBuffer.open(QIODevice::WriteOnly); - if (!desktop.save(&pngBuffer, "PNG")) // writes pixmap into bytes in PNG format - { + if (!desktop.save(&pngBuffer, "PNG")) { // writes pixmap into bytes in PNG format qDebug("Could not convert screenshot to PNG nor JPG"); return; // Failed :-( } @@ -244,42 +225,31 @@ void ServerConnection::handleMsg() _toServer.setField(_IMG, bytes); sendMessage(_toServer); } // message VNCSERVER - start local vncserver - else if (id == _VNCSERVER) - { + else if (id == _VNCSERVER) { if (clientApp->isExamMode()) { qDebug() << "denied request for vnc server (exam mode)"; return; } const bool enable = (_fromServer.getFieldString("ENABLE").toInt() != 0); - if (enable) - { + if (enable) { emit closeVnc(); // In case we are watching some other client, stop doing so VncServer::instance()->start(); - } - else - { + } else { VncServer::instance()->stop(); } - } - else if (id == _VNCCLIENT) - { + } else if (id == _VNCCLIENT) { if (clientApp->isExamMode()) { qDebug() << "denied request for vnc projection (exam mode)"; return; } const QString host(_fromServer.getFieldString("HOST")); const int port = _fromServer.getFieldString("PORT").toInt(); - if (host.isEmpty() || port <= 0) - { + if (host.isEmpty() || port <= 0) { emit closeVnc(); - } - else - { + } else { emit openVnc(host, port, _fromServer.getFieldString("ROPASS"), true, true, _fromServer.getFieldString("CAPTION"), _fromServer.getFieldString("CLIENTID").toInt(), _fromServer.getFieldBytes(_THUMB)); } - } - else if (id == _LOCK) - { + } else if (id == _LOCK) { const bool enable = (_fromServer.getFieldString("ENABLE").toInt() != 0); if (enable) _blank->lock(_fromServer.getFieldString("MESSAGE")); @@ -294,24 +264,17 @@ void ServerConnection::handleMsg() void ServerConnection::timerEvent(QTimerEvent *event) { - if (event->timerId() == _timerConnectionCheck) - { - if (_lastData < QDateTime::currentMSecsSinceEpoch()) - { + if (event->timerId() == _timerConnectionCheck) { + if (_lastData < QDateTime::currentMSecsSinceEpoch()) { this->disconnectFromServer(); killTimer(_timerConnectionCheck); } - } - else if (event->timerId() == _timerId) - { + } else if (event->timerId() == _timerId) { killTimer(_timerId); _timerId = 0; this->disconnectFromServer(); - } - else if (event->timerId() == _timerDelete) - { - if (_socket == NULL || _socket->state() == QAbstractSocket::UnconnectedState) - { + } else if (event->timerId() == _timerDelete) { + if (_socket == NULL || _socket->state() == QAbstractSocket::UnconnectedState) { if (_socket != NULL) _socket->deleteLater(); _socket = NULL; @@ -321,8 +284,7 @@ void ServerConnection::timerEvent(QTimerEvent *event) } _socket->abort(); qDebug("A socket is still pending..."); - } - else + } else killTimer(event->timerId()); } @@ -339,12 +301,9 @@ void ServerConnection::onVncServerStartStop(int port, QString& ropass, QString& { _toServer.reset(); _toServer.setField(_ID, _VNCSERVER); - if (port <= 0) - { + if (port <= 0) { _toServer.setField("PORT", QByteArray("0")); - } - else - { + } else { _toServer.setField("PORT", QString::number(port)); _toServer.setField("ROPASS", ropass); _toServer.setField("RWPASS", rwpass); @@ -374,8 +333,7 @@ void ServerConnection::onVncViewerStartStop(const bool started, const int client */ void ServerConnection::sslErrors(const QList<QSslError> & errors) { - for (QList<QSslError>::const_iterator it = errors.begin(); it != errors.end(); it++) - { + for (QList<QSslError>::const_iterator it = errors.begin(); it != errors.end(); it++) { QSslError err = *it; qDebug("Connect SSL: %s", qPrintable(err.errorString())); if (err.error() == QSslError::HostNameMismatch) @@ -392,25 +350,21 @@ void ServerConnection::sslErrors(const QList<QSslError> & errors) void ServerConnection::sock_dataArrival() { - if (_socket == NULL || _socket->state() != QAbstractSocket::ConnectedState) - { + if (_socket == NULL || _socket->state() != QAbstractSocket::ConnectedState) { qDebug("dataArrival called in bad state"); return; } - while (_socket->bytesAvailable() > 0) - { + while (_socket->bytesAvailable() > 0) { bool retval; retval = _fromServer.readMessage(_socket); // let the message read data from socket - if (retval == NM_READ_FAILED) // error parsing msg, disconnect client! - { + if (retval == NM_READ_FAILED) { // error parsing msg, disconnect client! this->disconnectFromServer(); return; } if (retval == NM_READ_INCOMPLETE) return; - if (_fromServer.readComplete()) // message is complete - { + if (_fromServer.readComplete()) { // message is complete this->handleMsg(); if (_socket == NULL) return; @@ -435,9 +389,8 @@ void ServerConnection::sock_error(QAbstractSocket::SocketError errcode) void ServerConnection::sock_connected() { - QByteArray cert(_socket->peerCertificate().digest(QCryptographicHash::Sha1)); - if (_certHash != cert) - { + QByteArray cert(_socket->peerCertificate().digest(QCryptographicHash::Sha1)); + if (_certHash != cert) { emit stateChange(ConnectWindow::InvalidCert); this->disconnectFromServer(); return; diff --git a/src/client/net/serverconnection.h b/src/client/net/serverconnection.h index 5e2631f..aa1d0b4 100644 --- a/src/client/net/serverconnection.h +++ b/src/client/net/serverconnection.h @@ -9,7 +9,7 @@ class BlankScreen; class ServerConnection : public QObject { -Q_OBJECT + Q_OBJECT private: QSslSocket *_socket; diff --git a/src/client/net/serverdiscovery.cpp b/src/client/net/serverdiscovery.cpp index 1d1e891..4a69e91 100644 --- a/src/client/net/serverdiscovery.cpp +++ b/src/client/net/serverdiscovery.cpp @@ -12,16 +12,15 @@ */ ServerDiscovery::ServerDiscovery(QObject *parent) : QObject(parent), - _minDiscoveryInterval(500), - _maxDiscoveryInterval(5000) + _minDiscoveryInterval(500), + _maxDiscoveryInterval(5000) { _hashErrorCount = 0; _ipErrorCount = 0; /* Try to get a UDP port for server discovery */ int tries = 10; - while (tries-- != 0) - { + while (tries-- != 0) { const quint16 port = (quint16)(qrand() % 10000) + 10000; if (_discoverySocket.bind(QHostAddress::Any, port)) break; @@ -109,19 +108,14 @@ void ServerDiscovery::doDiscovery() _packet.setField(_IPLIST, iplist); // Check if specifig manager IP is given. If not broadcast in whole network. - if (_mgrIP != QHostAddress::Null) - { + if (_mgrIP != QHostAddress::Null) { qDebug() << "Broadcasting to " << _mgrIP.toString(); if (!_packet.writeMessage(&_discoverySocket, _mgrIP, SERVICE_DISCOVERY_PORT)) qDebug("Failed"); - } else - { - foreach (QNetworkInterface interface, QNetworkInterface::allInterfaces()) - { - foreach (QNetworkAddressEntry entry, interface.addressEntries()) - { - if (!entry.broadcast().isNull() && entry.ip() != QHostAddress::LocalHost && entry.ip() != QHostAddress::LocalHostIPv6) - { + } else { + foreach (QNetworkInterface interface, QNetworkInterface::allInterfaces()) { + foreach (QNetworkAddressEntry entry, interface.addressEntries()) { + if (!entry.broadcast().isNull() && entry.ip() != QHostAddress::LocalHost && entry.ip() != QHostAddress::LocalHostIPv6) { qDebug() << "Broadcasting to " << entry.broadcast().toString(); if (!_packet.writeMessage(&_discoverySocket, entry.broadcast(), SERVICE_DISCOVERY_PORT)) qDebug("FAILED"); @@ -148,10 +142,9 @@ void ServerDiscovery::onUdpReadyRead() char data[UDPBUFSIZ]; QHostAddress addr; quint16 port; - while (_discoverySocket.hasPendingDatagrams()) - { + while (_discoverySocket.hasPendingDatagrams()) { // Discard any packets if discovery is stopped - if (!this->isActive()){ + if (!this->isActive()) { _discoverySocket.readDatagram(NULL, 0); continue; } @@ -171,16 +164,14 @@ void ServerDiscovery::onUdpReadyRead() const QByteArray cert(_packet.getFieldBytes(_CERT)); // Check if the source IP of the packet matches any of the addresses given in the IP list - if (!Network::isAddressInList(QString::fromUtf8(iplist), addr.toString())) - { + if (!Network::isAddressInList(QString::fromUtf8(iplist), addr.toString())) { ++_ipErrorCount; emit error(ErrorType::InvalidIpList, _hashErrorCount); continue; } // If so, check if the submitted hash seems valid - if (genSha1(&_nameBytes, &_salt2, &iplist, &port, &cert) != hash && _mgrIP != addr) - { + if (genSha1(&_nameBytes, &_salt2, &iplist, &port, &cert) != hash && _mgrIP != addr) { // did not match local session name, or other data was spoofed ++_hashErrorCount; emit error(ErrorType::InvalidHash, _ipErrorCount); @@ -189,7 +180,7 @@ void ServerDiscovery::onUdpReadyRead() /* Otherwise it's a valid reply */ qDebug() << "Server detected:" - << addr.toString() + ":" + QString::fromUtf8(port) + "/" + _nameBytes; + << addr.toString() + ":" + QString::fromUtf8(port) + "/" + _nameBytes; // Tell that a server hs been found emit serverDetected(addr.toString(), (quint16)QString::fromUtf8(port).toInt(), _nameBytes, cert, (_mgrIP == addr)); diff --git a/src/client/net/serverdiscovery.h b/src/client/net/serverdiscovery.h index a41c946..d7d6010 100644 --- a/src/client/net/serverdiscovery.h +++ b/src/client/net/serverdiscovery.h @@ -8,46 +8,47 @@ class ServerDiscovery : public QObject { - Q_OBJECT - - public: - enum class ErrorType{ - InvalidIpList, - InvalidHash - }; - - explicit ServerDiscovery(QObject *parent = 0); - ~ServerDiscovery(); - - void start(const QByteArray& sessionName, QString mgrIP); - void stop(); - inline bool isActive(){ return _discoveryTimer.isActive(); } - - private: - QTimer _discoveryTimer; - const int _minDiscoveryInterval; - const int _maxDiscoveryInterval; - int _hashErrorCount; - int _ipErrorCount; - QByteArray _nameBytes; - QByteArray _salt2; - QUdpSocket _discoverySocket; - NetworkMessage _packet; - - QHostAddress _mgrIP; - - static const int UDPBUFSIZ = 9000; - static const int SALT_LEN = 18; - - signals: - void serverDetected(const QString& host, const quint16 port, const QByteArray& sessionName, const QByteArray& certHash, bool autoConnect); - void error(ErrorType e, int count); - - public slots: - - private slots: - void doDiscovery(); - void onUdpReadyRead(); + Q_OBJECT + +public: + enum class ErrorType + { + InvalidIpList, + InvalidHash + }; + + explicit ServerDiscovery(QObject *parent = 0); + ~ServerDiscovery(); + + void start(const QByteArray& sessionName, QString mgrIP); + void stop(); + inline bool isActive() { return _discoveryTimer.isActive(); } + +private: + QTimer _discoveryTimer; + const int _minDiscoveryInterval; + const int _maxDiscoveryInterval; + int _hashErrorCount; + int _ipErrorCount; + QByteArray _nameBytes; + QByteArray _salt2; + QUdpSocket _discoverySocket; + NetworkMessage _packet; + + QHostAddress _mgrIP; + + static const int UDPBUFSIZ = 9000; + static const int SALT_LEN = 18; + +signals: + void serverDetected(const QString& host, const quint16 port, const QByteArray& sessionName, const QByteArray& certHash, bool autoConnect); + void error(ErrorType e, int count); + +public slots: + +private slots: + void doDiscovery(); + void onUdpReadyRead(); }; |