diff options
author | saturneric <[email protected]> | 2025-04-18 20:13:31 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2025-04-18 20:13:31 +0000 |
commit | 46321c6db1ec2bccdbbc19638584a3dd63cbb49b (patch) | |
tree | ba9ca11bfa2af580978738f26b62cb0ca88d662d | |
parent | Merge branch 'develop' (diff) | |
download | GpgFrontend-46321c6db1ec2bccdbbc19638584a3dd63cbb49b.tar.gz GpgFrontend-46321c6db1ec2bccdbbc19638584a3dd63cbb49b.zip |
fix: make sure gpg-agent is running after init
-rw-r--r-- | src/core/GpgCoreInit.cpp | 10 | ||||
-rw-r--r-- | src/core/function/gpg/GpgContext.cpp | 90 | ||||
-rw-r--r-- | src/core/utils/GpgUtils.cpp | 4 | ||||
-rw-r--r-- | src/init.cpp | 10 | ||||
-rw-r--r-- | src/ui/dialog/controller/SmartCardControllerDialog.cpp | 5 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowSlotUI.cpp | 15 |
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; } |