aheinecke@404: /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik aheinecke@404: * Software engineering by Intevation GmbH aheinecke@404: * aheinecke@404: * This file is Free Software under the GNU GPL (v>=2) aheinecke@404: * and comes with ABSOLUTELY NO WARRANTY! aheinecke@404: * See LICENSE.txt for details. aheinecke@404: */ rrenkert@333: #include "administratorwindow.h" rrenkert@333: rrenkert@333: #include rrenkert@333: #include rrenkert@333: #include rrenkert@333: #include rrenkert@333: #include rrenkert@333: #include rrenkert@333: #include rrenkert@333: #include rrenkert@333: #include rrenkert@333: #include rrenkert@333: #include rrenkert@333: #include rrenkert@335: #include rrenkert@344: #include rrenkert@394: #include rrenkert@398: #include rrenkert@333: rrenkert@348: #include "certificatetabledelegate.h" rrenkert@362: #include "createinstallerdialog.h" rrenkert@368: #include "createcertlistdialog.h" rrenkert@566: #include "certificatediffdialog.h" rrenkert@427: #include "aboutdialog.h" rrenkert@348: rrenkert@333: AdministratorWindow::AdministratorWindow() { rrenkert@412: setWindowTitle(tr("TrustBridge Administration")); rrenkert@394: QString path = QStandardPaths::locate( aheinecke@462: QStandardPaths::DataLocation, QString("current_certificates.txt")); aheinecke@453: mCertList.readList(path.toLocal8Bit()); rrenkert@333: createActions(); rrenkert@333: createMenuBar(); rrenkert@333: createContent(); rrenkert@394: loadCertificateTable(); aheinecke@540: resize(1190, 500); rrenkert@333: } rrenkert@333: rrenkert@333: void AdministratorWindow::createActions() rrenkert@333: { rrenkert@333: } rrenkert@333: rrenkert@333: void AdministratorWindow::createMenuBar() rrenkert@333: { rrenkert@333: menuBar = new QMenuBar(this); rrenkert@333: QMenu *menu = new QMenu(tr("Menu"), menuBar); rrenkert@333: menuBar->addMenu(menu); rrenkert@415: QAction *createInstaller = menu->addAction(tr("Create installer ...")); rrenkert@415: QAction *about = menu->addAction(tr("About TrustBridge")); rrenkert@333: menu->addSeparator(); rrenkert@333: QAction *quit = menu->addAction(tr("Quit")); rrenkert@333: connect(createInstaller, SIGNAL(triggered()), this, SLOT(createInstaller())); rrenkert@333: connect(about, SIGNAL(triggered()), this, SLOT(showAbout())); rrenkert@333: connect(quit, SIGNAL(triggered()), qApp, SLOT(quit())); rrenkert@333: setMenuBar(menuBar); rrenkert@333: } rrenkert@333: rrenkert@333: void AdministratorWindow::createContent() rrenkert@333: { rrenkert@333: // Create a central widget containing the main layout. rrenkert@333: QWidget *base = new QWidget; rrenkert@333: rrenkert@333: // Layouts and Container rrenkert@333: QVBoxLayout *mainLayout = new QVBoxLayout; rrenkert@333: QVBoxLayout *certLayout = new QVBoxLayout; rrenkert@333: QHBoxLayout *headerLayout = new QHBoxLayout; rrenkert@333: QVBoxLayout *headerTextLayout = new QVBoxLayout; rrenkert@333: QHBoxLayout *bottomLayout = new QHBoxLayout; rrenkert@333: rrenkert@333: // The certificate list rrenkert@412: QGroupBox *certBox = new QGroupBox( rrenkert@426: tr("All managed root certificates of the certificate list: ")); rrenkert@335: certificateView = new QTableView; rrenkert@343: certificateModel = new CertificateTabelModel(); rrenkert@398: QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(this); rrenkert@398: filterModel->setSourceModel(certificateModel); rrenkert@348: CertificateTableDelegate *delegate = new CertificateTableDelegate(certificateView); rrenkert@398: certificateView->setModel(filterModel); rrenkert@348: certificateView->setItemDelegate(delegate); rrenkert@426: certificateView->horizontalHeader()->setStretchLastSection(true); rrenkert@395: certificateView->resizeColumnsToContents(); rrenkert@395: certificateView->setColumnWidth(0, 60); rrenkert@343: certificateView->setSelectionBehavior(QAbstractItemView::SelectRows); rrenkert@376: connect(certificateView, SIGNAL(clicked(const QModelIndex&)), this, rrenkert@376: SLOT(clickedCertificate(const QModelIndex&))); rrenkert@343: certificateView->verticalHeader()->setVisible(false); rrenkert@398: certificateView->setSortingEnabled(true); rrenkert@335: certLayout->addWidget(certificateView); rrenkert@333: certBox->setLayout(certLayout); rrenkert@333: rrenkert@333: // The header (icon, about text) rrenkert@333: QImage *logoImage = new QImage(":/img/logo.png"); rrenkert@333: QLabel *logo = new QLabel; rrenkert@333: logo->setBackgroundRole(QPalette::Base); rrenkert@333: logo->setPixmap(QPixmap::fromImage(*logoImage)); rrenkert@427: QLabel *title = new QLabel("

" + tr("TrustBridge Administration") + "

"); rrenkert@412: QLabel *subTitle = new QLabel( rrenkert@412: tr("Management application of the BSI certificate installer")); rrenkert@333: headerTextLayout->addWidget(title); rrenkert@333: headerTextLayout->addWidget(subTitle); rrenkert@333: headerLayout->addWidget(logo); rrenkert@333: headerLayout->addLayout(headerTextLayout); rrenkert@333: headerLayout->setStretch(0, 0); rrenkert@333: headerLayout->setStretch(1, 10); rrenkert@333: rrenkert@333: // The buttons. rrenkert@333: bottomLayout->setAlignment(Qt::AlignBottom); rrenkert@412: saveButton = new QPushButton(QIcon(":/img/document-save.png"), tr("Save list")); rrenkert@368: connect(saveButton, SIGNAL(clicked()), this, SLOT(saveCertificateFile())); rrenkert@412: loadButton = new QPushButton(QIcon(":/img/document-open.png"), tr("Load list")); rrenkert@344: connect(loadButton, SIGNAL(clicked()), this, SLOT(loadCertificateFile())); rrenkert@412: addButton = new QPushButton(QIcon(":/img/document-new.png"), tr("Add certificate")); rrenkert@358: connect(addButton, SIGNAL(clicked()), this, SLOT(addCertificates())); rrenkert@412: removeButton = new QPushButton(QIcon(":/img/document-close.png"), tr("Remove certificate")); rrenkert@376: removeButton->setEnabled(false); rrenkert@376: connect(removeButton, SIGNAL(clicked()), this, SLOT(removeCertificates())); rrenkert@333: bottomLayout->addWidget(saveButton); rrenkert@333: bottomLayout->addWidget(loadButton); rrenkert@333: bottomLayout->addWidget(addButton); rrenkert@333: bottomLayout->addWidget(removeButton); rrenkert@333: bottomLayout->insertStretch(4, 10); rrenkert@333: rrenkert@333: mainLayout->addLayout(headerLayout); rrenkert@333: mainLayout->addWidget(certBox); rrenkert@333: mainLayout->addLayout(bottomLayout); rrenkert@333: rrenkert@333: rrenkert@333: // QMainWindow allready has a layout. All child layouts and widgets are rrenkert@333: // managed in the central widget. rrenkert@333: base->setLayout(mainLayout); rrenkert@333: setCentralWidget(base); rrenkert@333: } rrenkert@333: rrenkert@344: void AdministratorWindow::loadCertificateFile() rrenkert@344: { aheinecke@515: QString lastCertFile = mSettings.value("LastCertList", QDir::homePath()).toString(); rrenkert@344: QString certFile = QFileDialog::getOpenFileName( aheinecke@515: this, tr("Select certificate list file"), lastCertFile, "*.txt"); aheinecke@453: mCertList.readList(certFile.toLocal8Bit().constData()); aheinecke@453: if (!mCertList.isValid()) { aheinecke@515: QMessageBox::warning(this, tr("Error!"), tr("Failed to load the certificate list.")); aheinecke@462: } else { rrenkert@396: certificateModel->removeAll(); rrenkert@344: loadCertificateTable(); aheinecke@515: mSettings.setValue("LastCertList", certFile); rrenkert@344: } rrenkert@344: } rrenkert@344: rrenkert@368: void AdministratorWindow::saveCertificateFile() rrenkert@368: { rrenkert@566: CertificateDiffDialog *diffDialog = new CertificateDiffDialog(this); rrenkert@566: int ret = diffDialog->exec(); rrenkert@566: if (ret == QDialog::Accepted) { rrenkert@566: CreateCertListDialog *dialog = new CreateCertListDialog(this); rrenkert@566: dialog->show(); rrenkert@566: } rrenkert@368: } rrenkert@368: rrenkert@358: void AdministratorWindow::addCertificates() rrenkert@358: { rrenkert@429: QStringList certFiles = QFileDialog::getOpenFileNames( aheinecke@529: this, tr("Select certificate"), QDir::homePath(), "*.pem *.der *.crt *.cer"); rrenkert@429: for (int i = 0; i < certFiles.size(); i++) { rrenkert@429: QString certFile = certFiles.at(i); rrenkert@429: QList certs = Certificate::fromFileName(certFile); rrenkert@429: addToCertificateTable(certs); rrenkert@429: } rrenkert@427: certificateView->resizeColumnsToContents(); rrenkert@427: certificateView->setColumnWidth(0, 60); rrenkert@358: } rrenkert@358: rrenkert@376: void AdministratorWindow::removeCertificates() rrenkert@376: { rrenkert@376: QModelIndexList list = certificateView->selectionModel()->selectedRows(); rrenkert@376: for (int i = list.size() -1 ; i >= 0; i--) { rrenkert@376: certificateModel->removeRow(list.at(i).row(), list.at(i)); rrenkert@376: } rrenkert@376: } rrenkert@376: rrenkert@344: void AdministratorWindow::loadCertificateTable() { aheinecke@453: foreach(const Certificate &cert, mCertList.getCertificates()) { rrenkert@358: certificateModel->addCertificate(cert, true); rrenkert@358: } rrenkert@395: certificateView->resizeColumnsToContents(); rrenkert@395: certificateView->setColumnWidth(0, 60); rrenkert@358: } rrenkert@358: rrenkert@358: void AdministratorWindow::addToCertificateTable(const QList &certs) rrenkert@358: { rrenkert@358: foreach(const Certificate &cert, certs) { rrenkert@358: certificateModel->addCertificate(cert, false); rrenkert@344: } rrenkert@344: } rrenkert@344: rrenkert@333: void AdministratorWindow::showAbout() rrenkert@333: { rrenkert@427: AboutDialog *dialog = new AboutDialog(this); rrenkert@427: dialog->show(); rrenkert@333: } rrenkert@333: rrenkert@333: void AdministratorWindow::createInstaller() rrenkert@333: { rrenkert@333: qDebug() << "create Installer"; rrenkert@362: CreateInstallerDialog *dialog = new CreateInstallerDialog(this); rrenkert@362: dialog->show(); rrenkert@333: } rrenkert@333: rrenkert@376: void AdministratorWindow::clickedCertificate(const QModelIndex &index) rrenkert@376: { rrenkert@376: if (index.data(Qt::UserRole).toBool()) { rrenkert@376: removeButton->setEnabled(false); rrenkert@376: } rrenkert@376: else { rrenkert@376: removeButton->setEnabled(true); rrenkert@376: } rrenkert@376: } rrenkert@562: rrenkert@562: void AdministratorWindow::logChanges(const QString ¤tCerts) rrenkert@562: { rrenkert@562: QDir logDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); rrenkert@562: QString logFilePath = logDir.filePath("log.txt"); rrenkert@562: QFile logFile(logFilePath); rrenkert@562: rrenkert@562: if (!logFile.open(QIODevice::Append)) { rrenkert@562: qDebug() << "Failed to open log file: " << logFilePath; rrenkert@562: return; rrenkert@562: } rrenkert@562: rrenkert@562: CertificateList newCertList; rrenkert@562: newCertList.readList(currentCerts.toLocal8Bit()); rrenkert@562: QByteArray entries = createLogEntries(newCertList); rrenkert@562: if(logFile.write(entries) != entries.size()) { rrenkert@562: qDebug() << "Failed to write log file: " << logFilePath; rrenkert@562: return; rrenkert@562: } rrenkert@562: logFile.close(); rrenkert@562: } rrenkert@562: rrenkert@562: QByteArray AdministratorWindow::createLogEntries(const CertificateList &list) rrenkert@562: { rrenkert@562: QByteArray entries; rrenkert@562: QByteArray removeListEntries; rrenkert@562: rrenkert@562: QDateTime currentDate = QDateTime::currentDateTime(); rrenkert@562: QDateTime newListDate = list.date(); rrenkert@562: QDateTime listDate = mCertList.date(); rrenkert@562: rrenkert@562: entries.append("##### " + rrenkert@562: currentDate.toString("yyyy-MM-dd hh:mm") + rrenkert@562: tr(" new certificatelist ") + rrenkert@562: newListDate.toString(Qt::ISODate) + rrenkert@562: tr(" based on list from ") + rrenkert@562: listDate.toString(Qt::ISODate) + rrenkert@562: "#####\r\n"); rrenkert@562: entries.append(tr("signing certificate: \r\n")); rrenkert@562: entries.append(tr("new certificates:\r\n")); rrenkert@562: rrenkert@562: foreach (const Certificate& cert, list.getCertificates()) { rrenkert@562: if (!mCertList.getCertificates().contains(cert)) { rrenkert@562: QString certEntry(cert.subjectCN() + ": " + cert.base64Line() + "\r\n"); rrenkert@562: if (cert.isInstallCert()) { rrenkert@562: entries.append(certEntry); rrenkert@562: } rrenkert@562: else { rrenkert@562: removeListEntries.append(certEntry); rrenkert@562: } rrenkert@562: } rrenkert@562: } rrenkert@562: rrenkert@562: entries.append(tr("certificates marked to remove:\r\n")); rrenkert@562: entries.append(removeListEntries); rrenkert@562: entries.append("\r\n"); rrenkert@562: rrenkert@562: return entries; rrenkert@562: } rrenkert@565: rrenkert@565: QList AdministratorWindow::currentChanges() rrenkert@565: { rrenkert@565: QList changed; rrenkert@565: foreach(const Certificate& cert, certificates()) { rrenkert@565: if (!mCertList.getCertificates().contains(cert)) { rrenkert@565: changed.append(cert); rrenkert@565: } rrenkert@565: } rrenkert@565: return changed; rrenkert@565: }