aboutsummaryrefslogtreecommitdiffstats
path: root/src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp')
-rw-r--r--src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp526
1 files changed, 0 insertions, 526 deletions
diff --git a/src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp b/src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp
deleted file mode 100644
index 8d400c89..00000000
--- a/src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp
+++ /dev/null
@@ -1,526 +0,0 @@
-/**
- * Copyright (C) 2021 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
- *
- */
-
-#include "GnuPGInfoGatheringModule.h"
-
-#include <GFSDKBasic.h>
-#include <GFSDKBuildInfo.h>
-#include <GFSDKLog.h>
-#include <spdlog/spdlog.h>
-
-// qt
-#include <QCryptographicHash>
-#include <QFileInfo>
-#include <QJsonDocument>
-#include <QString>
-
-// c++
-#include <optional>
-
-#include "GpgInfo.h"
-
-template <>
-struct fmt::formatter<QString> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QString &qstr, FormatContext &ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- QByteArray utf8_array = qstr.toUtf8();
- return fmt::format_to(ctx.out(), "{}", utf8_array.constData());
- }
-};
-
-template <>
-struct fmt::formatter<QByteArray> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QByteArray &qarray, FormatContext &ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- return fmt::format_to(ctx.out(), "{}", qarray.constData());
- }
-};
-
-extern auto CalculateBinaryChacksum(const QString &path)
- -> std::optional<QString>;
-
-extern void GetGpgComponentInfos(void *, int, const char *, const char *);
-
-extern void GetGpgDirectoryInfos(void *, int, const char *, const char *);
-
-extern void GetGpgOptionInfos(void *, int, const char *, const char *);
-
-using Context = struct {
- QString gpgme_version;
- QString gpgconf_path;
- GpgComponentInfo component_info;
-};
-
-auto GFGetModuleGFSDKVersion() -> const char * {
- return GFModuleStrDup(GF_SDK_VERSION_STR);
-}
-
-auto GFGetModuleQtEnvVersion() -> const char * {
- return GFModuleStrDup(QT_VERSION_STR);
-}
-
-auto GFGetModuleID() -> const char * {
- return GFModuleStrDup("com.bktus.gpgfrontend.module.gnupg_info_gathering");
-}
-
-auto GFGetModuleVersion() -> const char * { return GFModuleStrDup("1.0.0"); }
-
-auto GFGetModuleMetaData() -> GFModuleMetaData * {
- auto *p_meta = static_cast<GFModuleMetaData *>(
- GFAllocateMemory(sizeof(GFModuleMetaData)));
- auto *h_meta = p_meta;
-
- p_meta->key = "Name";
- p_meta->value = "GatherGnupgInfo";
- p_meta->next = static_cast<GFModuleMetaData *>(
- GFAllocateMemory(sizeof(GFModuleMetaData)));
- p_meta = p_meta->next;
-
- p_meta->key = "Description";
- p_meta->value = "Try gathering gnupg informations";
- p_meta->next = static_cast<GFModuleMetaData *>(
- GFAllocateMemory(sizeof(GFModuleMetaData)));
- p_meta = p_meta->next;
-
- p_meta->key = "Author";
- p_meta->value = "Saturneric";
- p_meta->next = nullptr;
- return h_meta;
-}
-
-auto GFRegisterModule() -> int {
- GFModuleLogDebug("gnupg info gathering module registering");
- return 0;
-}
-
-auto GFActiveModule() -> int {
- GFModuleLogDebug("gnupg info gathering module activating");
- GFModuleListenEvent(GFGetModuleID(),
- GFModuleStrDup("REQUEST_GATHERING_GNUPG_INFO"));
- return 0;
-}
-
-auto GFExecuteModule(GFModuleEvent *event) -> int {
- GFModuleLogDebug(
- fmt::format("gnupg info gathering module executing, event id: {}",
- event->id)
- .c_str());
-
- GFModuleLogDebug("start to load extra info at module gnupginfogathering...");
-
- const auto *const gpgme_version = GFModuleRetrieveRTValueOrDefault(
- GFModuleStrDup("core"), GFModuleStrDup("gpgme.version"),
- GFModuleStrDup("0.0.0"));
- GFModuleLogDebug(
- fmt::format("got gpgme version from rt: {}", gpgme_version).c_str());
-
- const auto *const gpgconf_path = GFModuleRetrieveRTValueOrDefault(
- GFModuleStrDup("core"), GFModuleStrDup("gpgme.ctx.gpgconf_path"),
- GFModuleStrDup(""));
- GFModuleLogDebug(
- fmt::format("got gpgconf path from rt: {}", gpgconf_path).c_str());
-
- auto context = Context{gpgme_version, gpgconf_path};
-
- // get all components
- const char *argv[] = {GFModuleStrDup("--list-components")};
- GFExecuteCommandSync(gpgconf_path, 1, argv, GetGpgComponentInfos, &context);
- GFModuleLogDebug("load gnupg component info done.");
-
-#ifdef QT5_BUILD
- QVector<GFCommandExecuteContext> exec_contexts;
-#else
- QList<GFCommandExecuteContext> exec_contexts;
-#endif
-
- const char **argv_0 =
- static_cast<const char **>(GFAllocateMemory(sizeof(const char *)));
- argv_0[0] = GFModuleStrDup("--list-dirs");
-
- exec_contexts.push_back(
- {gpgconf_path, 1, argv_0, GetGpgDirectoryInfos, nullptr});
-
- char **components_c_array;
- int ret = GFModuleListRTChildKeys(
- GFGetModuleID(), GFModuleStrDup("gnupg.components"), &components_c_array);
- if (components_c_array == nullptr || ret == 0) return -1;
-
- QStringList components;
- auto *p_a = components_c_array;
- for (int i = 0; i < ret; i++) components.append(QString::fromUtf8(p_a[i]));
-
- for (const auto &component : components) {
- const auto *component_info_json = GFModuleRetrieveRTValueOrDefault(
- GFGetModuleID(),
- GFModuleStrDup(QString("gnupg.components.%1").arg(component).toUtf8()),
- nullptr);
-
- if (component_info_json == nullptr) continue;
-
- auto jsonlized_component_info =
- QJsonDocument::fromJson(component_info_json);
- assert(jsonlized_component_info.isObject());
-
- auto component_info = GpgComponentInfo(jsonlized_component_info.object());
- GFModuleLogDebug(fmt::format("gpgconf check options ready, "
- "component: {}",
- component_info.name)
- .c_str());
-
- if (component_info.name == "gpgme" || component_info.name == "gpgconf") {
- continue;
- }
-
- auto *context = new (GFAllocateMemory(sizeof(Context)))
- Context{gpgme_version, gpgconf_path, component_info};
-
- const char **argv_0 =
- static_cast<const char **>(GFAllocateMemory(sizeof(const char *) * 2));
- argv_0[0] = GFModuleStrDup("--list-options"),
- argv_0[1] = GFModuleStrDup(component_info.name.toUtf8());
- exec_contexts.push_back(
- {gpgconf_path, 2, argv_0, GetGpgOptionInfos, context});
- }
-
- GFExecuteCommandBatchSync(static_cast<int32_t>(exec_contexts.size()),
- exec_contexts.constData());
- GFModuleUpsertRTValueBool(GFGetModuleID(),
- GFModuleStrDup("gnupg.gathering_done"), 1);
-
- char **event_argv =
- static_cast<char **>(GFAllocateMemory(sizeof(char **) * 1));
- event_argv[0] = GFModuleStrDup("0");
-
- GFModuleTriggerModuleEventCallback(event, GFGetModuleID(), 1, event_argv);
-
- GFModuleLogDebug("gnupg external info gathering done");
- return 0;
-}
-
-auto GFDeactiveModule() -> int { return 0; }
-
-auto GFUnregisterModule() -> int {
- GFModuleLogDebug("gnupg info gathering module unregistering");
- return 0;
-}
-
-auto CalculateBinaryChacksum(const QString &path) -> std::optional<QString> {
- // check file info and access rights
- QFileInfo info(path);
- if (!info.exists() || !info.isFile() || !info.isReadable()) {
- GFModuleLogError(fmt::format("get info for file {} error, exists: {}",
- info.filePath(), info.exists())
- .c_str());
- return {};
- }
-
- // open and read file
- QFile f(info.filePath());
- if (!f.open(QIODevice::ReadOnly)) {
- GFModuleLogError(fmt::format("open {} to calculate checksum error: {}",
- path.toStdString(),
- f.errorString().toStdString())
- .c_str());
- return {};
- }
-
- QCryptographicHash hash_sha(QCryptographicHash::Sha256);
-
- // read data by chunks
- const qint64 buffer_size = 8192; // Define a suitable buffer size
- while (!f.atEnd()) {
- QByteArray const buffer = f.read(buffer_size);
- if (buffer.isEmpty()) {
- GFModuleLogError(fmt::format("error reading file {} during "
- "checksum calculation",
- path.toStdString())
- .c_str());
- return {};
- }
- hash_sha.addData(buffer);
- }
-
- // close the file
- f.close();
-
- // return the first 6 characters of the SHA-256 hash
- // of the file
- return QString(hash_sha.result().toHex()).left(6);
-}
-
-void GetGpgComponentInfos(void *data, int exit_code, const char *out,
- const char *err) {
- auto *context = reinterpret_cast<Context *>(data);
- auto p_out = QString::fromUtf8(out);
- auto p_err = QString::fromUtf8(err);
-
- GFModuleLogDebug(fmt::format("gpgconf components exit_code: {} "
- "process stdout size: {}",
- exit_code, p_out.size())
- .c_str());
-
- if (exit_code != 0) {
- GFModuleLogError(fmt::format("gpgconf execute error, process "
- "stderr: {}, "
- "process stdout: {}",
- p_err, p_out)
- .c_str());
- return;
- }
-
- std::vector<GpgComponentInfo> component_infos;
- GpgComponentInfo c_i_gpgme;
- c_i_gpgme.name = "gpgme";
- c_i_gpgme.desc = "GPG Made Easy";
- c_i_gpgme.version = context->gpgme_version;
- c_i_gpgme.path = "Embedded In";
- c_i_gpgme.binary_checksum = "/";
-
- GpgComponentInfo c_i_gpgconf;
- c_i_gpgconf.name = "gpgconf";
- c_i_gpgconf.desc = "GPG Configure";
- c_i_gpgconf.version = "/";
- c_i_gpgconf.path = context->gpgconf_path;
- auto gpgconf_binary_checksum = CalculateBinaryChacksum(context->gpgconf_path);
- c_i_gpgconf.binary_checksum =
- (gpgconf_binary_checksum.has_value() ? gpgconf_binary_checksum.value()
- : QString("/"));
-
- component_infos.push_back(c_i_gpgme);
- component_infos.push_back(c_i_gpgconf);
-
- auto const jsonlized_gpgme_component_info = c_i_gpgme.Json();
- auto const jsonlized_gpgconf_component_info = c_i_gpgconf.Json();
- GFModuleUpsertRTValue(
- GFGetModuleID(), GFModuleStrDup("gnupg.components.gpgme"),
- GFModuleStrDup(QJsonDocument(jsonlized_gpgme_component_info).toJson()));
- GFModuleUpsertRTValue(
- GFGetModuleID(), GFModuleStrDup("gnupg.components.gpgconf"),
- GFModuleStrDup(QJsonDocument(jsonlized_gpgconf_component_info).toJson()));
-
- auto line_split_list = p_out.split("\n");
-
- for (const auto &line : line_split_list) {
- auto info_split_list = line.split(":");
-
- if (info_split_list.size() != 3) continue;
-
- auto component_name = info_split_list[0].trimmed();
- auto component_desc = info_split_list[1].trimmed();
- auto component_path = info_split_list[2].trimmed();
-
-#ifdef WINDOWS
- // replace some special substrings on windows
- // platform
- component_path.replace("%3a", ":");
-#endif
-
- auto binary_checksum = CalculateBinaryChacksum(component_path);
-
- GFModuleLogDebug(
- fmt::format("gnupg component name: {} desc: "
- "{} checksum: {} path: {} ",
- component_name, component_desc,
- binary_checksum.has_value() ? binary_checksum.value() : "/",
- component_path)
- .c_str());
-
- QString version = "/";
-
- if (component_name == "gpg") {
- version = GFModuleRetrieveRTValueOrDefault(
- GFModuleStrDup("core"), GFModuleStrDup("gpgme.ctx.gnupg_version"),
- GFModuleStrDup("2.0.0"));
- }
- if (component_name == "gpg-agent") {
- GFModuleUpsertRTValue(GFGetModuleID(),
- GFModuleStrDup("gnupg.gpg_agent_path"),
- GFModuleStrDup(QString(component_path).toUtf8()));
- }
- if (component_name == "dirmngr") {
- GFModuleUpsertRTValue(GFGetModuleID(),
- GFModuleStrDup("gnupg.dirmngr_path"),
- GFModuleStrDup(QString(component_path).toUtf8()));
- }
- if (component_name == "keyboxd") {
- GFModuleUpsertRTValue(GFGetModuleID(),
- GFModuleStrDup("gnupg.keyboxd_path"),
- GFModuleStrDup(QString(component_path).toUtf8()));
- }
-
- {
- GpgComponentInfo c_i;
- c_i.name = component_name;
- c_i.desc = component_desc;
- c_i.version = version;
- c_i.path = component_path;
- c_i.binary_checksum =
- (binary_checksum.has_value() ? binary_checksum.value()
- : QString("/"));
-
- auto const jsonlized_component_info = c_i.Json();
- GFModuleUpsertRTValue(
- GFGetModuleID(),
- GFModuleStrDup(
- QString("gnupg.components.%1").arg(component_name).toUtf8()),
- GFModuleStrDup(QJsonDocument(jsonlized_component_info).toJson()));
-
- component_infos.push_back(c_i);
- }
-
- GFModuleLogDebug("load gnupg component info actually done.");
- }
-}
-
-void GetGpgDirectoryInfos(void *, int exit_code, const char *out,
- const char *err) {
- if (exit_code != 0) return;
-
- auto p_out = QString::fromUtf8(out);
- auto p_err = QString::fromUtf8(err);
- auto line_split_list = p_out.split("\n");
-
- for (const auto &line : line_split_list) {
- auto info_split_list = line.split(":");
- GFModuleLogDebug(fmt::format("gpgconf direcrotries info line: "
- "{} info size: {}",
- line, info_split_list.size())
- .c_str());
-
- if (info_split_list.size() != 2) continue;
-
- auto configuration_name = info_split_list[0].trimmed();
- auto configuration_value = info_split_list[1].trimmed();
-
-#ifdef WINDOWS
- // replace some special substrings on windows
- // platform
- configuration_value.replace("%3a", ":");
-#endif
-
- // record gnupg home path
- if (configuration_name == "homedir") {
- GFModuleUpsertRTValue(GFGetModuleID(), GFModuleStrDup("gnupg.home_path"),
- GFModuleStrDup(configuration_value.toUtf8()));
- }
-
- GFModuleUpsertRTValue(
- GFGetModuleID(),
- GFModuleStrDup(
- QString("gnupg.dirs.%1").arg(configuration_name).toUtf8()),
- GFModuleStrDup(configuration_value.toUtf8()));
- }
-}
-
-void GetGpgOptionInfos(void *data, int exit_code, const char *out,
- const char *err) {
- if (exit_code != 0) return;
-
- auto p_out = QString::fromUtf8(out);
- auto p_err = QString::fromUtf8(err);
- auto *context = reinterpret_cast<Context *>(data);
- auto component_name = context->component_info.name;
-
- GFModuleLogDebug(fmt::format("gpgconf {} avaliable options "
- "exit_code: {} process stdout "
- "size: {} ",
- component_name, exit_code, p_out.size())
- .c_str());
-
- std::vector<GpgOptionsInfo> options_infos;
-
- auto line_split_list = p_out.split("\n");
-
- for (const auto &line : line_split_list) {
- auto info_split_list = line.split(":");
-
- GFModuleLogDebug(fmt::format("component {} avaliable options "
- "line: {} info size: {}",
- component_name, line, info_split_list.size())
- .c_str());
-
- if (info_split_list.size() < 10) continue;
-
- // The format of each line is:
- // name:flags:level:description:type:alt-type:argname:default:argdef:value
-
- auto option_name = info_split_list[0].trimmed();
- auto option_flags = info_split_list[1].trimmed();
- auto option_level = info_split_list[2].trimmed();
- auto option_desc = info_split_list[3].trimmed();
- auto option_type = info_split_list[4].trimmed();
- auto option_alt_type = info_split_list[5].trimmed();
- auto option_argname = info_split_list[6].trimmed();
- auto option_default = info_split_list[7].trimmed();
- auto option_argdef = info_split_list[8].trimmed();
- auto option_value = info_split_list[9].trimmed();
-
- GpgOptionsInfo info;
- info.name = option_name;
- info.flags = option_flags;
- info.level = option_level;
- info.description = option_desc;
- info.type = option_type;
- info.alt_type = option_alt_type;
- info.argname = option_argname;
- info.default_value = option_default;
- info.argdef = option_argdef;
- info.value = option_value;
-
- auto const jsonlized_option_info = info.Json();
- GFModuleUpsertRTValue(
- GFGetModuleID(),
- GFModuleStrDup(QString("gnupg.components.%1.options.%2")
- .arg(component_name)
- .arg(option_name)
- .toUtf8()),
- GFModuleStrDup(QJsonDocument(jsonlized_option_info).toJson()));
- options_infos.push_back(info);
- }
-
- context->~Context();
- GFFreeMemory(context);
-}