Page MenuHome GnuPG

No OneTemporary

diff --git a/client/firsttimedialog.cpp b/client/firsttimedialog.cpp
index 58fbe8a..e914a20 100644
--- a/client/firsttimedialog.cpp
+++ b/client/firsttimedialog.cpp
@@ -1,176 +1,203 @@
// SPDX-FileCopyrightText: 2024 g10 code Gmbh
// SPDX-Contributor: Carl Schwan <carl.schwan@gnupg.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "firsttimedialog.h"
#include "config.h"
#include "gpgoljs_version.h"
#include "rootcagenerator/controller.h"
#include "ui_firsttimedialog.h"
#include "websocketclient.h"
#include <QCheckBox>
#include <QClipboard>
#include <QCloseEvent>
#include <QDesktopServices>
#include <QStatusBar>
#include <QTemporaryDir>
#include <QToolBar>
#include <KTitleWidget>
using namespace Qt::StringLiterals;
FirstTimeDialog::FirstTimeDialog(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::FirstTimeDialog)
, m_controller(new Controller(this))
{
ui->setupUi(this);
ui->welcomePage->setProperty("title", i18nc("@title", "Welcome to GpgOL/Web"));
ui->configurationPage->setProperty("title", i18nc("@title", "Welcome to GpgOL/Web"));
ui->configPage->setProperty("title", i18nc("@title", "Install Outlook Add-In"));
- ui->configServerPage->setProperty("title", i18nc("@title", "Config Remote Server"));
ui->installationPage->setProperty("title", i18nc("@title", "Setting Up the Local Server"));
SystemTrayIcon systemTrayIcon(QIcon::fromTheme(u"com.gnupg.gpgolweb"_s));
systemTrayIcon.setMainWindow(this);
systemTrayIcon.show();
m_backAction = new QAction(QIcon::fromTheme(u"draw-arrow-back-symbolic"_s), i18nc("@action:intoolbar", "Go back"));
connect(m_backAction, &QAction::triggered, this, [this]() {
if (m_controller->certificateAlreadyGenerated() || !Config::self()->isLocalServer()) {
ui->stack->setCurrentIndex(ui->stack->currentIndex() > 1 ? ConfigurationPage : WelcomePage);
} else {
ui->stack->setCurrentIndex(ConfigurationPage);
}
});
auto toolbar = new QToolBar(this);
toolbar->setMovable(false);
toolbar->addAction(m_backAction);
auto titleWidget = new KTitleWidget(this);
toolbar->addWidget(titleWidget);
addToolBar(Qt::TopToolBarArea, toolbar);
m_backAction->setVisible(false);
titleWidget->setText(ui->stack->currentWidget()->property("title").toString());
connect(ui->stack, &QStackedWidget::currentChanged, this, [titleWidget, this]() {
m_backAction->setVisible(ui->stack->currentIndex() > 0);
titleWidget->setText(ui->stack->currentWidget()->property("title").toString());
});
// center vertically
ui->mainLayout->insertStretch(0);
ui->mainLayout->addStretch();
ui->mainLayoutManifest->insertStretch(0);
ui->mainLayoutManifest->addStretch();
QPixmap logo = QIcon::fromTheme(u"com.gnupg.gpgolweb"_s).pixmap(64, 64);
ui->logo->setPixmap(logo);
ui->titleWelcome->setText(i18nc("@info", "GpgOL/Web %1", QString::fromLocal8Bit(GPGOLJS_VERSION_STRING)));
auto statusBar = new QStatusBar(this);
auto showOnStartup = new QCheckBox(i18nc("@option:check", "Show on startup"));
showOnStartup->setChecked(Config::self()->showLauncher());
connect(showOnStartup, &QCheckBox::toggled, this, [](bool checked) {
Config::self()->setShowLauncher(checked);
Config::self()->save();
});
statusBar->addPermanentWidget(showOnStartup, 1);
m_status = new QLabel;
statusBar->addPermanentWidget(m_status);
auto version = new QLabel(i18nc("@info", "Version: %1", QString::fromLocal8Bit(GPGOLJS_VERSION_STRING)));
statusBar->addPermanentWidget(version);
setStatusBar(statusBar);
connect(ui->setupButton, &QPushButton::clicked, this, &FirstTimeDialog::slotSetup);
connect(ui->configureButton, &QPushButton::clicked, this, [this]() {
ui->stack->setCurrentIndex(ConfigurationPage);
});
ui->manifestPath->setText(QLatin1StringView(DATAROUTDIR) + u"/gpgol/manifest.xml"_s);
connect(ui->openOutlookButton, &QPushButton::clicked, this, []() {
QDesktopServices::openUrl(QUrl(u"https://outlook.office.com/mail/jsmvvmdeeplink/?path=/options/manageapps&bO=4"_s));
});
connect(ui->manifestPathCopy, &QPushButton::clicked, this, [this]() {
QGuiApplication::clipboard()->setText(ui->manifestPath->text());
});
+ ui->remoteLabel->setEnabled(!Config::self()->isLocalServer());
+ ui->remoteServer->setEnabled(!Config::self()->isLocalServer());
+ ui->remoteServer->setText(Config::self()->remoteAddress().toString());
+
+ connect(ui->remoteOption, &QRadioButton::toggled, this, [this](bool checked) {
+ Config::self()->setIsLocalServer(!checked);
+ Config::self()->save();
+
+ ui->remoteLabel->setEnabled(!Config::self()->isLocalServer());
+ ui->remoteServer->setEnabled(!Config::self()->isLocalServer());
+ });
+
+ connect(ui->remoteServer, &QLineEdit::textChanged, this, [this]() {
+ Config::self()->setRemoteAddress(QUrl::fromUserInput(ui->remoteServer->text()));
+ Config::self()->save();
+ });
+
if (m_controller->certificateAlreadyGenerated() || !Config::self()->isLocalServer()) {
ui->stack->setCurrentIndex(WelcomePage);
if (m_controller->certificateAlreadyGenerated() && Config::self()->isLocalServer()) {
startLocalServer();
}
startWebsocketClient();
} else {
ui->stack->setCurrentIndex(ConfigurationPage);
}
}
FirstTimeDialog::~FirstTimeDialog() = default;
void FirstTimeDialog::slotStateChanged(const QString &stateDisplay)
{
m_status->setText(stateDisplay);
}
void FirstTimeDialog::closeEvent(QCloseEvent *e)
{
e->ignore();
hide();
}
void FirstTimeDialog::slotSetup()
{
if (ui->localOption->isChecked()) {
if (!m_controller->certificateAlreadyGenerated()) {
ui->stack->setCurrentIndex(InstallationPage);
const auto gnupghome = qgetenv("GNUPGHOME");
QTemporaryDir tempDir;
tempDir.setAutoRemove(false);
qputenv("GNUPGHOME", tempDir.path().toUtf8());
connect(m_controller, &Controller::finished, this, [gnupghome, this](KJob *) {
qputenv("GNUPGHOME", gnupghome);
+ if (!m_controller->error()) {
+ ui->installationPage->appendPlainText(m_controller->errorText());
+ return;
+ }
startWebsocketClient();
+ ui->stack->setCurrentIndex(ManifestPage);
});
+ connect(m_controller, &Controller::debutOutput, this, &FirstTimeDialog::slotTlsDebutOutput);
m_controller->start();
} else {
ui->stack->setCurrentIndex(ManifestPage);
startLocalServer();
startWebsocketClient();
}
} else {
- ui->stack->setCurrentIndex(ConfigServerPage);
+ ui->stack->setCurrentIndex(ManifestPage);
}
}
void FirstTimeDialog::startLocalServer()
{
if (m_serverProcess.state() != QProcess::NotRunning) {
return;
}
m_serverProcess.start(u"gpgol-server"_s);
}
void FirstTimeDialog::startWebsocketClient()
{
const auto clientId = QUuid::createUuid().toString(QUuid::WithoutBraces);
auto &websocketClient = WebsocketClient::self(QUrl(u"wss://localhost:5657/"_s), clientId);
connect(&websocketClient, &WebsocketClient::stateChanged, this, &FirstTimeDialog::slotStateChanged);
connect(&websocketClient, &WebsocketClient::stateChanged, &m_systemTrayIcon, &SystemTrayIcon::slotStateChanged);
m_systemTrayIcon.slotStateChanged(websocketClient.stateDisplay());
slotStateChanged(websocketClient.stateDisplay());
}
+
+void FirstTimeDialog::slotTlsDebutOutput(const QString &output)
+{
+ ui->installationPage->appendPlainText(output);
+}
diff --git a/client/firsttimedialog.h b/client/firsttimedialog.h
index 1e3a268..43dc00f 100644
--- a/client/firsttimedialog.h
+++ b/client/firsttimedialog.h
@@ -1,51 +1,51 @@
// SPDX-FileCopyrightText: 2024 g10 code Gmbh
// SPDX-Contributor: Carl Schwan <carl.schwan@gnupg.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "utils/systemtrayicon.h"
#include <QMainWindow>
#include <QProcess>
class QLabel;
class Controller;
namespace Ui
{
class FirstTimeDialog;
}
class FirstTimeDialog : public QMainWindow
{
Q_OBJECT
public:
explicit FirstTimeDialog(QWidget *parent = nullptr);
~FirstTimeDialog();
public Q_SLOTS:
void slotStateChanged(const QString &stateDisplay);
+ void slotTlsDebutOutput(const QString &output);
protected:
void closeEvent(QCloseEvent *e) override;
private:
void slotSetup();
void startLocalServer();
void startWebsocketClient();
enum Page {
WelcomePage = 0,
ConfigurationPage = 1,
ManifestPage = 2,
- ConfigServerPage = 3,
- InstallationPage = 4,
+ InstallationPage = 3,
};
QScopedPointer<Ui::FirstTimeDialog> ui;
QAction *m_backAction;
QLabel *m_status;
Controller *const m_controller;
SystemTrayIcon m_systemTrayIcon;
QProcess m_serverProcess;
};
diff --git a/client/firsttimedialog.ui b/client/firsttimedialog.ui
index eb8d44c..c0c7a98 100644
--- a/client/firsttimedialog.ui
+++ b/client/firsttimedialog.ui
@@ -1,161 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<!--
SPDX-FileCopyrightText: 2024 g10 Code GmbH
SPDX-Contributor: Carl Schwan <carl.schwan@gnupg.com>
SPDX-License-Identifier: GPL-2.0-or-later
-->
<class>FirstTimeDialog</class>
<widget class="QMainWindow" name="FirstTimeDialog">
<widget class="QStackedWidget" name="stack">
<widget class="QWidget" name="welcomePage">
<layout class="QVBoxLayout" name="mainLayout">
<item>
<widget class="QLabel" name="logo">
<property name="logo">
</property>
</widget>
</item>
<item>
<widget class="KTitleWidget" name="titleWelcome">
<property name="text">
<string>GpgOL/Web</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="configureButton">
<property name="text"><string>Configure</string></property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="configurationPage">
<layout class="QVBoxLayout" name="mainLayout">
<item>
<spacer>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>80</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel">
<property name="text">
<string>Choose your configuration:</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="localOption">
<property name="text">
<string>Running the server on this machine</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="remoteOption">
<property name="text">
<string>Running the server on a seperate server (recommanded for large deployment)</string>
</property>
</widget>
</item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="remoteLabel">
+ <property name="text">
+ <string>Remote Server</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="remoteServer">
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
<item>
<widget class="QPushButton" name="setupButton">
<property name="text"><string>Setup</string></property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<spacer>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>80</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="configPage">
<layout class="QVBoxLayout" name="mainLayoutManifest">
<item>
<widget class="QLabel">
<property name="text">
<string>Configure the Outlook extension by installing it from a file in "My Add-Ins" -> "User configured Add-Ins".</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLineEdit" name="manifestPath">
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="manifestPathCopy">
<property name="icon">
<iconset theme="edit-copy-symbolic" />
</property>
<property name="text">
<string>Copy</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="openOutlookButton">
<property name="text"><string>Open Outlouk Extension Manager</string></property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
- <widget class="QWidget" name="configServerPage">
- <layout class="QVBoxLayout">
- </layout>
- </widget>
- <widget class="QWidget" name="installationPage">
- <layout class="QVBoxLayout" name="mainLayoutServer">
- <item>
- <widget class="QLabel" name="stateLoading" />
- </item>
- </layout>
- </widget>
+ <widget class="QPlainTextEdit" name="installationPage" />
</widget>
</widget>
<customwidgets>
<customwidget>
<class>KTitleWidget</class>
<extends>QWidget</extends>
<header>ktitlewidget.h</header>
</customwidget>
</customwidgets>
</ui>
diff --git a/client/rootcagenerator/controller.cpp b/client/rootcagenerator/controller.cpp
index 3cbae09..4ad4b53 100644
--- a/client/rootcagenerator/controller.cpp
+++ b/client/rootcagenerator/controller.cpp
@@ -1,326 +1,341 @@
// SPDX-FileCopyrightText: 2023 g10 code GmbH
// SPDX-Contributor: Carl Schwan <carl.schwan@gnupg.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "controller.h"
#include "truststore.h"
#include <QDate>
#include <QDir>
#include <QSaveFile>
#include <QStandardPaths>
#include <QGpgME/ExportJob>
#include <QGpgME/ImportJob>
#include <QGpgME/KeyGenerationJob>
#include <QGpgME/KeyListJob>
#include <QGpgME/Protocol>
#include <Libkleo/Formatting>
#include <Libkleo/KeyParameters>
#include <Libkleo/KeyUsage>
#include <KLocalizedString>
using namespace Qt::StringLiterals;
using namespace Kleo;
using namespace GpgME;
static KeyParameters createRootCaParms()
{
KeyParameters keyParameters(KeyParameters::CMS);
keyParameters.setKeyType(GpgME::Subkey::PubkeyAlgo::AlgoRSA);
keyParameters.setKeyUsage(KeyUsage{KeyUsage::Sign | KeyUsage::Certify});
keyParameters.setDN(u"CN=RootGpgolJs"_s);
keyParameters.setEmail(u"localroot@gpgoljs.local"_s);
keyParameters.setKeyLength(3072);
keyParameters.setExpirationDate(QDate(2060, 10, 10));
keyParameters.setUseRandomSerial();
keyParameters.setControlStatements({u"%no-protection"_s});
return keyParameters;
}
static KeyParameters createTlsCertParms(QLatin1StringView keyGrip)
{
KeyParameters keyParameters(KeyParameters::CMS);
keyParameters.setKeyType(GpgME::Subkey::PubkeyAlgo::AlgoRSA);
keyParameters.setKeyUsage(KeyUsage{KeyUsage::Sign | KeyUsage::Encrypt});
keyParameters.setDN(u"CN=LocalGpgolJs"_s);
keyParameters.setEmail(u"local@gpgoljs.local"_s);
keyParameters.setKeyLength(3072);
keyParameters.setExpirationDate(QDate(2060, 10, 10));
keyParameters.setIssuerDN(u"CN=RootGpgolJs"_s);
keyParameters.setSigningKey(keyGrip);
keyParameters.setUseRandomSerial();
keyParameters.addDomainName(u"localhost"_s);
keyParameters.setControlStatements({u"%no-protection"_s});
return keyParameters;
}
Controller::Controller(QObject *parent)
: KJob(parent)
{
}
QString Controller::caUniqueName() const
{
return u"GPGOL2 CA "_s + QString::fromLatin1(m_ca.issuerSerial());
}
QByteArray Controller::caCert() const
{
return m_publicCA;
}
bool Controller::certificateAlreadyGenerated() const
{
auto certPath = QStandardPaths::locate(QStandardPaths::AppLocalDataLocation, QStringLiteral("certificate.pem"));
return !certPath.isEmpty();
}
void Controller::start()
{
if (certificateAlreadyGenerated()) {
emitResult();
return;
}
auto keyGenerationJob = QGpgME::smime()->keyGenerationJob();
connect(keyGenerationJob, &QGpgME::KeyGenerationJob::result, this, &Controller::slotRootCaCreatedSlot);
keyGenerationJob->start(createRootCaParms().toString());
}
void Controller::slotRootCaCreatedSlot(const GpgME::KeyGenerationResult &result, const QByteArray &pubKeyData, const QString &auditLog)
{
Q_UNUSED(auditLog)
if (result.error().code()) {
setErrorText(result.error().isCanceled() ? i18n("Operation canceled.")
: i18n("Could not create key pair: %1", Formatting::errorAsString(result.error())));
setError(UserDefinedError);
emitResult();
return;
}
auto importJob = QGpgME::smime()->importJob();
connect(importJob, &QGpgME::ImportJob::result, this, &Controller::slotRootCaImportedSlot);
importJob->start(pubKeyData);
}
void Controller::slotRootCaImportedSlot(const GpgME::ImportResult &result, const QString &auditLogAsHtml, const GpgME::Error &auditLogError)
{
Q_UNUSED(auditLogAsHtml)
Q_UNUSED(auditLogError)
- qWarning() << "got root ca imported";
+ Q_EMIT debutOutput(u"Imported root CA"_s);
+
if (result.error().code()) {
setErrorText(result.error().isCanceled() ? i18n("Operation canceled.")
: i18n("Could not create key pair: %1", Formatting::errorAsString(result.error())));
setError(UserDefinedError);
emitResult();
return;
}
// Get the keygrip
auto keyListJob = QGpgME::smime()->keyListJob();
connect(keyListJob, &QGpgME::KeyListJob::result, this, &Controller::slotKeyGripOptained);
keyListJob->start({u"RootGpgolJs"_s}, true);
// Export public key
auto exportJob = QGpgME::smime()->publicKeyExportJob(true);
const auto imports = result.imports();
const auto fingerprint = imports[0].fingerprint();
exportJob->start({QString::fromLatin1(fingerprint)});
connect(exportJob, &QGpgME::ExportJob::result, this, [this](const GpgME::Error &error, const QByteArray &keyData) {
if (error.code()) {
setErrorText(error.isCanceled() ? i18n("Operation canceled.") : i18n("Could not export public key: %1", Formatting::errorAsString(error)));
setError(UserDefinedError);
emitResult();
return;
}
m_publicCA = keyData;
checkFinished();
});
// Export private key
auto exportSecretJob = QGpgME::smime()->secretKeyExportJob(true);
exportSecretJob->start({QString::fromLatin1(fingerprint)});
connect(exportSecretJob, &QGpgME::ExportJob::result, this, [this](const GpgME::Error &error, const QByteArray &keyData) {
if (error.code()) {
setErrorText(error.isCanceled() ? i18n("Operation canceled.") : i18n("Could not export secret key: %1", Formatting::errorAsString(error)));
setError(UserDefinedError);
emitResult();
return;
}
m_secretCA = keyData;
checkFinished();
});
}
void Controller::slotKeyGripOptained(const GpgME::KeyListResult &result,
const std::vector<GpgME::Key> &keys,
const QString &auditLogAsHtml,
const GpgME::Error &auditLogError)
{
- qWarning() << "got key grip";
+ Q_EMIT debutOutput(u"Got the key grip of Root CA"_s);
Q_UNUSED(auditLogAsHtml)
Q_UNUSED(auditLogError)
if (result.error().code()) {
setErrorText(result.error().isCanceled() ? i18n("Operation canceled.") : i18n("Could not get keygrip : %1", Formatting::errorAsString(result.error())));
setError(UserDefinedError);
emitResult();
return;
}
m_ca = keys[0];
auto keyGenerationJob = QGpgME::smime()->keyGenerationJob();
connect(keyGenerationJob, &QGpgME::KeyGenerationJob::result, this, &Controller::slotCertCreatedSlot);
keyGenerationJob->start(createTlsCertParms(QLatin1StringView(keys[0].subkey(0).keyGrip())).toString());
}
void Controller::slotCertCreatedSlot(const GpgME::KeyGenerationResult &result, const QByteArray &pubKeyData, const QString &auditLog)
{
- qWarning() << "created tls cert";
+ Q_EMIT debutOutput(u"TLS certificate created"_s);
Q_UNUSED(auditLog)
if (result.error().code()) {
setErrorText(result.error().isCanceled() ? i18n("Operation canceled.")
: i18n("Could not create key pair for cert: %1", Formatting::errorAsString(result.error())));
setError(UserDefinedError);
emitResult();
return;
}
auto importJob = QGpgME::smime()->importJob();
connect(importJob, &QGpgME::ImportJob::result, this, &Controller::slotCertImportedSlot);
importJob->start(pubKeyData);
}
void Controller::slotCertImportedSlot(const GpgME::ImportResult &result, const QString &auditLogAsHtml, const GpgME::Error &auditLogError)
{
Q_UNUSED(auditLogAsHtml)
Q_UNUSED(auditLogError)
- qWarning() << "got cert imported";
if (result.error().code()) {
setErrorText(result.error().isCanceled() ? i18n("Operation canceled.") : i18n("Could not import cert: %1", Formatting::errorAsString(result.error())));
setError(UserDefinedError);
emitResult();
return;
}
auto keyListJob = QGpgME::smime()->keyListJob();
connect(keyListJob,
&QGpgME::KeyListJob::result,
this,
[this](const GpgME::KeyListResult &result, const std::vector<GpgME::Key> &keys, const QString &auditLogAsHtml, const GpgME::Error &auditLogError) {
m_tls = keys[0];
checkFinished();
});
keyListJob->start({u"RootGpgolJs"_s}, true);
// Export public key
auto exportJob = QGpgME::smime()->publicKeyExportJob(true);
const auto imports = result.imports();
const auto fingerprint = imports[0].fingerprint();
exportJob->start({QString::fromLatin1(fingerprint)});
connect(exportJob, &QGpgME::ExportJob::result, this, [this](const GpgME::Error &error, const QByteArray &keyData) {
if (error.code()) {
setErrorText(error.isCanceled() ? i18n("Operation canceled.") : i18n("Could not export public key: %1", Formatting::errorAsString(error)));
setError(UserDefinedError);
emitResult();
return;
}
m_publicTLS = keyData;
checkFinished();
});
// Export private key
auto exportSecretJob = QGpgME::smime()->secretKeyExportJob(true);
exportSecretJob->start({QString::fromLatin1(fingerprint)});
connect(exportSecretJob, &QGpgME::ExportJob::result, this, [this](const GpgME::Error &error, const QByteArray &keyData) {
if (error.code()) {
setErrorText(error.isCanceled() ? i18n("Operation canceled.") : i18n("Could not export secret key: %1", Formatting::errorAsString(error)));
setError(UserDefinedError);
emitResult();
return;
}
m_secretTLS = keyData;
checkFinished();
});
}
void Controller::checkFinished()
{
if (!m_secretCA.isEmpty() && !m_publicCA.isEmpty() && !m_publicTLS.isEmpty() && !m_secretTLS.isEmpty() && !m_ca.isNull() && !m_tls.isNull()) {
install();
emitResult();
}
}
void Controller::install()
{
auto keyPath = QStandardPaths::locate(QStandardPaths::AppLocalDataLocation, QStringLiteral("certificate-key.pem"));
// Install for gpgol-client
{
auto certPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
- qWarning() << "Installing certificate for gpgol-client in" << certPath;
+ Q_EMIT debutOutput(u"Installing certificate for gpgol-client in "_s + certPath);
QDir dir;
if (!dir.mkpath(certPath)) {
- qWarning() << "Unable to create" << certPath;
+ Q_EMIT debutOutput(u"Unable to create the following path: "_s + certPath);
+ setError(UserDefinedError);
+ emitResult();
+ return;
}
QSaveFile localhostPub(certPath + u"/certificate.pem"_s);
if (localhostPub.open(QIODeviceBase::WriteOnly)) {
localhostPub.write(m_publicTLS);
localhostPub.commit();
} else {
- qWarning() << "no permission to write" << localhostPub.fileName() << dir;
+ Q_EMIT debutOutput(u"No permission to write: "_s + localhostPub.fileName() + u" in "_s + dir.absolutePath());
+ setError(UserDefinedError);
+ emitResult();
+ return;
}
}
// Install for gpgol-server
{
#ifdef Q_OS_WIN
auto certPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + u"/AppData/Local/gpgol-server";
#else
auto certPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + u"/gpgol-server";
#endif
- qWarning() << "Installing certificate for gpgol-server in" << certPath;
+ Q_EMIT debutOutput(u"Installing certificate for gpgol-server in "_s + certPath);
QDir dir;
if (!dir.mkpath(certPath)) {
- qWarning() << "Unable to create" << certPath;
+ Q_EMIT debutOutput(u"Unable to create the following path: "_s + certPath);
+ setError(UserDefinedError);
+ emitResult();
+ return;
}
QSaveFile localhostPub(certPath + u"/certificate.pem"_s);
if (localhostPub.open(QIODeviceBase::WriteOnly)) {
localhostPub.write(m_publicTLS);
localhostPub.commit();
} else {
- qWarning() << "no permission to write" << localhostPub.fileName();
+ Q_EMIT debutOutput(u"No permission to write: "_s + localhostPub.fileName() + u" in "_s + dir.absolutePath());
+ setError(UserDefinedError);
+ emitResult();
+ return;
}
QSaveFile localhostKey(certPath + u"/certificate-key.pem"_s);
if (localhostKey.open(QIODeviceBase::WriteOnly)) {
localhostKey.write(m_secretTLS);
localhostKey.commit();
} else {
- qWarning() << "no permission to write";
+ Q_EMIT debutOutput(u"No permission to write: "_s + localhostKey.fileName() + u" in "_s + dir.absolutePath());
+ setError(UserDefinedError);
+ emitResult();
+ return;
}
}
auto trustStore = TrustStoreFactory::getPlatformTrustStore();
trustStore->install(*this);
}
\ No newline at end of file
diff --git a/client/rootcagenerator/controller.h b/client/rootcagenerator/controller.h
index 6aee332..df59fc9 100644
--- a/client/rootcagenerator/controller.h
+++ b/client/rootcagenerator/controller.h
@@ -1,55 +1,58 @@
// SPDX-FileCopyrightText: 2024 g10 code GmbH
// SPDX-Contributor: Carl Schwan <carl.schwan@gnupg.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <KJob>
#include <gpgme++/importresult.h>
#include <gpgme++/key.h>
#include <gpgme++/keygenerationresult.h>
#include <gpgme++/keylistresult.h>
static const QLatin1StringView ROOT_NAME = QLatin1StringView("rootCA.pem");
class Controller : public KJob
{
Q_OBJECT
public:
explicit Controller(QObject *parent = nullptr);
bool certificateAlreadyGenerated() const;
QString caUniqueName() const;
QByteArray caCert() const;
void start() override;
+Q_SIGNALS:
+ void debutOutput(const QString &output);
+
private:
void slotRootCaCreatedSlot(const GpgME::KeyGenerationResult &result, const QByteArray &request, const QString &auditLog);
void slotRootCaImportedSlot(const GpgME::ImportResult &result, const QString &auditLogAsHtml, const GpgME::Error &auditLogError);
void slotKeyGripOptained(const GpgME::KeyListResult &result,
const std::vector<GpgME::Key> &keys,
const QString &auditLogAsHtml,
const GpgME::Error &auditLogError);
void slotCertCreatedSlot(const GpgME::KeyGenerationResult &result, const QByteArray &request, const QString &auditLog);
void slotCertImportedSlot(const GpgME::ImportResult &result, const QString &auditLogAsHtml, const GpgME::Error &auditLogError);
void checkFinished();
void install();
private:
GpgME::Key m_ca;
QByteArray m_publicCA;
QByteArray m_secretCA;
GpgME::Key m_tls;
QByteArray m_publicTLS;
QByteArray m_secretTLS;
};

File Metadata

Mime Type
text/x-diff
Expires
Mon, May 12, 6:43 PM (1 d, 21 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
5e/ed/3e93be008047356e2c9c7aa983bd

Event Timeline