diff options
Diffstat (limited to 'src/core/GpgCoreInit.cpp')
-rw-r--r-- | src/core/GpgCoreInit.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp index ff9bb231..1735c316 100644 --- a/src/core/GpgCoreInit.cpp +++ b/src/core/GpgCoreInit.cpp @@ -387,6 +387,60 @@ auto DecideGnuPGPath(const QString& default_gnupg_path) -> QString { return default_gnupg_path; } +void EnsureGpgAgentConfHasPinentry(GpgContext& ctx) { + auto pinentry_path = DecidePinentry(); + if (pinentry_path.isEmpty()) { + LOG_W() << "no suitable pinentry found."; + return; + } + + QDir gnupg_dir(ctx.HomeDirectory()); + if (!gnupg_dir.exists()) { + gnupg_dir.mkpath("."); + } + + QString config_path = gnupg_dir.filePath("gpg-agent.conf"); + QFile config_file(config_path); + QStringList lines; + + LOG_D() << "checking pinentry config at:" << gnupg_dir; + + bool has_pinentry_line = false; + if (config_file.exists()) { + if (config_file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&config_file); + while (!in.atEnd()) { + QString line = in.readLine(); + if (line.trimmed().startsWith("pinentry-program")) { + has_pinentry_line = true; + } + lines.append(line); + } + config_file.close(); + } + } + + if (!has_pinentry_line) { + lines.append(QString("pinentry-program %1").arg(pinentry_path)); + if (config_file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream out(&config_file); + for (const QString& line : lines) { + out << line << '\n'; + } + config_file.close(); + LOG_D() << "updated gpg-agent.conf with pinentry:" << pinentry_path; + + // reload configure + GpgAdvancedOperator::GetInstance(ctx.GetChannel()) + .ReloadAllGpgComponents(); + } else { + LOG_W() << "failed to write to gpg-agent.conf"; + } + } else { + LOG_D() << "gpg-agent.conf already contains pinentry-program"; + } +} + auto InitBasicPath() -> bool { auto default_gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>( "core", "gpgme.ctx.gpgconf_path", QString{}); @@ -548,6 +602,7 @@ auto InitGpgFrontendCore(CoreInitArgs args) -> int { return ConvertToChannelObjectPtr<>(SecureCreateUniqueObject<GpgContext>( args, kGpgFrontendDefaultChannel)); }); + if (!default_ctx.Good()) { LOG_E() << "Init GpgME Default Context failed!" << "GpgFrontend cannot start under this situation!"; @@ -557,6 +612,10 @@ auto InitGpgFrontendCore(CoreInitArgs args) -> int { return -1; } +#if defined(__linux__) + EnsureGpgAgentConfHasPinentry(default_ctx); +#endif + Module::UpsertRTValue("core", "env.state.ctx", 1); if (!GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).FlushKeyCache()) { @@ -606,6 +665,10 @@ auto InitGpgFrontendCore(CoreInitArgs args) -> int { continue; } +#if defined(__linux__) + EnsureGpgAgentConfHasPinentry(ctx); +#endif + if (!GpgKeyGetter::GetInstance(ctx.GetChannel()).FlushKeyCache()) { LOG_E() << "gpgme context init key cache failed, index:" << channel_index; |