File indexing completed on 2024-05-12 05:17:11

0001 /*
0002    SPDX-FileCopyrightText: 2009 Andras Mantia <amantia@kde.org>
0003 
0004    SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
0005    SPDX-FileContributor: Kevin Ottens <kevin@kdab.com>
0006 
0007    SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include <QTest>
0011 
0012 #include "kimap/loginjob.h"
0013 #include "kimap/session.h"
0014 #include "kimaptest/fakeserver.h"
0015 
0016 #include <QTest>
0017 
0018 class TestUiProxy : public KIMAP::SessionUiProxy
0019 {
0020     bool ignoreSslError(const KSslErrorUiData &) override
0021     {
0022         return true;
0023     }
0024 };
0025 
0026 class LoginJobTest : public QObject
0027 {
0028     Q_OBJECT
0029 
0030 private Q_SLOTS:
0031 
0032     void shouldHandleLogin_data()
0033     {
0034         QTest::addColumn<QString>("user");
0035         QTest::addColumn<QString>("password");
0036         QTest::addColumn<QList<QByteArray>>("scenario");
0037 
0038         QList<QByteArray> scenario;
0039         scenario << FakeServer::greeting() << "C: A000001 LOGIN \"user\" \"password\""
0040                  << "S: A000001 OK User logged in";
0041 
0042         QTest::newRow("success") << QStringLiteral("user") << QStringLiteral("password") << scenario;
0043 
0044         scenario.clear();
0045         scenario << FakeServer::greeting() << "C: A000001 LOGIN \"user_bad\" \"password\""
0046                  << "S: A000001 NO Login failed: authentication failure";
0047 
0048         QTest::newRow("wrong login") << "user_bad" << QStringLiteral("password") << scenario;
0049 
0050         scenario.clear();
0051         scenario << FakeServer::greeting() << "C: A000001 LOGIN \"user\" \"aa\\\"bb\\\\cc[dd ee\""
0052                  << "S: A000001 OK User logged in";
0053 
0054         QTest::newRow("special chars") << QStringLiteral("user") << "aa\"bb\\cc[dd ee" << scenario;
0055 
0056         scenario.clear();
0057         scenario << FakeServer::preauth();
0058 
0059         QTest::newRow("already authenticated") << QStringLiteral("user") << QStringLiteral("password") << scenario;
0060     }
0061 
0062     void shouldHandleLogin()
0063     {
0064         QFETCH(QString, user);
0065         QFETCH(QString, password);
0066         QFETCH(QList<QByteArray>, scenario);
0067 
0068         FakeServer fakeServer;
0069         fakeServer.setScenario(scenario);
0070         fakeServer.startAndWait();
0071 
0072         KIMAP::Session *session = new KIMAP::Session(QStringLiteral("127.0.0.1"), 5989);
0073 
0074         KIMAP::LoginJob *login = new KIMAP::LoginJob(session);
0075         login->setUserName(user);
0076         login->setPassword(password);
0077         bool result = login->exec();
0078 
0079         QEXPECT_FAIL("wrong login", "Login with bad user name", Continue);
0080         QEXPECT_FAIL("already authenticated", "Trying to log on an already authenticated session", Continue);
0081         QVERIFY(result);
0082 
0083         fakeServer.quit();
0084         delete session;
0085     }
0086 
0087     void shouldHandleProxyLogin_data()
0088     {
0089         QTest::addColumn<QString>("user");
0090         QTest::addColumn<QString>("proxy");
0091         QTest::addColumn<QString>("password");
0092         QTest::addColumn<QList<QByteArray>>("scenario");
0093 
0094         QList<QByteArray> scenario;
0095         scenario << FakeServer::greeting() << "C: A000001 AUTHENTICATE PLAIN"
0096                  << "S: A000001 OK (success)"
0097                  << "C: A000001 LOGIN \"proxy\" \"user\" \"password\""
0098                  << "S: A000001 OK User logged in";
0099 
0100         QTest::newRow("success") << QStringLiteral("user") << "proxy" << QStringLiteral("password") << scenario;
0101     }
0102 
0103     void shouldHandleProxyLogin()
0104     {
0105         QFETCH(QString, user);
0106         QFETCH(QString, proxy);
0107         QFETCH(QString, password);
0108         QFETCH(QList<QByteArray>, scenario);
0109 
0110         FakeServer fakeServer;
0111         fakeServer.setScenario(scenario);
0112         fakeServer.startAndWait();
0113 
0114         KIMAP::Session *session = new KIMAP::Session(QStringLiteral("127.0.0.1"), 5989);
0115 
0116         KIMAP::LoginJob *login = new KIMAP::LoginJob(session);
0117         login->setAuthenticationMode(KIMAP::LoginJob::Plain);
0118         login->setUserName(user);
0119         login->setAuthorizationName(proxy);
0120         login->setPassword(password);
0121         bool result = login->exec();
0122 
0123         QVERIFY(result);
0124 
0125         fakeServer.quit();
0126         delete session;
0127     }
0128 
0129     void shouldSaveServerGreeting_data()
0130     {
0131         QTest::addColumn<QString>("greeting");
0132         QTest::addColumn<QList<QByteArray>>("scenario");
0133 
0134         QList<QByteArray> scenario;
0135         scenario << FakeServer::greeting() << "C: A000001 LOGIN \"user\" \"password\""
0136                  << "S: A000001 OK Welcome John Smith";
0137 
0138         QTest::newRow("greeting") << "Welcome John Smith" << scenario;
0139 
0140         scenario.clear();
0141         scenario << FakeServer::greeting() << "C: A000001 LOGIN \"user\" \"password\""
0142                  << "S: A000001 OK Welcome John Smith (last login: Feb 21, 2010)";
0143 
0144         QTest::newRow("greeting with parenthesis") << "Welcome John Smith (last login: Feb 21, 2010)" << scenario;
0145 
0146         scenario.clear();
0147         scenario << FakeServer::greeting() << "C: A000001 LOGIN \"user\" \"password\""
0148                  << "S: A000001 OK";
0149 
0150         QTest::newRow("no greeting") << "" << scenario;
0151 
0152         scenario.clear();
0153         scenario << FakeServer::greeting() << "C: A000001 LOGIN \"user\" \"password\""
0154                  << "S: A000001 NO Login failed: authentication failure";
0155 
0156         QTest::newRow("login failed") << "" << scenario;
0157     }
0158 
0159     void shouldSaveServerGreeting()
0160     {
0161         QFETCH(QString, greeting);
0162         QFETCH(QList<QByteArray>, scenario);
0163 
0164         FakeServer fakeServer;
0165         fakeServer.setScenario(scenario);
0166         fakeServer.startAndWait();
0167 
0168         KIMAP::Session *session = new KIMAP::Session(QStringLiteral("127.0.0.1"), 5989);
0169 
0170         KIMAP::LoginJob *login = new KIMAP::LoginJob(session);
0171         login->setUserName(QStringLiteral("user"));
0172         login->setPassword(QStringLiteral("password"));
0173         login->exec();
0174 
0175         QCOMPARE(login->serverGreeting(), greeting);
0176 
0177         fakeServer.quit();
0178         delete session;
0179     }
0180 
0181     void shouldUseSsl_data()
0182     {
0183         QTest::addColumn<QList<QByteArray>>("scenario");
0184         QTest::addColumn<int>("serverEncryption");
0185 
0186         {
0187             QList<QByteArray> scenario;
0188             scenario << FakeServer::greeting() << "C: A000001 CAPABILITY"
0189                      << "S: A000001 OK"
0190                      << "C: A000002 LOGIN \"user\" \"password\""
0191                      << "S: A000002 OK";
0192 
0193             // AnySslVersion doesn't mean the server can force a specific version (e.g. openssl always starts with a tls12 hello)
0194             QTest::newRow("any protocol with anyssl version") << scenario << static_cast<int>(QSsl::AnyProtocol);
0195 
0196             QTest::newRow("tlsv12") << scenario << static_cast<int>(QSsl::TlsV1_2);
0197             QTest::newRow("tlsv13") << scenario << static_cast<int>(QSsl::TlsV1_3);
0198         }
0199     }
0200 
0201     void shouldUseSsl()
0202     {
0203         QFETCH(QList<QByteArray>, scenario);
0204         QFETCH(int, serverEncryption);
0205 
0206         FakeServer fakeServer;
0207         fakeServer.setEncrypted(static_cast<QSsl::SslProtocol>(serverEncryption));
0208         fakeServer.setScenario(scenario);
0209         fakeServer.startAndWait();
0210 
0211         KIMAP::Session *session = new KIMAP::Session(QStringLiteral("127.0.0.1"), 5989);
0212 
0213         KIMAP::SessionUiProxy::Ptr uiProxy(new TestUiProxy);
0214         session->setUiProxy(uiProxy);
0215 
0216         KIMAP::LoginJob *login = new KIMAP::LoginJob(session);
0217         login->setUserName(QStringLiteral("user"));
0218         login->setPassword(QStringLiteral("password"));
0219         login->setEncryptionMode(KIMAP::LoginJob::SSLorTLS);
0220         QVERIFY(login->exec());
0221 
0222         fakeServer.quit();
0223         delete session;
0224     }
0225 
0226     void shouldUseStartTls_data()
0227     {
0228         QTest::addColumn<QList<QByteArray>>("scenario");
0229         QTest::addColumn<bool>("success");
0230 
0231         {
0232             QList<QByteArray> scenario;
0233             scenario << FakeServer::greeting() << "C: A000001 CAPABILITY"
0234                      << "S: * CAPABILITY IMAP4rev1 STARTTLS"
0235                      << "S: A000001 OK CAPABILITY completed"
0236                      << "C: A000002 STARTTLS"
0237                      << "S: A000002 OK"
0238                      << "C: A000003 CAPABILITY"
0239                      << "S: * CAPABILITY IMAP4rev1"
0240                      << "S: A000003 OK CAPABILITY completed"
0241                      << "C: A000004 LOGIN \"user\" \"password\""
0242                      << "S: A000004 OK";
0243             QTest::newRow("STARTTLS supported") << scenario << true;
0244         }
0245 
0246         {
0247             QList<QByteArray> scenario;
0248             scenario << FakeServer::greeting() << "C: A000001 CAPABILITY"
0249                      << "S: * CAPABILITY IMAP4rev1"
0250                      << "S: A000001 OK CAPABILITY completed";
0251 
0252             QTest::newRow("STARTTLS not supported") << scenario << false;
0253         }
0254     }
0255 
0256     void shouldUseStartTls()
0257     {
0258         QFETCH(QList<QByteArray>, scenario);
0259         QFETCH(bool, success);
0260 
0261         FakeServer fakeServer;
0262         fakeServer.setEncrypted(QSsl::AnyProtocol);
0263         fakeServer.setWaitForStartTls(true);
0264         fakeServer.setScenario(scenario);
0265         fakeServer.startAndWait();
0266 
0267         KIMAP::Session session(QStringLiteral("127.0.0.1"), 5989);
0268 
0269         KIMAP::SessionUiProxy::Ptr uiProxy(new TestUiProxy);
0270         session.setUiProxy(uiProxy);
0271 
0272         KIMAP::LoginJob login(&session);
0273         login.setUserName(QStringLiteral("user"));
0274         login.setPassword(QStringLiteral("password"));
0275         login.setEncryptionMode(KIMAP::LoginJob::STARTTLS);
0276         QCOMPARE(login.exec(), success);
0277 
0278         fakeServer.quit();
0279     }
0280 };
0281 
0282 QTEST_GUILESS_MAIN(LoginJobTest)
0283 
0284 #include "loginjobtest.moc"