andre@307: #include <cert.h>
andre@307: #include <certdb.h>
andre@307: #include <certt.h>
andre@307: 
andre@307: #include <nss.h>
andre@307: #include <pk11pub.h>
andre@307: 
andre@304: #include "nsstest.h"
andre@304: #include "nssstore.h"
andre@304: #include "strhelp.h"
andre@304: 
andre@304: #include <QTest>
aheinecke@330: #include <QTextCodec>
aheinecke@330: 
aheinecke@330: #ifdef WIN32
aheinecke@330: #define endl "\r\n"
aheinecke@330: #endif
andre@304: 
andre@307: QList<QByteArray> NSSTest::get_nss_certs (QTemporaryDir *nssDir)
andre@307: {
andre@307:   CERTCertList *list;
andre@307:   CERTCertListNode *node;
andre@307:   QList<QByteArray> retval;
andre@304: 
andre@307:   if (NSS_Initialize(nssDir->path().toLocal8Bit().constData(),
andre@307:               "", "", "secmod.db", NSS_INIT_READONLY)
andre@307:       == SECSuccess)
andre@307:     {
andre@307:       list = PK11_ListCerts(PK11CertListAll, NULL);
andre@307:       for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list);
andre@307:            node = CERT_LIST_NEXT(node)) {
andre@307:         retval << QByteArray((const char*)node->cert->derCert.data,
andre@307:                 (int)node->cert->derCert.len);
andre@307:       }
andre@307:       CERT_DestroyCertList(list);
andre@307:       NSS_Shutdown();
andre@307:     }
andre@307:   else
andre@307:     {
andre@307:       qDebug("Could not open nss certificate store!\n");
andre@307:     }
andre@307:   return retval;
andre@307: }
andre@307: 
andre@307: void NSSTest::setupTestDir(QTemporaryDir *nssDir)
andre@307: {
andre@307:     /* Copy the empty nss db in the temporary dir */
aheinecke@330:     QVERIFY(QFile::copy(":/nss/cert8.db", nssDir->path() + "/" +"cert8.db"));
aheinecke@330:     QVERIFY(QFile::copy(":/nss/key3.db", nssDir->path() + "/" +"key3.db"));
aheinecke@330:     QVERIFY(QFile::copy(":/nss/secmod.db", nssDir->path() + "/" +"secmod.db"));
andre@307: 
andre@307:     QVERIFY(QFile::setPermissions(nssDir->path() + "/" +"cert8.db",
andre@304:                 QFileDevice::ReadOwner | QFileDevice::WriteOwner));
andre@307:     QVERIFY(QFile::setPermissions(nssDir->path() + "/" +"key3.db",
andre@304:                 QFileDevice::ReadOwner | QFileDevice::WriteOwner));
andre@307:     QVERIFY(QFile::setPermissions(nssDir->path() + "/" +"secmod.db",
andre@304:                 QFileDevice::ReadOwner | QFileDevice::WriteOwner));
andre@346: //    nssDir->setAutoRemove(false);
andre@307: }
andre@307: 
andre@307: void NSSTest::initTestCase() {
aheinecke@330:     QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); /* use system default */
andre@304: 
andre@304:     /* Set up a temporary list */
andre@304:     QFile res(":/list-valid-signed.txt");
andre@304:     res.open(QIODevice::ReadOnly);
andre@304:     validListFile.open();
andre@304:     validListFile.write(res.readAll());
andre@304:     validListFile.close();
andre@304: 
andre@307:     setupTestDir(&ffNSSDir);
andre@307:     setupTestDir(&tbNSSDir);
andre@304: 
andre@304:     validList = CertificateList(validListFile.fileName().toLocal8Bit().data());
andre@304: 
andre@304:     /* Create the profiles.ini `s set environment variables*/
andre@346: //    fakeHome.setAutoRemove(false);
andre@304: #ifndef WIN32
andre@304:     QVERIFY(!setenv ("HOME", fakeHome.path().toLocal8Bit().constData(), 1));
andre@304:     fakeFirefoxDir = QDir(fakeHome.path() + "/.mozilla/firefox");
andre@304:     fakeThunderbirdDir = QDir(fakeHome.path() + "/.thunderbird");
andre@304: #else
aheinecke@326:     {
aheinecke@326:         char buf[fakeHome.path().toLocal8Bit().size() + 9];
aheinecke@326:         snprintf(buf, fakeHome.path().toLocal8Bit().size() + 9,
aheinecke@326:                 "APPDATA=%s",fakeHome.path().toLocal8Bit().constData());
aheinecke@326:         QVERIFY(_putenv (buf) != -1);
aheinecke@326:     }
andre@304:     fakeFirefoxDir = QDir(fakeHome.path() + "/Mozilla/firefox");
andre@304:     fakeThunderbirdDir = QDir(fakeHome.path() + "/Thunderbird");
andre@304: #endif
andre@304:     QVERIFY(fakeFirefoxDir.mkpath(fakeFirefoxDir.path()));
andre@304:     QVERIFY(fakeThunderbirdDir.mkpath(fakeThunderbirdDir.path()));
andre@304: 
andre@304:     QFile mozProfile(fakeFirefoxDir.absoluteFilePath("profiles.ini"));
andre@304:     QFile tbProfile(fakeThunderbirdDir.absoluteFilePath("profiles.ini"));
andre@304: 
andre@304:     /* Write profiles */
andre@304:     QVERIFY(mozProfile.open(QIODevice::WriteOnly));
andre@304:     QTextStream ffStream(&mozProfile);
andre@304:     ffStream << endl << "[General]"<<
andre@304:         "StartWithLastProfile=1" << endl <<
andre@304:         "[Profile0]" << endl <<
andre@304:         "Name=default" << endl <<
andre@304:         "IsRelative=1" << endl <<
andre@307:         "Path=" << fakeFirefoxDir.relativeFilePath(ffNSSDir.path()) << endl;
andre@304:     ffStream.flush();
andre@304:     mozProfile.close();
andre@304: 
andre@304:     QVERIFY(tbProfile.open(QIODevice::WriteOnly));
andre@304:     QTextStream tbStream(&tbProfile);
andre@304:     tbStream << endl << "[General]"<<
andre@304:         "StartWithLastProfile=1" << endl <<
andre@304:         "[Profile102]" << endl <<
andre@304:         "Name=default" << endl <<
andre@304:         "IsRelative=0" << endl <<
andre@307:         "Path=" << tbNSSDir.path() << endl;
andre@304:     tbStream.flush();
andre@304:     tbProfile.close();
andre@304: }
andre@304: 
andre@304: void NSSTest::testInstRemove() {
andre@304:     char ** to_install = NULL,
andre@304:          ** to_remove = NULL;
andre@304: 
andre@304:     QList<Certificate> instList;
andre@304: 
andre@307:     /* Install all certificates */
andre@304:     foreach (const Certificate &cert, validList.getCertificates()) {
andre@304:         if (!cert.isInstallCert())
andre@304:             continue;
andre@304:         instList << cert;
andre@304:         strv_append (&to_install, cert.base64Line().toLatin1().constData() + 2,
andre@304:                 cert.base64Line().size() - 2);
andre@304:     }
andre@304:     QVERIFY((size_t) instList.size() == strv_length(to_install));
andre@304: 
andre@305:     QVERIFY(write_stores_nss(to_install, to_remove) == 0);
andre@305: 
andre@307:     {
andre@307:         /* Verify that everything is installed */
andre@307:         QList<QByteArray> installedCertsFF = get_nss_certs(&ffNSSDir);
andre@307:         QList<QByteArray> installedCertsTB = get_nss_certs(&tbNSSDir);
andre@307: 
andre@307:         QVERIFY(installedCertsFF.size() == instList.size());
andre@307:         QVERIFY(installedCertsFF == installedCertsTB);
andre@307: 
andre@307:         for (int i = 0; to_install[i]; i++) {
andre@307:             QByteArray bai = QByteArray::fromBase64(to_install[i]);
andre@307:             QVERIFY(installedCertsFF.contains(bai));
andre@307:         }
andre@307:     }
andre@307: 
andre@307:     {
andre@307:         /* Remove one certificate */
andre@307:         QVERIFY(instList.size() > 2);
andre@307:         strv_append (&to_remove, to_install[1], qstrlen(to_install[1]));
andre@307: 
andre@307:         QVERIFY(write_stores_nss(NULL, to_remove) == 0);
andre@307: 
andre@307:         QList<QByteArray> installedCertsFF = get_nss_certs(&ffNSSDir);
andre@307:         QList<QByteArray> installedCertsTB = get_nss_certs(&tbNSSDir);
andre@307: 
andre@307:         QVERIFY(installedCertsFF == installedCertsTB);
andre@307: 
andre@307:         QByteArray bai = QByteArray::fromBase64(to_install[1]);
andre@307:         QVERIFY(!installedCertsTB.contains(bai));
andre@307: 
andre@307:         QVERIFY((size_t)installedCertsTB.size() == strv_length(to_install) - 1);
andre@307: 
andre@307:         for (int i = 0; to_install[i]; i++) {
andre@307:             if (i == 1) {
andre@307:                 continue;
andre@307:             }
andre@307:             QByteArray bai = QByteArray::fromBase64(to_install[i]);
andre@307:             QVERIFY(installedCertsTB.contains(bai));
andre@307:         }
andre@307:     }
andre@307: 
andre@307:     {
andre@307:         /* Readd all certificates check for duplication*/
andre@307:         QVERIFY(write_stores_nss(to_install, NULL) == 0);
andre@307: 
andre@307:         QList<QByteArray> installedCertsFF = get_nss_certs(&ffNSSDir);
andre@307:         QList<QByteArray> installedCertsTB = get_nss_certs(&tbNSSDir);
andre@307: 
andre@307:         QVERIFY(installedCertsFF == installedCertsTB);
andre@307: 
andre@307:         QVERIFY((size_t)installedCertsTB.size() == strv_length(to_install));
andre@307: 
andre@307:         for (int i = 0; to_install[i]; i++) {
andre@307:             QByteArray bai = QByteArray::fromBase64(to_install[i]);
andre@307:             QVERIFY(installedCertsTB.contains(bai));
andre@307:         }
andre@307:     }
andre@307: 
andre@307:     {
andre@307:         /* Remove all certificates */
andre@307:         QVERIFY(write_stores_nss(NULL, to_install) == 0);
andre@307: 
andre@307:         QList<QByteArray> installedCertsFF = get_nss_certs(&ffNSSDir);
andre@307:         QList<QByteArray> installedCertsTB = get_nss_certs(&tbNSSDir);
andre@307: 
andre@307:         QVERIFY(installedCertsFF == installedCertsTB);
andre@307: 
andre@307:         QVERIFY(installedCertsTB.size() == 0);
andre@307:     }
andre@304: }
andre@304: 
andre@304: QTEST_GUILESS_MAIN (NSSTest);