diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/GpgCoreInit.cpp | 132 | ||||
-rw-r--r-- | src/core/function/gpg/GpgContext.cpp | 34 | ||||
-rw-r--r-- | src/core/function/gpg/GpgContext.h | 1 | ||||
-rw-r--r-- | src/core/function/gpg/GpgKeyGetter.cpp | 1 | ||||
-rw-r--r-- | src/core/struct/settings_object/KeyDatabaseItemSO.h | 56 | ||||
-rw-r--r-- | src/core/struct/settings_object/KeyDatabaseListSO.h | 62 |
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 |