File indexing completed on 2024-06-23 05:15:11
0001 /* 0002 SPDX-FileCopyrightText: 2006-2007 Volker Krause <vkrause@kde.org> 0003 SPDX-FileCopyrightText: 2007 KovoKs <info@kovoks.nl> 0004 SPDX-FileCopyrightText: 2008 Thomas McGuire <thomas.mcguire@gmx.net> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 // Own 0010 #include "servertest.h" 0011 #include "socket.h" 0012 0013 #include "mailtransport_defs.h" 0014 #include <transportbase.h> 0015 0016 // Qt 0017 #include <QHash> 0018 #include <QHostInfo> 0019 #include <QProgressBar> 0020 #include <QRegularExpression> 0021 #include <QSet> 0022 #include <QTimer> 0023 0024 // KDE 0025 #include "mailtransport_debug.h" 0026 0027 using namespace MailTransport; 0028 0029 namespace MailTransport 0030 { 0031 class ServerTestPrivate 0032 { 0033 public: 0034 ServerTestPrivate(ServerTest *test); 0035 0036 ServerTest *const q; 0037 QString server; 0038 QString fakeHostname; 0039 QString testProtocol; 0040 0041 MailTransport::Socket *normalSocket = nullptr; 0042 MailTransport::Socket *secureSocket = nullptr; 0043 0044 QSet<int> connectionResults; 0045 QHash<int, QList<int>> authenticationResults; 0046 QSet<ServerTest::Capability> capabilityResults; 0047 QHash<int, uint> customPorts; 0048 QTimer *normalSocketTimer = nullptr; 0049 QTimer *secureSocketTimer = nullptr; 0050 QTimer *progressTimer = nullptr; 0051 0052 QProgressBar *testProgress = nullptr; 0053 0054 bool secureSocketFinished = false; 0055 bool normalSocketFinished = false; 0056 bool tlsFinished = false; 0057 bool popSupportsTLS; 0058 int normalStage; 0059 int secureStage; 0060 int encryptionMode; 0061 0062 bool normalPossible = true; 0063 bool securePossible = true; 0064 0065 void finalResult(); 0066 void handleSMTPIMAPResponse(int type, const QString &text); 0067 void sendInitialCapabilityQuery(MailTransport::Socket *socket); 0068 bool handlePopConversation(MailTransport::Socket *socket, int type, int stage, const QString &response, bool *shouldStartTLS); 0069 bool handleNntpConversation(MailTransport::Socket *socket, int type, int *stage, const QString &response, bool *shouldStartTLS); 0070 QList<int> parseAuthenticationList(const QStringList &authentications); 0071 0072 [[nodiscard]] inline bool isGmail(const QString &server) const 0073 { 0074 return server.endsWith(QLatin1StringView("gmail.com")) || server.endsWith(QLatin1StringView("googlemail.com")); 0075 } 0076 0077 // slots 0078 void slotNormalPossible(); 0079 void slotNormalNotPossible(); 0080 void slotSslPossible(); 0081 void slotSslNotPossible(); 0082 void slotTlsDone(); 0083 void slotReadNormal(const QString &text); 0084 void slotReadSecure(const QString &text); 0085 void slotUpdateProgress(); 0086 }; 0087 } 0088 0089 ServerTestPrivate::ServerTestPrivate(ServerTest *test) 0090 : q(test) 0091 { 0092 } 0093 0094 void ServerTestPrivate::finalResult() 0095 { 0096 if (!secureSocketFinished || !normalSocketFinished || !tlsFinished) { 0097 return; 0098 } 0099 0100 qCDebug(MAILTRANSPORT_LOG) << "Modes:" << connectionResults; 0101 qCDebug(MAILTRANSPORT_LOG) << "Capabilities:" << capabilityResults; 0102 qCDebug(MAILTRANSPORT_LOG) << "Normal:" << q->normalProtocols(); 0103 qCDebug(MAILTRANSPORT_LOG) << "SSL:" << q->secureProtocols(); 0104 qCDebug(MAILTRANSPORT_LOG) << "TLS:" << q->tlsProtocols(); 0105 0106 if (testProgress) { 0107 testProgress->hide(); 0108 } 0109 progressTimer->stop(); 0110 secureSocketFinished = false; 0111 normalSocketFinished = false; 0112 tlsFinished = false; 0113 0114 QList<int> resultsAsVector; 0115 resultsAsVector.reserve(connectionResults.size()); 0116 for (int res : std::as_const(connectionResults)) { 0117 resultsAsVector.append(res); 0118 } 0119 0120 Q_EMIT q->finished(resultsAsVector); 0121 } 0122 0123 QList<int> ServerTestPrivate::parseAuthenticationList(const QStringList &authentications) 0124 { 0125 QList<int> result; 0126 for (QStringList::ConstIterator it = authentications.begin(); it != authentications.end(); ++it) { 0127 QString current = (*it).toUpper(); 0128 if (current == QLatin1StringView("LOGIN")) { 0129 result << Transport::EnumAuthenticationType::LOGIN; 0130 } else if (current == QLatin1StringView("PLAIN")) { 0131 result << Transport::EnumAuthenticationType::PLAIN; 0132 } else if (current == QLatin1StringView("CRAM-MD5")) { 0133 result << Transport::EnumAuthenticationType::CRAM_MD5; 0134 } else if (current == QLatin1StringView("DIGEST-MD5")) { 0135 result << Transport::EnumAuthenticationType::DIGEST_MD5; 0136 } else if (current == QLatin1StringView("NTLM")) { 0137 result << Transport::EnumAuthenticationType::NTLM; 0138 } else if (current == QLatin1StringView("GSSAPI")) { 0139 result << Transport::EnumAuthenticationType::GSSAPI; 0140 } else if (current == QLatin1StringView("ANONYMOUS")) { 0141 result << Transport::EnumAuthenticationType::ANONYMOUS; 0142 } else if (current == QLatin1StringView("XOAUTH2")) { 0143 if (isGmail(server)) { 0144 result << Transport::EnumAuthenticationType::XOAUTH2; 0145 } 0146 } 0147 // APOP is handled by handlePopConversation() 0148 } 0149 qCDebug(MAILTRANSPORT_LOG) << authentications << result; 0150 0151 // LOGIN doesn't offer anything over PLAIN, requires more server 0152 // roundtrips and is not an official SASL mechanism, but a MS-ism, 0153 // so only enable it if PLAIN isn't available: 0154 if (result.contains(Transport::EnumAuthenticationType::PLAIN)) { 0155 result.removeAll(Transport::EnumAuthenticationType::LOGIN); 0156 } 0157 0158 return result; 0159 } 0160 0161 void ServerTestPrivate::handleSMTPIMAPResponse(int type, const QString &text) 0162 { 0163 if (!text.contains(QLatin1StringView("AUTH"), Qt::CaseInsensitive)) { 0164 qCDebug(MAILTRANSPORT_LOG) << "No authentication possible"; 0165 return; 0166 } 0167 0168 QStringList protocols; 0169 if (isGmail(server)) { 0170 protocols << QStringLiteral("XOAUTH2"); 0171 } 0172 0173 protocols << QStringLiteral("LOGIN") << QStringLiteral("PLAIN") << QStringLiteral("CRAM-MD5") << QStringLiteral("DIGEST-MD5") << QStringLiteral("NTLM") 0174 << QStringLiteral("GSSAPI") << QStringLiteral("ANONYMOUS"); 0175 0176 QStringList results; 0177 for (int i = 0; i < protocols.count(); ++i) { 0178 if (text.contains(protocols.at(i), Qt::CaseInsensitive)) { 0179 results.append(protocols.at(i)); 0180 } 0181 } 0182 0183 authenticationResults[type] = parseAuthenticationList(results); 0184 0185 // if we couldn't parse any authentication modes, default to clear-text 0186 if (authenticationResults[type].isEmpty()) { 0187 authenticationResults[type] << Transport::EnumAuthenticationType::CLEAR; 0188 } 0189 0190 qCDebug(MAILTRANSPORT_LOG) << "For type" << type << ", we have:" << authenticationResults[type]; 0191 } 0192 0193 void ServerTestPrivate::slotNormalPossible() 0194 { 0195 normalSocketTimer->stop(); 0196 connectionResults << Transport::EnumEncryption::None; 0197 } 0198 0199 void ServerTestPrivate::sendInitialCapabilityQuery(MailTransport::Socket *socket) 0200 { 0201 if (testProtocol == IMAP_PROTOCOL) { 0202 socket->write(QStringLiteral("1 CAPABILITY")); 0203 } else if (testProtocol == SMTP_PROTOCOL) { 0204 // Detect the hostname which we send with the EHLO command. 0205 // If there is a fake one set, use that, otherwise use the 0206 // local host name (and make sure it contains a domain, so the 0207 // server thinks it is valid). 0208 QString hostname; 0209 if (!fakeHostname.isNull()) { 0210 hostname = fakeHostname; 0211 } else { 0212 hostname = QHostInfo::localHostName(); 0213 if (hostname.isEmpty()) { 0214 hostname = QStringLiteral("localhost.invalid"); 0215 } else if (!hostname.contains(QChar::fromLatin1('.'))) { 0216 hostname += QLatin1StringView(".localnet"); 0217 } 0218 } 0219 qCDebug(MAILTRANSPORT_LOG) << "Hostname for EHLO is" << hostname; 0220 0221 socket->write(QLatin1StringView("EHLO ") + hostname); 0222 } 0223 } 0224 0225 void ServerTestPrivate::slotTlsDone() 0226 { 0227 // The server will not send a response after starting TLS. Therefore, we have to manually 0228 // call slotReadNormal(), because this is not triggered by a data received signal this time. 0229 slotReadNormal(QString()); 0230 } 0231 0232 bool ServerTestPrivate::handlePopConversation(MailTransport::Socket *socket, int type, int stage, const QString &response, bool *shouldStartTLS) 0233 { 0234 Q_ASSERT(shouldStartTLS != nullptr); 0235 0236 // Initial Greeting 0237 if (stage == 0) { 0238 // Regexp taken from POP3 ioslave 0239 const QString responseWithoutCRLF = response.isEmpty() ? response : response.chopped(2); 0240 static const QRegularExpression re(QStringLiteral("<[A-Za-z0-9\\.\\-_]+@[A-Za-z0-9\\.\\-_]+>$"), QRegularExpression::CaseInsensitiveOption); 0241 if (responseWithoutCRLF.indexOf(re) != -1) { 0242 authenticationResults[type] << Transport::EnumAuthenticationType::APOP; 0243 } 0244 0245 // Each server is supposed to support clear text login 0246 authenticationResults[type] << Transport::EnumAuthenticationType::CLEAR; 0247 0248 // If we are in TLS stage, the server does not send the initial greeting. 0249 // Assume that the APOP availability is the same as with an unsecured connection. 0250 if (type == Transport::EnumEncryption::TLS 0251 && authenticationResults[Transport::EnumEncryption::None].contains(Transport::EnumAuthenticationType::APOP)) { 0252 authenticationResults[Transport::EnumEncryption::TLS] << Transport::EnumAuthenticationType::APOP; 0253 } 0254 0255 socket->write(QStringLiteral("CAPA")); 0256 return true; 0257 } 0258 // CAPA result 0259 else if (stage == 1) { 0260 // Example: 0261 // CAPA 0262 // +OK 0263 // TOP 0264 // USER 0265 // SASL LOGIN CRAM-MD5 0266 // UIDL 0267 // RESP-CODES 0268 // . 0269 if (response.contains(QLatin1StringView("TOP"))) { 0270 capabilityResults += ServerTest::Top; 0271 } 0272 if (response.contains(QLatin1StringView("PIPELINING"))) { 0273 capabilityResults += ServerTest::Pipelining; 0274 } 0275 if (response.contains(QLatin1StringView("UIDL"))) { 0276 capabilityResults += ServerTest::UIDL; 0277 } 0278 if (response.contains(QLatin1StringView("STLS"))) { 0279 connectionResults << Transport::EnumEncryption::TLS; 0280 popSupportsTLS = true; 0281 } 0282 socket->write(QStringLiteral("AUTH")); 0283 return true; 0284 } 0285 // AUTH response 0286 else if (stage == 2) { 0287 // Example: 0288 // C: AUTH 0289 // S: +OK List of supported authentication methods follows 0290 // S: LOGIN 0291 // S: CRAM-MD5 0292 // S:. 0293 QString formattedReply = response; 0294 0295 // Get rid of trailing ".CRLF" 0296 formattedReply.chop(3); 0297 0298 // Get rid of the first +OK line 0299 formattedReply = formattedReply.right(formattedReply.size() - formattedReply.indexOf(QLatin1Char('\n')) - 1); 0300 formattedReply = formattedReply.replace(QLatin1Char(' '), QLatin1Char('-')).replace(QLatin1StringView("\r\n"), QLatin1StringView(" ")); 0301 0302 authenticationResults[type] += parseAuthenticationList(formattedReply.split(QLatin1Char(' '))); 0303 } 0304 0305 *shouldStartTLS = popSupportsTLS; 0306 return false; 0307 } 0308 0309 bool ServerTestPrivate::handleNntpConversation(MailTransport::Socket *socket, int type, int *stage, const QString &response, bool *shouldStartTLS) 0310 { 0311 Q_ASSERT(shouldStartTLS != nullptr); 0312 Q_ASSERT(stage != nullptr); 0313 0314 // Initial Greeting 0315 if (*stage == 0) { 0316 if (response.startsWith(QLatin1StringView("382 "))) { 0317 return true; 0318 } 0319 if (!response.isEmpty() && !response.startsWith(QLatin1StringView("200 "))) { 0320 return false; 0321 } 0322 0323 socket->write(QStringLiteral("CAPABILITIES")); 0324 return true; 0325 } 0326 // CAPABILITIES result 0327 else if (*stage == 1) { 0328 // Check whether we got "500 command 'CAPABILITIES' not recognized" 0329 if (response.startsWith(QLatin1StringView("500 "))) { 0330 return false; 0331 } 0332 0333 // Example: 0334 // 101 Capability list: 0335 // VERSION 2 0336 // IMPLEMENTATION INN 2.5.4 0337 // AUTHINFO USER SASL 0338 // HDR 0339 // LIST ACTIVE [etc] 0340 // OVER 0341 // POST 0342 // READER 0343 // SASL DIGEST-MD5 CRAM-MD5 NTLM PLAIN LOGIN 0344 // STARTTLS 0345 // . 0346 const QList<QStringView> lines = QStringView(response).split(QStringLiteral("\r\n"), Qt::SkipEmptyParts); 0347 for (const QStringView line : lines) { 0348 if (line.compare(QLatin1StringView("STARTTLS"), Qt::CaseInsensitive) == 0) { 0349 *shouldStartTLS = true; 0350 } else if (line.startsWith(QLatin1StringView("AUTHINFO "), Qt::CaseInsensitive)) { 0351 const QList<QStringView> authinfos = QStringView(line).split(QLatin1Char(' '), Qt::SkipEmptyParts); 0352 const QString s(QStringLiteral("USER")); 0353 const QStringView ref(s); 0354 if (authinfos.contains(ref)) { 0355 authenticationResults[type].append(Transport::EnumAuthenticationType::CLEAR); // XXX 0356 } 0357 } else if (line.startsWith(QLatin1StringView("SASL "), Qt::CaseInsensitive)) { 0358 const QStringList auths = line.mid(5).toString().split(QLatin1Char(' '), Qt::SkipEmptyParts); 0359 authenticationResults[type] += parseAuthenticationList(auths); 0360 } else if (line == QLatin1Char('.')) { 0361 return false; 0362 } 0363 } 0364 // We have not hit the end of the capabilities list yet, 0365 // so avoid the stage counter to rise without reason. 0366 --(*stage); 0367 return true; 0368 } 0369 0370 return false; 0371 } 0372 0373 // slotReadNormal() handles normal (no) encryption and TLS encryption. 0374 // At first, the communication is not encrypted, but if the server supports 0375 // the STARTTLS/STLS keyword, the same authentication query is done again 0376 // with TLS. 0377 void ServerTestPrivate::slotReadNormal(const QString &text) 0378 { 0379 Q_ASSERT(encryptionMode != Transport::EnumEncryption::SSL); 0380 static const int tlsHandshakeStage = 42; 0381 0382 qCDebug(MAILTRANSPORT_LOG) << "Stage" << normalStage + 1 << ", Mode" << encryptionMode; 0383 0384 // If we are in stage 42, we just do the handshake for TLS encryption and 0385 // then reset the stage to -1, so that all authentication modes and 0386 // capabilities are queried again for TLS encryption (some servers have 0387 // different authentication methods in normal and in TLS mode). 0388 if (normalStage == tlsHandshakeStage) { 0389 Q_ASSERT(encryptionMode == Transport::EnumEncryption::TLS); 0390 normalStage = -1; 0391 normalSocket->startTLS(); 0392 return; 0393 } 0394 0395 bool shouldStartTLS = false; 0396 normalStage++; 0397 0398 // Handle the whole POP and NNTP conversations separately, as 0399 // they are very different from IMAP and SMTP 0400 if (testProtocol == POP_PROTOCOL) { 0401 if (handlePopConversation(normalSocket, encryptionMode, normalStage, text, &shouldStartTLS)) { 0402 return; 0403 } 0404 } else if (testProtocol == NNTP_PROTOCOL) { 0405 if (handleNntpConversation(normalSocket, encryptionMode, &normalStage, text, &shouldStartTLS)) { 0406 return; 0407 } 0408 } else { 0409 // Handle the SMTP/IMAP conversation here. We just send the EHLO command in 0410 // sendInitialCapabilityQuery. 0411 if (normalStage == 0) { 0412 sendInitialCapabilityQuery(normalSocket); 0413 return; 0414 } 0415 0416 if (text.contains(QLatin1StringView("STARTTLS"), Qt::CaseInsensitive)) { 0417 connectionResults << Transport::EnumEncryption::TLS; 0418 shouldStartTLS = true; 0419 } 0420 handleSMTPIMAPResponse(encryptionMode, text); 0421 } 0422 0423 // If we reach here, the normal authentication/capabilities query is completed. 0424 // Now do the same for TLS. 0425 normalSocketFinished = true; 0426 0427 // If the server announced that STARTTLS/STLS is available, we'll add TLS to the 0428 // connection result, do the command and set the stage to 42 to start the handshake. 0429 if (shouldStartTLS && encryptionMode == Transport::EnumEncryption::None) { 0430 qCDebug(MAILTRANSPORT_LOG) << "Trying TLS..."; 0431 connectionResults << Transport::EnumEncryption::TLS; 0432 if (testProtocol == POP_PROTOCOL) { 0433 normalSocket->write(QStringLiteral("STLS")); 0434 } else if (testProtocol == IMAP_PROTOCOL) { 0435 normalSocket->write(QStringLiteral("2 STARTTLS")); 0436 } else { 0437 normalSocket->write(QStringLiteral("STARTTLS")); 0438 } 0439 encryptionMode = Transport::EnumEncryption::TLS; 0440 normalStage = tlsHandshakeStage; 0441 return; 0442 } 0443 0444 // If we reach here, either the TLS authentication/capabilities query is finished 0445 // or the server does not support the STARTTLS/STLS command. 0446 tlsFinished = true; 0447 finalResult(); 0448 } 0449 0450 void ServerTestPrivate::slotReadSecure(const QString &text) 0451 { 0452 secureStage++; 0453 if (testProtocol == POP_PROTOCOL) { 0454 bool dummy; 0455 if (handlePopConversation(secureSocket, Transport::EnumEncryption::SSL, secureStage, text, &dummy)) { 0456 return; 0457 } 0458 } else if (testProtocol == NNTP_PROTOCOL) { 0459 bool dummy; 0460 if (handleNntpConversation(secureSocket, Transport::EnumEncryption::SSL, &secureStage, text, &dummy)) { 0461 return; 0462 } 0463 } else { 0464 if (secureStage == 0) { 0465 sendInitialCapabilityQuery(secureSocket); 0466 return; 0467 } 0468 handleSMTPIMAPResponse(Transport::EnumEncryption::SSL, text); 0469 } 0470 secureSocketFinished = true; 0471 finalResult(); 0472 } 0473 0474 void ServerTestPrivate::slotNormalNotPossible() 0475 { 0476 if (testProtocol == SMTP_PROTOCOL && normalSocket->port() == SMTP_PORT) { 0477 // For SMTP, fallback to port 25 0478 normalSocket->setPort(SMTP_OLD_PORT); 0479 normalSocket->reconnect(); 0480 normalSocketTimer->start(10000); 0481 return; 0482 } 0483 0484 normalSocketTimer->stop(); 0485 normalPossible = false; 0486 normalSocketFinished = true; 0487 tlsFinished = true; 0488 finalResult(); 0489 } 0490 0491 void ServerTestPrivate::slotSslPossible() 0492 { 0493 secureSocketTimer->stop(); 0494 connectionResults << Transport::EnumEncryption::SSL; 0495 } 0496 0497 void ServerTestPrivate::slotSslNotPossible() 0498 { 0499 secureSocketTimer->stop(); 0500 securePossible = false; 0501 secureSocketFinished = true; 0502 finalResult(); 0503 } 0504 0505 void ServerTestPrivate::slotUpdateProgress() 0506 { 0507 if (testProgress) { 0508 testProgress->setValue(testProgress->value() + 1); 0509 } 0510 } 0511 0512 //---------------------- end private class -----------------------// 0513 0514 ServerTest::ServerTest(QObject *parent) 0515 : QObject(parent) 0516 , d(new ServerTestPrivate(this)) 0517 { 0518 d->normalSocketTimer = new QTimer(this); 0519 d->normalSocketTimer->setSingleShot(true); 0520 connect(d->normalSocketTimer, SIGNAL(timeout()), SLOT(slotNormalNotPossible())); 0521 0522 d->secureSocketTimer = new QTimer(this); 0523 d->secureSocketTimer->setSingleShot(true); 0524 connect(d->secureSocketTimer, SIGNAL(timeout()), SLOT(slotSslNotPossible())); 0525 0526 d->progressTimer = new QTimer(this); 0527 connect(d->progressTimer, SIGNAL(timeout()), SLOT(slotUpdateProgress())); 0528 } 0529 0530 ServerTest::~ServerTest() = default; 0531 0532 void ServerTest::start() 0533 { 0534 qCDebug(MAILTRANSPORT_LOG) << d.get(); 0535 0536 d->connectionResults.clear(); 0537 d->authenticationResults.clear(); 0538 d->capabilityResults.clear(); 0539 d->popSupportsTLS = false; 0540 d->normalStage = -1; 0541 d->secureStage = -1; 0542 d->encryptionMode = Transport::EnumEncryption::None; 0543 d->normalPossible = true; 0544 d->securePossible = true; 0545 0546 if (d->testProgress) { 0547 d->testProgress->setMaximum(20); 0548 d->testProgress->setValue(0); 0549 d->testProgress->setTextVisible(true); 0550 d->testProgress->show(); 0551 d->progressTimer->start(1000); 0552 } 0553 0554 d->normalSocket = new MailTransport::Socket(this); 0555 d->secureSocket = new MailTransport::Socket(this); 0556 d->normalSocket->setObjectName(QLatin1StringView("normal")); 0557 d->normalSocket->setServer(d->server); 0558 d->normalSocket->setProtocol(d->testProtocol); 0559 if (d->testProtocol == IMAP_PROTOCOL) { 0560 d->normalSocket->setPort(IMAP_PORT); 0561 d->secureSocket->setPort(IMAPS_PORT); 0562 } else if (d->testProtocol == SMTP_PROTOCOL) { 0563 d->normalSocket->setPort(SMTP_PORT); 0564 d->secureSocket->setPort(SMTPS_PORT); 0565 } else if (d->testProtocol == POP_PROTOCOL) { 0566 d->normalSocket->setPort(POP_PORT); 0567 d->secureSocket->setPort(POPS_PORT); 0568 } else if (d->testProtocol == NNTP_PROTOCOL) { 0569 d->normalSocket->setPort(NNTP_PORT); 0570 d->secureSocket->setPort(NNTPS_PORT); 0571 } 0572 0573 if (d->customPorts.contains(Transport::EnumEncryption::None)) { 0574 d->normalSocket->setPort(d->customPorts.value(Transport::EnumEncryption::None)); 0575 } 0576 if (d->customPorts.contains(Transport::EnumEncryption::SSL)) { 0577 d->secureSocket->setPort(d->customPorts.value(Transport::EnumEncryption::SSL)); 0578 } 0579 0580 connect(d->normalSocket, SIGNAL(connected()), SLOT(slotNormalPossible())); 0581 connect(d->normalSocket, SIGNAL(failed()), SLOT(slotNormalNotPossible())); 0582 connect(d->normalSocket, SIGNAL(data(QString)), SLOT(slotReadNormal(QString))); 0583 connect(d->normalSocket, SIGNAL(tlsDone()), SLOT(slotTlsDone())); 0584 d->normalSocket->reconnect(); 0585 d->normalSocketTimer->start(10000); 0586 0587 if (d->secureSocket->port() > 0) { 0588 d->secureSocket->setObjectName(QLatin1StringView("secure")); 0589 d->secureSocket->setServer(d->server); 0590 d->secureSocket->setProtocol(d->testProtocol + QLatin1Char('s')); 0591 d->secureSocket->setSecure(true); 0592 connect(d->secureSocket, SIGNAL(connected()), SLOT(slotSslPossible())); 0593 connect(d->secureSocket, SIGNAL(failed()), SLOT(slotSslNotPossible())); 0594 connect(d->secureSocket, SIGNAL(data(QString)), SLOT(slotReadSecure(QString))); 0595 d->secureSocket->reconnect(); 0596 d->secureSocketTimer->start(10000); 0597 } else { 0598 d->slotSslNotPossible(); 0599 } 0600 } 0601 0602 void ServerTest::setFakeHostname(const QString &fakeHostname) 0603 { 0604 d->fakeHostname = fakeHostname; 0605 } 0606 0607 QString ServerTest::fakeHostname() const 0608 { 0609 return d->fakeHostname; 0610 } 0611 0612 void ServerTest::setServer(const QString &server) 0613 { 0614 d->server = server; 0615 } 0616 0617 void ServerTest::setPort(Transport::EnumEncryption encryptionMode, uint port) 0618 { 0619 Q_ASSERT(encryptionMode == Transport::EnumEncryption::None || encryptionMode == Transport::EnumEncryption::SSL); 0620 d->customPorts.insert(encryptionMode, port); 0621 } 0622 0623 void ServerTest::setProgressBar(QProgressBar *pb) 0624 { 0625 d->testProgress = pb; 0626 } 0627 0628 void ServerTest::setProtocol(const QString &protocol) 0629 { 0630 d->testProtocol = protocol; 0631 d->customPorts.clear(); 0632 } 0633 0634 QString ServerTest::protocol() const 0635 { 0636 return d->testProtocol; 0637 } 0638 0639 QString ServerTest::server() const 0640 { 0641 return d->server; 0642 } 0643 0644 int ServerTest::port(TransportBase::EnumEncryption encryptionMode) const 0645 { 0646 Q_ASSERT(encryptionMode == Transport::EnumEncryption::None || encryptionMode == Transport::EnumEncryption::SSL); 0647 if (d->customPorts.contains(encryptionMode)) { 0648 return d->customPorts.value(static_cast<int>(encryptionMode)); 0649 } else { 0650 return -1; 0651 } 0652 } 0653 0654 QProgressBar *ServerTest::progressBar() const 0655 { 0656 return d->testProgress; 0657 } 0658 0659 QList<int> ServerTest::normalProtocols() const 0660 { 0661 return d->authenticationResults[TransportBase::EnumEncryption::None]; 0662 } 0663 0664 bool ServerTest::isNormalPossible() const 0665 { 0666 return d->normalPossible; 0667 } 0668 0669 QList<int> ServerTest::tlsProtocols() const 0670 { 0671 return d->authenticationResults[TransportBase::EnumEncryption::TLS]; 0672 } 0673 0674 QList<int> ServerTest::secureProtocols() const 0675 { 0676 return d->authenticationResults[Transport::EnumEncryption::SSL]; 0677 } 0678 0679 bool ServerTest::isSecurePossible() const 0680 { 0681 return d->securePossible; 0682 } 0683 0684 QList<ServerTest::Capability> ServerTest::capabilities() const 0685 { 0686 return d->capabilityResults.values(); 0687 } 0688 0689 #include "moc_servertest.cpp"