aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/function/gpg
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/function/gpg')
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.cpp318
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.h47
-rw-r--r--src/core/function/gpg/GpgBasicOperator.cpp306
-rw-r--r--src/core/function/gpg/GpgBasicOperator.h61
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp371
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.h61
-rw-r--r--src/core/function/gpg/GpgContext.cpp336
-rw-r--r--src/core/function/gpg/GpgContext.h76
-rw-r--r--src/core/function/gpg/GpgFileOpera.cpp540
-rw-r--r--src/core/function/gpg/GpgFileOpera.h158
-rw-r--r--src/core/function/gpg/GpgKeyGetter.cpp278
-rw-r--r--src/core/function/gpg/GpgKeyGetter.h74
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.cpp227
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.h138
-rw-r--r--src/core/function/gpg/GpgKeyManager.cpp239
-rw-r--r--src/core/function/gpg/GpgKeyManager.h60
-rw-r--r--src/core/function/gpg/GpgKeyOpera.cpp439
-rw-r--r--src/core/function/gpg/GpgKeyOpera.h49
-rw-r--r--src/core/function/gpg/GpgUIDOperator.cpp62
-rw-r--r--src/core/function/gpg/GpgUIDOperator.h23
20 files changed, 2182 insertions, 1681 deletions
diff --git a/src/core/function/gpg/GpgAdvancedOperator.cpp b/src/core/function/gpg/GpgAdvancedOperator.cpp
index 2a3bba42..8b60003c 100644
--- a/src/core/function/gpg/GpgAdvancedOperator.cpp
+++ b/src/core/function/gpg/GpgAdvancedOperator.cpp
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2023. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * 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
@@ -20,9 +20,10 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
//
@@ -32,152 +33,189 @@
#include "GpgAdvancedOperator.h"
#include "core/function/gpg/GpgCommandExecutor.h"
-#include "spdlog/spdlog.h"
-
-GpgFrontend::GpgAdvancedOperator::GpgAdvancedOperator(int channel)
- : SingletonFunctionObject(channel) {}
-
-bool GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--reload", "gpg-agent"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- SPDLOG_DEBUG("gpgconf reload exit code: {}", exit_code);
- success = true;
- }
- });
- return success;
+#include "core/module/ModuleManager.h"
+
+void GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache(
+ OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path,
+ {"--reload", "gpg-agent"},
+ [=](int exit_code, const QString & /*p_out*/,
+ const QString & /*p_err*/) {
+ GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--reload"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
- return success;
+void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
+ OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path,
+ {"--reload"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
- bool success = false;
-
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--verbose", "--kill", "all"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- return;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- if (!success) return false;
-
- success &= StartGpgAgent();
-
- success &= StartDirmngr();
-
- success &= StartKeyBoxd();
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path,
+ {"--verbose", "--kill", "all"},
+ [=](int exit_code, const QString &p_out, const QString &p_err) {
+ GF_CORE_LOG_DEBUG("gpgconf --kill all command got exit code: {}",
+ exit_code);
+ bool success = true;
+ if (exit_code != 0) {
+ success = false;
+ GF_CORE_LOG_ERROR(
+ "gpgconf execute error, process stderr: {}, process stdout: {}",
+ p_err, p_out);
+ return;
+ }
+
+ GF_CORE_LOG_DEBUG("gpgconf --kill --all execute result: {}", success);
+ if (!success) {
+ GF_CORE_LOG_ERROR(
+ "restart all component after core initilized failed");
+ Module::UpsertRTValue(
+ "core", "gpg_advanced_operator.restart_gpg_components", false);
+ return;
+ }
+
+ StartGpgAgent([](int err, DataObjectPtr) {
+ if (err >= 0) {
+ Module::UpsertRTValue(
+ "core", "gpg_advanced_operator.restart_gpg_components", true);
+ return;
+ }
+ });
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::ResetConfigures() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--apply-defaults"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::ResetConfigures(OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path,
+ {"--apply-defaults"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf apply-defaults exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartGpgAgent() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgAgentPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start gpg-agent successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("gpg-agent already started");
- } else {
- SPDLOG_ERROR(
- "gpg-agent execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartGpgAgent(OperationCallback cb) {
+ const auto gpg_agent_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.gpg_agent_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg agent path from rt: {}", gpg_agent_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (gpg_agent_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpg agent path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpg_agent_path,
+ {"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartDirmngr() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().DirmngrPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start dirmngr successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("dirmngr already started");
- } else {
- SPDLOG_ERROR(
- "dirmngr execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartDirmngr(OperationCallback cb) {
+ const auto dirmngr_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.dirmngr_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg dirmngr path from rt: {}", dirmngr_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (dirmngr_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid dirmngr path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {dirmngr_path,
+ {"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartKeyBoxd() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().KeyboxdPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start keyboxd successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("keyboxd already started");
- } else {
- SPDLOG_ERROR(
- "keyboxd execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartKeyBoxd(OperationCallback cb) {
+ const auto keyboxd_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.keyboxd_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg keyboxd path from rt: {}", keyboxd_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (keyboxd_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid keyboxd path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {keyboxd_path,
+ {"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
diff --git a/src/core/function/gpg/GpgAdvancedOperator.h b/src/core/function/gpg/GpgAdvancedOperator.h
index 5325020a..d6b57095 100644
--- a/src/core/function/gpg/GpgAdvancedOperator.h
+++ b/src/core/function/gpg/GpgAdvancedOperator.h
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2023. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * 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
@@ -20,42 +20,31 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
//
// Created by eric on 07.01.2023.
//
-#ifndef GPGFRONTEND_GPGADVANCEDOPERATOR_H
-#define GPGFRONTEND_GPGADVANCEDOPERATOR_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
+#include "core/typedef/CoreTypedef.h"
namespace GpgFrontend {
-class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
- : public SingletonFunctionObject<GpgAdvancedOperator> {
+class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator {
public:
/**
- * @brief Construct a new Basic Operator object
- *
- * @param channel Channel corresponding to the context
- */
- explicit GpgAdvancedOperator(
- int channel = SingletonFunctionObject::GetDefaultChannel());
-
- /**
* @brief
*
* @return true
* @return false
*/
- bool ClearGpgPasswordCache();
+ static void ClearGpgPasswordCache(OperationCallback);
/**
* @brief
@@ -63,7 +52,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool ReloadGpgComponents();
+ static void ReloadGpgComponents(OperationCallback);
/**
* @brief
@@ -71,7 +60,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool RestartGpgComponents();
+ static void RestartGpgComponents();
/**
* @brief
@@ -79,7 +68,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool ResetConfigures();
+ static void ResetConfigures(OperationCallback);
/**
* @brief
@@ -87,7 +76,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartGpgAgent();
+ static void StartGpgAgent(OperationCallback);
/**
* @brief
@@ -95,7 +84,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartDirmngr();
+ static void StartDirmngr(OperationCallback);
/**
* @brief
@@ -103,13 +92,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartKeyBoxd();
-
- private:
- GpgContext& ctx_ = GpgContext::GetInstance(
- SingletonFunctionObject::GetChannel()); ///< Corresponding context
+ static void StartKeyBoxd(OperationCallback);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGADVANCEDOPERATOR_H
diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp
index 71f84907..e5916c77 100644
--- a/src/core/function/gpg/GpgBasicOperator.cpp
+++ b/src/core/function/gpg/GpgBasicOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,195 +28,213 @@
#include "GpgBasicOperator.h"
-#include <vector>
+#include <gpg-error.h>
-#include "GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/model/GpgDecryptResult.h"
+#include "core/model/GpgEncryptResult.h"
+#include "core/model/GpgSignResult.h"
+#include "core/model/GpgVerifyResult.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgBasicOperator::GpgBasicOperator(int channel)
- : SingletonFunctionObject<GpgBasicOperator>(channel) {}
-
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Encrypt(
- KeyListPtr keys, GpgFrontend::BypeArrayRef in_buffer,
- GpgFrontend::ByteArrayPtr& out_buffer, GpgFrontend::GpgEncrResult& result) {
- // gpgme_encrypt_result_t e_result;
- gpgme_key_t recipients[keys->size() + 1];
+namespace GpgFrontend {
- int index = 0;
- for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+GpgBasicOperator::GpgBasicOperator(int channel)
+ : SingletonFunctionObject<GpgBasicOperator>(channel) {}
- // Last entry data_in array has to be nullptr
- recipients[keys->size()] = nullptr;
+void GpgBasicOperator::Encrypt(KeyArgsList keys, GFBuffer in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync([=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
- gpgme_error_t err = check_gpg_error(gpgme_op_encrypt(
- ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_));
- std::swap(result, temp_result);
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
- return err;
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Decrypt(
- BypeArrayRef in_buffer, GpgFrontend::ByteArrayPtr& out_buffer,
- GpgFrontend::GpgDecrResult& result) {
- gpgme_error_t err;
-
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
- err = check_gpg_error(gpgme_op_decrypt(ctx_, data_in, data_out));
-
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
-
- auto temp_result = _new_result(gpgme_op_decrypt_result(ctx_));
- std::swap(result, temp_result);
-
- return err;
+void GpgBasicOperator::Decrypt(GFBuffer in_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Verify(
- BypeArrayRef& in_buffer, ByteArrayPtr& sig_buffer,
- GpgVerifyResult& result) const {
- gpgme_error_t err;
-
- GpgData data_in(in_buffer.data(), in_buffer.size());
- GpgData data_out;
-
- if (sig_buffer != nullptr && sig_buffer->size() > 0) {
- GpgData sig_data(sig_buffer->data(), sig_buffer->size());
- err = check_gpg_error(gpgme_op_verify(ctx_, sig_data, data_in, nullptr));
- } else
- err = check_gpg_error(gpgme_op_verify(ctx_, data_in, nullptr, data_out));
-
- auto temp_result = _new_result(gpgme_op_verify_result(ctx_));
- std::swap(result, temp_result);
-
- return err;
+void GpgBasicOperator::Verify(GFBuffer in_buffer, GFBuffer sig_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ if (!sig_buffer.Empty()) {
+ GpgData sig_data(sig_buffer);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_verify", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Sign(
- KeyListPtr signers, BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- gpgme_sig_mode_t mode, GpgSignResult& result) {
- gpgme_error_t err;
-
- // Set Singers of this opera
- SetSigners(*signers);
+void GpgBasicOperator::Sign(KeyArgsList signers, GFBuffer in_buffer,
+ GpgSignMode mode, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (signers.empty()) return GPG_ERR_CANCELED;
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ GpgError err;
- err = check_gpg_error(gpgme_op_sign(ctx_, data_in, data_out, mode));
+ // Set Singers of this opera
+ SetSigners(signers, ascii);
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_result = _new_result(gpgme_op_sign_result(ctx_));
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_sign(ctx, data_in, data_out, mode));
- std::swap(result, temp_result);
-
- return err;
+ data_object->Swap({GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_sign", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgBasicOperator::DecryptVerify(
- BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgDecrResult& decrypt_result, GpgVerifyResult& verify_result) {
- gpgme_error_t err;
-
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
-
- err = check_gpg_error(gpgme_op_decrypt_verify(ctx_, data_in, data_out));
+void GpgBasicOperator::DecryptVerify(GFBuffer in_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_decr_result = _new_result(gpgme_op_decrypt_result(ctx_));
- std::swap(decrypt_result, temp_decr_result);
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
- auto temp_verify_result = _new_result(gpgme_op_verify_result(ctx_));
- std::swap(verify_result, temp_verify_result);
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
- return err;
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgBasicOperator::EncryptSign(
- KeyListPtr keys, KeyListPtr signers, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, GpgEncrResult& encr_result,
- GpgSignResult& sign_result) {
- gpgme_error_t err;
- SetSigners(*signers);
+void GpgBasicOperator::EncryptSign(KeyArgsList keys, KeyArgsList signers,
+ GFBuffer in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty() || signers.empty()) return GPG_ERR_CANCELED;
- // gpgme_encrypt_result_t e_result;
- gpgme_key_t recipients[keys->size() + 1];
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
- // set key for user
- int index = 0;
- for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- // Last entry dataIn array has to be nullptr
- recipients[keys->size()] = nullptr;
+ SetSigners(signers, ascii);
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- // If the last parameter isnt 0, a private copy of data is made
- err = check_gpg_error(gpgme_op_encrypt_sign(
- ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
+}
- auto temp_encr_result = _new_result(gpgme_op_encrypt_result(ctx_));
- swap(encr_result, temp_encr_result);
- auto temp_sign_result = _new_result(gpgme_op_sign_result(ctx_));
- swap(sign_result, temp_sign_result);
+void GpgBasicOperator::SetSigners(const KeyArgsList& signers, bool ascii) {
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
- return err;
-}
+ gpgme_signers_clear(ctx);
-void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) {
- gpgme_signers_clear(ctx_);
for (const GpgKey& key : signers) {
- SPDLOG_DEBUG("key fpr: {}", key.GetFingerprint());
+ GF_CORE_LOG_DEBUG("key fpr: {}", key.GetFingerprint());
if (key.IsHasActualSigningCapability()) {
- SPDLOG_DEBUG("signer");
- auto error = gpgme_signers_add(ctx_, gpgme_key_t(key));
- check_gpg_error(error);
+ GF_CORE_LOG_DEBUG("signer");
+ auto error = gpgme_signers_add(ctx, gpgme_key_t(key));
+ CheckGpgError(error);
}
}
- if (signers.size() != gpgme_signers_count(ctx_))
- SPDLOG_DEBUG("not all signers added");
+ if (signers.size() != gpgme_signers_count(ctx_.DefaultContext()))
+ GF_CORE_LOG_DEBUG("not all signers added");
}
-std::unique_ptr<GpgFrontend::KeyArgsList>
-GpgFrontend::GpgBasicOperator::GetSigners() {
- auto count = gpgme_signers_count(ctx_);
+auto GpgBasicOperator::GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList> {
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+
+ auto count = gpgme_signers_count(ctx);
auto signers = std::make_unique<std::vector<GpgKey>>();
- for (auto i = 0u; i < count; i++) {
- auto key = GpgKey(gpgme_signers_enum(ctx_, i));
+ for (auto i = 0U; i < count; i++) {
+ auto key = GpgKey(gpgme_signers_enum(ctx, i));
signers->push_back(GpgKey(std::move(key)));
}
return signers;
}
-gpg_error_t GpgFrontend::GpgBasicOperator::EncryptSymmetric(
- GpgFrontend::ByteArray& in_buffer, GpgFrontend::ByteArrayPtr& out_buffer,
- GpgFrontend::GpgEncrResult& result) {
- // deepcopy from ByteArray to GpgData
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
-
- gpgme_error_t err = check_gpg_error(gpgme_op_encrypt(
- ctx_, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
-
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
-
- // TODO(Saturneric): maybe a bug of gpgme
- if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
- auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_));
- std::swap(result, temp_result);
- }
-
- return err;
+void GpgBasicOperator::EncryptSymmetric(GFBuffer in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgBasicOperator.h b/src/core/function/gpg/GpgBasicOperator.h
index 696ac9dc..4b1a2688 100644
--- a/src/core/function/gpg/GpgBasicOperator.h
+++ b/src/core/function/gpg/GpgBasicOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,20 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
-#define GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/model/GFBuffer.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -52,19 +53,13 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
int channel = SingletonFunctionObject::GetDefaultChannel());
/**
- * @brief Call the interface provided by gpgme for encryption operation
+ * @brief
*
* All incoming data pointers out_buffer will be replaced with new valid
* values
*
- * @param keys list of public keys
- * @param in_buffer data that needs to be encrypted
- * @param out_buffer encrypted data
- * @param result the result of the operation
- * @return error code
*/
- gpg_error_t Encrypt(KeyListPtr keys, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, GpgEncrResult& result);
+ void Encrypt(KeyArgsList, GFBuffer, bool, const GpgOperationCallback&);
/**
* @brief Call the interface provided by GPGME to symmetrical encryption
@@ -72,10 +67,10 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param in_buffer Data for encryption
* @param out_buffer Encrypted data
* @param result Encrypted results
- * @return gpg_error_t
+ * @return GpgError
*/
- gpg_error_t EncryptSymmetric(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgEncrResult& result);
+ void EncryptSymmetric(GFBuffer in_buffer, bool ascii,
+ const GpgOperationCallback& cb);
/**
*
@@ -90,10 +85,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param sign_result Signature result
* @return
*/
- gpgme_error_t EncryptSign(KeyListPtr keys, KeyListPtr signers,
- BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgEncrResult& encr_result,
- GpgSignResult& sign_result);
+ void EncryptSign(KeyArgsList keys, KeyArgsList signers, GFBuffer in_buffer,
+ bool ascii, const GpgOperationCallback& cb);
/**
* @brief Call the interface provided by gpgme for decryption operation
@@ -103,8 +96,7 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpgme_error_t Decrypt(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgDecrResult& result);
+ void Decrypt(GFBuffer in_buffer, const GpgOperationCallback& cb);
/**
* @brief Call the interface provided by gpgme to perform decryption and
@@ -116,9 +108,7 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param verify_result the result of the verifying operation
* @return error code
*/
- gpgme_error_t DecryptVerify(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgDecrResult& decrypt_result,
- GpgVerifyResult& verify_result);
+ void DecryptVerify(GFBuffer in_buffer, const GpgOperationCallback& cb);
/**
* @brief Call the interface provided by gpgme for verification operation
@@ -128,8 +118,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpgme_error_t Verify(BypeArrayRef in_buffer, ByteArrayPtr& sig_buffer,
- GpgVerifyResult& result) const;
+ void Verify(GFBuffer in_buffer, GFBuffer sig_buffer,
+ const GpgOperationCallback& cb);
/**
* @brief Call the interface provided by gpgme for signing operation
@@ -151,9 +141,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpg_error_t Sign(KeyListPtr signers, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode,
- GpgSignResult& result);
+ void Sign(KeyArgsList signers, GFBuffer in_buffer, GpgSignMode mode,
+ bool ascii, const GpgOperationCallback& cb);
/**
* @brief Set the private key for signatures, this operation is a global
@@ -161,19 +150,17 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
*
* @param keys
*/
- void SetSigners(KeyArgsList& signers);
+ void SetSigners(const KeyArgsList& signers, bool ascii);
/**
* @brief Get a global signature private keys that has been set.
*
* @return Intelligent pointer pointing to the private key list
*/
- std::unique_ptr<KeyArgsList> GetSigners();
+ auto GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList>;
private:
GpgContext& ctx_ = GpgContext::GetInstance(
SingletonFunctionObject::GetChannel()); ///< Corresponding context
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
index 86c47c60..8c994515 100644
--- a/src/core/function/gpg/GpgCommandExecutor.cpp
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,252 +20,231 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgCommandExecutor.h"
-#include "GpgFunctionObject.h"
+#include "core/model/DataObject.h"
+#include "core/module/Module.h"
+#include "core/thread/Task.h"
#include "core/thread/TaskRunnerGetter.h"
-GpgFrontend::GpgCommandExecutor::GpgCommandExecutor(int channel)
- : SingletonFunctionObject<GpgCommandExecutor>(channel) {}
+namespace GpgFrontend {
-void GpgFrontend::GpgCommandExecutor::Execute(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func) {
- SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size());
+auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
+ -> Thread::Task * {
+ const auto &cmd = context.cmd;
+ const auto &arguments = context.arguments;
+ const auto &interact_function = context.int_func;
+ const auto &cmd_executor_callback = context.cb_func;
- Thread::Task::TaskCallback result_callback =
- [](int rtn, Thread::Task::DataObjectPtr data_object) {
- SPDLOG_DEBUG("data object use count: {}", data_object.use_count());
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
+ const QString joined_argument = QStringList::fromVector(arguments).join(" ");
+
+ GF_CORE_LOG_DEBUG("building task: called cmd {} arguments size: {}", cmd,
+ arguments.size());
- auto exit_code = data_object->PopObject<int>();
- auto process_stdout = data_object->PopObject<std::string>();
- auto process_stderr = data_object->PopObject<std::string>();
- auto callback = data_object->PopObject<
- std::function<void(int, std::string, std::string)>>();
+ Thread::Task::TaskCallback result_callback =
+ [cmd, joined_argument](int /*rtn*/, const DataObjectPtr &data_object) {
+ GF_CORE_LOG_DEBUG(
+ "data object args count of cmd executor result callback: {}",
+ data_object->GetObjectSize());
+ if (!data_object->Check<int, QString, GpgCommandExecutorCallback>()) {
+ GF_CORE_LOG_ERROR("data object checking failed");
+ return;
+ }
+
+ auto exit_code = ExtractParams<int>(data_object, 0);
+ auto process_stdout = ExtractParams<QString>(data_object, 1);
+ auto callback =
+ ExtractParams<GpgCommandExecutorCallback>(data_object, 2);
// call callback
- callback(exit_code, process_stdout, process_stderr);
+ GF_CORE_LOG_DEBUG(
+ "calling custom callback from caller of cmd {} {}, "
+ "exit_code: {}",
+ cmd, joined_argument, exit_code);
+ callback(exit_code, process_stdout, {});
};
Thread::Task::TaskRunnable runner =
- [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int {
- SPDLOG_DEBUG("process runner called, data object size: {}",
- data_object->GetObjectSize());
+ [joined_argument](const DataObjectPtr &data_object) -> int {
+ GF_CORE_LOG_DEBUG("process runner called, data object size: {}",
+ data_object->GetObjectSize());
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
+ if (!data_object->Check<QString, QStringList, GpgCommandExecutorInteractor,
+ GpgCommandExecutorCallback>()) {
+ GF_CORE_LOG_ERROR("data object checking failed");
+ return -1;
+ }
// get arguments
- auto cmd = data_object->PopObject<std::string>();
- SPDLOG_DEBUG("get cmd: {}", cmd);
- auto arguments = data_object->PopObject<std::vector<std::string>>();
+ auto cmd = ExtractParams<QString>(data_object, 0);
+ auto arguments = ExtractParams<QStringList>(data_object, 1);
auto interact_func =
- data_object->PopObject<std::function<void(QProcess *)>>();
+ ExtractParams<GpgCommandExecutorInteractor>(data_object, 2);
+ auto callback = ExtractParams<GpgCommandExecutorCallback>(data_object, 3);
+ // create process
auto *cmd_process = new QProcess();
+ // move to current thread
+ //
+ cmd_process->moveToThread(QThread::currentThread());
+ // set process channel mode
+ // this is to make sure we can get all output from stdout and stderr
cmd_process->setProcessChannelMode(QProcess::MergedChannels);
+ cmd_process->setProgram(cmd);
+
+ // set arguments
+ QStringList q_arguments;
+ for (const auto &argument : arguments) {
+ q_arguments.append(argument);
+ }
+ cmd_process->setArguments(q_arguments);
- QObject::connect(cmd_process, &QProcess::started,
- []() -> void { SPDLOG_DEBUG("process started"); });
+ QObject::connect(
+ cmd_process, &QProcess::started, [cmd, joined_argument]() -> void {
+ GF_CORE_LOG_DEBUG(
+ "\n== Process Execute Started ==\nCommand: {}\nArguments: "
+ "{}\n========================",
+ cmd, joined_argument);
+ });
QObject::connect(
cmd_process, &QProcess::readyReadStandardOutput,
[interact_func, cmd_process]() { interact_func(cmd_process); });
- QObject::connect(cmd_process, &QProcess::errorOccurred,
- [=](QProcess::ProcessError error) {
- SPDLOG_ERROR("error in executing command: {} error: {}",
- cmd, error);
- });
QObject::connect(
- cmd_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
- [=](int, QProcess::ExitStatus status) {
- if (status == QProcess::NormalExit)
- SPDLOG_DEBUG(
- "proceess finished, succeed in executing command: {}, exit "
- "status: {}",
- cmd, status);
- else
- SPDLOG_ERROR(
- "proceess finished, error in executing command: {}, exit "
- "status: {}",
- cmd, status);
+ cmd_process, &QProcess::errorOccurred,
+ [=](QProcess::ProcessError error) {
+ GF_CORE_LOG_ERROR(
+ "caught error while executing command: {} {}, error: {}", cmd,
+ joined_argument, error);
});
- cmd_process->setProgram(QString::fromStdString(cmd));
-
- QStringList q_arguments;
- for (const auto &argument : arguments)
- q_arguments.append(QString::fromStdString(argument));
- cmd_process->setArguments(q_arguments);
-
- SPDLOG_DEBUG("process execute ready, cmd: {} {}", cmd,
- q_arguments.join(" ").toStdString());
+ GF_CORE_LOG_DEBUG(
+ "\n== Process Execute Ready ==\nCommand: {}\nArguments: "
+ "{}\n========================",
+ cmd, joined_argument);
cmd_process->start();
cmd_process->waitForFinished();
- std::string process_stdout =
- cmd_process->readAllStandardOutput().toStdString(),
- process_stderr =
- cmd_process->readAllStandardError().toStdString();
+ QString process_stdout = cmd_process->readAllStandardOutput();
int exit_code = cmd_process->exitCode();
+ GF_CORE_LOG_DEBUG(
+ "\n==== Process Execution Summary ====\n"
+ "Command: {}\n"
+ "Arguments: {}\n"
+ "Exit Code: {}\n"
+ "---- Standard Output ----\n"
+ "{}\n"
+ "===============================",
+ cmd, joined_argument, exit_code, process_stdout);
+
cmd_process->close();
cmd_process->deleteLater();
- // transfer result
- SPDLOG_DEBUG("runner append object");
- data_object->AppendObject(std::move(process_stderr));
- data_object->AppendObject(std::move(process_stdout));
- data_object->AppendObject(std::move(exit_code));
- SPDLOG_DEBUG("runner append object done");
-
+ data_object->Swap({exit_code, process_stdout, callback});
return 0;
};
- // data transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
- SPDLOG_DEBUG("executor append object");
- data_object->AppendObject(std::move(callback));
- data_object->AppendObject(std::move(interact_func));
- data_object->AppendObject(std::move(arguments));
- data_object->AppendObject(std::move(std::string{cmd}));
- SPDLOG_DEBUG("executor append object done");
-
- auto *process_task = new GpgFrontend::Thread::Task(
- std::move(runner), fmt::format("Execute/{}", cmd), data_object,
+ return new Thread::Task(
+ std::move(runner), QString("GpgCommamdExecutor(%1){%2}").arg(cmd),
+ TransferParams(cmd, arguments, interact_function, cmd_executor_callback),
std::move(result_callback));
+}
+
+GpgCommandExecutor::ExecuteContext::ExecuteContext(
+ QString cmd, QList<QString> arguments, GpgCommandExecutorCallback callback,
+ Module::TaskRunnerPtr task_runner, GpgCommandExecutorInteractor int_func)
+ : cmd(std::move(cmd)),
+ arguments(std::move(arguments)),
+ cb_func(std::move(callback)),
+ int_func(std::move(int_func)),
+ task_runner(std::move(task_runner)) {}
+
+void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
+ Thread::Task *task = BuildTaskFromExecCtx(context);
QEventLoop looper;
- QObject::connect(process_task, &Thread::Task::SignalTaskEnd, &looper,
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, &looper,
&QEventLoop::quit);
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(process_task);
-
+ Thread::TaskRunnerPtr target_task_runner = nullptr;
+
+ if (context.task_runner != nullptr) {
+ target_task_runner = context.task_runner;
+ } else {
+ target_task_runner =
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
+ }
+ target_task_runner->PostTask(task);
+
+ // to arvoid dead lock issue we need to check if current thread is the same as
+ // target thread. if it is, we can't call exec() because it will block the
+ // current thread.
+ GF_CORE_LOG_TRACE("blocking until gpg command finish...");
// block until task finished
// this is to keep reference vaild until task finished
looper.exec();
}
-void GpgFrontend::GpgCommandExecutor::ExecuteConcurrently(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func) {
- SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size());
-
- Thread::Task::TaskCallback result_callback =
- [](int rtn, Thread::Task::DataObjectPtr data_object) {
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
-
- auto exit_code = data_object->PopObject<int>();
- auto process_stdout = data_object->PopObject<std::string>();
- auto process_stderr = data_object->PopObject<std::string>();
- auto callback = data_object->PopObject<
- std::function<void(int, std::string, std::string)>>();
-
- // call callback
- callback(exit_code, process_stdout, process_stderr);
- };
-
- Thread::Task::TaskRunnable runner =
- [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int {
- SPDLOG_DEBUG("process runner called, data object size: {}",
- data_object->GetObjectSize());
-
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
-
- SPDLOG_DEBUG("runner pop object");
- // get arguments
- auto cmd = data_object->PopObject<std::string>();
- auto arguments = data_object->PopObject<std::vector<std::string>>();
- auto interact_func =
- data_object->PopObject<std::function<void(QProcess *)>>();
- SPDLOG_DEBUG("runner pop object done");
-
- auto *cmd_process = new QProcess();
- cmd_process->setProcessChannelMode(QProcess::MergedChannels);
-
- QObject::connect(cmd_process, &QProcess::started,
- []() -> void { SPDLOG_DEBUG("process started"); });
- QObject::connect(
- cmd_process, &QProcess::readyReadStandardOutput,
- [interact_func, cmd_process]() { interact_func(cmd_process); });
- QObject::connect(cmd_process, &QProcess::errorOccurred,
- [=](QProcess::ProcessError error) {
- SPDLOG_ERROR("error in executing command: {} error: {}",
- cmd, error);
- });
- QObject::connect(
- cmd_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
- [=](int, QProcess::ExitStatus status) {
- if (status == QProcess::NormalExit)
- SPDLOG_DEBUG(
- "proceess finished, succeed in executing command: {}, exit "
- "status: {}",
- cmd, status);
- else
- SPDLOG_ERROR(
- "proceess finished, error in executing command: {}, exit "
- "status: {}",
- cmd, status);
- });
-
- cmd_process->setProgram(QString::fromStdString(cmd));
- cmd_process->setProcessChannelMode(QProcess::SeparateChannels);
-
- QStringList q_arguments;
- for (const auto &argument : arguments)
- q_arguments.append(QString::fromStdString(argument));
- cmd_process->setArguments(q_arguments);
-
- SPDLOG_DEBUG("process start ready, cmd: {} {}", cmd,
- q_arguments.join(" ").toStdString());
-
- cmd_process->start();
- cmd_process->waitForFinished();
-
- std::string process_stdout =
- cmd_process->readAllStandardOutput().toStdString(),
- process_stderr =
- cmd_process->readAllStandardError().toStdString();
- int exit_code = cmd_process->exitCode();
-
- cmd_process->close();
- cmd_process->deleteLater();
-
- // transfer result
- SPDLOG_DEBUG("runner append object");
- data_object->AppendObject(std::move(process_stderr));
- data_object->AppendObject(std::move(process_stdout));
- data_object->AppendObject(std::move(exit_code));
- SPDLOG_DEBUG("runner append object done");
-
- return 0;
- };
-
- // data transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
- data_object->AppendObject(std::move(callback));
- data_object->AppendObject(std::move(interact_func));
- data_object->AppendObject(std::move(arguments));
- data_object->AppendObject(std::move(std::string{cmd}));
-
- auto *process_task = new GpgFrontend::Thread::Task(
- std::move(runner), fmt::format("ExecuteConcurrently/{}", cmd),
- data_object, std::move(result_callback), false);
+void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
+ for (auto &context : contexts) {
+ const auto &cmd = context.cmd;
+ GF_CORE_LOG_INFO("gpg concurrently called cmd {}", cmd);
+
+ Thread::Task *task = BuildTaskFromExecCtx(context);
+
+ if (context.task_runner != nullptr) {
+ context.task_runner->PostTask(task);
+ } else {
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
+ ->PostTask(task);
+ }
+ }
+}
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(process_task);
+void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
+ QEventLoop looper;
+ auto remaining_tasks = contexts.size();
+ Thread::TaskRunnerPtr target_task_runner = nullptr;
+
+ for (auto &context : contexts) {
+ const auto &cmd = context.cmd;
+ GF_CORE_LOG_DEBUG("gpg concurrently called cmd: {}", cmd);
+
+ Thread::Task *task = BuildTaskFromExecCtx(context);
+
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, [&]() {
+ --remaining_tasks;
+ GF_CORE_LOG_DEBUG("remaining tasks: {}", remaining_tasks);
+ if (remaining_tasks <= 0) {
+ GF_CORE_LOG_DEBUG("no remaining task, quit");
+ looper.quit();
+ }
+ });
+
+ if (context.task_runner != nullptr) {
+ target_task_runner = context.task_runner;
+ } else {
+ target_task_runner =
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
+ }
+
+ target_task_runner->PostTask(task);
+ }
+
+ GF_CORE_LOG_TRACE("blocking until concurrent gpg commands finish...");
+ // block until task finished
+ // this is to keep reference vaild until task finished
+ looper.exec();
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgCommandExecutor.h b/src/core/function/gpg/GpgCommandExecutor.h
index da0e7a8b..d161406a 100644
--- a/src/core/function/gpg/GpgCommandExecutor.h
+++ b/src/core/function/gpg/GpgCommandExecutor.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,39 +20,43 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
-#define GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
+#pragma once
-#ifndef WINDOWS
-#include <boost/process.hpp>
-#endif
-
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/thread/Task.h"
+#include "core/module/Module.h"
namespace GpgFrontend {
+using GpgCommandExecutorCallback = std::function<void(int, QString, QString)>;
+using GpgCommandExecutorInteractor = std::function<void(QProcess *)>;
+
/**
* @brief Extra commands related to GPG
*
*/
-class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
- : public SingletonFunctionObject<GpgCommandExecutor> {
+class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor {
public:
- /**
- * @brief Construct a new Gpg Command Executor object
- *
- * @param channel Corresponding context
- */
- explicit GpgCommandExecutor(
- int channel = SingletonFunctionObject::GetDefaultChannel());
+ struct ExecuteContext {
+ QString cmd;
+ QStringList arguments;
+ GpgCommandExecutorCallback cb_func;
+ GpgCommandExecutorInteractor int_func;
+ Module::TaskRunnerPtr task_runner = nullptr;
+
+ ExecuteContext(
+ QString cmd, QStringList arguments,
+ GpgCommandExecutorCallback callback = [](int, const QString &,
+ const QString &) {},
+ Module::TaskRunnerPtr task_runner = nullptr,
+ GpgCommandExecutorInteractor int_func = [](QProcess *) {});
+ };
+
+ using ExecuteContexts = QList<ExecuteContext>;
/**
* @brief Excuting a command
@@ -60,22 +64,11 @@ class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
* @param arguments Command parameters
* @param interact_func Command answering function
*/
- void Execute(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback =
- [](int, std::string, std::string) {},
- std::function<void(QProcess *)> interact_func = [](QProcess *) {});
+ static void ExecuteSync(ExecuteContext);
- void ExecuteConcurrently(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func = [](QProcess *) {});
+ static void ExecuteConcurrentlyAsync(ExecuteContexts);
- private:
- GpgContext &ctx_ = GpgContext::GetInstance(
- SingletonFunctionObject::GetChannel()); ///< Corresponding context
+ static void ExecuteConcurrentlySync(ExecuteContexts);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
diff --git a/src/core/function/gpg/GpgContext.cpp b/src/core/function/gpg/GpgContext.cpp
new file mode 100644
index 00000000..104e254f
--- /dev/null
+++ b/src/core/function/gpg/GpgContext.cpp
@@ -0,0 +1,336 @@
+/**
+ * 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 "core/function/gpg/GpgContext.h"
+
+#include <gpg-error.h>
+#include <gpgme.h>
+
+#include <cassert>
+#include <mutex>
+
+#include "core/function/CoreSignalStation.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/model/GpgPassphraseContext.h"
+#include "core/module/ModuleManager.h"
+#include "core/utils/CacheUtils.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/MemoryUtils.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace GpgFrontend {
+
+class GpgContext::Impl {
+ public:
+ /**
+ * Constructor
+ * Set up gpgme-context, set paths to app-run path
+ */
+ Impl(GpgContext *parent, const GpgContextInitArgs &args)
+ : parent_(parent),
+ args_(args),
+ good_(default_ctx_initialize(args) && binary_ctx_initialize(args)) {}
+
+ ~Impl() {
+ if (ctx_ref_ != nullptr) {
+ gpgme_release(ctx_ref_);
+ }
+
+ if (binary_ctx_ref_ != nullptr) {
+ gpgme_release(binary_ctx_ref_);
+ }
+ }
+
+ [[nodiscard]] auto BinaryContext() const -> gpgme_ctx_t {
+ return binary_ctx_ref_;
+ }
+
+ [[nodiscard]] auto DefaultContext() const -> gpgme_ctx_t { return ctx_ref_; }
+
+ [[nodiscard]] auto Good() const -> bool { return good_; }
+
+ auto SetPassphraseCb(const gpgme_ctx_t &ctx, gpgme_passphrase_cb_t cb)
+ -> bool {
+ if (gpgme_get_pinentry_mode(ctx) != GPGME_PINENTRY_MODE_LOOPBACK) {
+ if (CheckGpgError(gpgme_set_pinentry_mode(
+ ctx, GPGME_PINENTRY_MODE_LOOPBACK)) != GPG_ERR_NO_ERROR) {
+ return false;
+ }
+ }
+ gpgme_set_passphrase_cb(ctx, cb, reinterpret_cast<void *>(parent_));
+ return true;
+ }
+
+ static auto TestPassphraseCb(void *opaque, const char *uid_hint,
+ const char *passphrase_info, int last_was_bad,
+ int fd) -> gpgme_error_t {
+ size_t res;
+ QString pass = "abcdefg\n";
+ auto pass_len = pass.size();
+
+ size_t off = 0;
+
+ do {
+ res = gpgme_io_write(fd, &pass[off], pass_len - off);
+ if (res > 0) off += res;
+ } while (res > 0 && off != pass_len);
+
+ return off == pass_len ? 0 : gpgme_error_from_errno(errno);
+ }
+
+ static auto CustomPassphraseCb(void *hook, const char *uid_hint,
+ const char *passphrase_info, int prev_was_bad,
+ int fd) -> gpgme_error_t {
+ auto context_cache = GetCacheValue("PinentryContext");
+ bool ask_for_new = context_cache == "NEW_PASSPHRASE";
+ auto context =
+ QSharedPointer<GpgPassphraseContext>(new GpgPassphraseContext(
+ uid_hint != nullptr ? uid_hint : "",
+ passphrase_info != nullptr ? passphrase_info : "",
+ prev_was_bad != 0, ask_for_new));
+
+ GF_CORE_LOG_DEBUG(
+ "custom passphrase cb called, uid: {}, info: {}, last_was_bad: {}",
+ uid_hint == nullptr ? "<empty>" : QString{uid_hint},
+ passphrase_info == nullptr ? "<empty>" : QString{passphrase_info},
+ prev_was_bad);
+
+ QEventLoop looper;
+ QObject::connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalUserInputPassphraseCallback,
+ &looper, &QEventLoop::quit);
+
+ emit CoreSignalStation::GetInstance()->SignalNeedUserInputPassphrase(
+ context);
+ looper.exec();
+
+ ResetCacheValue("PinentryContext");
+ auto passphrase = context->GetPassphrase().toStdString();
+ auto passpahrase_size = passphrase.size();
+ GF_CORE_LOG_DEBUG("get passphrase from pinentry size: {}",
+ passpahrase_size);
+
+ size_t res = 0;
+ if (passpahrase_size > 0) {
+ size_t off = 0;
+ do {
+ res = gpgme_io_write(fd, &passphrase[off], passpahrase_size - off);
+ if (res > 0) off += res;
+ } while (res > 0 && off != passpahrase_size);
+ }
+
+ res += gpgme_io_write(fd, "\n", 1);
+
+ GF_CORE_LOG_DEBUG("custom passphrase cd is about to return, res: {}", res);
+ return res == passpahrase_size + 1
+ ? 0
+ : gpgme_error_from_errno(GPG_ERR_CANCELED);
+ }
+
+ static auto TestStatusCb(void *hook, const char *keyword, const char *args)
+ -> gpgme_error_t {
+ GF_CORE_LOG_DEBUG("keyword {}", keyword);
+ return GPG_ERR_NO_ERROR;
+ }
+
+ private:
+ GpgContext *parent_;
+ GpgContextInitArgs args_{}; ///<
+ gpgme_ctx_t ctx_ref_ = nullptr; ///<
+ gpgme_ctx_t binary_ctx_ref_ = nullptr; ///<
+ bool good_ = true;
+ std::mutex ctx_ref_lock_;
+ std::mutex binary_ctx_ref_lock_;
+
+ static auto set_ctx_key_list_mode(const gpgme_ctx_t &ctx) -> bool {
+ assert(ctx != nullptr);
+
+ const auto gpgme_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.version", QString{"0.0.0"});
+ GF_CORE_LOG_DEBUG("got gpgme version version from rt: {}", gpgme_version);
+
+ if (gpgme_get_keylist_mode(ctx) == 0) {
+ GF_CORE_LOG_ERROR(
+ "ctx is not a valid pointer, reported by gpgme_get_keylist_mode");
+ return false;
+ }
+
+ // set keylist mode
+ return CheckGpgError(gpgme_set_keylist_mode(
+ ctx, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_WITH_SECRET |
+ GPGME_KEYLIST_MODE_SIGS |
+ GPGME_KEYLIST_MODE_SIG_NOTATIONS |
+ GPGME_KEYLIST_MODE_WITH_TOFU)) == GPG_ERR_NO_ERROR;
+ }
+
+ static 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{});
+
+ GF_CORE_LOG_DEBUG("ctx set engine info, db path: {}, app path: {}",
+ database_path, app_path);
+
+ auto app_path_buffer = app_path.toUtf8();
+ auto database_path_buffer = database_path.toUtf8();
+
+ auto err = gpgme_ctx_set_engine_info(
+ ctx, gpgme_get_protocol(ctx),
+ app_path.isEmpty() ? nullptr : app_path_buffer,
+ database_path.isEmpty() ? nullptr : database_path_buffer);
+
+ assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
+
+ return true;
+ }
+
+ auto common_ctx_initialize(const gpgme_ctx_t &ctx,
+ const GpgContextInitArgs &args) -> bool {
+ assert(ctx != nullptr);
+
+ if (args.custom_gpgconf && !args.custom_gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_DEBUG("set custom gpgconf path: {}",
+ args.custom_gpgconf_path);
+ auto err =
+ gpgme_ctx_set_engine_info(ctx, GPGME_PROTOCOL_GPGCONF,
+ args.custom_gpgconf_path.toUtf8(), nullptr);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("set gpg context engine info error: {}",
+ DescribeGpgErrCode(err).second);
+ return false;
+ }
+ }
+
+ // set context offline mode
+ GF_CORE_LOG_DEBUG("gpg context offline mode: {}", args_.offline_mode);
+ gpgme_set_offline(ctx, args_.offline_mode ? 1 : 0);
+
+ // set option auto import missing key
+ // invalid at offline mode
+ GF_CORE_LOG_DEBUG("gpg context auto import missing key: {}",
+ args_.offline_mode);
+ if (!args.offline_mode && args.auto_import_missing_key) {
+ if (CheckGpgError(gpgme_set_ctx_flag(ctx, "auto-key-import", "1")) !=
+ GPG_ERR_NO_ERROR) {
+ return false;
+ }
+ }
+
+ if (!set_ctx_key_list_mode(ctx)) {
+ GF_CORE_LOG_DEBUG("set ctx key list mode failed");
+ return false;
+ }
+
+ // for unit test
+ if (args_.test_mode) {
+ if (!SetPassphraseCb(ctx, TestPassphraseCb)) {
+ GF_CORE_LOG_ERROR("set passphrase cb failed, test");
+ return false;
+ };
+ } else if (!args_.use_pinentry) {
+ if (!SetPassphraseCb(ctx, CustomPassphraseCb)) {
+ GF_CORE_LOG_DEBUG("set passphrase cb failed, custom");
+ return false;
+ }
+ }
+
+ // set custom gpg key db path
+ if (!args_.db_path.isEmpty()) {
+ Module::UpsertRTValue("core", "gpgme.ctx.database_path", args_.db_path);
+ }
+
+ if (!set_ctx_openpgp_engine_info(ctx)) {
+ GF_CORE_LOG_ERROR("set gpgme context openpgp engine info failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ auto binary_ctx_initialize(const GpgContextInitArgs &args) -> bool {
+ gpgme_ctx_t p_ctx;
+ if (auto err = CheckGpgError(gpgme_new(&p_ctx)); err != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("get new gpg context error: {}",
+ DescribeGpgErrCode(err).second);
+ return false;
+ }
+ assert(p_ctx != nullptr);
+ binary_ctx_ref_ = p_ctx;
+
+ if (!common_ctx_initialize(binary_ctx_ref_, args)) {
+ GF_CORE_LOG_ERROR("get new ctx failed, binary");
+ return false;
+ }
+
+ gpgme_set_armor(binary_ctx_ref_, 0);
+ return true;
+ }
+
+ auto default_ctx_initialize(const GpgContextInitArgs &args) -> bool {
+ gpgme_ctx_t p_ctx;
+ if (CheckGpgError(gpgme_new(&p_ctx)) != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("get new ctx failed, default");
+ return false;
+ }
+ assert(p_ctx != nullptr);
+ ctx_ref_ = p_ctx;
+
+ if (!common_ctx_initialize(ctx_ref_, args)) {
+ return false;
+ }
+
+ gpgme_set_armor(ctx_ref_, 1);
+ return true;
+ }
+};
+
+GpgContext::GpgContext(int channel)
+ : SingletonFunctionObject<GpgContext>(channel),
+ p_(SecureCreateUniqueObject<Impl>(this, GpgContextInitArgs{})) {}
+
+GpgContext::GpgContext(GpgContextInitArgs args, int channel)
+ : SingletonFunctionObject<GpgContext>(channel),
+ p_(SecureCreateUniqueObject<Impl>(this, args)) {}
+
+auto GpgContext::Good() const -> bool { return p_->Good(); }
+
+auto GpgContext::BinaryContext() -> gpgme_ctx_t { return p_->BinaryContext(); }
+
+auto GpgContext::DefaultContext() -> gpgme_ctx_t {
+ return p_->DefaultContext();
+}
+
+GpgContext::~GpgContext() = default;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgContext.h b/src/core/function/gpg/GpgContext.h
new file mode 100644
index 00000000..d473a341
--- /dev/null
+++ b/src/core/function/gpg/GpgContext.h
@@ -0,0 +1,76 @@
+/**
+ * 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
+ *
+ */
+
+#pragma once
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/GpgFunctionObject.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+struct GpgContextInitArgs {
+ QString db_path = {}; ///<
+
+ bool test_mode = false; ///<
+ bool offline_mode = false; ///<
+ bool auto_import_missing_key = false; ///<
+
+ bool custom_gpgconf = false; ///<
+ QString custom_gpgconf_path; ///<
+
+ bool use_pinentry = false; ///<
+};
+
+/**
+ * @brief
+ *
+ */
+class GPGFRONTEND_CORE_EXPORT GpgContext
+ : public SingletonFunctionObject<GpgContext> {
+ public:
+ explicit GpgContext(int channel);
+
+ explicit GpgContext(GpgContextInitArgs args, int channel);
+
+ virtual ~GpgContext() override;
+
+ [[nodiscard]] auto Good() const -> bool;
+
+ auto BinaryContext() -> gpgme_ctx_t;
+
+ auto DefaultContext() -> gpgme_ctx_t;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp
index 30678cf0..e3d47cf6 100644
--- a/src/core/function/gpg/GpgFileOpera.cpp
+++ b/src/core/function/gpg/GpgFileOpera.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,235 +20,353 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgFileOpera.h"
-#include <memory>
-#include <string>
+#include "core/function/ArchiveFileOperator.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/model/GpgData.h"
+#include "core/model/GpgDecryptResult.h"
+#include "core/model/GpgEncryptResult.h"
+#include "core/model/GpgKey.h"
+#include "core/model/GpgSignResult.h"
+#include "core/model/GpgVerifyResult.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-#include "GpgBasicOperator.h"
-#include "GpgConstants.h"
-#include "function/FileOperator.h"
+namespace GpgFrontend {
-GpgFrontend::GpgFileOpera::GpgFileOpera(int channel)
+constexpr ssize_t kDataExchangerSize = 8192;
+
+GpgFileOpera::GpgFileOpera(int channel)
: SingletonFunctionObject<GpgFileOpera>(channel) {}
-GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile(
- KeyListPtr keys, const std::string& in_path, const std::string& out_path,
- GpgEncrResult& result, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer = nullptr;
-
- auto err = GpgBasicOperator::GetInstance(_channel).Encrypt(
- std::move(keys), in_buffer, out_buffer, result);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+void GpgFileOpera::EncryptFile(std::vector<GpgKey> keys, const QString& in_path,
+ bool ascii, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile(
- const std::string& in_path, const std::string& out_path,
- GpgDecrResult& result) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer;
-
- auto err =
- GpgBasicOperator::GetInstance().Decrypt(in_buffer, out_buffer, result);
-
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+void GpgFileOpera::EncryptDirectory(std::vector<GpgKey> keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ GF_CORE_LOG_DEBUG("encrypt directory start");
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
+
+ GF_CORE_LOG_DEBUG("encrypt directory finished, err: {}", err);
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 data exchanger operation, err: {}",
+ err);
+ });
+}
+
+void GpgFileOpera::DecryptFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))});
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
+}
+
+void GpgFileOpera::DecryptArchive(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ ArchiveFileOperator::ExtractArchiveFromDataExchanger(
+ ex, out_path, [](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG(
+ "extract archive from data exchanger operation, err: {}", err);
+ });
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(ex);
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))});
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys,
- const std::string& in_path,
- const std::string& out_path,
- GpgSignResult& result,
- int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer;
-
- auto err = GpgBasicOperator::GetInstance(_channel).Sign(
- std::move(keys), in_buffer, out_buffer, GPGME_SIG_MODE_DETACH, result);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+void GpgFileOpera::SignFile(KeyArgsList keys, const QString& in_path,
+ bool ascii, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ // Set Singers of this opera
+ GpgBasicOperator::GetInstance().SetSigners(keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(
+ gpgme_op_sign(ctx, data_in, data_out, GPGME_SIG_MODE_DETACH));
+
+ data_object->Swap({
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_sign", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile(
- const std::string& data_path, const std::string& sign_path,
- GpgVerifyResult& result, int _channel) {
-#ifdef WINDOWS
- auto data_path_std =
- std::filesystem::path(QString::fromStdString(data_path).toStdU16String());
- auto sign_path_std =
- std::filesystem::path(QString::fromStdString(sign_path).toStdU16String());
-#else
- auto data_path_std = std::filesystem::path(data_path);
- auto sign_path_std = std::filesystem::path(sign_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(data_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> sign_buffer = nullptr;
- if (!sign_path.empty()) {
- std::string sign_buffer_str;
- if (!FileOperator::ReadFileStd(sign_path_std, sign_buffer_str)) {
- throw std::runtime_error("read file error");
- }
- sign_buffer = std::make_unique<std::string>(sign_buffer_str);
- }
- auto err = GpgBasicOperator::GetInstance(_channel).Verify(
- in_buffer, sign_buffer, result);
- return err;
+void GpgFileOpera::VerifyFile(const QString& data_path,
+ const QString& sign_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(data_path, true);
+ GpgData data_out;
+ if (!sign_path.isEmpty()) {
+ GpgData sig_data(sign_path, true);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_verify", "2.1.0");
}
-gpg_error_t GpgFrontend::GpgFileOpera::EncryptSignFile(
- KeyListPtr keys, KeyListPtr signer_keys, const std::string& in_path,
- const std::string& out_path, GpgEncrResult& encr_res,
- GpgSignResult& sign_res, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer = nullptr;
-
- auto err = GpgBasicOperator::GetInstance(_channel).EncryptSign(
- std::move(keys), std::move(signer_keys), in_buffer, out_buffer, encr_res,
- sign_res);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+void GpgFileOpera::EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
}
-gpg_error_t GpgFrontend::GpgFileOpera::DecryptVerifyFile(
- const std::string& in_path, const std::string& out_path,
- GpgDecrResult& decr_res, GpgVerifyResult& verify_res) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer = nullptr;
- auto err = GpgBasicOperator::GetInstance().DecryptVerify(
- in_buffer, out_buffer, decr_res, verify_res);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write file error");
- };
-
- return err;
+void GpgFileOpera::EncryptSignDirectory(KeyArgsList keys,
+ KeyArgsList signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii);
+
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ });
}
-unsigned int GpgFrontend::GpgFileOpera::EncryptFileSymmetric(
- const std::string& in_path, const std::string& out_path,
- GpgFrontend::GpgEncrResult& result, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer;
- auto err = GpgBasicOperator::GetInstance(_channel).EncryptSymmetric(
- in_buffer, out_buffer, result);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+
+void GpgFileOpera::DecryptVerifyFile(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap({
+ GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
+}
+
+void GpgFileOpera::DecryptVerifyArchive(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ ArchiveFileOperator::ExtractArchiveFromDataExchanger(
+ ex, out_path, [](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("extract archive from ex operation, err: {}", err);
+ });
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(ex);
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap({
+ GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
+}
+
+void GpgFileOpera::EncryptFileSymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
+}
+
+void GpgFileOpera::EncryptDerectorySymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ });
}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgFileOpera.h b/src/core/function/gpg/GpgFileOpera.h
index dc81bc53..b015ebe9 100644
--- a/src/core/function/gpg/GpgFileOpera.h
+++ b/src/core/function/gpg/GpgFileOpera.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,59 +20,87 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGFILEOPERA_H
-#define GPGFRONTEND_GPGFILEOPERA_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
- * @brief Executive files related to the basic operations that are provided by
- * GpgBasicOperator
+ * @brief Executive files related to the basic operations of GPG
+ *
* @class class: GpgBasicOperator
*/
class GPGFRONTEND_CORE_EXPORT GpgFileOpera
: public SingletonFunctionObject<GpgFileOpera> {
public:
+ /**
+ * @brief Construct a new Gpg File Opera object
+ *
+ * @param channel
+ */
explicit GpgFileOpera(
int channel = SingletonFunctionObject::GetDefaultChannel());
/**
- * @brief Encrypted file
+ * @brief Encrypted file with public key
*
* @param keys Used public key
* @param in_path The path where the enter file is located
* @param out_path The path where the output file is located
* @param result Encrypted results
- * @param _channel Channel in context
+ * @param channel Channel in context
* @return unsigned int error code
*/
- static unsigned int EncryptFile(KeyListPtr keys, const std::string& in_path,
- const std::string& out_path,
- GpgEncrResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void EncryptFile(KeyArgsList keys, const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptDirectory(KeyArgsList keys, const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
/**
- * @brief 运用对称加密算法加密文件
+ * @brief Encrypted file symmetrically (with password)
*
* @param in_path
* @param out_path
* @param result
- * @param _channel
+ * @param channel
* @return unsigned int
*/
- static unsigned int EncryptFileSymmetric(
- const std::string& in_path, const std::string& out_path,
- GpgEncrResult& result, int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void EncryptFileSymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptDerectorySymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
@@ -82,37 +110,43 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param result
* @return GpgError
*/
- static GpgError DecryptFile(const std::string& in_path,
- const std::string& out_path,
- GpgDecrResult& result);
+ void DecryptFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
*
+ * @param in_path
+ * @param out_path
+ * @param cb
+ */
+ void DecryptArchive(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief Sign file with private key
+ *
* @param keys
* @param in_path
* @param out_path
* @param result
- * @param _channel
+ * @param channel
* @return GpgError
*/
- static GpgError SignFile(KeyListPtr keys, const std::string& in_path,
- const std::string& out_path, GpgSignResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void SignFile(KeyArgsList keys, const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
/**
- * @brief
+ * @brief Verify file with public key
*
- * @param data_path
- * @param sign_path
- * @param result
- * @param _channel
+ * @param data_path The path where the enter file is located
+ * @param sign_path The path where the signature file is located
+ * @param result Verify results
+ * @param channel Channel in context
* @return GpgError
*/
- static GpgError VerifyFile(const std::string& data_path,
- const std::string& sign_path,
- GpgVerifyResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void VerifyFile(const QString& data_path, const QString& sign_path,
+ const GpgOperationCallback& cb);
/**
* @brief
@@ -120,18 +154,28 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param keys
* @param signer_keys
* @param in_path
+ * @param ascii
* @param out_path
- * @param encr_res
- * @param sign_res
- * @param _channel
- * @return GpgError
+ * @param cb
*/
- static GpgError EncryptSignFile(KeyListPtr keys, KeyListPtr signer_keys,
- const std::string& in_path,
- const std::string& out_path,
- GpgEncrResult& encr_res,
- GpgSignResult& sign_res,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param signer_keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptSignDirectory(KeyArgsList keys, KeyArgsList signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
@@ -142,12 +186,22 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param verify_res
* @return GpgError
*/
- static GpgError DecryptVerifyFile(const std::string& in_path,
- const std::string& out_path,
- GpgDecrResult& decr_res,
- GpgVerifyResult& verify_res);
+ void DecryptVerifyFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param out_path
+ * @param cb
+ */
+ void DecryptVerifyArchive(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ private:
+ GpgContext& ctx_ = GpgContext::GetInstance(
+ SingletonFunctionObject::GetChannel()); ///< Corresponding context
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGFILEOPERA_H
diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp
index ee6d2b09..e22979d7 100644
--- a/src/core/function/gpg/GpgKeyGetter.cpp
+++ b/src/core/function/gpg/GpgKeyGetter.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -32,136 +32,212 @@
#include <mutex>
#include <shared_mutex>
-#include <utility>
-#include "GpgConstants.h"
-#include "model/GpgKey.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgKeyGetter::GpgKeyGetter(int channel)
- : SingletonFunctionObject<GpgKeyGetter>(channel) {
- SPDLOG_DEBUG("called channel: {}", channel);
-}
+namespace GpgFrontend {
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr,
- bool use_cache) {
- // find in cache first
- if (use_cache) {
- auto key = get_key_in_cache(fpr);
- if (key.IsGood()) return key;
+class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
+ public:
+ explicit Impl(int channel)
+ : SingletonFunctionObject<GpgKeyGetter::Impl>(channel) {
+ GF_CORE_LOG_DEBUG("called channel: {}", channel);
}
- gpgme_key_t _p_key = nullptr;
- gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 1);
- if (_p_key == nullptr) {
- SPDLOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
- return GetPubkey(fpr);
- } else {
- return GpgKey(std::move(_p_key));
- }
-}
+ auto GetKey(const QString& fpr, bool use_cache) -> GpgKey {
+ // find in cache first
+ if (use_cache) {
+ auto key = get_key_in_cache(fpr);
+ if (key.IsGood()) return key;
+ }
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey(const std::string& fpr,
- bool use_cache) {
- // find in cache first
- if (use_cache) {
- auto key = get_key_in_cache(fpr);
- if (key.IsGood()) return key;
+ gpgme_key_t p_key = nullptr;
+ gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 1);
+ if (p_key == nullptr) {
+ GF_CORE_LOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
+ return GetPubkey(fpr, true);
+ }
+ return GpgKey(std::move(p_key));
}
- gpgme_key_t _p_key = nullptr;
- gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 0);
- if (_p_key == nullptr) SPDLOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
- return GpgKey(std::move(_p_key));
-}
+ auto GetPubkey(const QString& fpr, bool use_cache) -> GpgKey {
+ // find in cache first
+ if (use_cache) {
+ auto key = get_key_in_cache(fpr);
+ if (key.IsGood()) return key;
+ }
-GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() {
- // get the lock
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ gpgme_key_t p_key = nullptr;
+ gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 0);
+ if (p_key == nullptr)
+ GF_CORE_LOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
+ return GpgKey(std::move(p_key));
+ }
- auto keys_list = std::make_unique<GpgKeyLinkList>();
+ auto FetchKey() -> KeyLinkListPtr {
+ if (keys_cache_.empty()) {
+ FlushKeyCache();
+ }
- for (const auto& [key, value] : keys_cache_) {
- keys_list->push_back(value.Copy());
+ auto keys_list = std::make_unique<GpgKeyLinkList>();
+
+ {
+ // get the lock
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ for (const auto& [key, value] : keys_cache_) {
+ keys_list->push_back(value);
+ }
+ }
+ return keys_list;
}
- return keys_list;
-}
-void GpgFrontend::GpgKeyGetter::FlushKeyCache() {
- SPDLOG_DEBUG("called channel id: {}", GetChannel());
+ auto FlushKeyCache() -> bool {
+ GF_CORE_LOG_DEBUG("flush key channel called, channel: {}", GetChannel());
- // clear the keys cache
- keys_cache_.clear();
+ // clear the keys cache
+ keys_cache_.clear();
- // init
- GpgError err = gpgme_op_keylist_start(ctx_, nullptr, 0);
+ // init
+ GpgError err = gpgme_op_keylist_start(ctx_.DefaultContext(), nullptr, 0);
- // for debug
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+ // for debug
+ assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
- // return when error
- if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return;
+ // return when error
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false;
- {
- // get the lock
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
- gpgme_key_t key;
- while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) {
- auto gpg_key = GpgKey(std::move(key));
-
- // detect if the key is in a smartcard
- // if so, try to get full information using gpgme_get_key()
- // this maybe a bug in gpgme
- if (gpg_key.IsHasCardKey()) {
- gpg_key = GetKey(gpg_key.GetId(), false);
+ {
+ // get the lock
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ gpgme_key_t key;
+ while ((err = gpgme_op_keylist_next(ctx_.DefaultContext(), &key)) ==
+ GPG_ERR_NO_ERROR) {
+ auto gpg_key = GpgKey(std::move(key));
+
+ // detect if the key is in a smartcard
+ // if so, try to get full information using gpgme_get_key()
+ // this maybe a bug in gpgme
+ if (gpg_key.IsHasCardKey()) {
+ gpg_key = GetKey(gpg_key.GetId(), false);
+ }
+
+ keys_cache_.insert({gpg_key.GetId(), std::move(gpg_key)});
}
+ }
+
+ GF_CORE_LOG_DEBUG("flush key channel cache address: {} object address: {}",
+ static_cast<void*>(&keys_cache_),
+ static_cast<void*>(this));
+
+ // for debug
+ assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_EOF);
+
+ err = gpgme_op_keylist_end(ctx_.DefaultContext());
+ assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
- keys_cache_.insert({gpg_key.GetId(), std::move(gpg_key)});
+ GF_CORE_LOG_DEBUG("flush key channel done, channel: {}", GetChannel());
+ return true;
+ }
+
+ auto GetKeys(const KeyIdArgsListPtr& ids) -> KeyListPtr {
+ auto keys = std::make_unique<KeyArgsList>();
+ for (const auto& key_id : *ids) keys->emplace_back(GetKey(key_id, true));
+ return keys;
+ }
+
+ auto GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr {
+ // get the lock
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ auto keys_copy = std::make_unique<GpgKeyLinkList>();
+ for (const auto& key : *keys) keys_copy->emplace_back(key);
+ return keys_copy;
+ }
+
+ auto GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr {
+ // get the lock
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ auto keys_copy = std::make_unique<KeyArgsList>();
+ for (const auto& key : *keys) keys_copy->emplace_back(key);
+ return keys_copy;
+ }
+
+ private:
+ /**
+ * @brief Get the gpgme context object
+ *
+ */
+ GpgContext& ctx_ =
+ GpgContext::GetInstance(SingletonFunctionObject::GetChannel());
+
+ /**
+ * @brief shared mutex for the keys cache
+ *
+ */
+ mutable std::mutex ctx_mutex_;
+
+ /**
+ * @brief cache the keys with key id
+ *
+ */
+ std::map<QString, GpgKey> keys_cache_;
+
+ /**
+ * @brief shared mutex for the keys cache
+ *
+ */
+ mutable std::mutex keys_cache_mutex_;
+
+ /**
+ * @brief Get the Key object
+ *
+ * @param id
+ * @return GpgKey
+ */
+ auto get_key_in_cache(const QString& key_id) -> GpgKey {
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ if (keys_cache_.find(key_id) != keys_cache_.end()) {
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ // return a copy of the key in cache
+ return keys_cache_[key_id];
}
+
+ // return a bad key
+ return {};
}
+};
- SPDLOG_DEBUG("cache address: {} object address: {}",
- static_cast<void*>(&keys_cache_), static_cast<void*>(this));
+GpgKeyGetter::GpgKeyGetter(int channel)
+ : SingletonFunctionObject<GpgKeyGetter>(channel),
+ p_(SecureCreateUniqueObject<Impl>(channel)) {
+ GF_CORE_LOG_DEBUG("called channel: {}", channel);
+}
- // for debug
- assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF);
+GpgKeyGetter::~GpgKeyGetter() = default;
- err = gpgme_op_keylist_end(ctx_);
- assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
+auto GpgKeyGetter::GetKey(const QString& key_id, bool use_cache) -> GpgKey {
+ return p_->GetKey(key_id, use_cache);
}
-GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys(
- const KeyIdArgsListPtr& ids) {
- auto keys = std::make_unique<KeyArgsList>();
- for (const auto& id : *ids) keys->emplace_back(GetKey(id));
- return keys;
+auto GpgKeyGetter::GetPubkey(const QString& key_id, bool use_cache) -> GpgKey {
+ return p_->GetPubkey(key_id, use_cache);
}
-GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
- const GpgFrontend::KeyLinkListPtr& keys) {
- // get the lock
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- auto keys_copy = std::make_unique<GpgKeyLinkList>();
- for (const auto& key : *keys) keys_copy->emplace_back(key.Copy());
- return keys_copy;
+auto GpgKeyGetter::FlushKeyCache() -> bool { return p_->FlushKeyCache(); }
+
+auto GpgKeyGetter::GetKeys(const KeyIdArgsListPtr& ids) -> KeyListPtr {
+ return p_->GetKeys(ids);
}
-GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
- const GpgFrontend::KeyListPtr& keys) {
- // get the lock
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- auto keys_copy = std::make_unique<KeyArgsList>();
- for (const auto& key : *keys) keys_copy->emplace_back(key.Copy());
- return keys_copy;
+auto GpgKeyGetter::GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr {
+ return p_->GetKeysCopy(keys);
}
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::get_key_in_cache(
- const std::string& id) {
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
- if (keys_cache_.find(id) != keys_cache_.end()) {
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- // return a copy of the key in cache
- return keys_cache_[id].Copy();
- }
- // return a bad key
- return GpgKey();
+auto GpgKeyGetter::GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr {
+ return p_->GetKeysCopy(keys);
}
+
+auto GpgKeyGetter::FetchKey() -> KeyLinkListPtr { return p_->FetchKey(); }
+
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyGetter.h b/src/core/function/gpg/GpgKeyGetter.h
index c96dbea7..91138623 100644
--- a/src/core/function/gpg/GpgKeyGetter.h
+++ b/src/core/function/gpg/GpgKeyGetter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,16 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
-#define GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+#pragma once
-#include <mutex>
-#include <vector>
-
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -50,8 +45,13 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
*
* @param channel
*/
- explicit GpgKeyGetter(
- int channel = SingletonFunctionObject::GetDefaultChannel());
+ explicit GpgKeyGetter(int channel = kGpgFrontendDefaultChannel);
+
+ /**
+ * @brief Destroy the Gpg Key Getter object
+ *
+ */
+ ~GpgKeyGetter();
/**
* @brief Get the Key object
@@ -59,7 +59,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param fpr
* @return GpgKey
*/
- GpgKey GetKey(const std::string& id, bool use_cache = true);
+ auto GetKey(const QString& key_id, bool use_cache = true) -> GpgKey;
/**
* @brief Get the Keys object
@@ -67,7 +67,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param ids
* @return KeyListPtr
*/
- KeyListPtr GetKeys(const KeyIdArgsListPtr& ids);
+ auto GetKeys(const KeyIdArgsListPtr& key_ids) -> KeyListPtr;
/**
* @brief Get the Pubkey object
@@ -75,20 +75,20 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param fpr
* @return GpgKey
*/
- GpgKey GetPubkey(const std::string& id, bool use_cache = true);
+ auto GetPubkey(const QString& key_id, bool use_cache = true) -> GpgKey;
/**
* @brief Get all the keys by receiving a linked list
*
* @return KeyLinkListPtr
*/
- KeyLinkListPtr FetchKey();
+ auto FetchKey() -> KeyLinkListPtr;
/**
* @brief flush the keys in the cache
*
*/
- void FlushKeyCache();
+ auto FlushKeyCache() -> bool;
/**
* @brief Get the Keys Copy object
@@ -96,7 +96,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param keys
* @return KeyListPtr
*/
- KeyListPtr GetKeysCopy(const KeyListPtr& keys);
+ auto GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr;
/**
* @brief Get the Keys Copy object
@@ -104,42 +104,10 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param keys
* @return KeyLinkListPtr
*/
- KeyLinkListPtr GetKeysCopy(const KeyLinkListPtr& keys);
+ auto GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr;
private:
- /**
- * @brief Get the gpgme context object
- *
- */
- GpgContext& ctx_ =
- GpgContext::GetInstance(SingletonFunctionObject::GetChannel());
-
- /**
- * @brief shared mutex for the keys cache
- *
- */
- mutable std::mutex ctx_mutex_;
-
- /**
- * @brief cache the keys with key id
- *
- */
- std::map<std::string, GpgKey> keys_cache_;
-
- /**
- * @brief shared mutex for the keys cache
- *
- */
- mutable std::mutex keys_cache_mutex_;
-
- /**
- * @brief Get the Key object
- *
- * @param id
- * @return GpgKey
- */
- GpgKey get_key_in_cache(const std::string& id);
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
diff --git a/src/core/function/gpg/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp
index 01349c94..09b51359 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.cpp
+++ b/src/core/function/gpg/GpgKeyImportExporter.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,79 +28,76 @@
#include "GpgKeyImportExporter.h"
-#include <memory>
+#include "core/GpgModel.h"
+#include "core/model/GpgImportInformation.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-#include "GpgConstants.h"
-#include "GpgKeyGetter.h"
+namespace GpgFrontend {
-GpgFrontend::GpgKeyImportExporter::GpgKeyImportExporter(int channel)
- : SingletonFunctionObject<GpgKeyImportExporter>(channel) {}
+GpgKeyImportExporter::GpgKeyImportExporter(int channel)
+ : SingletonFunctionObject<GpgKeyImportExporter>(channel),
+ ctx_(GpgContext::GetInstance(SingletonFunctionObject::GetChannel())) {}
/**
* Import key pair
* @param inBuffer input byte array
* @return Import information
*/
-GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExporter::ImportKey(
- StdBypeArrayPtr in_buffer) {
- if (in_buffer->empty()) return {};
+auto GpgKeyImportExporter::ImportKey(const GFBuffer& in_buffer)
+ -> std::shared_ptr<GpgImportInformation> {
+ if (in_buffer.Empty()) return {};
- GpgData data_in(in_buffer->data(), in_buffer->size());
- auto err = check_gpg_error(gpgme_op_import(ctx_, data_in));
+ GpgData data_in(in_buffer);
+ auto err = CheckGpgError(gpgme_op_import(ctx_.DefaultContext(), data_in));
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
gpgme_import_result_t result;
- result = gpgme_op_import_result(ctx_);
+ result = gpgme_op_import_result(ctx_.DefaultContext());
gpgme_import_status_t status = result->imports;
- auto import_info = std::make_unique<GpgImportInformation>(result);
+ auto import_info = SecureCreateSharedObject<GpgImportInformation>(result);
while (status != nullptr) {
- GpgImportedKey key;
+ GpgImportInformation::GpgImportedKey key;
key.import_status = static_cast<int>(status->status);
key.fpr = status->fpr;
- import_info->importedKeys.emplace_back(key);
+ import_info->imported_keys.emplace_back(key);
status = status->next;
}
- return *import_info;
+ return import_info;
}
/**
- * Export Key
- * @param uid_list key ids
- * @param out_buffer output byte array
+ * Export keys
+ * @param keys keys used
+ * @param outBuffer output byte array
* @return if success
*/
-bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
- ByteArrayPtr& out_buffer,
- bool secret) const {
- if (uid_list->empty()) return false;
+auto GpgKeyImportExporter::ExportKey(const GpgKey& key, bool secret, bool ascii,
+ bool shortest, bool ssh_mode) const
+ -> std::tuple<GpgError, GFBuffer> {
+ if (!key.IsGood()) return {GPG_ERR_CANCELED, {}};
- int _mode = 0;
- if (secret) _mode |= GPGME_EXPORT_MODE_SECRET;
+ int mode = 0;
+ if (secret) mode |= GPGME_EXPORT_MODE_SECRET;
+ if (shortest) mode |= GPGME_EXPORT_MODE_MINIMAL;
+ if (ssh_mode) mode |= GPGME_EXPORT_MODE_SSH;
- auto keys = GpgKeyGetter::GetInstance().GetKeys(uid_list);
- auto keys_array = new gpgme_key_t[keys->size() + 1];
+ std::vector<gpgme_key_t> keys_array;
- int index = 0;
- for (const auto& key : *keys) {
- keys_array[index++] = gpgme_key_t(key);
- }
- keys_array[index] = nullptr;
+ // Last entry data_in array has to be nullptr
+ keys_array.emplace_back(key);
+ keys_array.emplace_back(nullptr);
GpgData data_out;
- auto err = gpgme_op_export_keys(ctx_, keys_array, _mode, data_out);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false;
-
- delete[] keys_array;
-
- SPDLOG_DEBUG("export keys read_bytes: {}",
- gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
-
- swap(temp_out_buffer, out_buffer);
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
- return true;
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting a key finished, ascii: {}, read_bytes: {}", ascii,
+ gpgme_data_seek(data_out, 0, SEEK_END));
+ return {err, data_out.Read2GFBuffer()};
}
/**
@@ -109,114 +106,36 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
* @param outBuffer output byte array
* @return if success
*/
-bool GpgFrontend::GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys,
- ByteArrayPtr& out_buffer,
- bool secret) const {
- KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>();
- for (const auto& key : keys) key_ids->push_back(key.GetId());
- return ExportKeys(key_ids, out_buffer, secret);
+void GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, bool secret,
+ bool ascii, bool shortest, bool ssh_mode,
+ const GpgOperationCallback& cb) const {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
+
+ int mode = 0;
+ if (secret) mode |= GPGME_EXPORT_MODE_SECRET;
+ if (shortest) mode |= GPGME_EXPORT_MODE_MINIMAL;
+ if (ssh_mode) mode |= GPGME_EXPORT_MODE_SSH;
+
+ std::vector<gpgme_key_t> keys_array(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ keys_array.emplace_back(nullptr);
+
+ GpgData data_out;
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting keys finished, ascii: {}, read_bytes: {}",
+ ascii, gpgme_data_seek(data_out, 0, SEEK_END));
+
+ data_object->Swap({data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_export_keys", "2.1.0");
}
-/**
- * Export all the keys both private and public keys
- * @param uid_list key ids
- * @param out_buffer output byte array
- * @return if success
- */
-bool GpgFrontend::GpgKeyImportExporter::ExportAllKeys(
- KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer, bool secret) const {
- bool result = true;
- result = ExportKeys(uid_list, out_buffer, false) & result;
-
- ByteArrayPtr temp_buffer;
- if (secret) {
- result = ExportKeys(uid_list, temp_buffer, true) & result;
- }
- out_buffer->append(*temp_buffer);
- return result;
-}
-
-/**
- * Export the secret key of a key pair(including subkeys)
- * @param key target key pair
- * @param outBuffer output byte array
- * @return if successful
- */
-bool GpgFrontend::GpgKeyImportExporter::ExportSecretKey(
- const GpgKey& key, ByteArrayPtr& out_buffer) const {
- SPDLOG_DEBUG("export secret key: {}", key.GetId().c_str());
-
- gpgme_key_t target_key[2] = {gpgme_key_t(key), nullptr};
-
- GpgData data_out;
- // export private key to outBuffer
- gpgme_error_t err = gpgme_op_export_keys(ctx_, target_key,
- GPGME_EXPORT_MODE_SECRET, data_out);
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
-
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportKey(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(), 0, data_out);
-
- SPDLOG_DEBUG("export keys read_bytes: {}",
- gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportKeyOpenSSH(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(), GPGME_EXPORT_MODE_SSH,
- data_out);
-
- SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportSecretKeyShortest(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(),
- GPGME_EXPORT_MODE_MINIMAL, data_out);
-
- SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-GpgFrontend::GpgImportInformation::GpgImportInformation() = default;
-
-GpgFrontend::GpgImportInformation::GpgImportInformation(
- gpgme_import_result_t result) {
- if (result->unchanged) unchanged = result->unchanged;
- if (result->considered) considered = result->considered;
- if (result->no_user_id) no_user_id = result->no_user_id;
- if (result->imported) imported = result->imported;
- if (result->imported_rsa) imported_rsa = result->imported_rsa;
- if (result->unchanged) unchanged = result->unchanged;
- if (result->new_user_ids) new_user_ids = result->new_user_ids;
- if (result->new_sub_keys) new_sub_keys = result->new_sub_keys;
- if (result->new_signatures) new_signatures = result->new_signatures;
- if (result->new_revocations) new_revocations = result->new_revocations;
- if (result->secret_read) secret_read = result->secret_read;
- if (result->secret_imported) secret_imported = result->secret_imported;
- if (result->secret_unchanged) secret_unchanged = result->secret_unchanged;
- if (result->not_imported) not_imported = result->not_imported;
-}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyImportExporter.h b/src/core/function/gpg/GpgKeyImportExporter.h
index 6e90f436..14b2b2bf 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.h
+++ b/src/core/function/gpg/GpgKeyImportExporter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,67 +20,22 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef _GPGKEYIMPORTEXPORTOR_H
-#define _GPGKEYIMPORTEXPORTOR_H
+#pragma once
-#include <string>
-
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/model/GFBuffer.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
-/**
- * @brief
- *
- */
-class GpgImportedKey {
- public:
- std::string fpr; ///<
- int import_status; ///<
-};
-
-typedef std::list<GpgImportedKey> GpgImportedKeyList; ///<
-
-/**
- * @brief
- *
- */
-class GPGFRONTEND_CORE_EXPORT GpgImportInformation {
- public:
- GpgImportInformation();
-
- /**
- * @brief Construct a new Gpg Import Information object
- *
- * @param result
- */
- explicit GpgImportInformation(gpgme_import_result_t result);
-
- int considered = 0; ///<
- int no_user_id = 0; ///<
- int imported = 0; ///<
- int imported_rsa = 0; ///<
- int unchanged = 0; ///<
- int new_user_ids = 0; ///<
- int new_sub_keys = 0; ///<
- int new_signatures = 0; ///<
- int new_revocations = 0; ///<
- int secret_read = 0; ///<
- int secret_imported = 0; ///<
- int secret_unchanged = 0; ///<
- int not_imported = 0; ///<
-
- GpgImportedKeyList importedKeys; ///<
-};
+class GpgImportInformation;
/**
* @brief
@@ -103,31 +58,19 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter
* @param inBuffer
* @return GpgImportInformation
*/
- GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer);
+ auto ImportKey(const GFBuffer&) -> std::shared_ptr<GpgImportInformation>;
/**
* @brief
*
- * @param uid_list
- * @param out_buffer
- * @param secret
- * @return true
- * @return false
- */
- bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer,
- bool secret = false) const;
-
- /**
- * @brief
- *
- * @param keys
- * @param outBuffer
+ * @param key
* @param secret
- * @return true
- * @return false
+ * @param ascii
+ * @return std::tuple<GpgError, GFBuffer>
*/
- bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer,
- bool secret = false) const;
+ [[nodiscard]] auto ExportKey(const GpgKey& key, bool secret, bool ascii,
+ bool shortest, bool ssh_mode = false) const
+ -> std::tuple<GpgError, GFBuffer>;
/**
* @brief
@@ -138,55 +81,12 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter
* @return true
* @return false
*/
- bool ExportAllKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer,
- bool secret) const;
-
- /**
- * @brief
- *
- * @param key
- * @param out_buffer
- * @return true
- * @return false
- */
- bool ExportKey(const GpgKey& key, ByteArrayPtr& out_buffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param out_buffer
- * @return true
- * @return false
- */
- bool ExportKeyOpenSSH(const GpgKey& key, ByteArrayPtr& out_buffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param outBuffer
- * @return true
- * @return false
- */
- bool ExportSecretKey(const GpgKey& key, ByteArrayPtr& outBuffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param outBuffer
- * @return true
- * @return false
- */
- bool ExportSecretKeyShortest(const GpgKey& key,
- ByteArrayPtr& outBuffer) const;
+ void ExportKeys(const KeyArgsList& keys, bool secret, bool ascii,
+ bool shortest, bool ssh_mode,
+ const GpgOperationCallback& cb) const;
private:
- GpgContext& ctx_ =
- GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
+ GpgContext& ctx_;
};
} // namespace GpgFrontend
-
-#endif // _GPGKEYIMPORTEXPORTOR_H \ No newline at end of file
diff --git a/src/core/function/gpg/GpgKeyManager.cpp b/src/core/function/gpg/GpgKeyManager.cpp
index e556eec6..8d7d9a28 100644
--- a/src/core/function/gpg/GpgKeyManager.cpp
+++ b/src/core/function/gpg/GpgKeyManager.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,150 +28,146 @@
#include "GpgKeyManager.h"
-#include <boost/algorithm/string.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-#include <memory>
-#include <string>
-
-#include "GpgBasicOperator.h"
-#include "GpgKeyGetter.h"
-#include "spdlog/spdlog.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/utils/GpgUtils.h"
GpgFrontend::GpgKeyManager::GpgKeyManager(int channel)
: SingletonFunctionObject<GpgKeyManager>(channel) {}
-bool GpgFrontend::GpgKeyManager::SignKey(
+auto GpgFrontend::GpgKeyManager::SignKey(
const GpgFrontend::GpgKey& target, GpgFrontend::KeyArgsList& keys,
- const std::string& uid,
- const std::unique_ptr<boost::posix_time::ptime>& expires) {
- using namespace boost::posix_time;
-
- GpgBasicOperator::GetInstance().SetSigners(keys);
+ const QString& uid, const std::unique_ptr<QDateTime>& expires) -> bool {
+ GpgBasicOperator::GetInstance().SetSigners(keys, true);
unsigned int flags = 0;
unsigned int expires_time_t = 0;
- if (expires == nullptr)
+ if (expires == nullptr) {
flags |= GPGME_KEYSIGN_NOEXPIRE;
- else
- expires_time_t = to_time_t(*expires);
+ } else {
+ expires_time_t = expires->toSecsSinceEpoch();
+ }
- auto err = check_gpg_error(gpgme_op_keysign(
- ctx_, gpgme_key_t(target), uid.c_str(), expires_time_t, flags));
+ auto err = CheckGpgError(
+ gpgme_op_keysign(ctx_.DefaultContext(), static_cast<gpgme_key_t>(target),
+ uid.toUtf8(), expires_time_t, flags));
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgKeyManager::RevSign(
+auto GpgFrontend::GpgKeyManager::RevSign(
const GpgFrontend::GpgKey& key,
- const GpgFrontend::SignIdArgsListPtr& signature_id) {
+ const GpgFrontend::SignIdArgsListPtr& signature_id) -> bool {
auto& key_getter = GpgKeyGetter::GetInstance();
for (const auto& sign_id : *signature_id) {
auto signing_key = key_getter.GetKey(sign_id.first);
assert(signing_key.IsGood());
- auto err = check_gpg_error(gpgme_op_revsig(ctx_, gpgme_key_t(key),
- gpgme_key_t(signing_key),
- sign_id.second.c_str(), 0));
- if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return false;
+ auto err = CheckGpgError(
+ gpgme_op_revsig(ctx_.DefaultContext(), gpgme_key_t(key),
+ gpgme_key_t(signing_key), sign_id.second.toUtf8(), 0));
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false;
}
return true;
}
-bool GpgFrontend::GpgKeyManager::SetExpire(
- const GpgFrontend::GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
- std::unique_ptr<boost::posix_time::ptime>& expires) {
- using namespace boost::posix_time;
-
+auto GpgFrontend::GpgKeyManager::SetExpire(const GpgFrontend::GpgKey& key,
+ std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<QDateTime>& expires)
+ -> bool {
unsigned long expires_time = 0;
- if (expires != nullptr) expires_time = to_time_t(ptime(*expires));
+ if (expires != nullptr) expires_time = expires->toSecsSinceEpoch();
const char* sub_fprs = nullptr;
- if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().c_str();
+ if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().toUtf8();
- auto err = check_gpg_error(
- gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, sub_fprs, 0));
+ auto err = CheckGpgError(gpgme_op_setexpire(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key),
+ expires_time, sub_fprs, 0));
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
- int trust_level) {
+auto GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
+ int trust_level) -> bool {
if (trust_level < 0 || trust_level > 5) {
- SPDLOG_ERROR("illegal owner trust level: {}", trust_level);
+ GF_CORE_LOG_ERROR("illegal owner trust level: {}", trust_level);
}
- AutomatonNextStateHandler next_state_handler =
- [](AutomatonState state, std::string status, std::string args) {
- SPDLOG_DEBUG("next_state_handler state: {}, gpg_status: {}, args: {}",
- state, status, args);
- std::vector<std::string> tokens;
- boost::split(tokens, args, boost::is_any_of(" "));
-
- switch (state) {
- case AS_START:
- if (status == "GET_LINE" && args == "keyedit.prompt")
- return AS_COMMAND;
- return AS_ERROR;
- case AS_COMMAND:
- if (status == "GET_LINE" && args == "edit_ownertrust.value") {
- return AS_VALUE;
- }
- return AS_ERROR;
- case AS_VALUE:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- } else if (status == "GET_BOOL" &&
- args == "edit_ownertrust.set_ultimate.okay") {
- return AS_REALLY_ULTIMATE;
- }
- return AS_ERROR;
- case AS_REALLY_ULTIMATE:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- }
- return AS_ERROR;
- case AS_QUIT:
- if (status == "GET_LINE" && args == "keyedit.save.okay") {
- return AS_SAVE;
- }
- return AS_ERROR;
- case AS_ERROR:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- }
- return AS_ERROR;
- default:
- return AS_ERROR;
- };
- };
+ AutomatonNextStateHandler next_state_handler = [](AutomatonState state,
+ QString status,
+ QString args) {
+ GF_CORE_LOG_DEBUG("next_state_handler state: {}, gpg_status: {}, args: {}",
+ state, status, args);
+ auto tokens = args.split(' ');
+
+ switch (state) {
+ case AS_START:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_COMMAND;
+ }
+ return AS_ERROR;
+ case AS_COMMAND:
+ if (status == "GET_LINE" && args == "edit_ownertrust.value") {
+ return AS_VALUE;
+ }
+ return AS_ERROR;
+ case AS_VALUE:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ } else if (status == "GET_BOOL" &&
+ args == "edit_ownertrust.set_ultimate.okay") {
+ return AS_REALLY_ULTIMATE;
+ }
+ return AS_ERROR;
+ case AS_REALLY_ULTIMATE:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ }
+ return AS_ERROR;
+ case AS_QUIT:
+ if (status == "GET_LINE" && args == "keyedit.save.okay") {
+ return AS_SAVE;
+ }
+ return AS_ERROR;
+ case AS_ERROR:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ }
+ return AS_ERROR;
+ default:
+ return AS_ERROR;
+ };
+ };
AutomatonActionHandler action_handler =
[trust_level](AutomatonHandelStruct& handler, AutomatonState state) {
- SPDLOG_DEBUG("action_handler state: {}", state);
+ GF_CORE_LOG_DEBUG("action_handler state: {}", state);
switch (state) {
case AS_COMMAND:
- return std::string("trust");
+ return QString("trust");
case AS_VALUE:
handler.SetSuccess(true);
- return std::to_string(trust_level);
+ return QString::number(trust_level);
case AS_REALLY_ULTIMATE:
handler.SetSuccess(true);
- return std::string("Y");
+ return QString("Y");
case AS_QUIT:
- return std::string("quit");
+ return QString("quit");
case AS_SAVE:
handler.SetSuccess(true);
- return std::string("Y");
+ return QString("Y");
case AS_START:
case AS_ERROR:
- return std::string("");
+ return QString("");
default:
- return std::string("");
+ return QString("");
}
- return std::string("");
+ return QString("");
};
auto key_fpr = key.GetFingerprint();
@@ -180,49 +176,43 @@ bool GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
GpgData data_out;
- auto err = gpgme_op_interact(ctx_, gpgme_key_t(key), 0,
- GpgKeyManager::interactor_cb_fnc,
- (void*)&handel_struct, data_out);
- if (err != GPG_ERR_NO_ERROR) {
- SPDLOG_ERROR("fail to set owner trust level {} to key {}, err: {}",
- trust_level, key.GetId(), gpgme_strerror(err));
- }
-
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR &&
- handel_struct.Success();
+ auto err = gpgme_op_interact(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), 0,
+ GpgKeyManager::interactor_cb_fnc, (void*)&handel_struct, data_out);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR && handel_struct.Success();
}
-gpgme_error_t GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
- const char* status,
- const char* args,
- int fd) {
- auto handle_struct = static_cast<AutomatonHandelStruct*>(handle);
- std::string status_s = status;
- std::string args_s = args;
- SPDLOG_DEBUG("cb start status: {}, args: {}, fd: {}, handle struct state: {}",
- status_s, args_s, fd, handle_struct->CuurentStatus());
+auto GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
+ const char* status,
+ const char* args, int fd)
+ -> gpgme_error_t {
+ auto* handle_struct = static_cast<AutomatonHandelStruct*>(handle);
+ QString status_s = status;
+ QString args_s = args;
+ GF_CORE_LOG_DEBUG(
+ "cb start status: {}, args: {}, fd: {}, handle struct state: {}",
+ status_s, args_s, fd, handle_struct->CuurentStatus());
if (status_s == "KEY_CONSIDERED") {
- std::vector<std::string> tokens;
- boost::split(tokens, args, boost::is_any_of(" "));
+ auto tokens = QString(args).split(' ');
if (tokens.empty() || tokens[0] != handle_struct->KeyFpr()) {
- SPDLOG_ERROR("handle struct key fpr {} mismatch token: {}, exit...",
- handle_struct->KeyFpr(), tokens[0]);
+ GF_CORE_LOG_ERROR("handle struct key fpr {} mismatch token: {}, exit...",
+ handle_struct->KeyFpr(), tokens[0]);
return -1;
}
return 0;
}
- if (status_s == "GOT_IT" || status_s.empty()) {
- SPDLOG_DEBUG("status GOT_IT, continue...");
+ if (status_s == "GOT_IT" || status_s.isEmpty()) {
+ GF_CORE_LOG_DEBUG("status GOT_IT, continue...");
return 0;
}
AutomatonState next_state = handle_struct->NextState(status_s, args_s);
if (next_state == AS_ERROR) {
- SPDLOG_DEBUG("handle struct next state caught error, skipping...");
+ GF_CORE_LOG_DEBUG("handle struct next state caught error, skipping...");
return GPG_ERR_FALSE;
}
@@ -233,10 +223,11 @@ gpgme_error_t GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
// set state and preform action
handle_struct->SetStatus(next_state);
Command cmd = handle_struct->Action();
- SPDLOG_DEBUG("handle struct action done, next state: {}, action cmd: {}",
- next_state, cmd);
- if (!cmd.empty()) {
- gpgme_io_write(fd, cmd.c_str(), cmd.size());
+ GF_CORE_LOG_DEBUG("handle struct action done, next state: {}, action cmd: {}",
+ next_state, cmd);
+ if (!cmd.isEmpty()) {
+ auto btye_array = cmd.toUtf8();
+ gpgme_io_write(fd, btye_array, btye_array.size());
gpgme_io_write(fd, "\n", 1);
} else if (status_s == "GET_LINE") {
// avoid trapping in this state
diff --git a/src/core/function/gpg/GpgKeyManager.h b/src/core/function/gpg/GpgKeyManager.h
index 62f7baca..8b4d41b2 100644
--- a/src/core/function/gpg/GpgKeyManager.h
+++ b/src/core/function/gpg/GpgKeyManager.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,19 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
-#define GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
+#pragma once
#include <functional>
-#include <string>
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -60,8 +58,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @param expires expire date and time of the signature
* @return if successful
*/
- bool SignKey(const GpgKey& target, KeyArgsList& keys, const std::string& uid,
- const std::unique_ptr<boost::posix_time::ptime>& expires);
+ auto SignKey(const GpgKey& target, KeyArgsList& keys, const QString& uid,
+ const std::unique_ptr<QDateTime>& expires) -> bool;
/**
* @brief
@@ -71,8 +69,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @return true
* @return false
*/
- bool RevSign(const GpgFrontend::GpgKey& key,
- const GpgFrontend::SignIdArgsListPtr& signature_id);
+ auto RevSign(const GpgFrontend::GpgKey& key,
+ const GpgFrontend::SignIdArgsListPtr& signature_id) -> bool;
/**
* @brief Set the Expire object
@@ -83,21 +81,21 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @return true
* @return false
*/
- bool SetExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
- std::unique_ptr<boost::posix_time::ptime>& expires);
+ auto SetExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<QDateTime>& expires) -> bool;
/**
* @brief
*
* @return
*/
- bool SetOwnerTrustLevel(const GpgKey& key, int trust_level);
+ auto SetOwnerTrustLevel(const GpgKey& key, int trust_level) -> bool;
private:
- static gpgme_error_t interactor_cb_fnc(void* handle, const char* status,
- const char* args, int fd);
+ static auto interactor_cb_fnc(void* handle, const char* status,
+ const char* args, int fd) -> gpgme_error_t;
- using Command = std::string;
+ using Command = QString;
using AutomatonState = enum {
AS_START,
AS_COMMAND,
@@ -113,35 +111,37 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
using AutomatonActionHandler =
std::function<Command(AutomatonHandelStruct&, AutomatonState)>;
using AutomatonNextStateHandler =
- std::function<AutomatonState(AutomatonState, std::string, std::string)>;
+ std::function<AutomatonState(AutomatonState, QString, QString)>;
struct AutomatonHandelStruct {
void SetStatus(AutomatonState next_state) { current_state_ = next_state; }
- AutomatonState CuurentStatus() { return current_state_; }
+ auto CuurentStatus() -> AutomatonState { return current_state_; }
void SetHandler(AutomatonNextStateHandler next_state_handler,
AutomatonActionHandler action_handler) {
- next_state_handler_ = next_state_handler;
- action_handler_ = action_handler;
+ next_state_handler_ = std::move(next_state_handler);
+ action_handler_ = std::move(action_handler);
}
- AutomatonState NextState(std::string gpg_status, std::string args) {
- return next_state_handler_(current_state_, gpg_status, args);
+ auto NextState(QString gpg_status, QString args) -> AutomatonState {
+ return next_state_handler_(current_state_, std::move(gpg_status),
+ std::move(args));
}
- Command Action() { return action_handler_(*this, current_state_); }
+ auto Action() -> Command { return action_handler_(*this, current_state_); }
void SetSuccess(bool success) { success_ = success; }
- bool Success() { return success_; }
+ [[nodiscard]] auto Success() const -> bool { return success_; }
- std::string KeyFpr() { return key_fpr_; }
+ auto KeyFpr() -> QString { return key_fpr_; }
- AutomatonHandelStruct(std::string key_fpr) : key_fpr_(key_fpr) {}
+ explicit AutomatonHandelStruct(QString key_fpr)
+ : key_fpr_(std::move(key_fpr)) {}
private:
AutomatonState current_state_ = AS_START;
AutomatonNextStateHandler next_state_handler_;
AutomatonActionHandler action_handler_;
bool success_ = false;
- std::string key_fpr_;
+ QString key_fpr_;
};
GpgContext& ctx_ =
@@ -149,5 +149,3 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp
index d5919cff..d9133905 100644
--- a/src/core/function/gpg/GpgKeyOpera.cpp
+++ b/src/core/function/gpg/GpgKeyOpera.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,38 +28,42 @@
#include "GpgKeyOpera.h"
-#include <boost/asio.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-#include <boost/format.hpp>
-#include <boost/process/async_pipe.hpp>
-#include <memory>
-#include <string>
-#include <vector>
+#include <gpg-error.h>
-#include "GpgCommandExecutor.h"
-#include "GpgKeyGetter.h"
-#include "core/GpgConstants.h"
-#include "core/GpgGenKeyInfo.h"
+#include <memory>
-GpgFrontend::GpgKeyOpera::GpgKeyOpera(int channel)
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgCommandExecutor.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/model/DataObject.h"
+#include "core/model/GpgGenKeyInfo.h"
+#include "core/model/GpgGenerateKeyResult.h"
+#include "core/module/ModuleManager.h"
+#include "core/typedef/GpgTypedef.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/GpgUtils.h"
+
+namespace GpgFrontend {
+
+GpgKeyOpera::GpgKeyOpera(int channel)
: SingletonFunctionObject<GpgKeyOpera>(channel) {}
/**
* Delete keys
* @param uidList key ids
*/
-void GpgFrontend::GpgKeyOpera::DeleteKeys(
- GpgFrontend::KeyIdArgsListPtr key_ids) {
+void GpgKeyOpera::DeleteKeys(GpgFrontend::KeyIdArgsListPtr key_ids) {
GpgError err;
for (const auto& tmp : *key_ids) {
auto key = GpgKeyGetter::GetInstance().GetKey(tmp);
if (key.IsGood()) {
- err = check_gpg_error(
- gpgme_op_delete_ext(ctx_, gpgme_key_t(key),
- GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
+ err = CheckGpgError(gpgme_op_delete_ext(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
} else {
- SPDLOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
+ GF_CORE_LOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
}
}
}
@@ -72,26 +76,24 @@ void GpgFrontend::GpgKeyOpera::DeleteKeys(
* @param expires date and time
* @return if successful
*/
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
- const GpgKey& key, const SubkeyId& subkey_fpr,
- std::unique_ptr<boost::posix_time::ptime>& expires) {
+auto GpgKeyOpera::SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<QDateTime>& expires) -> GpgError {
unsigned long expires_time = 0;
if (expires != nullptr) {
- using namespace boost::posix_time;
- using namespace std::chrono;
- expires_time =
- to_time_t(*expires) - system_clock::to_time_t(system_clock::now());
+ expires_time = QDateTime::currentDateTime().secsTo(*expires);
}
- SPDLOG_DEBUG(key.GetId(), subkey_fpr, expires_time);
-
GpgError err;
- if (key.GetFingerprint() == subkey_fpr || subkey_fpr.empty())
- err = gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, nullptr, 0);
- else
- err = gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time,
- subkey_fpr.c_str(), 0);
+ if (key.GetFingerprint() == subkey_fpr || subkey_fpr.isEmpty()) {
+ err =
+ gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ expires_time, nullptr, 0);
+ } else {
+ err =
+ gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ expires_time, subkey_fpr.toUtf8(), 0);
+ }
return err;
}
@@ -102,48 +104,52 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
* @param outputFileName out file name(path)
* @return the process doing this job
*/
-void GpgFrontend::GpgKeyOpera::GenerateRevokeCert(
- const GpgKey& key, const std::string& output_file_path) {
+void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key,
+ const QString& output_path) {
+ const auto app_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{});
// get all components
- GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().AppPath,
- {"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o",
- output_file_path, "--gen-revoke", key.GetFingerprint().c_str()},
- [=](int exit_code, const std::string& p_out, const std::string& p_err) {
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gnupg gen revoke execute error, process stderr: {}, process "
- "stdout: {}",
- p_err, p_out);
- } else {
- SPDLOG_DEBUG(
- "gnupg gen revoke exit_code: {}, process stdout size: {}",
- exit_code, p_out.size());
- }
- },
- [](QProcess* proc) -> void {
- // Code From Gpg4Win
- while (proc->canReadLine()) {
- const QString line = QString::fromUtf8(proc->readLine()).trimmed();
- SPDLOG_DEBUG("line: {}", line.toStdString());
- if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
- proc->write("y\n");
- } else if (line == QLatin1String("[GNUPG:] GET_LINE "
- "ask_revocation_reason.code")) {
- proc->write("0\n");
- } else if (line == QLatin1String("[GNUPG:] GET_LINE "
- "ask_revocation_reason.text")) {
- proc->write("\n");
- } else if (line == QLatin1String(
- "[GNUPG:] GET_BOOL openfile.overwrite.okay")) {
- // We asked before
- proc->write("y\n");
- } else if (line == QLatin1String("[GNUPG:] GET_BOOL "
- "ask_revocation_reason.okay")) {
- proc->write("y\n");
- }
- }
- });
+ GpgCommandExecutor::ExecuteSync(
+ {app_path,
+ {"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o", output_path,
+ "--gen-revoke", key.GetFingerprint()},
+ [=](int exit_code, const QString& p_out, const QString& p_err) {
+ if (exit_code != 0) {
+ GF_CORE_LOG_ERROR(
+ "gnupg gen revoke execute error, process stderr: {}, process "
+ "stdout: {}",
+ p_err, p_out);
+ } else {
+ GF_CORE_LOG_DEBUG(
+ "gnupg gen revoke exit_code: {}, process stdout size: {}",
+ exit_code, p_out.size());
+ }
+ },
+ nullptr,
+ [](QProcess* proc) -> void {
+ // Code From Gpg4Win
+ while (proc->canReadLine()) {
+ const QString line = QString::fromUtf8(proc->readLine()).trimmed();
+ GF_CORE_LOG_DEBUG("line: {}", line.toStdString());
+ if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
+ proc->write("y\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_LINE "
+ "ask_revocation_reason.code")) {
+ proc->write("0\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_LINE "
+ "ask_revocation_reason.text")) {
+ proc->write("\n");
+ } else if (line ==
+ QLatin1String(
+ "[GNUPG:] GET_BOOL openfile.overwrite.okay")) {
+ // We asked before
+ proc->write("y\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_BOOL "
+ "ask_revocation_reason.okay")) {
+ proc->write("y\n");
+ }
+ }
+ }});
}
/**
@@ -151,138 +157,199 @@ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert(
* @param params key generation args
* @return error information
*/
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
- const std::unique_ptr<GenKeyInfo>& params, GpgGenKeyResult& result) {
- auto userid_utf8 = params->GetUserid();
- const char* userid = userid_utf8.c_str();
- auto algo_utf8 = params->GetAlgo() + params->GetKeySizeStr();
-
- SPDLOG_DEBUG("params: {} {}", params->GetAlgo(), params->GetKeySizeStr());
-
- const char* algo = algo_utf8.c_str();
- unsigned long expires = 0;
- {
- using namespace boost::posix_time;
- using namespace std::chrono;
- expires = to_time_t(ptime(params->GetExpireTime())) -
- system_clock::to_time_t(system_clock::now());
- }
+void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
+ auto userid_utf8 = params->GetUserid();
+ const char* userid = userid_utf8.toUtf8();
+ auto algo_utf8 = params->GetAlgo() + params->GetKeySizeStr();
+
+ GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(),
+ params->GetKeySizeStr());
+
+ auto algo = algo_utf8.toUtf8();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
+ flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
+ nullptr, flags);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{
+ gpgme_op_genkey_result(ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ }
- GpgError err;
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createkey", "2.1.0");
+}
- SPDLOG_DEBUG("ctx version, {}", ctx_.GetInfo(false).GnupgVersion);
+/**
+ * Generate a new subkey of a certain key pair
+ * @param key target key pair
+ * @param params opera args
+ * @return error info
+ */
+void GpgKeyOpera::GenerateSubkey(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [key, &ctx = ctx_, params](const DataObjectPtr&) -> GpgError {
+ if (!params->IsSubKey()) return GPG_ERR_CANCELED;
+
+ GF_CORE_LOG_DEBUG("generate subkey algo {} key size {}",
+ params->GetAlgo(), params->GetKeySizeStr());
+
+ auto algo = (params->GetAlgo() + params->GetKeySizeStr()).toUtf8();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires,
+ flags);
+
+ auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), algo, 0,
+ expires, flags);
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createsubkey", "2.1.13");
+}
- if (ctx_.GetInfo(false).GnupgVersion >= "2.1.0") {
- unsigned int flags = 0;
+void GpgKeyOpera::GenerateKeyWithSubkey(
+ const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&ctx = ctx_, params,
+ subkey_params](const DataObjectPtr& data_object) -> GpgError {
+ auto userid = params->GetUserid().toUtf8();
+ auto algo = (params->GetAlgo() + params->GetKeySizeStr()).toUtf8();
+ unsigned long expires = expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
+ flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
+ nullptr, flags);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ return err;
+ }
- if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
- if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
- if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
- if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
- if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
- if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+ auto genkey_result =
+ GpgGenerateKeyResult{gpgme_op_genkey_result(ctx.DefaultContext())};
- SPDLOG_DEBUG("args: {}", userid, algo, expires, flags);
+ auto key =
+ GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint());
+ if (!key.IsGood()) {
+ GF_CORE_LOG_ERROR("cannot get key which has been generate, fpr: {}",
+ genkey_result.GetFingerprint());
+ return err;
+ }
- err = gpgme_op_createkey(ctx_, userid, algo, 0, expires, nullptr, flags);
+ if (subkey_params == nullptr || !subkey_params->IsSubKey()) return err;
- } else {
- std::stringstream ss;
- auto param_format =
- boost::format{
- "<GnupgKeyParms format=\"internal\">\n"
- "Key-Type: %1%\n"
- "Key-Usage: sign\n"
- "Key-Length: %2%\n"
- "Name-Real: %3%\n"
- "Name-Comment: %4%\n"
- "Name-Email: %5%\n"} %
- params->GetAlgo() % params->GetKeyLength() % params->GetName() %
- params->GetComment() % params->GetEmail();
- ss << param_format;
-
- if (!params->IsNonExpired()) {
- auto date = params->GetExpireTime().date();
- ss << boost::format{"Expire-Date: %1%\n"} % to_iso_string(date);
- } else
- ss << boost::format{"Expire-Date: 0\n"};
- if (!params->IsNoPassPhrase())
- ss << boost::format{"Passphrase: %1%\n"} % params->GetPassPhrase();
-
- ss << "</GnupgKeyParms>";
-
- SPDLOG_DEBUG("params: {}", ss.str());
-
- err = gpgme_op_genkey(ctx_, ss.str().c_str(), nullptr, nullptr);
- }
+ GF_CORE_LOG_DEBUG(
+ "try to generate subkey of key: {}, algo {} key size {}",
+ key.GetId(), subkey_params->GetAlgo(),
+ subkey_params->GetKeySizeStr());
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) {
- auto temp_result = _new_result(gpgme_op_genkey_result(ctx_));
- std::swap(temp_result, result);
- }
+ algo = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr())
+ .toUtf8();
+ expires =
+ QDateTime::currentDateTime().secsTo(subkey_params->GetExpireTime());
- return check_gpg_error(err);
-}
+ flags = 0;
+ if (subkey_params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (subkey_params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (subkey_params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (subkey_params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (subkey_params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
-/**
- * Generate a new subkey of a certain key pair
- * @param key target key pair
- * @param params opera args
- * @return error info
- */
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey(
- const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params) {
- if (!params->IsSubKey()) return GPG_ERR_CANCELED;
-
- SPDLOG_DEBUG("generate subkey algo {} key size {}", params->GetAlgo(),
- params->GetKeySizeStr());
-
- auto algo_utf8 = (params->GetAlgo() + params->GetKeySizeStr());
- const char* algo = algo_utf8.c_str();
- unsigned long expires = 0;
- {
- using namespace boost::posix_time;
- using namespace std::chrono;
- expires = to_time_t(ptime(params->GetExpireTime())) -
- system_clock::to_time_t(system_clock::now());
- }
- unsigned int flags = 0;
+ GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
+ algo, expires, flags);
- if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
- if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
- if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
- if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
- if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
- if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+ err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), algo, 0,
+ expires, flags);
- SPDLOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires, flags);
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap(
+ {genkey_result, GpgGenerateKeyResult{gpgme_op_genkey_result(
+ ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({genkey_result, GpgGenerateKeyResult{}});
+ }
- auto err =
- gpgme_op_createsubkey(ctx_, gpgme_key_t(key), algo, 0, expires, flags);
- return check_gpg_error(err);
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyPassword(
- const GpgFrontend::GpgKey& key) {
- if (ctx_.GetInfo(false).GnupgVersion < "2.0.15") {
- SPDLOG_ERROR("operator not support");
- return GPG_ERR_NOT_SUPPORTED;
- }
- auto err = gpgme_op_passwd(ctx_, gpgme_key_t(key), 0);
- return check_gpg_error(err);
+void GpgKeyOpera::ModifyPassword(const GpgKey& key,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&key, &ctx = ctx_](const DataObjectPtr&) -> GpgError {
+ return gpgme_op_passwd(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), 0);
+ },
+ callback, "gpgme_op_passwd", "2.0.15");
}
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyTOFUPolicy(
- const GpgFrontend::GpgKey& key, gpgme_tofu_policy_t tofu_policy) {
- if (ctx_.GetInfo(false).GnupgVersion < "2.1.10") {
- SPDLOG_ERROR("operator not support");
+
+auto GpgKeyOpera::ModifyTOFUPolicy(const GpgKey& key,
+ gpgme_tofu_policy_t tofu_policy)
+ -> GpgError {
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"});
+ GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
+
+ if (CompareSoftwareVersion(gnupg_version, "2.1.10") < 0) {
+ GF_CORE_LOG_ERROR("operator not support");
return GPG_ERR_NOT_SUPPORTED;
}
- auto err = gpgme_op_tofu_policy(ctx_, gpgme_key_t(key), tofu_policy);
- return check_gpg_error(err);
+
+ auto err = gpgme_op_tofu_policy(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key), tofu_policy);
+ return CheckGpgError(err);
}
-void GpgFrontend::GpgKeyOpera::DeleteKey(const GpgFrontend::KeyId& key_id) {
+void GpgKeyOpera::DeleteKey(const GpgFrontend::KeyId& key_id) {
auto keys = std::make_unique<KeyIdArgsList>();
keys->push_back(key_id);
DeleteKeys(std::move(keys));
}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyOpera.h b/src/core/function/gpg/GpgKeyOpera.h
index 5446bd66..a060af1a 100644
--- a/src/core/function/gpg/GpgKeyOpera.h
+++ b/src/core/function/gpg/GpgKeyOpera.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,18 +20,18 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef _GPGKEYOPERA_H
-#define _GPGKEYOPERA_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include <functional>
+
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
@@ -77,8 +77,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param expires
* @return GpgError
*/
- GpgError SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
- std::unique_ptr<boost::posix_time::ptime>& expires);
+ auto SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<QDateTime>& expires) -> GpgError;
/**
* @brief
@@ -86,8 +86,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param key
* @param output_file_name
*/
- void GenerateRevokeCert(const GpgKey& key,
- const std::string& output_file_name);
+ void GenerateRevokeCert(const GpgKey& key, const QString& output_path);
/**
* @brief
@@ -95,7 +94,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param key
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError ModifyPassword(const GpgKey& key);
+ void ModifyPassword(const GpgKey& key, const GpgOperationCallback&);
/**
* @brief
@@ -104,8 +103,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param tofu_policy
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError ModifyTOFUPolicy(const GpgKey& key,
- gpgme_tofu_policy_t tofu_policy);
+ auto ModifyTOFUPolicy(const GpgKey& key, gpgme_tofu_policy_t tofu_policy)
+ -> GpgFrontend::GpgError;
/**
* @brief
*
@@ -113,8 +112,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param result
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params,
- GpgGenKeyResult& result);
+ void GenerateKey(const std::shared_ptr<GenKeyInfo>&,
+ const GpgOperationCallback&);
/**
* @brief
@@ -123,13 +122,23 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param params
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError GenerateSubkey(
- const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params);
+ void GenerateSubkey(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback&);
+
+ /**
+ * @brief
+ *
+ * @param params
+ * @param subkey_params
+ * @param callback
+ */
+ void GenerateKeyWithSubkey(const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params,
+ const GpgOperationCallback& callback);
private:
GpgContext& ctx_ =
GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
};
} // namespace GpgFrontend
-
-#endif // _GPGKEYOPERA_H \ No newline at end of file
diff --git a/src/core/function/gpg/GpgUIDOperator.cpp b/src/core/function/gpg/GpgUIDOperator.cpp
index 7e7a711e..6c0373de 100644
--- a/src/core/function/gpg/GpgUIDOperator.cpp
+++ b/src/core/function/gpg/GpgUIDOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,44 +28,38 @@
#include "GpgUIDOperator.h"
-#include "boost/format.hpp"
+#include "core/GpgModel.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgUIDOperator::GpgUIDOperator(int channel)
+namespace GpgFrontend {
+
+GpgUIDOperator::GpgUIDOperator(int channel)
: SingletonFunctionObject<GpgUIDOperator>(channel) {}
-bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key,
- const std::string& uid) {
- auto err = gpgme_op_adduid(ctx_, gpgme_key_t(key), uid.c_str(), 0);
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- return true;
- else
- return false;
+auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& uid) -> bool {
+ auto err = gpgme_op_adduid(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key), uid.toUtf8(), 0);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::RevUID(const GpgFrontend::GpgKey& key,
- const std::string& uid) {
- auto err =
- check_gpg_error(gpgme_op_revuid(ctx_, gpgme_key_t(key), uid.c_str(), 0));
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- return true;
- else
- return false;
+auto GpgUIDOperator::RevUID(const GpgKey& key, const QString& uid) -> bool {
+ auto err = CheckGpgError(gpgme_op_revuid(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.toUtf8(), 0));
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::SetPrimaryUID(const GpgFrontend::GpgKey& key,
- const std::string& uid) {
- auto err = check_gpg_error(gpgme_op_set_uid_flag(
- ctx_, gpgme_key_t(key), uid.c_str(), "primary", nullptr));
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- return true;
- else
- return false;
+auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key, const QString& uid)
+ -> bool {
+ auto err = CheckGpgError(gpgme_op_set_uid_flag(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.toUtf8(),
+ "primary", nullptr));
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key,
- const std::string& name,
- const std::string& comment,
- const std::string& email) {
- SPDLOG_DEBUG("new uuid: {} {} {}", name, comment, email);
- auto uid = boost::format("%1%(%2%)<%3%>") % name % comment % email;
- return AddUID(key, uid.str());
+auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& name,
+ const QString& comment, const QString& email)
+ -> bool {
+ GF_CORE_LOG_DEBUG("new uuid: {} {} {}", name, comment, email);
+ return AddUID(key, QString("%1(%2)<%3>").arg(name).arg(comment).arg(email));
}
+
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgUIDOperator.h b/src/core/function/gpg/GpgUIDOperator.h
index c4a7d87b..b2cec8bc 100644
--- a/src/core/function/gpg/GpgUIDOperator.h
+++ b/src/core/function/gpg/GpgUIDOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* 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.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
-#define GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
+#pragma once
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
@@ -54,7 +53,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid uid args(combine name&comment&email)
* @return if successful
*/
- bool AddUID(const GpgKey& key, const std::string& uid);
+ auto AddUID(const GpgKey& key, const QString& uid) -> bool;
/**
* create a new uid in certain key pair
@@ -64,8 +63,8 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param email
* @return
*/
- bool AddUID(const GpgKey& key, const std::string& name,
- const std::string& comment, const std::string& email);
+ auto AddUID(const GpgKey& key, const QString& name, const QString& comment,
+ const QString& email) -> bool;
/**
* Revoke(Delete) UID from certain key pair
@@ -73,7 +72,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid target uid
* @return if successful
*/
- bool RevUID(const GpgKey& key, const std::string& uid);
+ auto RevUID(const GpgKey& key, const QString& uid) -> bool;
/**
* Set one of a uid of a key pair as primary
@@ -81,7 +80,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid target uid
* @return if successful
*/
- bool SetPrimaryUID(const GpgKey& key, const std::string& uid);
+ auto SetPrimaryUID(const GpgKey& key, const QString& uid) -> bool;
private:
GpgContext& ctx_ =
@@ -89,5 +88,3 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H