aboutsummaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/GpgCoreInit.cpp132
-rw-r--r--src/core/function/gpg/GpgContext.cpp34
-rw-r--r--src/core/function/gpg/GpgContext.h1
-rw-r--r--src/core/function/gpg/GpgKeyGetter.cpp1
-rw-r--r--src/core/struct/settings_object/KeyDatabaseItemSO.h56
-rw-r--r--src/core/struct/settings_object/KeyDatabaseListSO.h62
6 files changed, 224 insertions, 62 deletions
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp
index 68acc4cc..d89398e3 100644
--- a/src/core/GpgCoreInit.cpp
+++ b/src/core/GpgCoreInit.cpp
@@ -36,7 +36,9 @@
#include "core/function/gpg/GpgAdvancedOperator.h"
#include "core/function/gpg/GpgContext.h"
#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/model/SettingsObject.h"
#include "core/module/ModuleManager.h"
+#include "core/struct/settings_object/KeyDatabaseListSO.h"
#include "core/thread/Task.h"
#include "core/thread/TaskRunnerGetter.h"
#include "core/utils/CommonUtils.h"
@@ -130,7 +132,7 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool {
Module::UpsertRTValue("core", "gpgme.ctx.gnupg_version",
QString(engine_info->version));
Module::UpsertRTValue(
- "core", "gpgme.ctx.database_path",
+ "core", "gpgme.ctx.default_database_path",
QString(engine_info->home_dir == nullptr ? ""
: engine_info->home_dir));
break;
@@ -298,12 +300,6 @@ void InitGpgFrontendCore(CoreInitArgs args) {
auto auto_import_missing_key =
settings.value("network/auto_import_missing_key", false).toBool();
- auto use_custom_key_database_path =
- settings.value("gnupg/use_custom_key_database_path", false).toBool();
-
- auto custom_key_database_path =
- settings.value("gnupg/custom_key_database_path", QString{}).toString();
-
auto use_pinentry_as_password_input_dialog =
settings
.value("gnupg/use_pinentry_as_password_input_dialog",
@@ -314,65 +310,101 @@ 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;
+
auto* task = new Thread::Task(
[=](const DataObjectPtr&) -> int {
// key database path
- QString key_database_fs_path;
+ QList<KeyDatabaseItemSO> buffered_key_dbs;
// try to use user defined key database
- if (use_custom_key_database_path &&
- !custom_key_database_path.isEmpty()) {
- if (VerifyKeyDatabasePath(QFileInfo(custom_key_database_path))) {
- key_database_fs_path =
- QFileInfo(custom_key_database_path).absoluteFilePath();
- LOG_D() << "use custom gpg key database: " << key_database_fs_path
- << "raw:" << custom_key_database_path;
-
- } else {
- LOG_W() << "custom gpg key database path is not suitable: "
- << key_database_fs_path
- << "raw:" << custom_key_database_path;
+ if (!key_databases.empty()) {
+ for (const auto& key_database : key_databases) {
+ if (VerifyKeyDatabasePath(QFileInfo(key_database.path))) {
+ auto key_database_fs_path =
+ QFileInfo(key_database.path).absoluteFilePath();
+ LOG_D() << "load gpg key database: " << key_database.path;
+ buffered_key_dbs.append(key_database);
+ } else {
+ LOG_W() << "gpg key database path is not suitable: "
+ << 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) {
- // init ctx, also checking the basic env
- auto& ctx = GpgFrontend::GpgContext::CreateInstance(
- kGpgFrontendDefaultChannel, [=]() -> ChannelObjectPtr {
- GpgFrontend::GpgContextInitArgs args;
-
- // set key database path
- if (!key_database_fs_path.isEmpty()) {
- args.db_path = key_database_fs_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;
-
- return ConvertToChannelObjectPtr<>(
- SecureCreateUniqueObject<GpgContext>(
- args, kGpgFrontendDefaultChannel));
- });
-
- // exit if failed
- if (!ctx.Good()) {
- FLOG_W("default gnupg context init error, abort");
- CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
- QCoreApplication::tr("GpgME Context initiation failed"));
- return -1;
+ 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++;
}
Module::UpsertRTValue("core", "env.state.ctx", 1);
}
diff --git a/src/core/function/gpg/GpgContext.cpp b/src/core/function/gpg/GpgContext.cpp
index a661f183..5c5dd813 100644
--- a/src/core/function/gpg/GpgContext.cpp
+++ b/src/core/function/gpg/GpgContext.cpp
@@ -209,13 +209,19 @@ class GpgContext::Impl {
GPGME_KEYLIST_MODE_WITH_TOFU)) == GPG_ERR_NO_ERROR;
}
- static auto set_ctx_openpgp_engine_info(gpgme_ctx_t ctx) -> bool {
+ auto set_ctx_openpgp_engine_info(gpgme_ctx_t ctx) -> bool {
const auto app_path = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.app_path", QString{});
- const auto database_path = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.database_path", QString{});
+ "core", QString("gpgme.ctx.app_path").arg(parent_->GetChannel()),
+ QString{});
- LOG_D() << "ctx set engine info, db path: " << database_path
+ QString database_path;
+ // set custom gpg key db path
+ if (!args_.db_path.isEmpty()) {
+ database_path = args_.db_path;
+ }
+
+ LOG_D() << "ctx set engine info, channel: " << parent_->GetChannel()
+ << ", db name: " << args_.db_name << ", db path: " << args_.db_path
<< ", app path: " << app_path;
auto app_path_buffer = app_path.toUtf8();
@@ -281,17 +287,23 @@ class GpgContext::Impl {
}
}
- // set custom gpg key db path
- if (!args_.db_path.isEmpty()) {
- LOG_D() << "set context database path to" << args_.db_path;
- Module::UpsertRTValue("core", "gpgme.ctx.database_path", args_.db_path);
- }
-
if (!set_ctx_openpgp_engine_info(ctx)) {
FLOG_W("set gpgme context openpgp engine info failed");
return false;
}
+ Module::UpsertRTValue(
+ "core", QString("gpgme.ctx.list.%1.channel").arg(parent_->GetChannel()),
+ parent_->GetChannel());
+ Module::UpsertRTValue(
+ "core",
+ QString("gpgme.ctx.list.%1.database_name").arg(parent_->GetChannel()),
+ args_.db_name);
+ Module::UpsertRTValue(
+ "core",
+ QString("gpgme.ctx.list.%1.database_path").arg(parent_->GetChannel()),
+ args_.db_path);
+
return true;
}
diff --git a/src/core/function/gpg/GpgContext.h b/src/core/function/gpg/GpgContext.h
index 1ff22b8a..f98adde8 100644
--- a/src/core/function/gpg/GpgContext.h
+++ b/src/core/function/gpg/GpgContext.h
@@ -40,6 +40,7 @@ namespace GpgFrontend {
*
*/
struct GpgContextInitArgs {
+ QString db_name; ///<
QString db_path; ///<
bool test_mode = false; ///<
diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp
index af77b067..5d002b0d 100644
--- a/src/core/function/gpg/GpgKeyGetter.cpp
+++ b/src/core/function/gpg/GpgKeyGetter.cpp
@@ -31,7 +31,6 @@
#include <gpg-error.h>
#include <mutex>
-#include <shared_mutex>
#include "core/GpgModel.h"
#include "core/function/gpg/GpgContext.h"
diff --git a/src/core/struct/settings_object/KeyDatabaseItemSO.h b/src/core/struct/settings_object/KeyDatabaseItemSO.h
new file mode 100644
index 00000000..e15165ad
--- /dev/null
+++ b/src/core/struct/settings_object/KeyDatabaseItemSO.h
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2021-2024 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+struct KeyDatabaseItemSO {
+ QString name;
+ QString path;
+
+ KeyDatabaseItemSO() = default;
+
+ explicit KeyDatabaseItemSO(const QJsonObject& j) {
+ if (const auto v = j["name"]; v.isString()) {
+ name = v.toString();
+ }
+ if (const auto v = j["path"]; v.isString()) {
+ path = v.toString();
+ }
+ }
+
+ [[nodiscard]] auto ToJson() const -> QJsonObject {
+ QJsonObject j;
+ j["name"] = name;
+ j["path"] = path;
+ return j;
+ }
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/struct/settings_object/KeyDatabaseListSO.h b/src/core/struct/settings_object/KeyDatabaseListSO.h
new file mode 100644
index 00000000..3e5e1320
--- /dev/null
+++ b/src/core/struct/settings_object/KeyDatabaseListSO.h
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2021-2024 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/struct/settings_object/KeyDatabaseItemSO.h"
+
+namespace GpgFrontend {
+
+struct KeyDatabaseListSO {
+ QList<KeyDatabaseItemSO> key_databases;
+
+ KeyDatabaseListSO() = default;
+
+ explicit KeyDatabaseListSO(const QJsonObject& j) {
+ if (const auto v = j["key_databases"]; v.isArray()) {
+ const QJsonArray j_array = v.toArray();
+ for (const auto& key_database : j_array) {
+ if (key_database.isObject()) {
+ key_databases.append(KeyDatabaseItemSO(key_database.toObject()));
+ }
+ }
+ }
+ }
+
+ auto ToJson() -> QJsonObject {
+ QJsonObject j;
+ auto j_array = QJsonArray();
+ for (const auto& s : key_databases) {
+ j_array.push_back(s.ToJson());
+ }
+ j["key_databases"] = j_array;
+ return j;
+ }
+};
+
+} // namespace GpgFrontend \ No newline at end of file