23 #include "servertest.h"
26 #include <mailtransport/transportbase.h>
31 #include <QProgressBar>
37 using namespace MailTransport;
39 namespace MailTransport {
41 class ServerTestPrivate
64 bool secureSocketFinished;
65 bool normalSocketFinished;
76 void handleSMTPIMAPResponse(
int type,
const QString &text );
79 const QString &response,
bool *shouldStartTLS );
83 void slotNormalPossible();
84 void slotNormalNotPossible();
85 void slotSslPossible();
86 void slotSslNotPossible();
88 void slotReadNormal(
const QString &text );
89 void slotReadSecure(
const QString &text );
90 void slotUpdateProgress();
95 ServerTestPrivate::ServerTestPrivate(
ServerTest *test )
96 : q( test ), testProgress( 0 ), secureSocketFinished( false ),
97 normalSocketFinished( false ), tlsFinished( false ),
98 normalPossible( true ), securePossible( true )
102 void ServerTestPrivate::finalResult()
104 if ( !secureSocketFinished || !normalSocketFinished || !tlsFinished ) {
108 kDebug() <<
"Modes:" << connectionResults;
109 kDebug() <<
"Capabilities:" << capabilityResults;
110 kDebug() <<
"Normal:" << q->normalProtocols();
111 kDebug() <<
"SSL:" << q->secureProtocols();
112 kDebug() <<
"TLS:" << q->tlsProtocols();
114 if ( testProgress ) {
115 testProgress->hide();
117 progressTimer->stop();
118 secureSocketFinished =
false;
119 normalSocketFinished =
false;
120 tlsFinished = false ;
122 emit q->finished( connectionResults.toList() );
129 it != authentications.
end(); ++it ) {
132 result << Transport::EnumAuthenticationType::LOGIN;
134 result << Transport::EnumAuthenticationType::PLAIN;
136 result << Transport::EnumAuthenticationType::CRAM_MD5;
138 result << Transport::EnumAuthenticationType::DIGEST_MD5;
140 result << Transport::EnumAuthenticationType::NTLM;
142 result << Transport::EnumAuthenticationType::GSSAPI;
144 result << Transport::EnumAuthenticationType::ANONYMOUS;
148 kDebug() << authentications << result;
153 if ( result.contains( Transport::EnumAuthenticationType::PLAIN ) ) {
154 result.
removeAll( Transport::EnumAuthenticationType::LOGIN );
160 void ServerTestPrivate::handleSMTPIMAPResponse(
int type,
const QString &text )
163 kDebug() <<
"No authentication possible";
174 for (
int i = 0; i < protocols.
count(); ++i ) {
175 if ( text.
contains( protocols.
at( i ), Qt::CaseInsensitive ) ) {
176 results.
append( protocols.
at( i ) );
180 authenticationResults[type] = parseAuthenticationList( results );
183 if ( authenticationResults[type].size() == 0 ) {
184 authenticationResults[type] << Transport::EnumAuthenticationType::CLEAR;
187 kDebug() <<
"For type" << type <<
", we have:" << authenticationResults[type];
190 void ServerTestPrivate::slotNormalPossible()
192 normalSocketTimer->stop();
193 connectionResults << Transport::EnumEncryption::None;
198 if ( testProtocol == IMAP_PROTOCOL ) {
201 }
else if ( testProtocol == SMTP_PROTOCOL ) {
208 if ( !fakeHostname.isNull() ) {
209 hostname = fakeHostname;
218 kDebug() <<
"Hostname for EHLO is" << hostname;
224 void ServerTestPrivate::slotTlsDone()
233 const QString &response,
bool *shouldStartTLS )
235 Q_ASSERT( shouldStartTLS != 0 );
241 QString responseWithoutCRLF = response;
242 responseWithoutCRLF.
chop( 2 );
244 Qt::CaseInsensitive );
245 if ( responseWithoutCRLF.
indexOf( re ) != -1 ) {
246 authenticationResults[type] << Transport::EnumAuthenticationType::APOP;
250 authenticationResults[type] << Transport::EnumAuthenticationType::CLEAR;
254 if ( type == Transport::EnumEncryption::TLS &&
255 authenticationResults[Transport::EnumEncryption::None].
256 contains( Transport::EnumAuthenticationType::APOP ) ) {
257 authenticationResults[Transport::EnumEncryption::TLS]
258 << Transport::EnumAuthenticationType::APOP;
266 else if ( stage == 1 ) {
286 connectionResults << Transport::EnumEncryption::TLS;
287 popSupportsTLS =
true;
294 else if ( stage == 2 ) {
301 QString formattedReply = response;
304 formattedReply.
chop( 3 );
307 formattedReply = formattedReply.
right( formattedReply.
size() -
313 authenticationResults[type] +=
317 *shouldStartTLS = popSupportsTLS;
325 void ServerTestPrivate::slotReadNormal(
const QString &text )
327 Q_ASSERT( encryptionMode != Transport::EnumEncryption::SSL );
328 static const int tlsHandshakeStage = 42;
330 kDebug() <<
"Stage" << normalStage + 1 <<
", Mode" << encryptionMode;
336 if ( normalStage == tlsHandshakeStage ) {
337 Q_ASSERT( encryptionMode == Transport::EnumEncryption::TLS );
339 normalSocket->startTLS();
343 bool shouldStartTLS =
false;
348 if ( testProtocol == POP_PROTOCOL ) {
349 if ( handlePopConversation( normalSocket, encryptionMode, normalStage, text,
350 &shouldStartTLS ) ) {
356 if ( normalStage == 0 ) {
357 sendInitialCapabilityQuery( normalSocket );
362 connectionResults << Transport::EnumEncryption::TLS;
363 shouldStartTLS =
true;
365 handleSMTPIMAPResponse( encryptionMode, text );
370 normalSocketFinished =
true;
374 if ( shouldStartTLS && encryptionMode == Transport::EnumEncryption::None ) {
375 kDebug() <<
"Trying TLS...";
376 connectionResults << Transport::EnumEncryption::TLS;
377 if ( testProtocol == POP_PROTOCOL ) {
379 }
else if ( testProtocol == IMAP_PROTOCOL ) {
384 encryptionMode = Transport::EnumEncryption::TLS;
385 normalStage = tlsHandshakeStage;
395 void ServerTestPrivate::slotReadSecure(
const QString &text )
398 if ( testProtocol == POP_PROTOCOL ) {
400 if ( handlePopConversation( secureSocket, Transport::EnumEncryption::SSL,
401 secureStage, text, &dummy ) ) {
405 if ( secureStage == 0 ) {
406 sendInitialCapabilityQuery( secureSocket );
409 handleSMTPIMAPResponse( Transport::EnumEncryption::SSL, text );
411 secureSocketFinished =
true;
415 void ServerTestPrivate::slotNormalNotPossible()
417 normalSocketTimer->stop();
418 normalPossible =
false;
419 normalSocketFinished =
true;
424 void ServerTestPrivate::slotSslPossible()
426 secureSocketTimer->stop();
427 connectionResults << Transport::EnumEncryption::SSL;
430 void ServerTestPrivate::slotSslNotPossible()
432 secureSocketTimer->stop();
433 securePossible =
false;
434 secureSocketFinished =
true;
438 void ServerTestPrivate::slotUpdateProgress()
440 if ( testProgress ) {
441 testProgress->setValue( testProgress->value() + 1 );
448 :
QWidget( parent ), d( new ServerTestPrivate( this ) )
450 d->normalSocketTimer =
new QTimer(
this );
451 d->normalSocketTimer->setSingleShot(
true );
452 connect( d->normalSocketTimer, SIGNAL(timeout()), SLOT(slotNormalNotPossible()) );
454 d->secureSocketTimer =
new QTimer(
this );
455 d->secureSocketTimer->setSingleShot(
true );
456 connect( d->secureSocketTimer, SIGNAL(timeout()), SLOT(slotSslNotPossible()) );
458 d->progressTimer =
new QTimer(
this );
459 connect( d->progressTimer, SIGNAL(timeout()), SLOT(slotUpdateProgress()) );
471 d->connectionResults.clear();
472 d->authenticationResults.clear();
473 d->capabilityResults.clear();
474 d->popSupportsTLS =
false;
477 d->encryptionMode = Transport::EnumEncryption::None;
478 d->normalPossible =
true;
479 d->securePossible =
true;
481 if ( d->testProgress ) {
482 d->testProgress->setMaximum( 20 );
483 d->testProgress->setValue( 0 );
484 d->testProgress->setTextVisible(
true );
485 d->testProgress->show();
486 d->progressTimer->start( 1000 );
492 d->normalSocket->setServer( d->server );
493 d->normalSocket->setProtocol( d->testProtocol );
494 if ( d->testProtocol == IMAP_PROTOCOL ) {
495 d->normalSocket->setPort( IMAP_PORT );
496 d->secureSocket->setPort( IMAPS_PORT );
497 }
else if ( d->testProtocol == SMTP_PROTOCOL ) {
498 d->normalSocket->setPort( SMTP_PORT );
499 d->secureSocket->setPort( SMTPS_PORT );
500 }
else if ( d->testProtocol == POP_PROTOCOL ) {
501 d->normalSocket->setPort( POP_PORT );
502 d->secureSocket->setPort( POPS_PORT );
505 if ( d->customPorts.contains( Transport::EnumEncryption::None ) ) {
506 d->normalSocket->setPort( d->customPorts.value( Transport::EnumEncryption::None ) );
508 if ( d->customPorts.contains( Transport::EnumEncryption::SSL ) ) {
509 d->secureSocket->setPort( d->customPorts.value( Transport::EnumEncryption::SSL ) );
512 connect( d->normalSocket, SIGNAL(connected()), SLOT(slotNormalPossible()) );
513 connect( d->normalSocket, SIGNAL(failed()), SLOT(slotNormalNotPossible()) );
515 SLOT(slotReadNormal(
QString)) );
516 connect( d->normalSocket, SIGNAL(tlsDone()), SLOT(slotTlsDone()));
517 d->normalSocket->reconnect();
518 d->normalSocketTimer->start( 10000 );
521 d->secureSocket->setServer( d->server );
522 d->secureSocket->setProtocol( d->testProtocol +
QLatin1Char(
's' ) );
523 d->secureSocket->setSecure(
true );
524 connect( d->secureSocket, SIGNAL(connected()), SLOT(slotSslPossible()) );
525 connect( d->secureSocket, SIGNAL(failed()), SLOT(slotSslNotPossible()) );
527 SLOT(slotReadSecure(
QString)) );
528 d->secureSocket->reconnect();
529 d->secureSocketTimer->start( 10000 );
539 return d->fakeHostname;
549 Q_ASSERT( encryptionMode == Transport::EnumEncryption::None ||
550 encryptionMode == Transport::EnumEncryption::SSL );
551 d->customPorts.insert( encryptionMode, port );
556 d->testProgress = pb;
566 return d->testProtocol;
576 Q_ASSERT( encryptionMode == Transport::EnumEncryption::None ||
577 encryptionMode == Transport::EnumEncryption::SSL );
578 if ( d->customPorts.contains( encryptionMode ) ) {
579 return d->customPorts.value( static_cast<int>( encryptionMode ) );
587 return d->testProgress;
592 return d->authenticationResults[TransportBase::EnumEncryption::None];
597 return d->normalPossible;
602 return d->authenticationResults[TransportBase::EnumEncryption::TLS];
607 return d->authenticationResults[Transport::EnumEncryption::SSL];
612 return d->securePossible;
617 return d->capabilityResults.toList();
620 #include "moc_servertest.cpp"
void setFakeHostname(const QString &fakeHostname)
Sets a fake hostname for the test.
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
void setServer(const QString &server)
Sets the server to test.
POP3 only. The server supports fetching only the headers.
virtual void write(const QString &text)
Write text to the socket.
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
const T & at(int i) const
This class can be used to test certain server to see if they support stuff.
bool isNormalPossible()
tells you if the normal server is available
int count(const T &value) const
void append(const T &value)
int removeAll(const T &value)
void setProtocol(const QString &protocol)
Sets protocol the protocol to test, currently supported are "smtp", "pop" and "imap".
ServerTest(QWidget *parent=0)
Creates a new server test.
bool isSecurePossible()
tells you if the ssl server is available
void setPort(Transport::EnumEncryption::type encryptionMode, uint port)
Set a custom port to use.
int port(Transport::EnumEncryption::type encryptionMode)
QString right(int n) const
QList< Capability > capabilities() const
Get the special capabilities of the server.
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QString & replace(int position, int n, QChar after)
~ServerTest()
Destroys the server test.
Responsible for communicating with the server, it's designed to work with the ServerTest class...
Internal file containing constant definitions etc.
QString server()
Returns the server to test.
POP3 only. The server supports pipeplining of commands.
QProgressBar * progressBar()
Returns the used progress bar.
QString protocol()
Returns the protocol.
QList< int > normalProtocols()
Get the protocols for the normal connections.
void start()
Starts the test.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QList< int > tlsProtocols()
Get the protocols for the TLS connections.
void setProgressBar(QProgressBar *pb)
Makes pb the progressbar to use.
POP3 only. The server has support for unique identifiers.
QList< int > secureProtocols()
Get the protocols for the SSL connections.