summaryrefslogblamecommitdiffstats
path: root/src/server/net/sslserver.cpp
blob: ffbf26284170a5b0ef5e1fad861f6bd2a6adad0d (plain) (tree)































                                                                                



                               









                                                                                                                            
                                                    





































































                                                                                                      
/*
 # 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/SslServer.cpp
 #    - provide QTcpServer-like behaviour for SSL
 # -----------------------------------------------------------------------------
 */

#include "sslserver.h"
#include <QtNetwork/QSslCipher>
#include <QtNetwork/QSslSocket>
#include "certmanager.h"

SslServer::SslServer()
{
	_tmr = startTimer(5123);
	//QSslSocket::setDefaultCiphers(QSslSocket::supportedCiphers());
}

SslServer::~SslServer()
{
	killTimer((_tmr));
}

/**
 * Handle incomming connection.
 * @param socketDescriptor
 */
void SslServer::incomingConnection(int socketDescriptor)
{
	QSslSocket *serverSocket = new QSslSocket(NULL);
	connect(serverSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &)));
	QSslKey key;
	QSslCertificate cert;
	CertManager::getPrivateKeyAndCert("manager", key, cert);
	serverSocket->setPrivateKey(key);
	serverSocket->setLocalCertificate(cert);
	serverSocket->setPeerVerifyMode(QSslSocket::VerifyNone);
	serverSocket->setProtocol(QSsl::TlsV1SslV3);
	//printf("Keylen %d\n", serverSocket->privateKey().length());
	if (serverSocket->setSocketDescriptor(socketDescriptor))
	{
		// Once the connection is successfully encrypted, raise our newConnection event
		connect(serverSocket, SIGNAL(encrypted()), this, SIGNAL(newConnection()));
		serverSocket->startServerEncryption();
		_pending.push_back(serverSocket);
	}
	else
	{
		serverSocket->deleteLater();
	}
}

void SslServer::sslErrors(const QList<QSslError> & errors)
{
	//qDebug("FIXME: SSL ERRORS on SERVER: %s", qPrintable(errors.begin()->errorString()));
}

void SslServer::timerEvent(QTimerEvent* event)
{
	// Remove all sockets marked for deletion
	while (!_delete.isEmpty())
	{
		QSslSocket *sock = _delete.takeFirst();
		sock->blockSignals(true);
		sock->deleteLater();
	}
	_delete = _pending;
	_pending.clear();
}

bool SslServer::hasPendingConnections()
{
	for (QList<QSslSocket*>::iterator it(_pending.begin()); it != _pending.end(); it++)
	{
		qDebug("State: %d - Encrypted: %d", (int)(*it)->state(), (*it)->isEncrypted());
		if ((*it)->state() == QAbstractSocket::ConnectedState && (*it)->isEncrypted())
			return true;
	}
	return false;
}

QTcpSocket* SslServer::nextPendingConnection()
{
	for (QList<QSslSocket*>::iterator it(_pending.begin()); it != _pending.end(); it++)
	{
		if ((*it)->state() == QAbstractSocket::ConnectedState && (*it)->isEncrypted())
		{
			QSslSocket *sock = *it;
			QObject::disconnect(sock, SIGNAL(encrypted()), this, SIGNAL(newConnection()));
			_pending.removeAll(sock);
			_delete.removeAll(sock);
			return sock;
		}
	}
	for (QList<QSslSocket*>::iterator it(_delete.begin()); it != _delete.end(); it++)
	{
		if ((*it)->state() == QAbstractSocket::ConnectedState && (*it)->isEncrypted())
		{
			QSslSocket *sock = *it;
			QObject::disconnect(sock, SIGNAL(encrypted()), this, SIGNAL(newConnection()));
			_pending.removeAll(sock);
			_delete.removeAll(sock);
			return sock;
		}
	}
	return NULL;
}