aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/GpgCoreInit.cpp
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2024-11-22 22:06:30 +0000
committersaturneric <[email protected]>2024-11-22 22:06:30 +0000
commite16e15db09d89a997db73e313b966f95e6c59f56 (patch)
tree4f6be7375b983eda33b5faa37b9c7a3af0a57ed6 /src/core/GpgCoreInit.cpp
parentfix: correct the path to the executable of app image mode (diff)
downloadGpgFrontend-e16e15db09d89a997db73e313b966f95e6c59f56.tar.gz
GpgFrontend-e16e15db09d89a997db73e313b966f95e6c59f56.zip
feat: rewrite core init processes and add env option
Diffstat (limited to 'src/core/GpgCoreInit.cpp')
-rw-r--r--src/core/GpgCoreInit.cpp512
1 files changed, 351 insertions, 161 deletions
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp
index e796738e..8a625f9d 100644
--- a/src/core/GpgCoreInit.cpp
+++ b/src/core/GpgCoreInit.cpp
@@ -89,35 +89,74 @@ auto SearchKeyDatabasePath(const QList<QString>& candidate_paths) -> QString {
return {};
}
-auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool {
- // init gpgme subsystem and get gpgme library version
- Module::UpsertRTValue("core", "gpgme.version",
- QString(gpgme_check_version(nullptr)));
+auto GetDefaultKeyDatabasePath(const QString& gpgconf_path) -> QString {
+ if (gpgconf_path.isEmpty()) return {};
- gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr));
-#ifdef LC_MESSAGES
- gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr));
-#endif
+ QFileInfo info(gpgconf_path);
+ if (!info.exists() || !info.isFile()) return {};
- if (!gpgconf_path.isEmpty()) {
- CheckGpgError(gpgme_set_engine_info(GPGME_PROTOCOL_GPGCONF,
- gpgconf_path.toUtf8(), nullptr));
+ auto* p = new QProcess(QCoreApplication::instance());
+ p->setProgram(info.absoluteFilePath());
+ p->setArguments({"--list-dirs", "homedir"});
+ p->start();
+
+ p->waitForFinished();
+ auto home_path = p->readAll().trimmed();
+ p->deleteLater();
+
+ QFileInfo home_info(home_path);
+ return home_info.absoluteFilePath();
+}
+
+auto InitGpgME() -> bool {
+ const auto* ver = gpgme_check_version(nullptr);
+ if (ver == nullptr) {
+ LOG_E() << "gpgme_check_version() failed, abort...";
+ return false;
+ ;
}
+ Module::UpsertRTValue("core", "gpgme.version", QString(ver));
- if (!gnupg_path.isEmpty()) {
- CheckGpgError(gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP,
- gnupg_path.toUtf8(), nullptr));
+ // require gnupg version > 2.1.0
+ if (gpgme_set_global_flag("require-gnupg", "2.1.0") != 0) {
+ LOG_E() << "gpgme_set_global_flag() with argument 'require-gnupg' failed, "
+ "abort...";
+ return false;
+ }
+
+ if (CheckGpgError(
+ gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr))) !=
+ GPG_ERR_NO_ERROR) {
+ LOG_E() << "gpgme_set_locale() with argument LC_CTYPE failed, abort...";
+ return false;
+ }
+
+#ifdef LC_MESSAGES
+ if (CheckGpgError(gpgme_set_locale(nullptr, LC_MESSAGES,
+ setlocale(LC_MESSAGES, nullptr))) !=
+ GPG_ERR_NO_ERROR) {
+ LOG_E() << "gpgme_set_locale() with argument LC_MESSAGES failed, abort...";
+ return false;
}
+#endif
gpgme_ctx_t p_ctx;
- CheckGpgError(gpgme_new(&p_ctx));
+ if (CheckGpgError(gpgme_new(&p_ctx)) != GPG_ERR_NO_ERROR) {
+ LOG_E() << "gpgme_new() failed, abort...";
+ return false;
+ }
// get engine info
auto* engine_info = gpgme_ctx_get_engine_info(p_ctx);
+ if (engine_info == nullptr) {
+ LOG_E() << "gpgme_ctx_get_engine_info() failed, abort...";
+ return false;
+ }
+
// Check ENV before running
- bool find_openpgp = false;
- bool find_gpgconf = false;
- bool find_cms = false;
+ bool has_gpgconf = false;
+ bool has_openpgp = false;
+ bool has_cms = false;
while (engine_info != nullptr) {
if (strcmp(engine_info->version, "1.0.0") == 0) {
@@ -127,7 +166,7 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool {
switch (engine_info->protocol) {
case GPGME_PROTOCOL_OpenPGP:
- find_openpgp = true;
+ has_openpgp = true;
Module::UpsertRTValue("core", "gpgme.engine.openpgp", 1);
Module::UpsertRTValue("core", "gpgme.ctx.app_path",
@@ -140,21 +179,20 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool {
: engine_info->home_dir));
break;
case GPGME_PROTOCOL_CMS:
- find_cms = true;
+ has_cms = true;
Module::UpsertRTValue("core", "gpgme.engine.cms", 1);
Module::UpsertRTValue("core", "gpgme.ctx.cms_path",
QString(engine_info->file_name));
break;
case GPGME_PROTOCOL_GPGCONF:
- find_gpgconf = true;
+ has_gpgconf = true;
Module::UpsertRTValue("core", "gpgme.engine.gpgconf", 1);
Module::UpsertRTValue("core", "gpgme.ctx.gpgconf_path",
QString(engine_info->file_name));
break;
case GPGME_PROTOCOL_ASSUAN:
-
Module::UpsertRTValue("core", "gpgme.engine.assuan", 1);
Module::UpsertRTValue("core", "gpgme.ctx.assuan_path",
QString(engine_info->file_name));
@@ -178,21 +216,62 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool {
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gnupg_version", QString{"0.0.0"});
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", QString{});
- // conditional check: only support gpg 2.1.x now
- if (!(GFCompareSoftwareVersion(gnupg_version, "2.1.0") >= 0 && find_gpgconf &&
- find_openpgp && find_cms)) {
- FLOG_W("gpgme env check failed, abort");
+ if (!has_gpgconf) {
+ FLOG_E() << "cannot get gpgconf backend engine, abort...";
return false;
}
- Module::UpsertRTValue("core", "env.state.gpgme", 1);
+ if (!has_openpgp) {
+ FLOG_E() << "cannot get openpgp backend engine, abort...";
+ return false;
+ }
+
+ if (!has_cms) {
+ FLOG_E() << "cannot get cms backend engine, abort...";
+ return false;
+ }
+
+ // ensure, and check twice: only support gpg > 2.1.0
+ if (!(GFCompareSoftwareVersion(gnupg_version, "2.1.0") >= 0)) {
+ FLOG_F("gpgme env check failed, abort");
+ return false;
+ }
+
+ return true;
+}
+
+auto RefreshGpgMEBackendEngine(const QString& gpgconf_path,
+ const QString& gnupg_path,
+ const QString& home_path) -> bool {
+ if (!gpgconf_path.isEmpty()) {
+ auto err = CheckGpgError(gpgme_set_engine_info(
+ GPGME_PROTOCOL_GPGCONF, gpgconf_path.toUtf8(), nullptr));
+ if (err != GPG_ERR_NO_ERROR) {
+ LOG_W() << "cannot set gpgconf path of gpgme, fallback using default "
+ "gpgconf path, target gpgconf path:"
+ << gpgconf_path;
+ }
+ }
+
+ if (!gnupg_path.isEmpty()) {
+ auto err = CheckGpgError(gpgme_set_engine_info(
+ GPGME_PROTOCOL_OpenPGP, gnupg_path.toUtf8(), home_path.toUtf8()));
+ if (err != GPG_ERR_NO_ERROR) {
+ LOG_W() << "cannot set gnupg path and home path of gpgme, fallback using "
+ "default gpgconf path, target gnupg path:"
+ << gnupg_path << "target home path: " << home_path;
+ }
+ }
+
return true;
}
-auto GetGnuPGPathByGpgConf(const QString& gnupg_install_fs_path) -> QString {
- auto* process = new QProcess();
- process->setProgram(gnupg_install_fs_path);
+auto GetGnuPGPathByGpgConf(const QString& gpgconf_install_fs_path) -> QString {
+ auto* process = new QProcess(QCoreApplication::instance());
+ process->setProgram(gpgconf_install_fs_path);
process->start();
process->waitForFinished(1000);
auto output_buffer = process->readAllStandardOutput();
@@ -224,36 +303,44 @@ auto GetGnuPGPathByGpgConf(const QString& gnupg_install_fs_path) -> QString {
}
return "";
}
-auto DetectGpgConfPath() -> QString {
+
+auto DecideGpgConfPath(const QString& default_gpgconf_path) -> QString {
auto settings = GlobalSettingStation::GetInstance().GetSettings();
auto use_custom_gnupg_install_path =
settings.value("gnupg/use_custom_gnupg_install_path", false).toBool();
auto custom_gnupg_install_path =
settings.value("gnupg/custom_gnupg_install_path", QString{}).toString();
- QString gnupg_install_fs_path;
+ QString gpgconf_install_fs_path;
// user defined
if (use_custom_gnupg_install_path && !custom_gnupg_install_path.isEmpty()) {
// check gpgconf path
- gnupg_install_fs_path = custom_gnupg_install_path;
+ gpgconf_install_fs_path = custom_gnupg_install_path;
#if defined(_WIN32) || defined(WIN32)
gnupg_install_fs_path += "/gpgconf.exe";
#else
- gnupg_install_fs_path += "/gpgconf";
+ gpgconf_install_fs_path += "/gpgconf";
#endif
- if (!VerifyGpgconfPath(QFileInfo(gnupg_install_fs_path))) {
- LOG_W() << "core loaded custom gpgconf path is illegal: "
- << gnupg_install_fs_path;
- gnupg_install_fs_path = "";
+ if (!VerifyGpgconfPath(QFileInfo(gpgconf_install_fs_path))) {
+ LOG_W() << "the gpgconf path by settings is illegal, path: "
+ << gpgconf_install_fs_path;
+ gpgconf_install_fs_path = "";
}
}
+ if (gpgconf_install_fs_path.isEmpty() &&
+ !default_gpgconf_path.trimmed().isEmpty()) {
+ LOG_I() << "using default gpgconf path found by gpgme: "
+ << default_gpgconf_path;
+ return QFileInfo(default_gpgconf_path).absoluteFilePath();
+ }
+
// custom not found or not defined then fallback to default candidate path
- if (gnupg_install_fs_path.isEmpty()) {
+ if (gpgconf_install_fs_path.isEmpty()) {
// platform detection
#if defined(__APPLE__) && defined(__MACH__)
- gnupg_install_fs_path = SearchGpgconfPath(
+ gpgconf_install_fs_path = SearchGpgconfPath(
{"/usr/local/bin/gpgconf", "/opt/homebrew/bin/gpgconf"});
#elif defined(_WIN32) || defined(WIN32)
gnupg_install_fs_path =
@@ -265,35 +352,118 @@ auto DetectGpgConfPath() -> QString {
#endif
}
- if (!gnupg_install_fs_path.isEmpty()) {
- return QFileInfo(gnupg_install_fs_path).absoluteFilePath();
+ if (!gpgconf_install_fs_path.isEmpty()) {
+ return QFileInfo(gpgconf_install_fs_path).absoluteFilePath();
}
return "";
}
-auto DetectGnuPGPath(QString gpgconf_path) -> QString {
+auto DecideGnuPGPath(const QString& gpgconf_path) -> QString {
return GetGnuPGPathByGpgConf(gpgconf_path);
}
-void InitGpgFrontendCore(CoreInitArgs args) {
- // initialize global register table
- Module::UpsertRTValue("core", "env.state.gpgme", 0);
- Module::UpsertRTValue("core", "env.state.ctx", 0);
- Module::UpsertRTValue("core", "env.state.basic", 0);
- Module::UpsertRTValue("core", "env.state.all", 0);
+auto InitBasicPath() -> bool {
+ auto default_gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+
+ auto default_gnupg_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{});
+
+ LOG_I() << "default gpgconf path found by gpgme: " << default_gpgconf_path;
+ LOG_I() << "default gnupg path found by gpgme: " << default_gnupg_path;
+
+ auto target_gpgconf_path = DecideGpgConfPath(default_gpgconf_path);
+ auto target_gnupg_path = default_gnupg_path;
+ if (target_gpgconf_path != default_gpgconf_path) {
+ target_gnupg_path = DecideGnuPGPath(target_gpgconf_path);
+ }
+ LOG_I() << "gpgconf path used: " << target_gpgconf_path;
+ LOG_I() << "gnupg path provided by gpgconf: " << target_gnupg_path;
- auto gpgconf_install_fs_path = DetectGpgConfPath();
- auto gnupg_install_fs_path = DetectGnuPGPath(gpgconf_install_fs_path);
- LOG_I() << "detected gpgconf path: " << gpgconf_install_fs_path;
- LOG_I() << "detected gnupg path: " << gnupg_install_fs_path;
+ if (target_gpgconf_path.isEmpty()) {
+ LOG_E() << "Cannot find gpgconf!"
+ << "GpgFrontend cannot start under this situation!";
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
+ QCoreApplication::tr("Cannot Find GpgConf"));
+ return false;
+ }
- // initialize library gpgme
- if (!InitGpgME(gpgconf_install_fs_path, gnupg_install_fs_path)) {
+ if (target_gnupg_path.isEmpty()) {
+ LOG_E() << "Cannot find GnuPG by gpgconf!"
+ << "GpgFrontend cannot start under this situation!";
CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
- QCoreApplication::tr("GpgME initiation failed"));
- return;
+ QCoreApplication::tr("Cannot Find GnuPG"));
+ return false;
}
+ auto default_home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.default_database_path", QString{});
+ if (default_home_path.trimmed().isEmpty()) {
+ default_home_path = GetDefaultKeyDatabasePath(target_gpgconf_path);
+ }
+
+ LOG_I() << "home path provided by gpgconf: " << default_home_path;
+ if (default_home_path.isEmpty()) {
+ LOG_E() << "Cannot find default home path by gpgconf!"
+ << "GpgFrontend cannot start under this situation!";
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
+ QCoreApplication::tr("Cannot Find Home Path"));
+ return false;
+ }
+
+ RefreshGpgMEBackendEngine(target_gpgconf_path, target_gnupg_path,
+ default_home_path);
+
+ Module::UpsertRTValue("core", "gpgme.ctx.gpgconf_path",
+ QString(target_gpgconf_path));
+ Module::UpsertRTValue("core", "gpgme.ctx.app_path",
+ QString(target_gnupg_path));
+ Module::UpsertRTValue("core", "gpgme.ctx.default_database_path",
+ QString(default_home_path));
+
+ return true;
+}
+
+auto GetKeyDatabases(QString& default_home_path) -> QList<KeyDatabaseItemSO> {
+ auto key_db_list_so = SettingsObject("key_database_list");
+ auto key_db_list = KeyDatabaseListSO(key_db_list_so);
+ auto key_dbs = key_db_list.key_databases;
+
+ key_dbs.removeIf(
+ [default_home_path](const KeyDatabaseItemSO& key_database) -> bool {
+ return key_database.path == default_home_path;
+ });
+ key_db_list_so.Store(key_db_list.ToJson());
+ return key_dbs;
+}
+
+auto InitGpgFrontendCore(CoreInitArgs args) -> int {
+ // initialize gpgme
+ if (!InitGpgME()) {
+ LOG_E() << "Oops, GpgME init failed!"
+ << "GpgFrontend cannot start under this situation!";
+ Module::UpsertRTValue("core", "env.state.gpgme", -1);
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
+ QCoreApplication::tr("GpgME Initiation Failed"));
+ return -1;
+ }
+
+ Module::UpsertRTValue("core", "env.state.gpgme", 1);
+
+ // decide gpgconf, gnupg and default home path
+ if (!InitBasicPath()) {
+ LOG_E() << "Oops, Basic Path init failed!"
+ << "GpgFrontend cannot start under this situation!";
+ return -1;
+ }
+
+ auto default_gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ auto default_gnupg_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{});
+ auto default_home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.default_database_path", QString{});
+
auto settings = GlobalSettingStation::GetInstance().GetSettings();
// read settings from config file
@@ -313,18 +483,72 @@ void InitGpgFrontendCore(CoreInitArgs args) {
auto restart_all_gnupg_components_on_start =
settings.value("gnupg/restart_gpg_agent_on_start", false).toBool();
- auto key_database_list =
- KeyDatabaseListSO(SettingsObject("key_database_list"));
- const auto key_databases = key_database_list.key_databases;
+ // unit test mode
+ if (!args.unit_test_mode) {
+ Module::UpsertRTValue("core", "env.state.basic", 1);
+ Module::UpsertRTValue("core", "env.state.all", 1);
+ CoreSignalStation::GetInstance()->SignalGoodGnupgEnv();
+ LOG_I() << "Basic ENV Checking Finished";
+ return 0;
+ }
+
+ // load default context
+ auto& default_ctx = GpgFrontend::GpgContext::CreateInstance(
+ kGpgFrontendDefaultChannel, [=]() -> ChannelObjectPtr {
+ GpgFrontend::GpgContextInitArgs args;
+
+ // set key database path
+ if (!default_home_path.isEmpty()) {
+ args.db_name = "DEFAULT";
+ args.db_path = default_home_path;
+ }
+
+ args.offline_mode = forbid_all_gnupg_connection;
+ args.auto_import_missing_key = auto_import_missing_key;
+ args.use_pinentry = use_pinentry_as_password_input_dialog;
+
+ LOG_D() << "gpgme default context at channel 0, key db name:"
+ << args.db_name << "key db path:" << args.db_path;
+
+ return ConvertToChannelObjectPtr<>(SecureCreateUniqueObject<GpgContext>(
+ args, kGpgFrontendDefaultChannel));
+ });
+ if (!default_ctx.Good()) {
+ FLOG_E() << "Init GpgME Default Context failed!"
+ << "GpgFrontend cannot start under this situation!";
+ Module::UpsertRTValue("core", "env.state.ctx", -1);
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
+ QCoreApplication::tr("GpgME Default Context Initiation Failed"));
+ return -1;
+ }
+
+ Module::UpsertRTValue("core", "env.state.ctx", 1);
+
+ if (!GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).FlushKeyCache()) {
+ FLOG_E() << "Init GpgME Default Key Database failed!"
+ << "GpgFrontend cannot start under this situation!";
+ Module::UpsertRTValue("core", "env.state.ctx", -1);
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
+ QCoreApplication::tr("Gpg Default Key Database Initiation Failed"));
+ return -1;
+ };
+
+ Module::UpsertRTValue("core", "env.state.basic", 1);
+ CoreSignalStation::GetInstance()->SignalGoodGnupgEnv();
+ LOG_I() << "Basic ENV Checking Finished";
+
+ auto key_dbs = GetKeyDatabases(default_home_path);
auto* task = new Thread::Task(
[=](const DataObjectPtr&) -> int {
// key database path
QList<KeyDatabaseItemSO> buffered_key_dbs;
+ LOG_I() << "AAAAAA";
+
// try to use user defined key database
- if (!key_databases.empty()) {
- for (const auto& key_database : key_databases) {
+ if (!key_dbs.empty()) {
+ for (const auto& key_database : key_dbs) {
if (VerifyKeyDatabasePath(QFileInfo(key_database.path))) {
auto key_database_fs_path =
QFileInfo(key_database.path).absoluteFilePath();
@@ -335,109 +559,55 @@ void InitGpgFrontendCore(CoreInitArgs args) {
<< key_database.path;
}
}
- } else {
- QString key_database_fs_path;
-
-#if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
- // use user's home path by default
- key_database_fs_path =
- SearchKeyDatabasePath({QDir::home().path() + "/.gnupg"});
-#endif
- if (key_database_fs_path.isEmpty()) {
- key_database_fs_path = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.default_database_path", QString{});
- }
-
- // add the default key database path
- if (!key_database_fs_path.isEmpty()) {
- auto so = SettingsObject("key_database_list");
- auto key_database_list = KeyDatabaseListSO(so);
-
- auto key_database = KeyDatabaseItemSO();
- key_database.name = "Default";
- key_database.path = key_database_fs_path;
- key_database_list.key_databases.append(key_database);
- so.Store(key_database_list.ToJson());
- buffered_key_dbs.append(key_database);
- }
}
- if (args.load_default_gpg_context) {
- int channel_index = kGpgFrontendDefaultChannel;
- for (const auto& key_db : buffered_key_dbs) {
- // init ctx, also checking the basic env
- auto& ctx = GpgFrontend::GpgContext::CreateInstance(
- channel_index, [=]() -> ChannelObjectPtr {
- GpgFrontend::GpgContextInitArgs args;
-
- // set key database path
- if (!key_db.path.isEmpty()) {
- args.db_name = key_db.name;
- args.db_path = key_db.path;
- }
-
- // set custom gnupg path
- if (!gnupg_install_fs_path.isEmpty()) {
- args.gpgconf_path = gnupg_install_fs_path;
- }
-
- args.offline_mode = forbid_all_gnupg_connection;
- args.auto_import_missing_key = auto_import_missing_key;
- args.use_pinentry = use_pinentry_as_password_input_dialog;
-
- LOG_D() << "new gpgme context, channel" << channel_index
- << ", key db name" << args.db_name << "key db path"
- << args.db_path << "";
-
- return ConvertToChannelObjectPtr<>(
- SecureCreateUniqueObject<GpgContext>(args,
- channel_index));
- });
-
- // exit if failed
- if (channel_index == kGpgFrontendDefaultChannel && !ctx.Good()) {
- FLOG_W() << "gnupg default context init error, key database: "
- << key_db.name << "key database path: " << key_db.path;
- CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
- QCoreApplication::tr("GpgME Context initiation failed"));
- return -1;
- }
-
- FLOG_D() << "gnupg context init success, index" << channel_index
- << " key database: " << key_db.name
- << "key database path: " << key_db.path;
-
- channel_index++;
+ int channel_index = kGpgFrontendDefaultChannel + 1;
+ for (const auto& key_db : buffered_key_dbs) {
+ // init ctx, also checking the basic env
+ auto& ctx = GpgFrontend::GpgContext::CreateInstance(
+ channel_index, [=]() -> ChannelObjectPtr {
+ GpgFrontend::GpgContextInitArgs args;
+
+ // set key database path
+ if (!key_db.path.isEmpty()) {
+ args.db_name = key_db.name;
+ args.db_path = key_db.path;
+ }
+
+ args.offline_mode = forbid_all_gnupg_connection;
+ args.auto_import_missing_key = auto_import_missing_key;
+ args.use_pinentry = use_pinentry_as_password_input_dialog;
+
+ LOG_D() << "new gpgme context, channel" << channel_index
+ << ", key db name" << args.db_name << "key db path"
+ << args.db_path << "";
+
+ return ConvertToChannelObjectPtr<>(
+ SecureCreateUniqueObject<GpgContext>(args, channel_index));
+ });
+
+ if (!ctx.Good()) {
+ FLOG_E() << "gpgme context init failed, index:" << channel_index;
+ continue;
}
- Module::UpsertRTValue("core", "env.state.ctx", 1);
- }
- if (args.load_default_gpg_context) {
- // load keys from all key dbs
- for (int channel : GpgContext::GetAllChannelId()) {
- if (!GpgKeyGetter::GetInstance(channel).FlushKeyCache()) {
- CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
- QCoreApplication::tr("Gpg Key Database initiation failed"));
- };
+ if (!GpgKeyGetter::GetInstance(ctx.GetChannel()).FetchKey()) {
+ FLOG_E() << "gpgme context init key cache failed, index:"
+ << channel_index;
+ continue;
}
- }
-
- FLOG_D(
- "basic env checking finished, including gpgme, ctx, and key infos");
- Module::UpsertRTValue("core", "env.state.basic", 1);
- CoreSignalStation::GetInstance()->SignalGoodGnupgEnv();
-
- if (restart_all_gnupg_components_on_start) {
- GpgAdvancedOperator::RestartGpgComponents();
+ channel_index++;
}
+ Module::UpsertRTValue("core", "env.state.all", 1);
+
return 0;
},
- "core_init_task");
+ "core_key_dbs_init_task");
QObject::connect(task, &Thread::Task::SignalTaskEnd, []() {
-
+ LOG_I() << "All Key Database(s) Initialize Finished";
});
// start the thread to check ctx and gnupg state
@@ -445,25 +615,34 @@ void InitGpgFrontendCore(CoreInitArgs args) {
GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
->PostTask(task);
+
+ if (restart_all_gnupg_components_on_start) {
+ GpgAdvancedOperator::RestartGpgComponents();
+ }
+ return 0;
}
void StartMonitorCoreInitializationStatus() {
auto* task = new Thread::Task(
[=](const DataObjectPtr&) -> int {
+ int core_init_state = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "env.state.basic", 0);
for (;;) {
- if (Module::RetrieveRTValueTypedOrDefault<>("core", "env.state.basic",
- 0)) {
- break;
- }
+ if (core_init_state != 0) break;
+ core_init_state = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "env.state.basic", 0);
LOG_D() << "monitor: core env is still initializing, waiting...";
QThread::msleep(15);
}
+ if (core_init_state < 0) return -1;
+
// waiting for module first
+ bool module_init_done =
+ Module::ModuleManager::GetInstance().IsAllModulesRegistered();
for (;;) {
- if (Module::ModuleManager::GetInstance().IsAllModulesRegistered())
- break;
+ if (module_init_done) break;
LOG_D() << "monitor: some modules are still going to be registered, "
"waiting...";
@@ -471,16 +650,27 @@ void StartMonitorCoreInitializationStatus() {
}
LOG_D() << "monitor: good, all module are registered.";
+ int key_db_init_state =
+ Module::RetrieveRTValueTypedOrDefault<>("core", "env.state.all", 0);
+ for (;;) {
+ if (key_db_init_state != 0) break;
+ key_db_init_state = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "env.state.all", 0);
+
+ LOG_D() << "monitor: key dbs are still initializing, waiting...";
+ QThread::msleep(15);
+ }
+ LOG_D() << "monitor: good, all key db are loaded.";
+
LOG_D()
<< "monitor: core is fully initialized, sending signal to ui...";
- Module::UpsertRTValue("core", "env.state.all", 1);
CoreSignalStation::GetInstance()->SignalCoreFullyLoaded();
return 0;
},
"waiting_core_init_task");
QObject::connect(task, &Thread::Task::SignalTaskEnd, [=]() {
- LOG_D() << "monitor task ended, call back to main thead.";
+ LOG_D() << "monitor: monitor task ended, call back to main thead.";
});
// start the thread to check ctx and gnupg state