summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandro Knauß <knauss@kolabsys.com>2014-05-30 15:43:04 (GMT)
committerSandro Knauß <knauss@kolabsys.com>2014-05-30 15:43:04 (GMT)
commitbb731504eac98d378c7677b9ca9aa697b3cad735 (patch)
treefb0b1ba2dee27c7157f42604c975dcda6a4ea396
parente180af6d57394557281a0c8b3b503199c0220954 (diff)
downloadlibcalendaring-bb731504eac98d378c7677b9ca9aa697b3cad735.tar.gz
Add support for subclassing Fakeserver.
This patch is only moving a new version of fakeserver from: kdepimlibs d04fcaa1 [master] from 29 May 2014.
-rw-r--r--kimap/tests/kimaptest/CMakeLists.txt1
-rw-r--r--kimap/tests/kimaptest/fakeserver.cpp70
-rw-r--r--kimap/tests/kimaptest/fakeserver.h18
-rw-r--r--kimap/tests/kimaptest/sslserver.cpp113
-rw-r--r--kimap/tests/kimaptest/sslserver.h41
5 files changed, 217 insertions, 26 deletions
diff --git a/kimap/tests/kimaptest/CMakeLists.txt b/kimap/tests/kimaptest/CMakeLists.txt
index 423ce4d..f3d2b7d 100644
--- a/kimap/tests/kimaptest/CMakeLists.txt
+++ b/kimap/tests/kimaptest/CMakeLists.txt
@@ -5,6 +5,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}")
set(kimaptest_LIB_SRCS
fakeserver.cpp
mockjob.cpp
+ sslserver.cpp
)
find_package(Qt4 4.6.0 REQUIRED)
diff --git a/kimap/tests/kimaptest/fakeserver.cpp b/kimap/tests/kimaptest/fakeserver.cpp
index e101174..2caea27 100644
--- a/kimap/tests/kimaptest/fakeserver.cpp
+++ b/kimap/tests/kimaptest/fakeserver.cpp
@@ -21,6 +21,7 @@
// Own
#include "fakeserver.h"
+#include "sslserver.h"
// Qt
#include <QDebug>
@@ -28,7 +29,6 @@
#include <QTest>
#include <QTcpServer>
-// KDE
#include "kimap/imapstreamparser.h"
QByteArray FakeServer::preauth()
@@ -41,12 +41,11 @@ QByteArray FakeServer::greeting()
return "S: * OK localhost Test Library server ready";
}
-FakeServer::FakeServer( QObject* parent ) : QThread( parent )
+FakeServer::FakeServer( QObject* parent ) : QThread( parent ), m_encrypted(false), m_starttls(false)
{
- moveToThread(this);
+ moveToThread( this );
}
-
FakeServer::~FakeServer()
{
quit();
@@ -62,10 +61,10 @@ void FakeServer::startAndWait()
void FakeServer::dataAvailable()
{
- QMutexLocker locker(&m_mutex);
+ QMutexLocker locker( &m_mutex );
QTcpSocket *socket = qobject_cast<QTcpSocket*>( sender() );
- Q_ASSERT( socket!=0 );
+ Q_ASSERT( socket != 0 );
int scenarioNumber = m_clientSockets.indexOf( socket );
@@ -73,14 +72,19 @@ void FakeServer::dataAvailable()
readClientPart( scenarioNumber );
writeServerPart( scenarioNumber );
+ if (m_starttls) {
+ m_starttls = false;
+ qDebug() << "start tls";
+ static_cast<QSslSocket*>(socket)->startServerEncryption();
+ }
}
void FakeServer::newConnection()
{
- QMutexLocker locker(&m_mutex);
+ QMutexLocker locker( &m_mutex );
m_clientSockets << m_tcpServer->nextPendingConnection();
- connect(m_clientSockets.last(), SIGNAL(readyRead()), this, SLOT(dataAvailable()));
+ connect( m_clientSockets.last(), SIGNAL(readyRead()), this, SLOT(dataAvailable()) );
m_clientParsers << new KIMAP::ImapStreamParser( m_clientSockets.last(), true );
QVERIFY( m_clientSockets.size() <= m_scenarios.size() );
@@ -88,14 +92,24 @@ void FakeServer::newConnection()
writeServerPart( m_clientSockets.size() - 1 );
}
+void FakeServer::setEncrypted( QSsl::SslProtocol protocol )
+{
+ m_encrypted = true;
+ m_sslProtocol = protocol;
+}
+
void FakeServer::run()
{
- m_tcpServer = new QTcpServer();
+ if (m_encrypted) {
+ m_tcpServer = new SslServer(m_sslProtocol);
+ } else {
+ m_tcpServer = new QTcpServer();
+ }
if ( !m_tcpServer->listen( QHostAddress( QHostAddress::LocalHost ), 5989 ) ) {
- qFatal("Unable to start the server");
+ qFatal( "Unable to start the server" );
}
- connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
+ connect( m_tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection()) );
exec();
@@ -112,7 +126,7 @@ void FakeServer::started()
void FakeServer::setScenario( const QList<QByteArray> &scenario )
{
- QMutexLocker locker(&m_mutex);
+ QMutexLocker locker( &m_mutex );
m_scenarios.clear();
m_scenarios << scenario;
@@ -120,7 +134,7 @@ void FakeServer::setScenario( const QList<QByteArray> &scenario )
void FakeServer::addScenario( const QList<QByteArray> &scenario )
{
- QMutexLocker locker(&m_mutex);
+ QMutexLocker locker( &m_mutex );
m_scenarios << scenario;
}
@@ -147,7 +161,7 @@ void FakeServer::addScenarioFromFile( const QString &fileName )
bool FakeServer::isScenarioDone( int scenarioNumber ) const
{
- QMutexLocker locker(&m_mutex);
+ QMutexLocker locker( &m_mutex );
if ( scenarioNumber < m_scenarios.size() ) {
return m_scenarios[scenarioNumber].isEmpty();
@@ -174,8 +188,8 @@ void FakeServer::writeServerPart( int scenarioNumber )
QList<QByteArray> scenario = m_scenarios[scenarioNumber];
QTcpSocket *clientSocket = m_clientSockets[scenarioNumber];
- while ( !scenario.isEmpty()
- && ( scenario.first().startsWith( "S: " ) || scenario.first().startsWith( "W: " ) ) ) {
+ while ( !scenario.isEmpty() &&
+ ( scenario.first().startsWith( "S: " ) || scenario.first().startsWith( "W: " ) ) ) {
QByteArray rule = scenario.takeFirst();
if ( rule.startsWith( "S: " ) ) {
@@ -187,8 +201,8 @@ void FakeServer::writeServerPart( int scenarioNumber )
}
}
- if ( !scenario.isEmpty()
- && scenario.first().startsWith( "X" ) ) {
+ if ( !scenario.isEmpty() &&
+ scenario.first().startsWith( "X" ) ) {
scenario.takeFirst();
clientSocket->close();
}
@@ -200,17 +214,25 @@ void FakeServer::writeServerPart( int scenarioNumber )
m_scenarios[scenarioNumber] = scenario;
}
+void FakeServer::compareReceived(const QByteArray& received, const QByteArray& expected) const
+{
+ QCOMPARE( QString::fromUtf8( received ), QString::fromUtf8( expected ) );
+ QCOMPARE( received, expected );
+}
+
void FakeServer::readClientPart( int scenarioNumber )
{
QList<QByteArray> scenario = m_scenarios[scenarioNumber];
KIMAP::ImapStreamParser *clientParser = m_clientParsers[scenarioNumber];
- while ( !scenario.isEmpty()
- && scenario.first().startsWith( "C: " ) ) {
- QByteArray received = "C: "+clientParser->readUntilCommandEnd().trimmed();
- QByteArray expected = scenario.takeFirst();
- QCOMPARE( QString::fromUtf8( received ), QString::fromUtf8( expected ) );
- QCOMPARE( received, expected );
+ while ( !scenario.isEmpty() &&
+ scenario.first().startsWith( "C: " ) ) {
+ QByteArray received = "C: "+clientParser->readUntilCommandEnd().trimmed();
+ QByteArray expected = scenario.takeFirst();
+ compareReceived(received, expected);
+ if (received.contains("STARTTLS")) {
+ m_starttls = true;
+ }
}
if ( !scenario.isEmpty() ) {
diff --git a/kimap/tests/kimaptest/fakeserver.h b/kimap/tests/kimaptest/fakeserver.h
index 22b970c..add3626 100644
--- a/kimap/tests/kimaptest/fakeserver.h
+++ b/kimap/tests/kimaptest/fakeserver.h
@@ -19,7 +19,6 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
#ifndef FAKESERVER_H
#define FAKESERVER_H
@@ -28,6 +27,7 @@
#include <QTcpServer>
#include <QThread>
#include <QMutex>
+#include <QSsl>
namespace KIMAP
{
@@ -130,6 +130,11 @@ public:
~FakeServer();
/**
+ * Sets the encryption mode used by the server socket.
+ */
+ void setEncrypted( QSsl::SslProtocol protocol );
+
+ /**
* Starts the server and waits for it to be ready
*
* You should use this instead of start() to avoid race conditions.
@@ -202,6 +207,13 @@ public:
*/
bool isAllScenarioDone() const;
+protected:
+ /**
+ * Whether the received content is the same as the expected.
+ * Use QCOMPARE, if creating subclasses.
+ */
+ virtual void compareReceived(const QByteArray& received, const QByteArray& expected) const;
+
private Q_SLOTS:
void newConnection();
void dataAvailable();
@@ -216,7 +228,9 @@ private:
mutable QMutex m_mutex;
QList<QTcpSocket*> m_clientSockets;
QList<KIMAP::ImapStreamParser*> m_clientParsers;
+ bool m_encrypted;
+ bool m_starttls;
+ QSsl::SslProtocol m_sslProtocol;
};
#endif
-
diff --git a/kimap/tests/kimaptest/sslserver.cpp b/kimap/tests/kimaptest/sslserver.cpp
new file mode 100644
index 0000000..4b2fb29
--- /dev/null
+++ b/kimap/tests/kimaptest/sslserver.cpp
@@ -0,0 +1,113 @@
+/*
+ Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#include "sslserver.h"
+
+#include <QFile>
+#include <QSslKey>
+
+#include <KDebug>
+
+
+static QByteArray staticCert() {
+ //a dummy certificate
+ return QByteArray(
+"-----BEGIN CERTIFICATE-----\n\
+MIIB+zCCAWQCCQDBBi7xZ2944DANBgkqhkiG9w0BAQUFADBCMQswCQYDVQQGEwJY\n\
+WDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBh\n\
+bnkgTHRkMB4XDTEzMTIwNTA5MDcxNVoXDTQxMDQyMjA5MDcxNVowQjELMAkGA1UE\n\
+BhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBD\n\
+b21wYW55IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyuZdeqTgzX2E\n\
+Q+tOj8/QzT8jHOUvwleqv56hAOEbZ5pLhYPesaSqV0lADiYHKjCRVIrhJQXePf7y\n\
+MrJ3zE6hbHEMoIj+ku6ttNQkfJif30wmbXxLXO+RqraYgJW730kcbi2Jyq7ciEC1\n\
+SVeiIaaiV2yUFBc/ARDFBc7733Y053UCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAE\n\
+BmB+mGtQzdmOAPbRYegA2ybuUARnW467qMOQpj5dV2LN+bizCbqrsz2twFKWS7oK\n\
+EiC1bd6EGHnF6inFksUwODqeb+rjQ85pFBWskG51LWvX2/hoS+0x2V37vUYMxnDH\n\
+rOEQiDe3oerErB0x9FMWk7VivEqO5HGEdxy7fGl3vg==\n\
+-----END CERTIFICATE-----");
+}
+
+static QByteArray staticKey() {
+ //a dummy key without password
+ return QByteArray(
+"-----BEGIN RSA PRIVATE KEY-----\n\
+MIICXgIBAAKBgQDK5l16pODNfYRD606Pz9DNPyMc5S/CV6q/nqEA4RtnmkuFg96x\n\
+pKpXSUAOJgcqMJFUiuElBd49/vIysnfMTqFscQygiP6S7q201CR8mJ/fTCZtfEtc\n\
+75GqtpiAlbvfSRxuLYnKrtyIQLVJV6IhpqJXbJQUFz8BEMUFzvvfdjTndQIDAQAB\n\
+AoGBAIdNfXLGtl5x4BzGspn2NEBaZRjkwKdxfJzRtH34nyTEYK5FVODTdQBGCaAl\n\
+vctlndRp1F+y/RQMighCuN6WZM/SdkzxkGGJVzDDuMw0Cwc48aqtMA3A3x/3bQkK\n\
+kk2A5sLBc1TuC4DYSP5zkoXDbvBsHHN+tGAaC348Df6of1J1AkEA7ye3W9JUN4uK\n\
+2cPrnh7EKwQ2pFypeE/UNQ+LXR9h8XK90mxwiShU9sRFlNIA+pPcZ2aBxoY9m3rJ\n\
+4GHitl4ajwJBANkw6xM9IdgjMD8OQonpZTHSrKki/MaSSe9eBJ+WiCkTKL+Y9aTm\n\
+28sU7I+j3V38kYf5zyWXkyWmmNaQ4VaU77sCQQDMx7BM0qPEUBtb7lQxt9x3jQsQ\n\
+4DtIxupJaP8HhRjDu2Fo7evKthtSlauTC+NErRl7/J1BFa9pE9IK7SZIy/lnAkB6\n\
+ssga9k5IbJi1BrlQcCpbG0mvw7RJ+hsKv3KdNc12Zvx+QUuE/WbuM8Pw4gINNsKA\n\
+rv/3nMnkW1m83dxvrXRBAkEAmy3nO9HXdcKtSseseLJ6h9RB/R0XE1EvG8CKvveS\n\
+IiVUnppVeiLFa7ItwHOovgqvWVbePd5xl6+yBGxUXznjWA==\n\
+-----END RSA PRIVATE KEY-----");
+}
+
+SslServer::SslServer(QSsl::SslProtocol protocol)
+: QTcpServer(),
+ mProtocol(protocol)
+{
+
+}
+
+void SslServer::incomingConnection(int handle)
+{
+ QSslSocket *socket = new QSslSocket();
+ socket->setSocketDescriptor(handle);
+
+ socket->setProtocol(mProtocol);
+
+ QSslKey ssl_key(staticKey(), QSsl::Rsa);
+ QSslCertificate ssl_cert(staticCert());
+ Q_ASSERT(ssl_cert.isValid());
+
+ socket->setPrivateKey(ssl_key);
+ socket->setLocalCertificate(ssl_cert);
+ socket->setCaCertificates(QList<QSslCertificate>() << ssl_cert);
+ socket->setPeerVerifyMode(QSslSocket::VerifyNone);
+ socket->ignoreSslErrors();
+ connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
+ connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError)));
+ if (mProtocol != QSsl::TlsV1) {
+ socket->startServerEncryption();
+ }
+ addPendingConnection(socket);
+}
+
+void SslServer::sslErrors(const QList<QSslError> &errors)
+{
+ foreach (const QSslError &error, errors) {
+ kWarning() << "Received ssl error: " << error.errorString();
+ }
+ QSslSocket *socket = qobject_cast<QSslSocket *>(QObject::sender());
+ if(socket) {
+ socket->disconnectFromHost();
+ }
+}
+
+void SslServer::error(QAbstractSocket::SocketError error)
+{
+ QSslSocket *socket = qobject_cast<QSslSocket *>(QObject::sender());
+ if(socket) {
+ kWarning() << socket->errorString();
+ }
+ kWarning() << error;
+}
diff --git a/kimap/tests/kimaptest/sslserver.h b/kimap/tests/kimaptest/sslserver.h
new file mode 100644
index 0000000..3fd141a
--- /dev/null
+++ b/kimap/tests/kimaptest/sslserver.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 2013 Christian Mollekopf <mollekopf@kolabsys.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SSLSERVER_H
+#define SSLSERVER_H
+
+#include <QTcpServer>
+#include <QSslSocket>
+
+class SslServer: public QTcpServer
+{
+ Q_OBJECT
+public:
+ SslServer(QSsl::SslProtocol);
+ virtual void incomingConnection(int handle);
+
+private slots:
+ void sslErrors(const QList<QSslError> &errors);
+ void error(QAbstractSocket::SocketError);
+
+private:
+ QSsl::SslProtocol mProtocol;
+ QSslSocket mSocket;
+};
+
+#endif