Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F23020826
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
29 KB
Subscribers
None
View Options
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
Details
Attached
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
Attached To
rOJ GpgOL.js
Event Timeline
Log In to Comment