aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2025-04-18 20:13:31 +0000
committersaturneric <[email protected]>2025-04-18 20:13:31 +0000
commit46321c6db1ec2bccdbbc19638584a3dd63cbb49b (patch)
treeba9ca11bfa2af580978738f26b62cb0ca88d662d
parentMerge branch 'develop' (diff)
downloadGpgFrontend-46321c6db1ec2bccdbbc19638584a3dd63cbb49b.tar.gz
GpgFrontend-46321c6db1ec2bccdbbc19638584a3dd63cbb49b.zip
fix: make sure gpg-agent is running after init
-rw-r--r--src/core/GpgCoreInit.cpp10
-rw-r--r--src/core/function/gpg/GpgContext.cpp90
-rw-r--r--src/core/utils/GpgUtils.cpp4
-rw-r--r--src/init.cpp10
-rw-r--r--src/ui/dialog/controller/SmartCardControllerDialog.cpp5
-rw-r--r--src/ui/main_window/MainWindowSlotUI.cpp15
6 files changed, 103 insertions, 31 deletions
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp
index 561c3e24..e556cad4 100644
--- a/src/core/GpgCoreInit.cpp
+++ b/src/core/GpgCoreInit.cpp
@@ -695,16 +695,6 @@ auto InitGpgFrontendCore(CoreInitArgs args) -> int {
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
->PostTask(task);
- const auto size = GpgContext::GetAllChannelId().size();
- for (auto i = 0; i < size; i++) {
- if (!args.unit_test_mode && restart_all_gnupg_components_on_start) {
- assert(GpgAdvancedOperator::GetInstance().RestartGpgComponents());
- } else {
- // ensure gpg-agent is running
- assert(GpgAdvancedOperator::GetInstance().LaunchAllGpgComponents());
- }
- }
-
return 0;
}
diff --git a/src/core/function/gpg/GpgContext.cpp b/src/core/function/gpg/GpgContext.cpp
index ca00c452..76e3df9f 100644
--- a/src/core/function/gpg/GpgContext.cpp
+++ b/src/core/function/gpg/GpgContext.cpp
@@ -207,8 +207,12 @@ class GpgContext::Impl {
QMap<QString, QString> component_dirs_;
void init(const GpgContextInitArgs &args) {
- good_ = default_ctx_initialize(args) && binary_ctx_initialize(args);
+ // init
get_gpg_conf_dirs();
+ kill_gpg_agent();
+
+ good_ = launch_gpg_agent() && default_ctx_initialize(args) &&
+ binary_ctx_initialize(args);
}
static auto component_type_to_q_string(GpgComponentType type) -> QString {
@@ -421,6 +425,90 @@ class GpgContext::Impl {
component_dirs_[configuration_name] = configuration_value;
}
}
+
+ auto kill_gpg_agent() -> bool {
+ const auto gpgconf = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+
+ if (gpgconf.trimmed().isEmpty()) {
+ LOG_E() << "gpgconf path is empty!";
+ return false;
+ }
+
+ LOG_D() << "get gpgconf path: " << gpgconf;
+
+ auto args =
+ QStringList{"--homedir", QDir::toNativeSeparators(HomeDirectory()),
+ "--kill", "gpg-agent"};
+
+ LOG_E() << "gpgconf kill args: " << args
+ << "channel:" << parent_->GetChannel();
+
+ QProcess process;
+ process.setProgram(gpgconf);
+ process.setArguments(args);
+ process.setProcessChannelMode(QProcess::MergedChannels);
+ process.start();
+ if (!process.waitForFinished(3000)) {
+ LOG_W() << "timeout executing gpgconf: " << gpgconf << "ags: " << args;
+ return false;
+ }
+
+ LOG_D() << "try to kill gpg-agent before launch: " << process.exitCode()
+ << "output: " << process.readAll();
+ return process.exitCode() == 0;
+ }
+
+ auto launch_gpg_agent() -> bool {
+ const auto gpg_agent = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gnupg.components.gpg-agent.path", QString{});
+
+ if (gpg_agent.trimmed().isEmpty()) {
+ LOG_E() << "gpg-agent path is empty!";
+ return false;
+ }
+
+ LOG_D() << "get gpg-agent path: " << gpg_agent;
+ QFileInfo info(gpg_agent);
+ if (!info.exists() || !info.isFile()) {
+ LOG_E() << "gpg-agent is not exists or is not a binary file!";
+ return false;
+ }
+
+ auto args =
+ QStringList{"--homedir", QDir::toNativeSeparators(HomeDirectory()),
+ "--daemon", "--enable-ssh-support"};
+
+ auto pinentry = DecidePinentry();
+ if (pinentry != nullptr) {
+ args.append({"--pinentry-program", pinentry});
+ }
+
+ if (parent_->GetChannel() != kGpgFrontendDefaultChannel) {
+ args.append("--disable-scdaemon");
+ }
+
+ LOG_E() << "gpg-agent start args: " << args
+ << "channel:" << parent_->GetChannel();
+
+ QProcess process;
+ process.setProgram(info.absoluteFilePath());
+ process.setArguments(args);
+ process.setProcessChannelMode(QProcess::MergedChannels);
+
+ process.start();
+ if (!process.waitForFinished(3000)) {
+ LOG_W() << "timeout starting gpg-agent daemon: " << gpg_agent
+ << "ags: " << args;
+ return false;
+ }
+
+ QString output = process.readAll();
+ LOG_D() << "gpg-agent daemon start output:" << output
+ << "exit code: " << process.exitCode();
+
+ return true;
+ }
};
GpgContext::GpgContext(int channel)
diff --git a/src/core/utils/GpgUtils.cpp b/src/core/utils/GpgUtils.cpp
index d8f147bb..c8f58889 100644
--- a/src/core/utils/GpgUtils.cpp
+++ b/src/core/utils/GpgUtils.cpp
@@ -294,9 +294,9 @@ auto GetCanonicalKeyDatabasePath(const QDir& app_path,
QFileInfo info(target_path);
if (!info.exists()) {
- LOG_W() << "key database not exists:" << info.canonicalFilePath()
+ LOG_W() << "key database not exists:" << info.absoluteFilePath()
<< ", making a new directory...";
- QDir().mkdir(info.canonicalFilePath());
+ QDir().mkdir(info.absoluteFilePath());
}
if (VerifyKeyDatabasePath(info)) {
diff --git a/src/init.cpp b/src/init.cpp
index 3d1f344b..312198a7 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -184,14 +184,12 @@ void ShutdownGlobalBasicEnv(const GFCxtWPtr &p_ctx) {
.toBool();
if (ctx->unit_test_mode || kill_all_gnupg_daemon_at_close) {
- const auto size = GpgContext::GetAllChannelId().size();
- for (auto i = 0; i < size; i++) {
- assert(GpgAdvancedOperator::GetInstance().KillAllGpgComponents());
+ for (const auto &channel : GpgContext::GetAllChannelId()) {
+ assert(GpgAdvancedOperator::GetInstance(channel).KillAllGpgComponents());
}
} else if (!ctx->unit_test_mode && clear_gpg_password_cache) {
- const auto size = GpgContext::GetAllChannelId().size();
- for (auto i = 0; i < size; i++) {
- assert(GpgAdvancedOperator::GetInstance().ClearGpgPasswordCache());
+ for (const auto &channel : GpgContext::GetAllChannelId()) {
+ assert(GpgAdvancedOperator::GetInstance(channel).ClearGpgPasswordCache());
}
}
diff --git a/src/ui/dialog/controller/SmartCardControllerDialog.cpp b/src/ui/dialog/controller/SmartCardControllerDialog.cpp
index 797fe052..ba142305 100644
--- a/src/ui/dialog/controller/SmartCardControllerDialog.cpp
+++ b/src/ui/dialog/controller/SmartCardControllerDialog.cpp
@@ -112,9 +112,8 @@ SmartCardControllerDialog::SmartCardControllerDialog(QWidget* parent)
connect(ui_->restartGpgAgentButton, &QPushButton::clicked, this, [=](bool) {
bool ret = true;
- const auto size = GpgContext::GetAllChannelId().size();
- for (auto i = 0; i < size; i++) {
- ret = GpgAdvancedOperator::GetInstance().RestartGpgComponents();
+ for (const auto& channel : GpgContext::GetAllChannelId()) {
+ ret = GpgAdvancedOperator::GetInstance(channel).RestartGpgComponents();
if (!ret) break;
}
diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp
index 6b945beb..b6e7b3e4 100644
--- a/src/ui/main_window/MainWindowSlotUI.cpp
+++ b/src/ui/main_window/MainWindowSlotUI.cpp
@@ -312,9 +312,8 @@ void MainWindow::SlotGeneralDecryptVerify(bool) {
void MainWindow::slot_clean_gpg_password_cache(bool) {
bool ret = true;
- const auto size = GpgContext::GetAllChannelId().size();
- for (auto i = 0; i < size; i++) {
- ret = GpgAdvancedOperator::GetInstance().ClearGpgPasswordCache();
+ for (const auto& channel : GpgContext::GetAllChannelId()) {
+ ret = GpgAdvancedOperator::GetInstance(channel).ClearGpgPasswordCache();
if (!ret) break;
}
@@ -329,9 +328,8 @@ void MainWindow::slot_clean_gpg_password_cache(bool) {
void MainWindow::slot_reload_gpg_components(bool) {
bool ret = true;
- const auto size = GpgContext::GetAllChannelId().size();
- for (auto i = 0; i < size; i++) {
- ret = GpgAdvancedOperator::GetInstance().ReloadAllGpgComponents();
+ for (const auto& channel : GpgContext::GetAllChannelId()) {
+ ret = GpgAdvancedOperator::GetInstance(channel).ReloadAllGpgComponents();
if (!ret) break;
}
@@ -348,9 +346,8 @@ void MainWindow::slot_reload_gpg_components(bool) {
void MainWindow::slot_restart_gpg_components(bool) {
bool ret = true;
- const auto size = GpgContext::GetAllChannelId().size();
- for (auto i = 0; i < size; i++) {
- ret = GpgAdvancedOperator::GetInstance().RestartGpgComponents();
+ for (const auto& channel : GpgContext::GetAllChannelId()) {
+ ret = GpgAdvancedOperator::GetInstance(channel).RestartGpgComponents();
if (!ret) break;
}