From ce3329047d378a14006ce74ec273ac59e3375303 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 12 May 2010 19:42:27 +0200 Subject: initial import of latest svn version --- src/net/pvsDiscoveredServer.cpp | 152 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 src/net/pvsDiscoveredServer.cpp (limited to 'src/net/pvsDiscoveredServer.cpp') diff --git a/src/net/pvsDiscoveredServer.cpp b/src/net/pvsDiscoveredServer.cpp new file mode 100644 index 0000000..dddb5a0 --- /dev/null +++ b/src/net/pvsDiscoveredServer.cpp @@ -0,0 +1,152 @@ +/* +# Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg +# +# This program is free software distributed under the GPL version 2. +# See http://openslx.org/COPYING +# +# If you have any feedback please consult http://openslx.org/feedback and +# send your suggestions, praise, or complaints to feedback@openslx.org +# +# General information about OpenSLX can be found at http://openslx.org/ +# ----------------------------------------------------------------------------- +# src/net/pvsDiscoveredServer.cpp +# - represents an entry in the list of available servers +# - handles some extra things like validating the identity of the remote host +# ----------------------------------------------------------------------------- +*/ + +#include "pvsDiscoveredServer.h" +#include "src/util/serviceDiscoveryUtil.h" +#include + +PVSDiscoveredServer::PVSDiscoveredServer(QObject* parent, QHostAddress host, int port, QByteArray fingerprint, QString name) + : QObject(parent) +{ + _validated = false; + _socket = NULL; + _host = host; + _port = port; + _fingerprint = fingerprint; + _name = name; + _lastUpdate = QDateTime::currentDateTime(); + _lastCheck = QDateTime::fromTime_t(1000000); + this->validateCertificate(); +} + +PVSDiscoveredServer::~PVSDiscoveredServer() { + delete _socket; +} + +void PVSDiscoveredServer::ssl_Error( const QList & errors ) +{ + for (QList::const_iterator it = errors.begin(); it != errors.end(); it++) + { + QSslError err = *it; + if (err.error() == QSslError::HostNameMismatch) continue; // We don't pay attention to hostnames for validation + if (err.error() == QSslError::SelfSignedCertificate) { + continue; // Also, this will always be the case; we check the fingerprint later + } + //ConsoleLog writeNetwork(err.errorString().toUtf8().data()); + //ConsoleLog writeNetwork("***** SSL ERROR, ABORTING *****"); + printf("Unhandled SSL Error in SD: %s\n", err.errorString().toUtf8().data()); + return; + } + _socket->ignoreSslErrors(); +} + +void PVSDiscoveredServer::sock_dataArrival() +{ + if (_socket == NULL) return; + + char charbuff[2000]; + while (_socket->bytesAvailable()) + { + _socket->read(charbuff, 2000); + } +} + +void PVSDiscoveredServer::sock_connected() +{ + QByteArray cert = _socket->peerCertificate().digest(QCryptographicHash::Sha1); + if (_socket->peerCertificate().isNull()) + { + printf("**** WARNING - PEER CERTIFICATE IS NULL ****\n"); + } + else + { + printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::Organization).toUtf8().data()); + printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::CommonName).toUtf8().data()); + printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::LocalityName).toUtf8().data()); + printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::OrganizationalUnitName ).toUtf8().data()); + printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::CountryName ).toUtf8().data()); + printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::StateOrProvinceName ).toUtf8().data()); + } + if (cert == _fingerprint && !_validated) + { + _validated = true; + emit validated(this); + printf("Validated certificate of %s :)\n", _socket->peerAddress().toString().toUtf8().data()); + } + else + { + printf("Certificate of %s is invalid :(\n", _socket->peerAddress().toString().toUtf8().data()); + QByteArray is, should; + is = cert.toBase64(); + should = _fingerprint.toBase64(); + printf("Is %s and should be %s\n", is.data(), should.data()); + } + _socket->disconnectFromHost(); +} + +void PVSDiscoveredServer::validateCertificate() +{ + if (_validated) return; // Nothing to do, this one is legit + QDateTime now = QDateTime::currentDateTime(); + if (_lastCheck.secsTo(now) < 30) return; // Too soon! + if (_host.isNull() || _port < 1 || _port > 65535) return; // Invalid + if (_socket != NULL) { + disconnect(_socket, SIGNAL(connected()), this, SLOT(sock_connected())); + disconnect(_socket, SIGNAL(readyRead()), this, SLOT(sock_dataArrival())); + disconnect(_socket, SIGNAL(sslErrors(const QList &)), + this, SLOT(ssl_Error(const QList &)) + ); + _socket->abort(); + _socket->deleteLater(); + } + _socket = new QSslSocket(this); + _socket->setProtocol(QSsl::SslV3); + _socket->setPeerVerifyMode(QSslSocket::VerifyPeer); + connect(_socket, SIGNAL(encrypted()), this, SLOT(sock_connected())); + connect(_socket, SIGNAL(readyRead()), this, SLOT(sock_dataArrival())); + connect(_socket, SIGNAL(sslErrors(const QList &)), + this, SLOT(ssl_Error(const QList &)) + ); + _socket->connectToHostEncrypted(_host.toString(), _port); + _lastCheck = now; +} + +bool PVSDiscoveredServer::hasFingerprint(QByteArray &fingerprint) +{ + return _fingerprint == fingerprint; +} + +bool PVSDiscoveredServer::hasHost(QHostAddress &host) +{ + return _host == host; +} + +void PVSDiscoveredServer::update(int port) +{ + _port = port; + _lastUpdate = QDateTime::currentDateTime(); +} + +int PVSDiscoveredServer::getAge() +{ + return _lastUpdate.secsTo(QDateTime::currentDateTime()); +} + +QString PVSDiscoveredServer::getName() +{ + return _name; +} -- cgit v1.2.3-55-g7522