Skip to content

Commit 46321c6

Browse files
committed
fix: make sure gpg-agent is running after init
1 parent a7ea8e6 commit 46321c6

6 files changed

Lines changed: 103 additions & 31 deletions

File tree

src/core/GpgCoreInit.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -695,16 +695,6 @@ auto InitGpgFrontendCore(CoreInitArgs args) -> int {
695695
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
696696
->PostTask(task);
697697

698-
const auto size = GpgContext::GetAllChannelId().size();
699-
for (auto i = 0; i < size; i++) {
700-
if (!args.unit_test_mode && restart_all_gnupg_components_on_start) {
701-
assert(GpgAdvancedOperator::GetInstance().RestartGpgComponents());
702-
} else {
703-
// ensure gpg-agent is running
704-
assert(GpgAdvancedOperator::GetInstance().LaunchAllGpgComponents());
705-
}
706-
}
707-
708698
return 0;
709699
}
710700

src/core/function/gpg/GpgContext.cpp

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,12 @@ class GpgContext::Impl {
207207
QMap<QString, QString> component_dirs_;
208208

209209
void init(const GpgContextInitArgs &args) {
210-
good_ = default_ctx_initialize(args) && binary_ctx_initialize(args);
210+
// init
211211
get_gpg_conf_dirs();
212+
kill_gpg_agent();
213+
214+
good_ = launch_gpg_agent() && default_ctx_initialize(args) &&
215+
binary_ctx_initialize(args);
212216
}
213217

214218
static auto component_type_to_q_string(GpgComponentType type) -> QString {
@@ -421,6 +425,90 @@ class GpgContext::Impl {
421425
component_dirs_[configuration_name] = configuration_value;
422426
}
423427
}
428+
429+
auto kill_gpg_agent() -> bool {
430+
const auto gpgconf = Module::RetrieveRTValueTypedOrDefault<>(
431+
"core", "gpgme.ctx.gpgconf_path", QString{});
432+
433+
if (gpgconf.trimmed().isEmpty()) {
434+
LOG_E() << "gpgconf path is empty!";
435+
return false;
436+
}
437+
438+
LOG_D() << "get gpgconf path: " << gpgconf;
439+
440+
auto args =
441+
QStringList{"--homedir", QDir::toNativeSeparators(HomeDirectory()),
442+
"--kill", "gpg-agent"};
443+
444+
LOG_E() << "gpgconf kill args: " << args
445+
<< "channel:" << parent_->GetChannel();
446+
447+
QProcess process;
448+
process.setProgram(gpgconf);
449+
process.setArguments(args);
450+
process.setProcessChannelMode(QProcess::MergedChannels);
451+
process.start();
452+
if (!process.waitForFinished(3000)) {
453+
LOG_W() << "timeout executing gpgconf: " << gpgconf << "ags: " << args;
454+
return false;
455+
}
456+
457+
LOG_D() << "try to kill gpg-agent before launch: " << process.exitCode()
458+
<< "output: " << process.readAll();
459+
return process.exitCode() == 0;
460+
}
461+
462+
auto launch_gpg_agent() -> bool {
463+
const auto gpg_agent = Module::RetrieveRTValueTypedOrDefault<>(
464+
"core", "gnupg.components.gpg-agent.path", QString{});
465+
466+
if (gpg_agent.trimmed().isEmpty()) {
467+
LOG_E() << "gpg-agent path is empty!";
468+
return false;
469+
}
470+
471+
LOG_D() << "get gpg-agent path: " << gpg_agent;
472+
QFileInfo info(gpg_agent);
473+
if (!info.exists() || !info.isFile()) {
474+
LOG_E() << "gpg-agent is not exists or is not a binary file!";
475+
return false;
476+
}
477+
478+
auto args =
479+
QStringList{"--homedir", QDir::toNativeSeparators(HomeDirectory()),
480+
"--daemon", "--enable-ssh-support"};
481+
482+
auto pinentry = DecidePinentry();
483+
if (pinentry != nullptr) {
484+
args.append({"--pinentry-program", pinentry});
485+
}
486+
487+
if (parent_->GetChannel() != kGpgFrontendDefaultChannel) {
488+
args.append("--disable-scdaemon");
489+
}
490+
491+
LOG_E() << "gpg-agent start args: " << args
492+
<< "channel:" << parent_->GetChannel();
493+
494+
QProcess process;
495+
process.setProgram(info.absoluteFilePath());
496+
process.setArguments(args);
497+
process.setProcessChannelMode(QProcess::MergedChannels);
498+
499+
process.start();
500+
if (!process.waitForFinished(3000)) {
501+
LOG_W() << "timeout starting gpg-agent daemon: " << gpg_agent
502+
<< "ags: " << args;
503+
return false;
504+
}
505+
506+
QString output = process.readAll();
507+
LOG_D() << "gpg-agent daemon start output:" << output
508+
<< "exit code: " << process.exitCode();
509+
510+
return true;
511+
}
424512
};
425513

426514
GpgContext::GpgContext(int channel)

src/core/utils/GpgUtils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,9 @@ auto GetCanonicalKeyDatabasePath(const QDir& app_path,
294294

295295
QFileInfo info(target_path);
296296
if (!info.exists()) {
297-
LOG_W() << "key database not exists:" << info.canonicalFilePath()
297+
LOG_W() << "key database not exists:" << info.absoluteFilePath()
298298
<< ", making a new directory...";
299-
QDir().mkdir(info.canonicalFilePath());
299+
QDir().mkdir(info.absoluteFilePath());
300300
}
301301

302302
if (VerifyKeyDatabasePath(info)) {

src/init.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,14 +184,12 @@ void ShutdownGlobalBasicEnv(const GFCxtWPtr &p_ctx) {
184184
.toBool();
185185

186186
if (ctx->unit_test_mode || kill_all_gnupg_daemon_at_close) {
187-
const auto size = GpgContext::GetAllChannelId().size();
188-
for (auto i = 0; i < size; i++) {
189-
assert(GpgAdvancedOperator::GetInstance().KillAllGpgComponents());
187+
for (const auto &channel : GpgContext::GetAllChannelId()) {
188+
assert(GpgAdvancedOperator::GetInstance(channel).KillAllGpgComponents());
190189
}
191190
} else if (!ctx->unit_test_mode && clear_gpg_password_cache) {
192-
const auto size = GpgContext::GetAllChannelId().size();
193-
for (auto i = 0; i < size; i++) {
194-
assert(GpgAdvancedOperator::GetInstance().ClearGpgPasswordCache());
191+
for (const auto &channel : GpgContext::GetAllChannelId()) {
192+
assert(GpgAdvancedOperator::GetInstance(channel).ClearGpgPasswordCache());
195193
}
196194
}
197195

src/ui/dialog/controller/SmartCardControllerDialog.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,8 @@ SmartCardControllerDialog::SmartCardControllerDialog(QWidget* parent)
112112

113113
connect(ui_->restartGpgAgentButton, &QPushButton::clicked, this, [=](bool) {
114114
bool ret = true;
115-
const auto size = GpgContext::GetAllChannelId().size();
116-
for (auto i = 0; i < size; i++) {
117-
ret = GpgAdvancedOperator::GetInstance().RestartGpgComponents();
115+
for (const auto& channel : GpgContext::GetAllChannelId()) {
116+
ret = GpgAdvancedOperator::GetInstance(channel).RestartGpgComponents();
118117
if (!ret) break;
119118
}
120119

src/ui/main_window/MainWindowSlotUI.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,8 @@ void MainWindow::SlotGeneralDecryptVerify(bool) {
312312

313313
void MainWindow::slot_clean_gpg_password_cache(bool) {
314314
bool ret = true;
315-
const auto size = GpgContext::GetAllChannelId().size();
316-
for (auto i = 0; i < size; i++) {
317-
ret = GpgAdvancedOperator::GetInstance().ClearGpgPasswordCache();
315+
for (const auto& channel : GpgContext::GetAllChannelId()) {
316+
ret = GpgAdvancedOperator::GetInstance(channel).ClearGpgPasswordCache();
318317
if (!ret) break;
319318
}
320319

@@ -329,9 +328,8 @@ void MainWindow::slot_clean_gpg_password_cache(bool) {
329328

330329
void MainWindow::slot_reload_gpg_components(bool) {
331330
bool ret = true;
332-
const auto size = GpgContext::GetAllChannelId().size();
333-
for (auto i = 0; i < size; i++) {
334-
ret = GpgAdvancedOperator::GetInstance().ReloadAllGpgComponents();
331+
for (const auto& channel : GpgContext::GetAllChannelId()) {
332+
ret = GpgAdvancedOperator::GetInstance(channel).ReloadAllGpgComponents();
335333
if (!ret) break;
336334
}
337335

@@ -348,9 +346,8 @@ void MainWindow::slot_reload_gpg_components(bool) {
348346

349347
void MainWindow::slot_restart_gpg_components(bool) {
350348
bool ret = true;
351-
const auto size = GpgContext::GetAllChannelId().size();
352-
for (auto i = 0; i < size; i++) {
353-
ret = GpgAdvancedOperator::GetInstance().RestartGpgComponents();
349+
for (const auto& channel : GpgContext::GetAllChannelId()) {
350+
ret = GpgAdvancedOperator::GetInstance(channel).RestartGpgComponents();
354351
if (!ret) break;
355352
}
356353

0 commit comments

Comments
 (0)