summaryrefslogtreecommitdiffstats
path: root/src/server/net/sslserver.cpp
blob: f75f174fb3e9bb3fae08ef29edf0b83d1017d70f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
 # 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() const
{
	for (QList<QSslSocket*>::const_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;
}