@@ -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
426514GpgContext::GpgContext (int channel)
0 commit comments