aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2025-04-18 15:54:54 +0000
committersaturneric <[email protected]>2025-04-18 15:54:54 +0000
commit8f14fdc7325cb9635e3d92873baaa58f430fca01 (patch)
tree323f462c283ac2151a23cfffd08d52a678c06541
parentfix: add missing libGLESv2.dll on windows platform (diff)
downloadGpgFrontend-8f14fdc7325cb9635e3d92873baaa58f430fca01.tar.gz
GpgFrontend-8f14fdc7325cb9635e3d92873baaa58f430fca01.zip
feat: add more info check
-rw-r--r--src/core/GpgCoreInit.cpp35
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.cpp93
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.h28
-rw-r--r--src/core/function/gpg/GpgAssuanHelper.cpp38
-rw-r--r--src/core/function/gpg/GpgAssuanHelper.h6
-rw-r--r--src/core/function/gpg/GpgAutomatonHandler.cpp69
-rw-r--r--src/core/function/gpg/GpgAutomatonHandler.h8
-rw-r--r--src/core/function/gpg/GpgBasicOperator.cpp44
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp190
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.h70
-rw-r--r--src/core/function/gpg/GpgComponentInfoGetter.cpp64
-rw-r--r--src/core/function/gpg/GpgComponentInfoGetter.h72
-rw-r--r--src/core/function/gpg/GpgFileOpera.cpp61
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.cpp2
-rw-r--r--src/core/function/gpg/GpgKeyManager.cpp26
-rw-r--r--src/core/function/gpg/GpgKeyManager.h3
-rw-r--r--src/core/function/gpg/GpgKeyOpera.cpp36
-rw-r--r--src/core/function/gpg/GpgSmartCardManager.cpp96
-rw-r--r--src/core/function/gpg/GpgSmartCardManager.h16
-rw-r--r--src/core/function/gpg/GpgUIDOperator.cpp19
-rw-r--r--src/core/function/gpg/GpgUIDOperator.h3
-rw-r--r--src/core/utils/AsyncUtils.cpp28
-rw-r--r--src/core/utils/AsyncUtils.h12
-rw-r--r--src/core/utils/CommonUtils.cpp5
-rw-r--r--src/core/utils/CommonUtils.h10
-rw-r--r--src/core/utils/GpgUtils.cpp32
-rw-r--r--src/core/utils/GpgUtils.h19
-rw-r--r--src/init.cpp10
-rw-r--r--src/ui/UserInterfaceUtils.cpp13
-rw-r--r--src/ui/UserInterfaceUtils.h3
-rw-r--r--src/ui/dialog/ADSKsPicker.cpp3
-rw-r--r--src/ui/dialog/controller/SmartCardControllerDialog.cpp73
-rw-r--r--src/ui/function/GpgOperaHelper.cpp22
-rw-r--r--src/ui/main_window/MainWindow.h2
-rw-r--r--src/ui/main_window/MainWindowSlotUI.cpp80
35 files changed, 826 insertions, 465 deletions
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp
index b544d071..ff9bb231 100644
--- a/src/core/GpgCoreInit.cpp
+++ b/src/core/GpgCoreInit.cpp
@@ -225,17 +225,17 @@ auto InitGpgME() -> bool {
"core", "gpgme.ctx.gnupg_version", QString{});
if (!has_gpgconf) {
- FLOG_E() << "cannot get gpgconf backend engine, abort...";
+ LOG_E() << "cannot get gpgconf backend engine, abort...";
return false;
}
if (!has_openpgp) {
- FLOG_E() << "cannot get openpgp backend engine, abort...";
+ LOG_E() << "cannot get openpgp backend engine, abort...";
return false;
}
if (!has_cms) {
- FLOG_E() << "cannot get cms backend engine, abort...";
+ LOG_E() << "cannot get cms backend engine, abort...";
return false;
}
@@ -520,8 +520,8 @@ auto InitGpgFrontendCore(CoreInitArgs args) -> int {
assert(!key_dbs.isEmpty());
if (key_dbs.isEmpty()) {
- FLOG_E() << "Cannot find any valid key database!"
- << "GpgFrontend cannot start under this situation!";
+ LOG_E() << "Cannot find any valid key database!"
+ << "GpgFrontend cannot start under this situation!";
Module::UpsertRTValue("core", "env.state.ctx", -1);
CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
QCoreApplication::tr("No valid Key Database"));
@@ -549,8 +549,8 @@ auto InitGpgFrontendCore(CoreInitArgs args) -> int {
args, kGpgFrontendDefaultChannel));
});
if (!default_ctx.Good()) {
- FLOG_E() << "Init GpgME Default Context failed!"
- << "GpgFrontend cannot start under this situation!";
+ LOG_E() << "Init GpgME Default Context failed!"
+ << "GpgFrontend cannot start under this situation!";
Module::UpsertRTValue("core", "env.state.ctx", -1);
CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
QCoreApplication::tr("GpgME Default Context Initiation Failed"));
@@ -560,8 +560,8 @@ auto InitGpgFrontendCore(CoreInitArgs args) -> int {
Module::UpsertRTValue("core", "env.state.ctx", 1);
if (!GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).FlushKeyCache()) {
- FLOG_E() << "Init GpgME Default Key Database failed!"
- << "GpgFrontend cannot start under this situation!";
+ LOG_E() << "Init GpgME Default Key Database failed!"
+ << "GpgFrontend cannot start under this situation!";
Module::UpsertRTValue("core", "env.state.ctx", -1);
CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
QCoreApplication::tr("Gpg Default Key Database Initiation Failed"));
@@ -602,13 +602,13 @@ auto InitGpgFrontendCore(CoreInitArgs args) -> int {
});
if (!ctx.Good()) {
- FLOG_E() << "gpgme context init failed, index:" << channel_index;
+ LOG_E() << "gpgme context init failed, index:" << channel_index;
continue;
}
if (!GpgKeyGetter::GetInstance(ctx.GetChannel()).FlushKeyCache()) {
- FLOG_E() << "gpgme context init key cache failed, index:"
- << channel_index;
+ LOG_E() << "gpgme context init key cache failed, index:"
+ << channel_index;
continue;
}
@@ -631,9 +631,16 @@ auto InitGpgFrontendCore(CoreInitArgs args) -> int {
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
->PostTask(task);
- if (!args.unit_test_mode && restart_all_gnupg_components_on_start) {
- GpgAdvancedOperator::RestartGpgComponents(nullptr);
+ const auto size = GpgContext::GetAllChannelId().size();
+ for (auto i = 0; i < size; i++) {
+ if (!args.unit_test_mode && restart_all_gnupg_components_on_start) {
+ assert(GpgAdvancedOperator::GetInstance().RestartGpgComponents());
+ } else {
+ // ensure gpg-agent is running
+ assert(GpgAdvancedOperator::GetInstance().LaunchAllGpgComponents());
+ }
}
+
return 0;
}
diff --git a/src/core/function/gpg/GpgAdvancedOperator.cpp b/src/core/function/gpg/GpgAdvancedOperator.cpp
index 492297c6..c9af8b59 100644
--- a/src/core/function/gpg/GpgAdvancedOperator.cpp
+++ b/src/core/function/gpg/GpgAdvancedOperator.cpp
@@ -33,91 +33,38 @@
#include "GpgAdvancedOperator.h"
#include "core/function/gpg/GpgCommandExecutor.h"
-#include "core/module/ModuleManager.h"
-#include "core/utils/GpgUtils.h"
-
namespace GpgFrontend {
-void ExecuteGpgCommand(const QString &operation, const QStringList &extra_args,
- OperationCallback cb) {
- const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.gpgconf_path", QString{});
-
- if (gpgconf_path.isEmpty()) {
- FLOG_W("cannot get valid gpgconf path from rt, abort.");
- if (cb) cb(-1, TransferParams());
- return;
- }
-
- auto key_dbs = GetGpgKeyDatabaseInfos();
- auto total_tasks = static_cast<int>(key_dbs.size());
- std::atomic<int> completed_tasks{0};
- std::vector<int> results(total_tasks, 0);
-
- // kill default gpg-agent
- key_dbs.push_back({});
-
- int task_index = 0;
- for (const auto &key_db : key_dbs) {
- const int current_index = task_index++;
- const auto target_home_dir =
- QDir::toNativeSeparators(QFileInfo(key_db.path).canonicalFilePath());
-
- QStringList arguments = !target_home_dir.isEmpty()
- ? QStringList{"--homedir", target_home_dir}
- : QStringList{};
- arguments.append(extra_args);
-
- GpgCommandExecutor::ExecuteSync(
- {gpgconf_path, arguments,
- [=, &completed_tasks, &results](int exit_code, const QString &,
- const QString &) {
- FLOG_D("%s exit code: %d", qPrintable(operation), exit_code);
-
- results[current_index] = exit_code;
-
- if (++completed_tasks == total_tasks && cb) {
- int final_result =
- std::all_of(results.begin(), results.end(),
- [](int result) { return result >= 0; })
- ? 0
- : -1;
- cb(final_result, TransferParams());
- }
- }});
- }
-}
-
-void GpgAdvancedOperator::ClearGpgPasswordCache(OperationCallback cb) {
- ExecuteGpgCommand("Clear GPG Password Cache", {"--reload", "gpg-agent"},
- std::move(cb));
+auto GpgAdvancedOperator::ClearGpgPasswordCache() -> bool {
+ auto [ret, out] = exec_.GpgConfExecuteSync({{"--reload", "gpg-agent"}});
+ return ret == 0;
}
-void GpgAdvancedOperator::ReloadGpgComponents(OperationCallback cb) {
- const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.gpgconf_path", QString{});
- ExecuteGpgCommand("Reload GPG Components", {"--reload", "all"},
- std::move(cb));
+auto GpgAdvancedOperator::ReloadAllGpgComponents() -> bool {
+ auto [ret, out] = exec_.GpgConfExecuteSync({{"--reload", "all"}});
+ return ret == 0;
}
-void GpgAdvancedOperator::KillAllGpgComponents(OperationCallback cb) {
- ExecuteGpgCommand("Kill All GPG Components", {"--kill", "all"},
- std::move(cb));
+auto GpgAdvancedOperator::KillAllGpgComponents() -> bool {
+ auto [ret, out] = exec_.GpgConfExecuteSync({{"--kill", "all"}});
+ return ret == 0;
}
-void GpgAdvancedOperator::ResetConfigures(OperationCallback cb) {
- ExecuteGpgCommand("Reset Gnupg Configures", {"--apply-defaults"},
- std::move(cb));
+auto GpgAdvancedOperator::ResetConfigures() -> bool {
+ auto [ret, out] = exec_.GpgConfExecuteSync({{"--apply-defaults"}});
+ return ret == 0;
}
-void GpgAdvancedOperator::LaunchGpgComponents(OperationCallback cb) {
- ExecuteGpgCommand("Launch All GPG Components", {"--launch", "all"},
- std::move(cb));
+auto GpgAdvancedOperator::LaunchAllGpgComponents() -> bool {
+ auto [ret, out] = exec_.GpgConfExecuteSync({{"--launch", "all"}});
+ return ret == 0;
}
-void GpgAdvancedOperator::RestartGpgComponents(OperationCallback cb) {
- KillAllGpgComponents(nullptr);
- LaunchGpgComponents(std::move(cb));
+auto GpgAdvancedOperator::RestartGpgComponents() -> bool {
+ if (!KillAllGpgComponents()) return false;
+ return LaunchAllGpgComponents();
}
+GpgAdvancedOperator::GpgAdvancedOperator(int channel)
+ : SingletonFunctionObject<GpgAdvancedOperator>(channel) {}
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgAdvancedOperator.h b/src/core/function/gpg/GpgAdvancedOperator.h
index 57279adb..1099c3b3 100644
--- a/src/core/function/gpg/GpgAdvancedOperator.h
+++ b/src/core/function/gpg/GpgAdvancedOperator.h
@@ -32,19 +32,29 @@
#pragma once
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgCommandExecutor.h"
#include "core/model/DataObject.h"
namespace GpgFrontend {
-class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator {
+class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
+ : public SingletonFunctionObject<GpgAdvancedOperator> {
public:
/**
+ * @brief Construct a new Gpg Advanced Operator object
+ *
+ * @param channel
+ */
+ explicit GpgAdvancedOperator(int channel);
+
+ /**
* @brief
*
* @return true
* @return false
*/
- static void ClearGpgPasswordCache(OperationCallback);
+ auto ClearGpgPasswordCache() -> bool;
/**
* @brief
@@ -52,7 +62,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator {
* @return true
* @return false
*/
- static void ReloadGpgComponents(OperationCallback);
+ auto ReloadAllGpgComponents() -> bool;
/**
* @brief
@@ -60,7 +70,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator {
* @return true
* @return false
*/
- static void RestartGpgComponents(OperationCallback);
+ auto RestartGpgComponents() -> bool;
/**
* @brief
@@ -68,7 +78,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator {
* @return true
* @return false
*/
- static void ResetConfigures(OperationCallback);
+ auto ResetConfigures() -> bool;
/**
* @brief
@@ -76,13 +86,17 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator {
* @return true
* @return false
*/
- static void LaunchGpgComponents(OperationCallback);
+ auto LaunchAllGpgComponents() -> bool;
/**
* @brief
*
*/
- static void KillAllGpgComponents(OperationCallback);
+ auto KillAllGpgComponents() -> bool;
+
+ private:
+ GpgCommandExecutor& exec_ =
+ GpgCommandExecutor::GetInstance(SingletonFunctionObject::GetChannel());
};
} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgAssuanHelper.cpp b/src/core/function/gpg/GpgAssuanHelper.cpp
index 0d1b9cdc..128ecaa9 100644
--- a/src/core/function/gpg/GpgAssuanHelper.cpp
+++ b/src/core/function/gpg/GpgAssuanHelper.cpp
@@ -44,14 +44,14 @@ GpgAssuanHelper::~GpgAssuanHelper() {
}
}
-auto GpgAssuanHelper::ConnectToSocket(GpgComponentType type) -> bool {
- if (assuan_ctx_.contains(type)) return true;
+auto GpgAssuanHelper::ConnectToSocket(GpgComponentType type) -> GpgError {
+ if (assuan_ctx_.contains(type)) return GPG_ERR_NO_ERROR;
auto socket_path = ctx_.ComponentDirectory(type);
if (socket_path.isEmpty()) {
LOG_W() << "socket path of component: " << component_type_to_q_string(type)
<< " is empty";
- return false;
+ return GPG_ERR_ENOPKG;
}
QFileInfo info(socket_path);
@@ -65,7 +65,7 @@ auto GpgAssuanHelper::ConnectToSocket(GpgComponentType type) -> bool {
if (!info.exists()) {
LOG_W() << "socket path is still not exists: " << socket_path
<< "abort...";
- return false;
+ return GPG_ERR_ENOTSOCK;
}
}
@@ -76,7 +76,7 @@ auto GpgAssuanHelper::ConnectToSocket(GpgComponentType type) -> bool {
ASSUAN_INVALID_PID, 0);
if (err != GPG_ERR_NO_ERROR) {
LOG_W() << "failed to connect to socket:" << CheckGpgError(err);
- return false;
+ return err;
}
LOG_D() << "connected to socket by assuan protocol: "
@@ -86,21 +86,23 @@ auto GpgAssuanHelper::ConnectToSocket(GpgComponentType type) -> bool {
nullptr, nullptr, nullptr, nullptr);
if (err != GPG_ERR_NO_ERROR) {
LOG_W() << "failed to test assuan connection:" << CheckGpgError(err);
- return false;
+ return err;
}
assuan_ctx_[type] = a_ctx;
- return true;
+ return err;
}
auto GpgAssuanHelper::SendCommand(GpgComponentType type, const QString& command,
DataCallback data_cb,
InqueryCallback inquery_cb,
- StatusCallback status_cb) -> bool {
+ StatusCallback status_cb) -> GpgError {
if (!assuan_ctx_.contains(type)) {
LOG_W() << "haven't connect to: " << component_type_to_q_string(type)
<< ", trying to make a connection";
- if (!ConnectToSocket(type)) return false;
+
+ auto err = CheckGpgError(ConnectToSocket(type));
+ if (err != GPG_ERR_NO_ERROR) return err;
}
auto context = QSharedPointer<AssuanCallbackContext>::create();
@@ -122,15 +124,15 @@ auto GpgAssuanHelper::SendCommand(GpgComponentType type, const QString& command,
if (CheckGpgError(err) == 32877) {
assuan_ctx_.remove(type);
}
- return false;
+ return err;
}
- return true;
+ return err;
}
auto GpgAssuanHelper::SendStatusCommand(GpgComponentType type,
const QString& command)
- -> std::tuple<bool, QStringList> {
+ -> std::tuple<GpgError, QStringList> {
GpgAssuanHelper::DataCallback d_cb =
[&](const QSharedPointer<GpgAssuanHelper::AssuanCallbackContext>& ctx)
-> gpg_error_t {
@@ -147,29 +149,29 @@ auto GpgAssuanHelper::SendStatusCommand(GpgComponentType type,
return 0;
};
- QStringList status_lines;
+ QStringList lines;
GpgAssuanHelper::StatusCallback s_cb =
[&](const QSharedPointer<GpgAssuanHelper::AssuanCallbackContext>& ctx)
-> gpg_error_t {
LOG_D() << "status callback of command: " << command << ": "
<< ctx->status;
- status_lines.append(ctx->status);
+ lines.append(ctx->status);
return 0;
};
auto ret = SendCommand(type, command, d_cb, i_cb, s_cb);
- return {ret, status_lines};
+ return {ret, lines};
}
auto GpgAssuanHelper::SendDataCommand(GpgComponentType type,
const QString& command)
-> std::tuple<bool, QStringList> {
- QStringList data_lines;
+ QStringList lines;
GpgAssuanHelper::DataCallback d_cb =
[&](const QSharedPointer<GpgAssuanHelper::AssuanCallbackContext>& ctx)
-> gpg_error_t {
LOG_D() << "data callback of command " << command << ": " << ctx->buffer;
- data_lines.push_back(QString::fromUtf8(ctx->buffer));
+ lines.push_back(QString::fromUtf8(ctx->buffer));
return 0;
};
@@ -192,7 +194,7 @@ auto GpgAssuanHelper::SendDataCommand(GpgComponentType type,
};
auto ret = SendCommand(type, command, d_cb, i_cb, s_cb);
- return {ret, data_lines};
+ return {ret, lines};
}
auto GpgAssuanHelper::default_data_callback(void* opaque, const void* buffer,
diff --git a/src/core/function/gpg/GpgAssuanHelper.h b/src/core/function/gpg/GpgAssuanHelper.h
index 294d33e0..7f3854b6 100644
--- a/src/core/function/gpg/GpgAssuanHelper.h
+++ b/src/core/function/gpg/GpgAssuanHelper.h
@@ -81,7 +81,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAssuanHelper
* @return true
* @return false
*/
- auto ConnectToSocket(GpgComponentType) -> bool;
+ auto ConnectToSocket(GpgComponentType) -> GpgError;
/**
* @brief
@@ -96,7 +96,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAssuanHelper
*/
auto SendCommand(GpgComponentType type, const QString& command,
DataCallback data_cb, InqueryCallback inquery_cb,
- StatusCallback status_cb) -> bool;
+ StatusCallback status_cb) -> GpgError;
/**
* @brief
@@ -106,7 +106,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAssuanHelper
* @return std::tuple<bool, QStringList>
*/
auto SendStatusCommand(GpgComponentType type, const QString& command)
- -> std::tuple<bool, QStringList>;
+ -> std::tuple<GpgError, QStringList>;
/**
* @brief
diff --git a/src/core/function/gpg/GpgAutomatonHandler.cpp b/src/core/function/gpg/GpgAutomatonHandler.cpp
index 656bb018..afa55299 100644
--- a/src/core/function/gpg/GpgAutomatonHandler.cpp
+++ b/src/core/function/gpg/GpgAutomatonHandler.cpp
@@ -39,65 +39,61 @@ GpgAutomatonHandler::GpgAutomatonHandler(int channel)
auto InteratorCbFunc(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;
+ auto* handel = static_cast<AutomatonHandelStruct*>(handle);
+ const auto status_s = QString::fromUtf8(status);
+ const auto args_s = QString::fromUtf8(args);
if (status_s == "KEY_CONSIDERED") {
auto tokens = QString(args).split(' ');
- if (handle_struct->KeyFpr().isEmpty()) return 0;
+ if (handel->KeyFpr().isEmpty()) return GPG_ERR_NO_ERROR;
- if (tokens.empty() || tokens[0] != handle_struct->KeyFpr()) {
- LOG_W() << "handle struct key fpr: " << handle_struct->KeyFpr()
+ if (tokens.empty() || tokens[0] != handel->KeyFpr()) {
+ LOG_W() << "handle struct key fpr: " << handel->KeyFpr()
<< "mismatch token: " << tokens[0] << ", exit...";
-
+ handel->SetSuccess(false);
return -1;
}
- return 0;
+ return GPG_ERR_NO_ERROR;
}
if (status_s == "CARDCTRL") {
auto tokens = QString(args).split(' ');
- if (handle_struct->SerialNumber().isEmpty()) return 0;
+ if (handel->SerialNumber().isEmpty()) return GPG_ERR_NO_ERROR;
- if (tokens.empty() || tokens[0] != handle_struct->SerialNumber()) {
- LOG_W() << "handle struct serial number: "
- << handle_struct->SerialNumber()
+ if (tokens.empty() || tokens[0] != handel->SerialNumber()) {
+ LOG_W() << "handle struct serial number: " << handel->SerialNumber()
<< "mismatch token: " << tokens[0] << ", exit...";
-
+ handel->SetSuccess(false);
return -1;
}
- return 0;
+ return GPG_ERR_NO_ERROR;
}
if (status_s == "GOT_IT" || status_s.isEmpty()) {
FLOG_D("gpg reply is GOT_IT, continue...");
- return 0;
+ return GPG_ERR_NO_ERROR;
}
- LOG_D() << "current state" << handle_struct->CurrentStatus()
+ LOG_D() << "current state" << handel->CurrentStatus()
<< "gpg status: " << status_s << ", args: " << args_s;
- handle_struct->SetPromptStatus(status_s, args_s);
+ handel->SetPromptStatus(status_s, args_s);
- AutomatonState next_state = handle_struct->NextState(status_s, args_s);
+ AutomatonState next_state = handel->NextState(status_s, args_s);
if (next_state == GpgAutomatonHandler::kAS_ERROR) {
- FLOG_D("handle struct next state caught error, abort...");
+ FLOG_D("handel next state caught error, abort...");
+ handel->SetSuccess(false);
return -1;
}
- LOG_D() << "next state" << next_state;
-
- if (next_state == GpgAutomatonHandler::kAS_SAVE) {
- handle_struct->SetSuccess(true);
- }
+ LOG_D() << "next state:" << next_state;
// set state and preform action
- handle_struct->SetStatus(next_state);
- GpgAutomatonHandler::Command cmd = handle_struct->Action();
+ handel->SetStatus(next_state);
+ GpgAutomatonHandler::Command cmd = handel->Action();
LOG_D() << "next action, cmd:" << cmd;
@@ -110,32 +106,33 @@ auto InteratorCbFunc(void* handle, const char* status, const char* args,
return GPG_ERR_FALSE;
}
- return 0;
+ return GPG_ERR_NO_ERROR;
}
auto DoInteractImpl(GpgContext& ctx_, const GpgKeyPtr& key, bool card_edit,
const QString& id,
AutomatonNextStateHandler next_state_handler,
- AutomatonActionHandler action_handler, int flags) -> bool {
+ AutomatonActionHandler action_handler,
+ int flags) -> std::tuple<GpgError, bool> {
gpgme_key_t p_key = key == nullptr ? nullptr : static_cast<gpgme_key_t>(*key);
- AutomatonHandelStruct handel_struct(card_edit, id);
- handel_struct.SetHandler(std::move(next_state_handler),
- std::move(action_handler));
+ AutomatonHandelStruct handel(card_edit, id);
+ handel.SetHandler(std::move(next_state_handler), std::move(action_handler));
GpgData data_out;
auto err =
gpgme_op_interact(ctx_.DefaultContext(), p_key, flags, InteratorCbFunc,
- static_cast<void*>(&handel_struct), data_out);
- return CheckGpgError(err) == GPG_ERR_NO_ERROR && handel_struct.Success();
+ static_cast<void*>(&handel), data_out);
+ return {err, handel.Success()};
}
auto GpgAutomatonHandler::DoInteract(
const GpgKeyPtr& key, AutomatonNextStateHandler next_state_handler,
- AutomatonActionHandler action_handler, int flags) -> bool {
+ AutomatonActionHandler action_handler,
+ int flags) -> std::tuple<GpgError, bool> {
assert(key != nullptr);
- if (key == nullptr) return false;
+ if (key == nullptr) return {GPG_ERR_USER_1, false};
return DoInteractImpl(ctx_, key, false, key->ID(),
std::move(next_state_handler),
std::move(action_handler), flags);
@@ -143,7 +140,7 @@ auto GpgAutomatonHandler::DoInteract(
auto GpgAutomatonHandler::DoCardInteract(
const QString& serial_number, AutomatonNextStateHandler next_state_handler,
- AutomatonActionHandler action_handler) -> bool {
+ AutomatonActionHandler action_handler) -> std::tuple<GpgError, bool> {
return DoInteractImpl(ctx_, nullptr, true, serial_number,
std::move(next_state_handler),
std::move(action_handler), GPGME_INTERACT_CARD);
diff --git a/src/core/function/gpg/GpgAutomatonHandler.h b/src/core/function/gpg/GpgAutomatonHandler.h
index 4363cf30..7ab2bf44 100644
--- a/src/core/function/gpg/GpgAutomatonHandler.h
+++ b/src/core/function/gpg/GpgAutomatonHandler.h
@@ -83,7 +83,7 @@ class GpgAutomatonHandler
AutomatonState current_state_ = kAS_START;
AutomatonNextStateHandler next_state_handler_;
AutomatonActionHandler action_handler_;
- bool success_ = false;
+ bool success_ = true;
bool card_edit_;
QString id_;
QString prompt_status_;
@@ -110,7 +110,8 @@ class GpgAutomatonHandler
*/
auto DoInteract(const GpgKeyPtr& key,
AutomatonNextStateHandler next_state_handler,
- AutomatonActionHandler action_handler, int flags = 0) -> bool;
+ AutomatonActionHandler action_handler,
+ int flags = 0) -> std::tuple<GpgError, bool>;
/**
* @brief
@@ -122,7 +123,8 @@ class GpgAutomatonHandler
*/
auto DoCardInteract(const QString& serial_number,
AutomatonNextStateHandler next_state_handler,
- AutomatonActionHandler action_handler) -> bool;
+ AutomatonActionHandler action_handler)
+ -> std::tuple<GpgError, bool>;
private:
GpgContext& ctx_ =
diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp
index 2f624b60..bdb687bc 100644
--- a/src/core/function/gpg/GpgBasicOperator.cpp
+++ b/src/core/function/gpg/GpgBasicOperator.cpp
@@ -88,39 +88,43 @@ void GpgBasicOperator::Encrypt(const GpgAbstractKeyPtrList& keys,
const GFBuffer& in_buffer, bool ascii,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return EncryptImpl(ctx_, keys, in_buffer, ascii, data_object);
},
- cb, "gpgme_op_encrypt", "2.1.0");
+ cb, "gpgme_op_encrypt", "2.2.0");
}
auto GpgBasicOperator::EncryptSync(const GpgAbstractKeyPtrList& keys,
const GFBuffer& in_buffer, bool ascii)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return EncryptImpl(ctx_, keys, in_buffer, ascii, data_object);
},
- "gpgme_op_encrypt", "2.1.0");
+ "gpgme_op_encrypt", "2.2.0");
}
void GpgBasicOperator::EncryptSymmetric(const GFBuffer& in_buffer, bool ascii,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return EncryptImpl(ctx_, {}, in_buffer, ascii, data_object);
},
- cb, "gpgme_op_encrypt_symmetric", "2.1.0");
+ cb, "gpgme_op_encrypt_symmetric", "2.2.0");
}
auto GpgBasicOperator::EncryptSymmetricSync(const GFBuffer& in_buffer,
bool ascii)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return EncryptImpl(ctx_, {}, in_buffer, ascii, data_object);
},
- "gpgme_op_encrypt_symmetric", "2.1.0");
+ "gpgme_op_encrypt_symmetric", "2.2.0");
}
auto DecryptImpl(GpgContext& ctx_, const GFBuffer& in_buffer,
@@ -141,19 +145,21 @@ auto DecryptImpl(GpgContext& ctx_, const GFBuffer& in_buffer,
void GpgBasicOperator::Decrypt(const GFBuffer& in_buffer,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return DecryptImpl(ctx_, in_buffer, data_object);
},
- cb, "gpgme_op_decrypt", "2.1.0");
+ cb, "gpgme_op_decrypt", "2.2.0");
}
auto GpgBasicOperator::DecryptSync(const GFBuffer& in_buffer)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return DecryptImpl(ctx_, in_buffer, data_object);
},
- "gpgme_op_decrypt", "2.1.0");
+ "gpgme_op_decrypt", "2.2.0");
}
auto VerifyImpl(GpgContext& ctx_, const GFBuffer& in_buffer,
@@ -185,20 +191,22 @@ void GpgBasicOperator::Verify(const GFBuffer& in_buffer,
const GFBuffer& sig_buffer,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return VerifyImpl(ctx_, in_buffer, sig_buffer, data_object);
},
- cb, "gpgme_op_verify", "2.1.0");
+ cb, "gpgme_op_verify", "2.2.0");
}
auto GpgBasicOperator::VerifySync(const GFBuffer& in_buffer,
const GFBuffer& sig_buffer)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return VerifyImpl(ctx_, in_buffer, sig_buffer, data_object);
},
- "gpgme_op_verify", "2.1.0");
+ "gpgme_op_verify", "2.2.0");
}
auto SignImpl(GpgContext& ctx_, const GpgAbstractKeyPtrList& signers,
@@ -228,20 +236,22 @@ void GpgBasicOperator::Sign(const GpgAbstractKeyPtrList& signers,
const GFBuffer& in_buffer, GpgSignMode mode,
bool ascii, const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return SignImpl(ctx_, signers, in_buffer, mode, ascii, data_object);
},
- cb, "gpgme_op_sign", "2.1.0");
+ cb, "gpgme_op_sign", "2.2.0");
}
auto GpgBasicOperator::SignSync(
const GpgAbstractKeyPtrList& signers, const GFBuffer& in_buffer,
GpgSignMode mode, bool ascii) -> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return SignImpl(ctx_, signers, in_buffer, mode, ascii, data_object);
},
- "gpgme_op_sign", "2.1.0");
+ "gpgme_op_sign", "2.2.0");
}
auto DecryptVerifyImpl(GpgContext& ctx_, const GFBuffer& in_buffer,
@@ -266,19 +276,21 @@ auto DecryptVerifyImpl(GpgContext& ctx_, const GFBuffer& in_buffer,
void GpgBasicOperator::DecryptVerify(const GFBuffer& in_buffer,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return DecryptVerifyImpl(ctx_, in_buffer, data_object);
},
- cb, "gpgme_op_decrypt_verify", "2.1.0");
+ cb, "gpgme_op_decrypt_verify", "2.2.0");
}
auto GpgBasicOperator::DecryptVerifySync(const GFBuffer& in_buffer)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return DecryptVerifyImpl(ctx_, in_buffer, data_object);
},
- "gpgme_op_decrypt_verify", "2.1.0");
+ "gpgme_op_decrypt_verify", "2.2.0");
}
auto EncryptSignImpl(GpgContext& ctx_, const GpgAbstractKeyPtrList& keys,
@@ -315,11 +327,12 @@ void GpgBasicOperator::EncryptSign(const GpgAbstractKeyPtrList& keys,
const GFBuffer& in_buffer, bool ascii,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return EncryptSignImpl(ctx_, keys, signers, in_buffer, ascii,
data_object);
},
- cb, "gpgme_op_encrypt_sign", "2.1.0");
+ cb, "gpgme_op_encrypt_sign", "2.2.0");
}
auto GpgBasicOperator::EncryptSignSync(const GpgAbstractKeyPtrList& keys,
@@ -327,11 +340,12 @@ auto GpgBasicOperator::EncryptSignSync(const GpgAbstractKeyPtrList& keys,
const GFBuffer& in_buffer, bool ascii)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return EncryptSignImpl(ctx_, keys, signers, in_buffer, ascii,
data_object);
},
- "gpgme_op_encrypt_sign", "2.1.0");
+ "gpgme_op_encrypt_sign", "2.2.0");
}
void GpgBasicOperator::SetSigners(const GpgAbstractKeyPtrList& signers,
@@ -346,7 +360,7 @@ auto GpgBasicOperator::GetSigners(bool ascii) -> KeyArgsList {
auto signers = KeyArgsList{};
for (auto i = 0U; i < count; i++) {
auto key = GpgKey(gpgme_signers_enum(ctx, i));
- signers.push_back(GpgKey(std::move(key)));
+ signers.push_back(GpgKey(key));
}
return signers;
}
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
index dd8a500e..72988a55 100644
--- a/src/core/function/gpg/GpgCommandExecutor.cpp
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -41,26 +41,25 @@ 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;
+ const auto &int_func = context.int_func;
+ const auto &cb = context.cb_func;
- Thread::Task::TaskCallback result_callback =
- [cmd](int /*rtn*/, const DataObjectPtr &data_object) {
- LOG_D() << "data object args count of cmd executor result callback:"
- << data_object->GetObjectSize();
+ Thread::Task::TaskCallback result_callback = [cmd](int /*rtn*/,
+ const DataObjectPtr &obj) {
+ LOG_D() << "data object args count of cmd executor result callback:"
+ << obj->GetObjectSize();
- if (!data_object->Check<int, QString, GpgCommandExecutorCallback>()) {
- FLOG_W("data object checking failed");
- return;
- }
+ if (!obj->Check<int, QByteArray, GpgCommandExecutorCallback>()) {
+ FLOG_W("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);
+ auto code = ExtractParams<int>(obj, 0);
+ auto out = ExtractParams<QByteArray>(obj, 1);
+ auto cb = ExtractParams<GpgCommandExecutorCallback>(obj, 2);
- callback(exit_code, process_stdout, {});
- };
+ cb(code, out, {});
+ };
Thread::Task::TaskRunnable runner =
[](const DataObjectPtr &data_object) -> int {
@@ -82,71 +81,67 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
const QString joined_argument = arguments.join(" ");
// create process
- auto *cmd_process = new QProcess();
+ auto *pcs = new QProcess();
// move to current thread
//
- cmd_process->moveToThread(QThread::currentThread());
+ pcs->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);
+ pcs->setProcessChannelMode(QProcess::MergedChannels);
+ pcs->setProgram(cmd);
// set arguments
QStringList q_arguments;
for (const auto &argument : arguments) {
q_arguments.append(argument);
}
- cmd_process->setArguments(q_arguments);
+ pcs->setArguments(q_arguments);
+ QObject::connect(pcs, &QProcess::started, [cmd, joined_argument]() -> void {
+ LOG_D() << "\n== Process Execute Started ==\nCommand: " << cmd
+ << "\nArguments: " << joined_argument
+ << " \n========================";
+ });
+ QObject::connect(pcs, &QProcess::readyReadStandardOutput,
+ [interact_func, pcs]() { interact_func(pcs); });
QObject::connect(
- cmd_process, &QProcess::started, [cmd, joined_argument]() -> void {
- LOG_D() << "\n== Process Execute Started ==\nCommand: " << cmd
- << "\nArguments: " << joined_argument
- << " \n========================";
+ pcs, &QProcess::errorOccurred, [=](QProcess::ProcessError error) {
+ LOG_W() << "caught error while executing command: " << cmd
+ << joined_argument << ", error:" << error;
});
- QObject::connect(
- cmd_process, &QProcess::readyReadStandardOutput,
- [interact_func, cmd_process]() { interact_func(cmd_process); });
- QObject::connect(cmd_process, &QProcess::errorOccurred,
- [=](QProcess::ProcessError error) {
- LOG_W()
- << "caught error while executing command: " << cmd
- << joined_argument << ", error:" << error;
- });
LOG_D() << "\n== Process Execute Ready ==\nCommand: " << cmd
<< "\nArguments: " << joined_argument
<< "\n========================";
- cmd_process->start();
- cmd_process->waitForFinished();
+ pcs->start();
+ pcs->waitForFinished();
- QString process_stdout = cmd_process->readAllStandardOutput();
- int exit_code = cmd_process->exitCode();
+ auto out = pcs->readAllStandardOutput();
+ auto code = pcs->exitCode();
LOG_D() << "\n==== Process Execution Summary ====\n"
<< "Command: " << cmd << "\n"
<< "Arguments: " << joined_argument << "\n"
- << "Exit Code: " << exit_code << "\n"
+ << "Exit Code: " << code << "\n"
<< "---- Standard Output ----\n"
- << process_stdout << "\n"
+ << out << "\n"
<< "===============================";
- cmd_process->close();
- cmd_process->deleteLater();
+ pcs->close();
+ pcs->deleteLater();
- data_object->Swap({exit_code, process_stdout, callback});
+ data_object->Swap({code, out, callback});
return 0;
};
return new Thread::Task(
std::move(runner),
QString("GpgCommamdExecutor(%1){%2}").arg(cmd).arg(arguments.join(' ')),
- TransferParams(cmd, arguments, interact_function, cmd_executor_callback),
- std::move(result_callback));
+ TransferParams(cmd, arguments, int_func, cb), std::move(result_callback));
}
-void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
+void GpgCommandExecutor::ExecuteSync(const ExecuteContext &context) {
Thread::Task *task = BuildTaskFromExecCtx(context);
QPointer<Thread::Task> p_t = task;
@@ -174,8 +169,9 @@ void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
looper->deleteLater();
}
-void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
- for (auto &context : contexts) {
+void GpgCommandExecutor::ExecuteConcurrentlyAsync(
+ const ExecuteContexts &contexts) {
+ for (const auto &context : contexts) {
Thread::Task *task = BuildTaskFromExecCtx(context);
if (context.task_runner != nullptr) {
@@ -189,12 +185,13 @@ void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
}
}
-void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
+void GpgCommandExecutor::ExecuteConcurrentlySync(
+ const ExecuteContexts &contexts) {
QEventLoop looper;
auto remaining_tasks = contexts.size();
Thread::TaskRunnerPtr target_task_runner = nullptr;
- for (auto &context : contexts) {
+ for (const auto &context : contexts) {
const auto &cmd = context.cmd;
LOG_D() << "gpg concurrently called cmd: " << cmd;
@@ -235,24 +232,30 @@ GpgCommandExecutor::ExecuteContext::ExecuteContext(
int_func(std::move(int_func)),
task_runner(std::move(task_runner)) {}
+GpgCommandExecutor::ExecuteContext::ExecuteContext(
+ QStringList arguments, GpgCommandExecutorCallback callback,
+ Module::TaskRunnerPtr task_runner, GpgCommandExecutorInterator int_func)
+ : arguments(std::move(arguments)),
+ cb_func(std::move(callback)),
+ int_func(std::move(int_func)),
+ task_runner(std::move(task_runner)) {}
+
GpgCommandExecutor::GpgCommandExecutor(int channel)
: GpgFrontend::SingletonFunctionObject<GpgCommandExecutor>(channel) {}
-void GpgCommandExecutor::GpgExecuteSync(const ExecuteContext &context) {
- const auto gpg_path = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.app_path", QString{});
-
- if (context.cmd.isEmpty() && gpg_path.isEmpty()) {
+auto PrepareContext(const GpgContext &ctx_, const QString &path,
+ const GpgCommandExecutor::ExecuteContext &context)
+ -> std::tuple<bool, GpgCommandExecutor::ExecuteContext> {
+ if (context.cmd.isEmpty() && path.isEmpty()) {
LOG_E() << "failed to execute gpg command, gpg binary path is empty.";
- return;
+ return {false, {}};
}
- LOG_D() << "got gpg binary path:" << gpg_path;
- LOG_D() << "context channel:" << GetChannel()
+ LOG_D() << "got path:" << path << "context channel:" << ctx_.GetChannel()
<< "home path: " << ctx_.HomeDirectory();
- ExecuteContext ctx = {
- context.cmd.isEmpty() ? gpg_path : context.cmd,
+ GpgCommandExecutor::ExecuteContext ctx = {
+ context.cmd.isEmpty() ? path : context.cmd,
context.arguments,
context.cb_func,
context.task_runner,
@@ -260,10 +263,71 @@ void GpgCommandExecutor::GpgExecuteSync(const ExecuteContext &context) {
};
if (!ctx.arguments.contains("--homedir") && !ctx_.HomeDirectory().isEmpty()) {
- ctx.arguments.append("--homedir");
- ctx.arguments.append(ctx_.HomeDirectory());
+ ctx.arguments.prepend(QDir::toNativeSeparators((ctx_.HomeDirectory())));
+ ctx.arguments.prepend("--homedir");
+ }
+
+ return {true, ctx};
+}
+
+auto PrepareExecuteSyncContext(const GpgContext &ctx_, const QString &path,
+ const GpgCommandExecutor::ExecuteContext
+ &context) -> std::tuple<int, QString> {
+ auto ctx = context;
+
+ int pcs_exit_code;
+ QString pcs_stdout;
+
+ // proxy
+ ctx.cb_func = [&](int exit_code, const QString &out, const QString &) {
+ pcs_exit_code = exit_code;
+ pcs_stdout = out;
+ };
+
+ auto [ret, ctx2] = PrepareContext(ctx_, path, ctx);
+ if (ret) {
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(ctx2);
+ return {pcs_exit_code, pcs_stdout};
}
+ return {-1, "invalid context"};
+}
+
+void PrepareExecuteAsyncContext(
+ const GpgContext &ctx_, const QString &path,
+ const GpgCommandExecutor::ExecuteContext &context) {
+ auto [ret, ctx] = PrepareContext(ctx_, path, context);
+ GpgFrontend::GpgCommandExecutor::ExecuteConcurrentlyAsync({ctx});
+}
+
+auto GpgCommandExecutor::GpgExecuteSync(const ExecuteContext &context)
+ -> std::tuple<int, QString> {
+ return PrepareExecuteSyncContext(ctx_,
+ Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{}),
+ context);
+}
+
+auto GpgCommandExecutor::GpgConfExecuteSync(const ExecuteContext &context)
+
+ -> std::tuple<int, QString> {
+ return PrepareExecuteSyncContext(
+ ctx_,
+ Module::RetrieveRTValueTypedOrDefault<>("core", "gpgme.ctx.gpgconf_path",
+ QString{}),
+ context);
+}
+
+void GpgCommandExecutor::GpgExecuteAsync(const ExecuteContext &context) {
+ PrepareExecuteAsyncContext(ctx_,
+ Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{}),
+ context);
+}
- return ExecuteSync(ctx);
+void GpgCommandExecutor::GpgConfExecuteAsync(const ExecuteContext &context) {
+ PrepareExecuteAsyncContext(ctx_,
+ Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{}),
+ context);
}
} // 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 fd2181d3..046b61e4 100644
--- a/src/core/function/gpg/GpgCommandExecutor.h
+++ b/src/core/function/gpg/GpgCommandExecutor.h
@@ -51,12 +51,42 @@ class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
GpgCommandExecutorInterator int_func;
Module::TaskRunnerPtr task_runner = nullptr;
+ /**
+ * @brief Construct a new Execute Context object
+ *
+ */
+ ExecuteContext() = default;
+
+ /**
+ * @brief Construct a new Execute Context object
+ *
+ * @param cmd
+ * @param arguments
+ * @param callback
+ * @param task_runner
+ * @param int_func
+ */
ExecuteContext(
QString cmd, QStringList arguments,
GpgCommandExecutorCallback callback = [](int, const QString &,
const QString &) {},
Module::TaskRunnerPtr task_runner = nullptr,
GpgCommandExecutorInterator int_func = [](QProcess *) {});
+
+ /**
+ * @brief Construct a new Execute Context object
+ *
+ * @param arguments
+ * @param callback
+ * @param task_runner
+ * @param int_func
+ */
+ ExecuteContext(
+ QStringList arguments,
+ GpgCommandExecutorCallback callback = [](int, const QString &,
+ const QString &) {},
+ Module::TaskRunnerPtr task_runner = nullptr,
+ GpgCommandExecutorInterator int_func = [](QProcess *) {});
};
using ExecuteContexts = QContainer<ExecuteContext>;
@@ -69,13 +99,45 @@ class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
* @param arguments Command parameters
* @param interact_func Command answering function
*/
- static void ExecuteSync(ExecuteContext);
+ static void ExecuteSync(const ExecuteContext &);
+
+ /**
+ * @brief
+ *
+ */
+ static void ExecuteConcurrentlyAsync(const ExecuteContexts &);
+
+ /**
+ * @brief
+ *
+ */
+ static void ExecuteConcurrentlySync(const ExecuteContexts &);
- static void ExecuteConcurrentlyAsync(ExecuteContexts);
+ /**
+ * @brief
+ *
+ */
+ auto GpgExecuteSync(const ExecuteContext &) -> std::tuple<int, QString>;
+
+ /**
+ * @brief
+ *
+ */
+ auto GpgConfExecuteSync(const ExecuteContext &) -> std::tuple<int, QString>;
- static void ExecuteConcurrentlySync(ExecuteContexts);
+ /**
+ * @brief
+ *
+ * @param context
+ */
+ void GpgExecuteAsync(const ExecuteContext &);
- void GpgExecuteSync(const ExecuteContext &);
+ /**
+ * @brief
+ *
+ * @param context
+ */
+ void GpgConfExecuteAsync(const ExecuteContext &);
private:
GpgContext &ctx_ =
diff --git a/src/core/function/gpg/GpgComponentInfoGetter.cpp b/src/core/function/gpg/GpgComponentInfoGetter.cpp
new file mode 100644
index 00000000..317f334f
--- /dev/null
+++ b/src/core/function/gpg/GpgComponentInfoGetter.cpp
@@ -0,0 +1,64 @@
+/**
+ * Copyright (C) 2021-2024 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgComponentInfoGetter.h"
+
+namespace GpgFrontend {
+
+GpgComponentInfoGetter::GpgComponentInfoGetter(int channel)
+ : GpgFrontend::SingletonFunctionObject<GpgComponentInfoGetter>(channel) {}
+
+auto GpgComponentInfoGetter::GetGpgAgentVersion() -> QString {
+ if (!gpg_agent_version_.isEmpty()) return gpg_agent_version_;
+
+ auto [r, s] =
+ assuan_.SendDataCommand(GpgComponentType::kGPG_AGENT, "GETINFO version");
+ if (s.isEmpty()) {
+ LOG_D() << "invalid response of GETINFO version: " << s;
+ return {};
+ }
+
+ gpg_agent_version_ = s.front();
+ return gpg_agent_version_;
+}
+
+auto GpgComponentInfoGetter::GetScdaemonVersion() -> QString {
+ if (!scdaemon_version_.isEmpty()) return scdaemon_version_;
+
+ auto [r, s] = assuan_.SendDataCommand(GpgComponentType::kGPG_AGENT,
+ "SCD GETINFO version");
+ if (s.isEmpty()) {
+ LOG_D() << "invalid response of SCD GETINFO version: " << s;
+ return {};
+ }
+
+ scdaemon_version_ = s.front();
+ return scdaemon_version_;
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgComponentInfoGetter.h b/src/core/function/gpg/GpgComponentInfoGetter.h
new file mode 100644
index 00000000..3f8b560b
--- /dev/null
+++ b/src/core/function/gpg/GpgComponentInfoGetter.h
@@ -0,0 +1,72 @@
+/**
+ * Copyright (C) 2021-2024 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/gpg/GpgAssuanHelper.h"
+#include "core/function/gpg/GpgContext.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgComponentInfoGetter
+ : public SingletonFunctionObject<GpgComponentInfoGetter> {
+ public:
+ /**
+ * @brief Construct a new Gpg Assuan Helper object
+ *
+ * @param channel
+ */
+ explicit GpgComponentInfoGetter(int channel);
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ auto GetGpgAgentVersion() -> QString;
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ auto GetScdaemonVersion() -> QString;
+
+ private:
+ GpgContext& ctx_ =
+ GpgContext::GetInstance(SingletonFunctionObject::GetChannel());
+ GpgAssuanHelper& assuan_ =
+ GpgAssuanHelper::GetInstance(SingletonFunctionObject::GetChannel());
+
+ QString gpg_agent_version_;
+ QString scdaemon_version_;
+};
+
+}; // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp
index 334aae6f..b498461f 100644
--- a/src/core/function/gpg/GpgFileOpera.cpp
+++ b/src/core/function/gpg/GpgFileOpera.cpp
@@ -32,7 +32,6 @@
#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"
@@ -95,22 +94,24 @@ void GpgFileOpera::EncryptFile(const GpgAbstractKeyPtrList& keys,
const QString& out_path,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return EncryptFileImpl(ctx_, keys, in_path, ascii, out_path,
data_object);
},
- cb, "gpgme_op_encrypt", "2.1.0");
+ cb, "gpgme_op_encrypt", "2.2.0");
}
auto GpgFileOpera::EncryptFileSync(
const GpgAbstractKeyPtrList& keys, const QString& in_path, bool ascii,
const QString& out_path) -> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return EncryptFileImpl(ctx_, keys, in_path, ascii, out_path,
data_object);
},
- "gpgme_op_encrypt", "2.1.0");
+ "gpgme_op_encrypt", "2.2.0");
}
void GpgFileOpera::EncryptDirectory(const GpgAbstractKeyPtrList& keys,
@@ -120,6 +121,7 @@ void GpgFileOpera::EncryptDirectory(const GpgAbstractKeyPtrList& keys,
auto ex = CreateStandardGFDataExchanger();
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
GpgData data_in(ex);
GpgData data_out(out_path, false);
@@ -127,7 +129,7 @@ void GpgFileOpera::EncryptDirectory(const GpgAbstractKeyPtrList& keys,
return EncryptFileGpgDataImpl(ctx_, keys, data_in, ascii, data_out,
data_object);
},
- cb, "gpgme_op_encrypt", "2.1.0");
+ cb, "gpgme_op_encrypt", "2.2.0");
CreateArchiveHelper(in_path, ex);
}
@@ -155,20 +157,22 @@ auto DecryptFileImpl(GpgContext& ctx_, const QString& in_path,
void GpgFileOpera::DecryptFile(const QString& in_path, const QString& out_path,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return DecryptFileImpl(ctx_, in_path, out_path, data_object);
},
- cb, "gpgme_op_decrypt", "2.1.0");
+ cb, "gpgme_op_decrypt", "2.2.0");
}
auto GpgFileOpera::DecryptFileSync(const QString& in_path,
const QString& out_path)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return DecryptFileImpl(ctx_, in_path, out_path, data_object);
},
- "gpgme_op_decrypt", "2.1.0");
+ "gpgme_op_decrypt", "2.2.0");
}
void GpgFileOpera::DecryptArchive(const QString& in_path,
@@ -177,13 +181,14 @@ void GpgFileOpera::DecryptArchive(const QString& in_path,
auto ex = ExtractArchiveHelper(out_path);
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
GpgData data_in(in_path, true);
GpgData data_out(ex);
return DecryptFileGpgDataImpl(ctx_, data_in, data_out, data_object);
},
- cb, "gpgme_op_decrypt", "2.1.0");
+ cb, "gpgme_op_decrypt", "2.2.0");
}
auto SignFileGpgDataImpl(GpgContext& ctx_, GpgBasicOperator& basic_opera_,
@@ -221,22 +226,24 @@ void GpgFileOpera::SignFile(const GpgAbstractKeyPtrList& keys,
const QString& out_path,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return SignFileImpl(ctx_, basic_opera_, keys, in_path, ascii, out_path,
data_object);
},
- cb, "gpgme_op_sign", "2.1.0");
+ cb, "gpgme_op_sign", "2.2.0");
}
auto GpgFileOpera::SignFileSync(
const GpgAbstractKeyPtrList& keys, const QString& in_path, bool ascii,
const QString& out_path) -> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return SignFileImpl(ctx_, basic_opera_, keys, in_path, ascii, out_path,
data_object);
},
- "gpgme_op_sign", "2.1.0");
+ "gpgme_op_sign", "2.2.0");
}
auto VerifyFileImpl(GpgContext& ctx_, const QString& data_path,
@@ -266,20 +273,22 @@ void GpgFileOpera::VerifyFile(const QString& data_path,
const QString& sign_path,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return VerifyFileImpl(ctx_, data_path, sign_path, data_object);
},
- cb, "gpgme_op_verify", "2.1.0");
+ cb, "gpgme_op_verify", "2.2.0");
}
auto GpgFileOpera::VerifyFileSync(const QString& data_path,
const QString& sign_path)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return VerifyFileImpl(ctx_, data_path, sign_path, data_object);
},
- "gpgme_op_verify", "2.1.0");
+ "gpgme_op_verify", "2.2.0");
}
auto EncryptSignFileGpgDataImpl(GpgContext& ctx_,
@@ -324,11 +333,12 @@ void GpgFileOpera::EncryptSignFile(const GpgAbstractKeyPtrList& keys,
const QString& out_path,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return EncryptSignFileImpl(ctx_, basic_opera_, keys, signer_keys,
in_path, ascii, out_path, data_object);
},
- cb, "gpgme_op_encrypt_sign", "2.1.0");
+ cb, "gpgme_op_encrypt_sign", "2.2.0");
}
auto GpgFileOpera::EncryptSignFileSync(
@@ -336,11 +346,12 @@ auto GpgFileOpera::EncryptSignFileSync(
const QString& in_path, bool ascii,
const QString& out_path) -> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
return EncryptSignFileImpl(ctx_, basic_opera_, keys, signer_keys,
in_path, ascii, out_path, data_object);
},
- "gpgme_op_encrypt_sign", "2.1.0");
+ "gpgme_op_encrypt_sign", "2.2.0");
}
void GpgFileOpera::EncryptSignDirectory(
@@ -350,6 +361,7 @@ void GpgFileOpera::EncryptSignDirectory(
auto ex = CreateStandardGFDataExchanger();
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
GpgData data_in(ex);
GpgData data_out(out_path, false);
@@ -358,7 +370,7 @@ void GpgFileOpera::EncryptSignDirectory(
data_in, ascii, data_out,
data_object);
},
- cb, "gpgme_op_encrypt_sign", "2.1.0");
+ cb, "gpgme_op_encrypt_sign", "2.2.0");
CreateArchiveHelper(in_path, ex);
}
@@ -389,20 +401,22 @@ void GpgFileOpera::DecryptVerifyFile(const QString& in_path,
const QString& out_path,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return DecryptVerifyFileImpl(ctx_, in_path, out_path, data_object);
},
- cb, "gpgme_op_decrypt_verify", "2.1.0");
+ cb, "gpgme_op_decrypt_verify", "2.2.0");
}
auto GpgFileOpera::DecryptVerifyFileSync(const QString& in_path,
const QString& out_path)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return DecryptVerifyFileImpl(ctx_, in_path, out_path, data_object);
},
- "gpgme_op_decrypt_verify", "2.1.0");
+ "gpgme_op_decrypt_verify", "2.2.0");
}
void GpgFileOpera::DecryptVerifyArchive(const QString& in_path,
@@ -411,33 +425,36 @@ void GpgFileOpera::DecryptVerifyArchive(const QString& in_path,
auto ex = ExtractArchiveHelper(out_path);
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
GpgData data_in(in_path, true);
GpgData data_out(ex);
return DecryptVerifyFileGpgDataImpl(ctx_, data_in, data_out,
data_object);
},
- cb, "gpgme_op_decrypt_verify", "2.1.0");
+ cb, "gpgme_op_decrypt_verify", "2.2.0");
}
void GpgFileOpera::EncryptFileSymmetric(const QString& in_path, bool ascii,
const QString& out_path,
const GpgOperationCallback& cb) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return EncryptFileImpl(ctx_, {}, in_path, ascii, out_path, data_object);
},
- cb, "gpgme_op_encrypt_symmetric", "2.1.0");
+ cb, "gpgme_op_encrypt_symmetric", "2.2.0");
}
auto GpgFileOpera::EncryptFileSymmetricSync(const QString& in_path, bool ascii,
const QString& out_path)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return EncryptFileImpl(ctx_, {}, in_path, ascii, out_path, data_object);
},
- "gpgme_op_encrypt_symmetric", "2.1.0");
+ "gpgme_op_encrypt_symmetric", "2.2.0");
}
void GpgFileOpera::EncryptDirectorySymmetric(const QString& in_path, bool ascii,
@@ -446,6 +463,7 @@ void GpgFileOpera::EncryptDirectorySymmetric(const QString& in_path, bool ascii,
auto ex = CreateStandardGFDataExchanger();
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) {
GpgData data_in(ex);
GpgData data_out(out_path, false);
@@ -453,7 +471,7 @@ void GpgFileOpera::EncryptDirectorySymmetric(const QString& in_path, bool ascii,
return EncryptFileGpgDataImpl(ctx_, {}, data_in, ascii, data_out,
data_object);
},
- cb, "gpgme_op_encrypt_symmetric", "2.1.0");
+ cb, "gpgme_op_encrypt_symmetric", "2.2.0");
CreateArchiveHelper(in_path, ex);
}
@@ -466,6 +484,7 @@ auto GpgFileOpera::EncryptDirectorySymmetricSync(
CreateArchiveHelper(in_path, ex);
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
GpgData data_in(ex);
GpgData data_out(out_path, false);
@@ -473,7 +492,7 @@ auto GpgFileOpera::EncryptDirectorySymmetricSync(
return EncryptFileGpgDataImpl(ctx_, {}, data_in, ascii, data_out,
data_object);
},
- "gpgme_op_encrypt_symmetric", "2.1.0");
+ "gpgme_op_encrypt_symmetric", "2.2.0");
}
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp
index eda36273..4e306233 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.cpp
+++ b/src/core/function/gpg/GpgKeyImportExporter.cpp
@@ -105,6 +105,7 @@ void GpgKeyImportExporter::ExportKeys(const GpgAbstractKeyPtrList& keys,
bool ssh_mode,
const GpgOperationCallback& cb) const {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
if (keys.empty()) return GPG_ERR_CANCELED;
@@ -139,6 +140,7 @@ void GpgKeyImportExporter::ExportAllKeys(const GpgAbstractKeyPtrList& keys,
bool secret, bool ascii,
const GpgOperationCallback& cb) const {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
if (keys.empty()) return GPG_ERR_CANCELED;
diff --git a/src/core/function/gpg/GpgKeyManager.cpp b/src/core/function/gpg/GpgKeyManager.cpp
index 1fa050bb..5fca4ed4 100644
--- a/src/core/function/gpg/GpgKeyManager.cpp
+++ b/src/core/function/gpg/GpgKeyManager.cpp
@@ -31,7 +31,6 @@
#include "core/function/gpg/GpgAutomatonHandler.h"
#include "core/function/gpg/GpgBasicOperator.h"
#include "core/function/gpg/GpgKeyGetter.h"
-#include "core/model/GpgData.h"
#include "core/utils/GpgUtils.h"
namespace GpgFrontend {
@@ -69,9 +68,9 @@ auto GpgKeyManager::RevSign(const GpgKeyPtr& key,
auto signing_key = key_getter.GetKey(sign_id.first);
assert(signing_key.IsGood());
- auto err = CheckGpgError(
- gpgme_op_revsig(ctx_.DefaultContext(), gpgme_key_t(*key),
- gpgme_key_t(signing_key), sign_id.second.toUtf8(), 0));
+ auto err = CheckGpgError(gpgme_op_revsig(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(*key),
+ static_cast<gpgme_key_t>(signing_key), sign_id.second.toUtf8(), 0));
if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false;
}
return true;
@@ -102,7 +101,7 @@ auto GpgKeyManager::SetOwnerTrustLevel(const GpgKeyPtr& key,
}
GpgAutomatonHandler::AutomatonNextStateHandler next_state_handler =
- [](AutomatonState state, QString status, QString args) {
+ [](AutomatonState state, const QString& status, const QString& args) {
auto tokens = args.split(' ');
switch (state) {
@@ -162,15 +161,14 @@ auto GpgKeyManager::SetOwnerTrustLevel(const GpgKeyPtr& key,
return QString("Y");
case GpgAutomatonHandler::kAS_START:
case GpgAutomatonHandler::kAS_ERROR:
- return QString("");
default:
return QString("");
}
return QString("");
};
- return GpgAutomatonHandler::GetInstance(GetChannel())
- .DoInteract(key, next_state_handler, action_handler);
+ auto [err, succ] = auto_.DoInteract(key, next_state_handler, action_handler);
+ return err == GPG_ERR_NO_ERROR && !succ;
}
auto GpgKeyManager::DeleteSubkey(const GpgKeyPtr& key,
@@ -182,7 +180,7 @@ auto GpgKeyManager::DeleteSubkey(const GpgKeyPtr& key,
}
AutomatonNextStateHandler next_state_handler =
- [](AutomatonState state, QString status, QString args) {
+ [](AutomatonState state, const QString& status, const QString& args) {
auto tokens = args.split(' ');
switch (state) {
@@ -247,8 +245,8 @@ auto GpgKeyManager::DeleteSubkey(const GpgKeyPtr& key,
return QString("");
};
- return GpgAutomatonHandler::GetInstance(GetChannel())
- .DoInteract(key, next_state_handler, action_handler);
+ auto [err, succ] = auto_.DoInteract(key, next_state_handler, action_handler);
+ return err == GPG_ERR_NO_ERROR && !succ;
}
auto GpgKeyManager::RevokeSubkey(const GpgKeyPtr& key, int subkey_index,
@@ -270,7 +268,7 @@ auto GpgKeyManager::RevokeSubkey(const GpgKeyPtr& key, int subkey_index,
reason_text.split('\n', Qt::SkipEmptyParts));
AutomatonNextStateHandler next_state_handler =
- [](AutomatonState state, QString status, QString args) {
+ [](AutomatonState state, const QString& status, const QString& args) {
auto tokens = args.split(' ');
switch (state) {
@@ -363,8 +361,8 @@ auto GpgKeyManager::RevokeSubkey(const GpgKeyPtr& key, int subkey_index,
return QString("");
};
- return GpgAutomatonHandler::GetInstance(GetChannel())
- .DoInteract(key, next_state_handler, action_handler);
+ auto [err, succ] = auto_.DoInteract(key, next_state_handler, action_handler);
+ return err == GPG_ERR_NO_ERROR && !succ;
}
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgKeyManager.h b/src/core/function/gpg/GpgKeyManager.h
index ccf69b53..384319f8 100644
--- a/src/core/function/gpg/GpgKeyManager.h
+++ b/src/core/function/gpg/GpgKeyManager.h
@@ -29,6 +29,7 @@
#pragma once
#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgAutomatonHandler.h"
#include "core/function/gpg/GpgContext.h"
#include "core/typedef/GpgTypedef.h"
@@ -114,6 +115,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
private:
GpgContext& ctx_ =
GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
+ GpgAutomatonHandler& auto_ = GpgAutomatonHandler::GetInstance(
+ SingletonFunctionObject::GetChannel()); ///<
};
} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp
index e97eebd8..bcc3cc44 100644
--- a/src/core/function/gpg/GpgKeyOpera.cpp
+++ b/src/core/function/gpg/GpgKeyOpera.cpp
@@ -215,19 +215,21 @@ auto GenerateKeyImpl(GpgContext& ctx,
void GpgKeyOpera::GenerateKey(const QSharedPointer<KeyGenerateInfo>& params,
const GpgOperationCallback& callback) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return GenerateKeyImpl(ctx_, params, data_object);
},
- callback, "gpgme_op_createkey", "2.1.0");
+ callback, "gpgme_op_createkey", "2.2.0");
}
auto GpgKeyOpera::GenerateKeySync(const QSharedPointer<KeyGenerateInfo>& params)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return GenerateKeyImpl(ctx_, params, data_object);
},
- "gpgme_op_createkey", "2.1.0");
+ "gpgme_op_createkey", "2.2.0");
}
auto GenerateSubKeyImpl(GpgContext& ctx, const GpgKeyPtr& key,
@@ -270,6 +272,7 @@ void GpgKeyOpera::GenerateSubkey(const GpgKeyPtr& key,
const QSharedPointer<KeyGenerateInfo>& params,
const GpgOperationCallback& callback) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return GenerateSubKeyImpl(ctx_, key, params, data_object);
},
@@ -280,6 +283,7 @@ auto GpgKeyOpera::GenerateSubkeySync(
const GpgKeyPtr& key, const QSharedPointer<KeyGenerateInfo>& params)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return GenerateSubKeyImpl(ctx_, key, params, data_object);
},
@@ -318,11 +322,12 @@ void GpgKeyOpera::GenerateKeyWithSubkey(
const QSharedPointer<KeyGenerateInfo>& s_params,
const GpgOperationCallback& callback) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return GenerateKeyWithSubkeyImpl(ctx_, key_getter_, p_params, s_params,
data_object);
},
- callback, "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0");
+ callback, "gpgme_op_createkey&gpgme_op_createsubkey", "2.2.0");
}
auto GpgKeyOpera::GenerateKeyWithSubkeySync(
@@ -330,36 +335,35 @@ auto GpgKeyOpera::GenerateKeyWithSubkeySync(
const QSharedPointer<KeyGenerateInfo>& s_params)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return GenerateKeyWithSubkeyImpl(ctx_, key_getter_, p_params, s_params,
data_object);
},
- "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0");
+ "gpgme_op_createkey&gpgme_op_createsubkey", "2.2.0");
}
void GpgKeyOpera::ModifyPassword(const GpgKeyPtr& key,
const GpgOperationCallback& callback) {
RunGpgOperaAsync(
+ GetChannel(),
[&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");
+ callback, "gpgme_op_passwd", "2.2.0");
}
auto GpgKeyOpera::ModifyTOFUPolicy(
const GpgKeyPtr& key, gpgme_tofu_policy_t tofu_policy) -> GpgError {
- const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"});
- LOG_D() << "got gnupg version from rt: " << gnupg_version;
-
- if (GFCompareSoftwareVersion(gnupg_version, "2.1.10") < 0) {
- FLOG_W("operator not support");
- return GPG_ERR_NOT_SUPPORTED;
- }
+ auto [err, obj] = RunGpgOperaSync(
+ GetChannel(),
+ [=](const DataObjectPtr&) -> GpgError {
+ return gpgme_op_tofu_policy(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(*key), tofu_policy);
+ },
+ "gpgme_op_tofu_policy", "2.2.0");
- auto err = gpgme_op_tofu_policy(ctx_.DefaultContext(),
- static_cast<gpgme_key_t>(*key), tofu_policy);
return CheckGpgError(err);
}
@@ -388,6 +392,7 @@ auto AddADSKImpl(GpgContext& ctx, const GpgKeyPtr& key, const GpgSubKey& adsk,
void GpgKeyOpera::AddADSK(const GpgKeyPtr& key, const GpgSubKey& adsk,
const GpgOperationCallback& callback) {
RunGpgOperaAsync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return AddADSKImpl(ctx_, key, adsk, data_object);
},
@@ -397,6 +402,7 @@ void GpgKeyOpera::AddADSK(const GpgKeyPtr& key, const GpgSubKey& adsk,
auto GpgKeyOpera::AddADSKSync(const GpgKeyPtr& key, const GpgSubKey& adsk)
-> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
+ GetChannel(),
[=](const DataObjectPtr& data_object) -> GpgError {
return AddADSKImpl(ctx_, key, adsk, data_object);
},
diff --git a/src/core/function/gpg/GpgSmartCardManager.cpp b/src/core/function/gpg/GpgSmartCardManager.cpp
index 5442ea88..203c36ec 100644
--- a/src/core/function/gpg/GpgSmartCardManager.cpp
+++ b/src/core/function/gpg/GpgSmartCardManager.cpp
@@ -30,17 +30,16 @@
#include "core/function/gpg/GpgAutomatonHandler.h"
#include "core/utils/CommonUtils.h"
+#include "core/utils/GpgUtils.h"
namespace GpgFrontend {
GpgSmartCardManager::GpgSmartCardManager(int channel)
: SingletonFunctionObject<GpgSmartCardManager>(channel) {}
-auto GpgSmartCardManager::Fetch(const QString& serial_number) -> bool {
+auto GpgSmartCardManager::Fetch(const QString& serial_number) -> GpgError {
GpgAutomatonHandler::AutomatonNextStateHandler next_state_handler =
- [=](AutomatonState state, QString status, QString args) {
- auto tokens = args.split(' ');
-
+ [=](AutomatonState state, const QString& status, const QString& args) {
switch (state) {
case GpgAutomatonHandler::kAS_START:
if (status == "GET_LINE" && args == "cardedit.prompt") {
@@ -63,7 +62,7 @@ auto GpgSmartCardManager::Fetch(const QString& serial_number) -> bool {
};
};
- AutomatonActionHandler action_handler = [](AutomatonHandelStruct& handler,
+ AutomatonActionHandler action_handler = [](AutomatonHandelStruct&,
AutomatonState state) {
switch (state) {
case GpgAutomatonHandler::kAS_COMMAND:
@@ -78,25 +77,22 @@ auto GpgSmartCardManager::Fetch(const QString& serial_number) -> bool {
return QString("");
};
- return GpgAutomatonHandler::GetInstance(GetChannel())
- .DoCardInteract(serial_number, next_state_handler, action_handler);
+ auto [err, succ] =
+ GpgAutomatonHandler::GetInstance(GetChannel())
+ .DoCardInteract(serial_number, next_state_handler, action_handler);
+
+ if (err == GPG_ERR_NO_ERROR && !succ) return GPG_ERR_USER_1;
+ return err;
}
auto GpgSmartCardManager::IsSCDVersionSupported() -> bool {
- auto [r, s] = assuan_.SendDataCommand(GpgComponentType::kGPG_AGENT,
- "SCD GETINFO version");
- if (s.isEmpty()) {
- LOG_D() << "invalid response of SCD GETINFO version: " << s;
- return false;
- }
-
- return GFCompareSoftwareVersion(s.front(), "2.3.0") > 0;
+ return GFSoftwareVersionGreaterThan(info_.GetScdaemonVersion(), "2.3.0");
}
auto GpgSmartCardManager::GetSerialNumbers() -> QStringList {
auto [r, s] = assuan_.SendStatusCommand(GpgComponentType::kGPG_AGENT,
"SCD SERIALNO --all");
- if (!r) {
+ if (r != GPG_ERR_NO_ERROR) {
cached_scd_serialno_status_hash_.clear();
cache_scd_card_serial_numbers_.clear();
return {};
@@ -112,9 +108,9 @@ auto GpgSmartCardManager::GetSerialNumbers() -> QStringList {
cached_scd_serialno_status_hash_.clear();
cache_scd_card_serial_numbers_.clear();
- auto [ret, status] = assuan_.SendStatusCommand(GpgComponentType::kGPG_AGENT,
+ auto [err, status] = assuan_.SendStatusCommand(GpgComponentType::kGPG_AGENT,
"SCD GETINFO all_active_apps");
- if (!ret || status.empty()) {
+ if (err != GPG_ERR_NO_ERROR || status.empty()) {
LOG_D() << "command SCD GETINFO all_active_apps failed, resetting...";
return {};
}
@@ -142,14 +138,14 @@ auto GpgSmartCardManager::GetSerialNumbers() -> QStringList {
}
auto GpgSmartCardManager::SelectCardBySerialNumber(const QString& serial_number)
- -> std::tuple<bool, QString> {
+ -> std::tuple<GpgError, QString> {
if (serial_number.isEmpty()) return {false, "Serial Number is empty."};
- auto [ret, status] = assuan_.SendStatusCommand(
+ auto [err, status] = assuan_.SendStatusCommand(
GpgComponentType::kGPG_AGENT,
QString("SCD SERIALNO --demand=%1 openpgp").arg(serial_number));
- if (!ret || status.isEmpty()) {
- return {false, status.join(' ')};
+ if (err != GPG_ERR_NO_ERROR || status.isEmpty()) {
+ return {err, status.join(' ')};
}
auto line = status.front();
@@ -157,22 +153,21 @@ auto GpgSmartCardManager::SelectCardBySerialNumber(const QString& serial_number)
if (token.size() != 2) {
LOG_E() << "invalid response of command SERIALNO: " << line;
- return {false, line};
+ return {GPG_ERR_USER_1, line};
}
LOG_D() << "selected smart card by serial number: " << serial_number;
-
- return {true, {}};
+ return {err, {}};
}
auto GpgSmartCardManager::FetchCardInfoBySerialNumber(
const QString& serial_number) -> QSharedPointer<GpgOpenPGPCard> {
if (serial_number.trimmed().isEmpty()) return nullptr;
- auto [ret, status] = assuan_.SendStatusCommand(
+ auto [err, status] = assuan_.SendStatusCommand(
GpgComponentType::kGPG_AGENT, "SCD LEARN --force " + serial_number);
- if (!ret || status.isEmpty()) {
- LOG_E() << "scd learn failed: " << status;
+ if (err != GPG_ERR_NO_ERROR || status.isEmpty()) {
+ LOG_E() << "scd learn failed, err: " << CheckGpgError(err) << "" << status;
return nullptr;
}
@@ -201,7 +196,7 @@ auto PercentDataEscape(const QByteArray& data, bool plus_escape = false,
}
}
- for (unsigned char ch : data) {
+ for (char ch : data) {
if (ch == '\0') {
result += "%00";
} else if (ch == '%') {
@@ -219,29 +214,25 @@ auto PercentDataEscape(const QByteArray& data, bool plus_escape = false,
}
auto GpgSmartCardManager::ModifyAttr(const QString& attr, const QString& value)
- -> std::tuple<bool, QString> {
+ -> std::tuple<GpgError, QString> {
if (attr.trimmed().isEmpty() || value.trimmed().isEmpty()) {
- return {false, "ATTR or Value is empty"};
+ return {GPG_ERR_INV_ARG, "ATTR or Value is empty"};
}
const auto command = QString("SCD SETATTR %1 ").arg(attr);
const auto escaped_command =
PercentDataEscape(value.trimmed().toUtf8(), true, command);
- auto [r, s] =
+ auto [err, status] =
assuan_.SendStatusCommand(GpgComponentType::kGPG_AGENT, escaped_command);
-
- if (!r) {
- LOG_E() << "SCD SETATTR command failed for attr" << attr;
- return {false, s.join(' ')};
- }
-
- return {true, {}};
+ return {err, status.join(' ')};
}
auto GpgSmartCardManager::ModifyPin(const QString& pin_ref)
- -> std::tuple<bool, QString> {
- if (pin_ref.trimmed().isEmpty()) return {false, "PIN Reference is empty"};
+ -> std::tuple<GpgError, QString> {
+ if (pin_ref.trimmed().isEmpty()) {
+ return {GPG_ERR_INV_ARG, "PIN Reference is empty"};
+ }
QString command;
if (pin_ref == "OPENPGP.1") {
@@ -254,23 +245,17 @@ auto GpgSmartCardManager::ModifyPin(const QString& pin_ref)
command = QString("SCD PASSWD %1").arg(pin_ref);
}
- auto [success, status] =
+ auto [err, status] =
assuan_.SendStatusCommand(GpgComponentType::kGPG_AGENT, command);
-
- if (!success) {
- LOG_E() << "modify pin of smart failed: " << status;
- return {false, status.join(' ')};
- }
-
- return {true, {}};
+ return {err, status.join(' ')};
}
auto GpgSmartCardManager::GenerateKey(
const QString& serial_number, const QString& name, const QString& email,
const QString& comment, const QDateTime& expire,
- bool non_expire) -> std::tuple<bool, QString> {
+ bool non_expire) -> std::tuple<GpgError, QString> {
if (name.isEmpty() || email.isEmpty()) {
- return {false, "name or email is empty"};
+ return {GPG_ERR_INV_ARG, "name or email is empty"};
}
qint64 days_before_expire = 0;
@@ -280,8 +265,6 @@ auto GpgSmartCardManager::GenerateKey(
GpgAutomatonHandler::AutomatonNextStateHandler next_state_handler =
[=](AutomatonState state, const QString& status, const QString& args) {
- auto tokens = args.split(' ');
-
switch (state) {
case GpgAutomatonHandler::kAS_START:
if (status == "GET_LINE" && args == "cardedit.prompt") {
@@ -382,9 +365,10 @@ auto GpgSmartCardManager::GenerateKey(
return QString{};
};
- return {
+ auto [err, succ] =
GpgAutomatonHandler::GetInstance(GetChannel())
- .DoCardInteract(serial_number, next_state_handler, action_handler),
- "unknown error"};
+ .DoCardInteract(serial_number, next_state_handler, action_handler);
+ if (err == GPG_ERR_NO_ERROR && !succ) return {GPG_ERR_USER_1, {}};
+ return {err, {}};
}
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgSmartCardManager.h b/src/core/function/gpg/GpgSmartCardManager.h
index 2fe194f3..02b07fa2 100644
--- a/src/core/function/gpg/GpgSmartCardManager.h
+++ b/src/core/function/gpg/GpgSmartCardManager.h
@@ -30,9 +30,9 @@
#include "core/function/basic/GpgFunctionObject.h"
#include "core/function/gpg/GpgAssuanHelper.h"
+#include "core/function/gpg/GpgComponentInfoGetter.h"
#include "core/function/gpg/GpgContext.h"
#include "core/model/GpgOpenPGPCard.h"
-#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -63,7 +63,8 @@ class GPGFRONTEND_CORE_EXPORT GpgSmartCardManager
*
* @return std::tuple<bool, QString>
*/
- auto SelectCardBySerialNumber(const QString&) -> std::tuple<bool, QString>;
+ auto SelectCardBySerialNumber(const QString&)
+ -> std::tuple<GpgError, QString>;
/**
* @brief
@@ -81,7 +82,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSmartCardManager
* @return true
* @return false
*/
- auto Fetch(const QString& serial_number) -> bool;
+ auto Fetch(const QString& serial_number) -> GpgError;
/**
* @brief
@@ -89,7 +90,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSmartCardManager
* @return std::tuple<bool, QString>
*/
auto ModifyAttr(const QString& attr,
- const QString& value) -> std::tuple<bool, QString>;
+ const QString& value) -> std::tuple<GpgError, QString>;
/**
* @brief
@@ -97,7 +98,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSmartCardManager
* @param pin_ref
* @return std::tuple<bool, QString>
*/
- auto ModifyPin(const QString& pin_ref) -> std::tuple<bool, QString>;
+ auto ModifyPin(const QString& pin_ref) -> std::tuple<GpgError, QString>;
/**
* @brief
@@ -107,7 +108,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSmartCardManager
auto GenerateKey(const QString& serial_number, const QString& name,
const QString& email, const QString& comment,
const QDateTime& expire,
- bool non_expire) -> std::tuple<bool, QString>;
+ bool non_expire) -> std::tuple<GpgError, QString>;
/**
* @brief
@@ -122,6 +123,9 @@ class GPGFRONTEND_CORE_EXPORT GpgSmartCardManager
GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
GpgAssuanHelper& assuan_ =
GpgAssuanHelper::GetInstance(SingletonFunctionObject::GetChannel()); ///<
+ GpgComponentInfoGetter& info_ = GpgComponentInfoGetter::GetInstance(
+ SingletonFunctionObject::GetChannel()); ///<
+
QString cached_scd_serialno_status_hash_;
QContainer<QString> cache_scd_card_serial_numbers_;
};
diff --git a/src/core/function/gpg/GpgUIDOperator.cpp b/src/core/function/gpg/GpgUIDOperator.cpp
index e07b4192..ca056be0 100644
--- a/src/core/function/gpg/GpgUIDOperator.cpp
+++ b/src/core/function/gpg/GpgUIDOperator.cpp
@@ -29,7 +29,6 @@
#include "GpgUIDOperator.h"
#include "core/function/gpg/GpgAutomatonHandler.h"
-#include "core/model/GpgData.h"
#include "core/utils/GpgUtils.h"
namespace GpgFrontend {
@@ -65,8 +64,8 @@ auto GpgUIDOperator::DeleteUID(const GpgKeyPtr& key, int uid_index) -> bool {
}
AutomatonNextStateHandler next_state_handler = [](AutomatonState state,
- QString status,
- QString args) {
+ const QString& status,
+ const QString& args) {
auto tokens = args.split(' ');
switch (state) {
@@ -124,15 +123,14 @@ auto GpgUIDOperator::DeleteUID(const GpgKeyPtr& key, int uid_index) -> bool {
return QString("Y");
case GpgAutomatonHandler::kAS_START:
case GpgAutomatonHandler::kAS_ERROR:
- return QString("");
default:
return QString("");
}
return QString("");
};
- return GpgAutomatonHandler::GetInstance(GetChannel())
- .DoInteract(key, next_state_handler, action_handler);
+ auto [err, succ] = auto_.DoInteract(key, next_state_handler, action_handler);
+ return err == GPG_ERR_NO_ERROR && !succ;
}
auto GpgUIDOperator::RevokeUID(const GpgKeyPtr& key, int uid_index,
@@ -153,8 +151,8 @@ auto GpgUIDOperator::RevokeUID(const GpgKeyPtr& key, int uid_index,
reason_text.split('\n', Qt::SkipEmptyParts));
AutomatonNextStateHandler next_state_handler = [](AutomatonState state,
- QString status,
- QString args) {
+ const QString& status,
+ const QString& args) {
auto tokens = args.split(' ');
switch (state) {
@@ -240,15 +238,14 @@ auto GpgUIDOperator::RevokeUID(const GpgKeyPtr& key, int uid_index,
return QString("Y");
case GpgAutomatonHandler::kAS_START:
case GpgAutomatonHandler::kAS_ERROR:
- return QString("");
default:
return QString("");
}
return QString("");
};
- return GpgAutomatonHandler::GetInstance(GetChannel())
- .DoInteract(key, next_state_handler, action_handler);
+ auto [err, succ] = auto_.DoInteract(key, next_state_handler, action_handler);
+ return err == GPG_ERR_NO_ERROR && !succ;
}
} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgUIDOperator.h b/src/core/function/gpg/GpgUIDOperator.h
index e5e2f190..0e222388 100644
--- a/src/core/function/gpg/GpgUIDOperator.h
+++ b/src/core/function/gpg/GpgUIDOperator.h
@@ -28,6 +28,7 @@
#pragma once
+#include "core/function/gpg/GpgAutomatonHandler.h"
#include "core/function/gpg/GpgContext.h"
#include "core/typedef/GpgTypedef.h"
@@ -100,6 +101,8 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
private:
GpgContext& ctx_ =
GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
+ GpgAutomatonHandler& auto_ = GpgAutomatonHandler::GetInstance(
+ SingletonFunctionObject::GetChannel()); ///<
};
} // namespace GpgFrontend
diff --git a/src/core/utils/AsyncUtils.cpp b/src/core/utils/AsyncUtils.cpp
index a4bc66fa..a3ab9eb8 100644
--- a/src/core/utils/AsyncUtils.cpp
+++ b/src/core/utils/AsyncUtils.cpp
@@ -28,24 +28,20 @@
#include "AsyncUtils.h"
+#include "core/model/DataObject.h"
#include "core/module/ModuleManager.h"
#include "core/thread/Task.h"
#include "core/thread/TaskRunnerGetter.h"
-#include "core/utils/CommonUtils.h"
-#include "model/DataObject.h"
+#include "core/utils/GpgUtils.h"
namespace GpgFrontend {
-auto RunGpgOperaAsync(const GpgOperaRunnable& runnable,
+auto RunGpgOperaAsync(int channel, const GpgOperaRunnable& runnable,
const GpgOperationCallback& callback,
- const QString& operation, const QString& minial_version)
+ const QString& operation, const QString& minimal_version)
-> Thread::Task::TaskHandler {
- const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.gnupg_version", minial_version);
-
- if (GFCompareSoftwareVersion(gnupg_version, minial_version) < 0) {
- LOG_W() << "operation" << operation
- << " not support for gnupg version: " << gnupg_version;
+ if (!CheckGpgVersion(channel, minimal_version)) {
+ LOG_W() << "operation: " << operation << "is not supported.";
callback(GPG_ERR_NOT_SUPPORTED, TransferParams());
return Thread::Task::TaskHandler(nullptr);
}
@@ -75,15 +71,11 @@ auto RunGpgOperaAsync(const GpgOperaRunnable& runnable,
return handler;
}
-auto RunGpgOperaSync(const GpgOperaRunnable& runnable, const QString& operation,
- const QString& minial_version)
+auto RunGpgOperaSync(int channel, const GpgOperaRunnable& runnable,
+ const QString& operation, const QString& minimal_version)
-> std::tuple<GpgError, DataObjectPtr> {
- const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.gnupg_version", minial_version);
-
- if (GFCompareSoftwareVersion(gnupg_version, minial_version) < 0) {
- LOG_W() << "operation" << operation
- << " not support for gnupg version: " << gnupg_version;
+ if (!CheckGpgVersion(channel, minimal_version)) {
+ LOG_W() << "operation: " << operation << "is not supported.";
return {GPG_ERR_NOT_SUPPORTED, TransferParams()};
}
diff --git a/src/core/utils/AsyncUtils.h b/src/core/utils/AsyncUtils.h
index eb55cf89..5be3b230 100644
--- a/src/core/utils/AsyncUtils.h
+++ b/src/core/utils/AsyncUtils.h
@@ -41,24 +41,24 @@ namespace GpgFrontend {
* @param runnable
* @param callback
* @param operation
- * @param minial_version
+ * @param minimal_version
*/
auto GPGFRONTEND_CORE_EXPORT
-RunGpgOperaAsync(const GpgOperaRunnable& runnable,
+RunGpgOperaAsync(int channel, const GpgOperaRunnable& runnable,
const GpgOperationCallback& callback, const QString& operation,
- const QString& minial_version) -> Thread::Task::TaskHandler;
+ const QString& minimal_version) -> Thread::Task::TaskHandler;
/**
* @brief
*
* @param runnable
* @param operation
- * @param minial_version
+ * @param minimal_version
* @return std::tuple<GpgError, DataObjectPtr>
*/
auto GPGFRONTEND_CORE_EXPORT RunGpgOperaSync(
- const GpgOperaRunnable& runnable, const QString& operation,
- const QString& minial_version) -> std::tuple<GpgError, DataObjectPtr>;
+ int channel, const GpgOperaRunnable& runnable, const QString& operation,
+ const QString& minimal_version) -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief
diff --git a/src/core/utils/CommonUtils.cpp b/src/core/utils/CommonUtils.cpp
index ce36c71e..eec5deef 100644
--- a/src/core/utils/CommonUtils.cpp
+++ b/src/core/utils/CommonUtils.cpp
@@ -74,6 +74,11 @@ auto GFCompareSoftwareVersion(const QString& a, const QString& b) -> int {
return 0;
}
+auto GFSoftwareVersionGreaterThan(const QString& a, const QString& b) -> bool {
+ if (a.isEmpty()) return false;
+ return GFCompareSoftwareVersion(a, b) > 0;
+}
+
auto GFStrDup(const QString& s) -> char* {
if (s.isEmpty()) return nullptr;
diff --git a/src/core/utils/CommonUtils.h b/src/core/utils/CommonUtils.h
index d62f4867..b7d18891 100644
--- a/src/core/utils/CommonUtils.h
+++ b/src/core/utils/CommonUtils.h
@@ -90,4 +90,14 @@ auto GPGFRONTEND_CORE_EXPORT ParseHexEncodedVersionTuple(const QString &s)
*/
auto GPGFRONTEND_CORE_EXPORT IsEmailAddress(const QString &) -> bool;
+/**
+ * @brief if a > b
+ *
+ * @param a
+ * @param b
+ * @return auto
+ */
+auto GPGFRONTEND_CORE_EXPORT
+GFSoftwareVersionGreaterThan(const QString &a, const QString &b) -> bool;
+
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/GpgUtils.cpp b/src/core/utils/GpgUtils.cpp
index b8824673..13f6ef05 100644
--- a/src/core/utils/GpgUtils.cpp
+++ b/src/core/utils/GpgUtils.cpp
@@ -30,12 +30,15 @@
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgAbstractKeyGetter.h"
+#include "core/function/gpg/GpgComponentInfoGetter.h"
#include "core/model/GpgKey.h"
#include "core/model/GpgKeyGroup.h"
#include "core/model/KeyDatabaseInfo.h"
#include "core/model/SettingsObject.h"
#include "core/module/ModuleManager.h"
#include "core/struct/settings_object/KeyDatabaseListSO.h"
+#include "core/utils/CommonUtils.h"
+
namespace GpgFrontend {
inline auto Trim(QString& s) -> QString { return s.trimmed(); }
@@ -424,4 +427,33 @@ auto GPGFRONTEND_CORE_EXPORT IsKeyGroupID(const KeyId& id) -> bool {
return id.startsWith("#&");
}
+auto GPGFRONTEND_CORE_EXPORT
+GpgAgentVersionGreaterThan(int channel, const QString& v) -> bool {
+ return GFSoftwareVersionGreaterThan(
+ GpgComponentInfoGetter::GetInstance(channel).GetGpgAgentVersion(), v);
+}
+
+auto GPGFRONTEND_CORE_EXPORT CheckGpgVersion(int channel,
+ const QString& v) -> bool {
+ const auto ver =
+ GpgComponentInfoGetter::GetInstance(channel).GetGpgAgentVersion();
+
+ if (ver.isEmpty() || !GFSoftwareVersionGreaterThan(ver, v)) {
+ LOG_W() << "operation not support for gpg-agent version: " << ver
+ << "minimal version: " << v;
+ return false;
+ }
+
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", QString{});
+
+ if (gnupg_version.isEmpty() ||
+ GFCompareSoftwareVersion(gnupg_version, v) < 0) {
+ LOG_W() << "operation not support for gnupg version: " << gnupg_version
+ << "minimal version: " << v;
+ return false;
+ }
+
+ return true;
+}
} // namespace GpgFrontend
diff --git a/src/core/utils/GpgUtils.h b/src/core/utils/GpgUtils.h
index 13612b4f..d0fe1701 100644
--- a/src/core/utils/GpgUtils.h
+++ b/src/core/utils/GpgUtils.h
@@ -202,4 +202,23 @@ auto GPGFRONTEND_CORE_EXPORT GetGpgKeyByGpgAbstractKey(GpgAbstractKey*)
* @return false
*/
auto GPGFRONTEND_CORE_EXPORT IsKeyGroupID(const KeyId& id) -> bool;
+
+/**
+ * @brief
+ *
+ * @return bool
+ */
+auto GPGFRONTEND_CORE_EXPORT GpgAgentVersionGreaterThan(int channel,
+ const QString&) -> bool;
+
+/**
+ * @brief
+ *
+ * @param channel
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT CheckGpgVersion(int channel,
+ const QString&) -> bool;
+
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/init.cpp b/src/init.cpp
index 71f24668..3d1f344b 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -184,9 +184,15 @@ void ShutdownGlobalBasicEnv(const GFCxtWPtr &p_ctx) {
.toBool();
if (ctx->unit_test_mode || kill_all_gnupg_daemon_at_close) {
- GpgAdvancedOperator::KillAllGpgComponents(nullptr);
+ const auto size = GpgContext::GetAllChannelId().size();
+ for (auto i = 0; i < size; i++) {
+ assert(GpgAdvancedOperator::GetInstance().KillAllGpgComponents());
+ }
} else if (!ctx->unit_test_mode && clear_gpg_password_cache) {
- GpgAdvancedOperator::ClearGpgPasswordCache(nullptr);
+ const auto size = GpgContext::GetAllChannelId().size();
+ for (auto i = 0; i < size; i++) {
+ assert(GpgAdvancedOperator::GetInstance().ClearGpgPasswordCache());
+ }
}
// first should shutdown the module system
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
index 8d277ab4..ed76824a 100644
--- a/src/ui/UserInterfaceUtils.cpp
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -167,16 +167,17 @@ void CommonUtils::RaiseMessageBox(QWidget *parent, GpgError err) {
}
}
-void CommonUtils::RaiseFailureMessageBox(QWidget *parent, GpgError err) {
+void CommonUtils::RaiseFailureMessageBox(QWidget *parent, GpgError err,
+ const QString &msg) {
GpgErrorDesc desc = DescribeGpgErrCode(err);
GpgErrorCode err_code = CheckGpgError2ErrCode(err);
QMessageBox::critical(parent, tr("Failure"),
- tr("Gpg Operation failed.\n\nError code: %1\nSource: "
- " %2\nDescription: %3")
- .arg(err_code)
- .arg(desc.first)
- .arg(desc.second));
+ tr("Gpg Operation failed.") + "\n\n" +
+ tr("Error code: %1").arg(err_code) + "\n\n\n" +
+ tr("Source: %1").arg(desc.first) + "\n" +
+ tr("Description: %1").arg(desc.second) + "\n" +
+ tr("Error Message: %1").arg(msg));
}
void CommonUtils::SlotImportKeys(QWidget *parent, int channel,
diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h
index fe912fcf..b544ffc3 100644
--- a/src/ui/UserInterfaceUtils.h
+++ b/src/ui/UserInterfaceUtils.h
@@ -113,7 +113,8 @@ class CommonUtils : public QWidget {
*
* @param err
*/
- static void RaiseFailureMessageBox(QWidget* parent, GpgError err);
+ static void RaiseFailureMessageBox(QWidget* parent, GpgError err,
+ const QString& msg = {});
/**
* @brief
diff --git a/src/ui/dialog/ADSKsPicker.cpp b/src/ui/dialog/ADSKsPicker.cpp
index 878c5e96..56039a15 100644
--- a/src/ui/dialog/ADSKsPicker.cpp
+++ b/src/ui/dialog/ADSKsPicker.cpp
@@ -115,8 +115,7 @@ void ADSKsPicker::slot_add_adsk(const QContainer<GpgSubKey>& s_keys) {
for (const auto& info : err_sub_key_infos) {
failed_info.append(info);
}
- QString details = failed_info.join("\n\n");
-
+ auto details = failed_info.join("\n\n");
auto* msg_box = new QMessageBox(nullptr);
msg_box->setIcon(QMessageBox::Warning);
msg_box->setWindowTitle(err_sub_key_infos.size() == s_keys.size()
diff --git a/src/ui/dialog/controller/SmartCardControllerDialog.cpp b/src/ui/dialog/controller/SmartCardControllerDialog.cpp
index 73dd48b9..797fe052 100644
--- a/src/ui/dialog/controller/SmartCardControllerDialog.cpp
+++ b/src/ui/dialog/controller/SmartCardControllerDialog.cpp
@@ -33,6 +33,7 @@
#include "core/function/gpg/GpgSmartCardManager.h"
#include "core/utils/GpgUtils.h"
#include "ui/UISignalStation.h"
+#include "ui/UserInterfaceUtils.h"
#include "ui/dialog/key_generate/GenerateCardKeyDialog.h"
//
@@ -110,18 +111,22 @@ SmartCardControllerDialog::SmartCardControllerDialog(QWidget* parent)
[=](bool) { modify_key_pin("OPENPGP.2"); });
connect(ui_->restartGpgAgentButton, &QPushButton::clicked, this, [=](bool) {
- GpgFrontend::GpgAdvancedOperator::RestartGpgComponents(
- [=](int err, DataObjectPtr) {
- if (err >= 0) {
- QMessageBox::information(
- this, tr("Successful Operation"),
- tr("Restart all the GnuPG's components successfully"));
- } else {
- QMessageBox::critical(
- this, tr("Failed Operation"),
- tr("Failed to restart all or one of the GnuPG's component(s)"));
- }
- });
+ bool ret = true;
+ const auto size = GpgContext::GetAllChannelId().size();
+ for (auto i = 0; i < size; i++) {
+ ret = GpgAdvancedOperator::GetInstance().RestartGpgComponents();
+ if (!ret) break;
+ }
+
+ if (ret) {
+ QMessageBox::information(
+ this, tr("Successful Operation"),
+ tr("Restart all the GnuPG's components successfully"));
+ } else {
+ QMessageBox::critical(
+ this, tr("Failed Operation"),
+ tr("Failed to restart all or one of the GnuPG's component(s)"));
+ }
});
connect(ui_->generateKeysButton, &QPushButton::clicked, this, [=](bool) {
@@ -163,11 +168,13 @@ void SmartCardControllerDialog::select_smart_card_by_serial_number(
return;
}
- auto [ret, err] =
+ auto [err, status] =
GpgSmartCardManager::GetInstance(channel_).SelectCardBySerialNumber(
serial_number);
- if (!ret) {
- LOG_E() << "select card by serial number failed: " << err;
+ if (err != GPG_ERR_NO_ERROR) {
+ LOG_E() << "select card by serial number failed, err:" << CheckGpgError(err)
+ << "status:" << status;
+ CommonUtils::RaiseFailureMessageBox(this, err, status);
reset_status();
return;
}
@@ -188,6 +195,7 @@ void SmartCardControllerDialog::fetch_smart_card_info(
GpgSmartCardManager::GetInstance(channel_).FetchCardInfoBySerialNumber(
serial_number);
if (card_info == nullptr) {
+ LOG_E() << "card info is nullptr, serial number:" << serial_number;
reset_status();
return;
}
@@ -446,9 +454,14 @@ void SmartCardControllerDialog::slot_disable_controllers(bool disable) {
void SmartCardControllerDialog::slot_fetch_smart_card_keys() {
ui_->fetchButton->setDisabled(true);
- GpgSmartCardManager::GetInstance().Fetch(
+ auto err = GpgSmartCardManager::GetInstance().Fetch(
ui_->currentCardComboBox->currentText());
+ if (err != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseFailureMessageBox(this, err);
+ return;
+ }
+
QTimer::singleShot(1000, [=]() {
GpgCommandExecutor::GetInstance(channel_).GpgExecuteSync(
{{},
@@ -524,14 +537,13 @@ void SmartCardControllerDialog::modify_key_attribute(const QString& attr) {
}
}
- auto [r, err] =
+ auto [err, status] =
GpgSmartCardManager::GetInstance(channel_).ModifyAttr(attr, value);
- if (!r) {
- LOG_D() << "SCD SETATTR command failed for attr" << attr;
- QMessageBox::critical(
- this, tr("Failed"),
- tr("Failed to set attribute '%1'. Reason: %2. ").arg(attr).arg(err));
+ if (err != GPG_ERR_NO_ERROR) {
+ LOG_D() << "SCD SETATTR command failed for attr:" << attr
+ << ", err:" << CheckGpgError(err);
+ CommonUtils::RaiseFailureMessageBox(this, err, status);
return;
}
QMessageBox::information(this, tr("Success"),
@@ -540,22 +552,11 @@ void SmartCardControllerDialog::modify_key_attribute(const QString& attr) {
}
void SmartCardControllerDialog::modify_key_pin(const QString& pinref) {
- auto [success, err] =
+ auto [err, status] =
GpgSmartCardManager::GetInstance(channel_).ModifyPin(pinref);
- if (!success) {
- QString message;
- if (pinref == "OPENPGP.3") {
- message = tr("Failed to change Admin PIN.");
- } else if (pinref == "OPENPGP.2") {
- message = tr("Failed to set the Reset Code.");
- } else {
- message = tr("Failed to change PIN.");
- }
-
- message += tr("Reason: ") + err;
-
- QMessageBox::critical(this, tr("Error"), message);
+ if (err != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseFailureMessageBox(this, err, status);
return;
}
diff --git a/src/ui/function/GpgOperaHelper.cpp b/src/ui/function/GpgOperaHelper.cpp
index 91bc6c38..82742b93 100644
--- a/src/ui/function/GpgOperaHelper.cpp
+++ b/src/ui/function/GpgOperaHelper.cpp
@@ -90,6 +90,12 @@ auto GpgOperaHelper::BuildSimpleGpgFileOperasHelper(
// stop waiting
op_hd();
+ if (CheckGpgError(err) == GPG_ERR_NOT_SUPPORTED) {
+ opera_results.append({-1, "# " + tr("Operation Not Supported"),
+ QFileInfo(path).fileName()});
+ return;
+ }
+
if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
!data_obj->Check<ResultType>()) {
opera_results.append(
@@ -126,6 +132,12 @@ auto GpgOperaHelper::BuildComplexGpgFileOperasHelper(
// stop waiting
op_hd();
+ if (CheckGpgError(err) == GPG_ERR_NOT_SUPPORTED) {
+ opera_results.append({-1, "# " + tr("Operation Not Supported"),
+ QFileInfo(path).fileName()});
+ return;
+ }
+
if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
!data_obj->Check<ResultTypeA, ResultTypeB>()) {
opera_results.append(
@@ -169,6 +181,11 @@ auto GpgOperaHelper::BuildSimpleGpgOperasHelper(
// stop waiting
op_hd();
+ if (CheckGpgError(err) == GPG_ERR_NOT_SUPPORTED) {
+ opera_results.append({-1, "# " + tr("Operation Not Supported"), {}});
+ return;
+ }
+
if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
!data_obj->Check<ResultType, GFBuffer>()) {
opera_results.append({-1, "# " + tr("Critical Error"), {}});
@@ -207,6 +224,11 @@ auto GpgOperaHelper::BuildComplexGpgOperasHelper(
// stop waiting
op_hd();
+ if (CheckGpgError(err) == GPG_ERR_NOT_SUPPORTED) {
+ opera_results.append({-1, "# " + tr("Operation Not Supported"), {}});
+ return;
+ }
+
if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
!data_obj->Check<ResultTypeA, ResultTypeB, GFBuffer>()) {
opera_results.append({-1, "# " + tr("Critical Error"), {}});
diff --git a/src/ui/main_window/MainWindow.h b/src/ui/main_window/MainWindow.h
index 15fb9fb1..16092609 100644
--- a/src/ui/main_window/MainWindow.h
+++ b/src/ui/main_window/MainWindow.h
@@ -528,7 +528,7 @@ class MainWindow : public GeneralMainWindow {
*
* @param results
*/
- void slot_update_operations_menu_by_checked_keys(unsigned int type);
+ void slot_update_operations_menu_by_checked_keys(unsigned int mask);
/**
* @brief
diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp
index e0a72ed1..6b945beb 100644
--- a/src/ui/main_window/MainWindowSlotUI.cpp
+++ b/src/ui/main_window/MainWindowSlotUI.cpp
@@ -311,46 +311,58 @@ void MainWindow::SlotGeneralDecryptVerify(bool) {
}
void MainWindow::slot_clean_gpg_password_cache(bool) {
- GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache(
- [=](int err, DataObjectPtr) {
- if (err >= 0) {
- QMessageBox::information(this, tr("Successful Operation"),
- tr("Clear password cache successfully"));
- } else {
- QMessageBox::critical(this, tr("Failed Operation"),
- tr("Failed to clear password cache of GnuPG"));
- }
- });
+ bool ret = true;
+ const auto size = GpgContext::GetAllChannelId().size();
+ for (auto i = 0; i < size; i++) {
+ ret = GpgAdvancedOperator::GetInstance().ClearGpgPasswordCache();
+ if (!ret) break;
+ }
+
+ if (ret) {
+ QMessageBox::information(this, tr("Successful Operation"),
+ tr("Clear password cache successfully"));
+ } else {
+ QMessageBox::critical(this, tr("Failed Operation"),
+ tr("Failed to clear password cache of GnuPG"));
+ }
}
void MainWindow::slot_reload_gpg_components(bool) {
- GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
- [=](int err, DataObjectPtr) {
- if (err >= 0) {
- QMessageBox::information(
- this, tr("Successful Operation"),
- tr("Reload all the GnuPG's components successfully"));
- } else {
- QMessageBox::critical(
- this, tr("Failed Operation"),
- tr("Failed to reload all or one of the GnuPG's component(s)"));
- }
- });
+ bool ret = true;
+ const auto size = GpgContext::GetAllChannelId().size();
+ for (auto i = 0; i < size; i++) {
+ ret = GpgAdvancedOperator::GetInstance().ReloadAllGpgComponents();
+ if (!ret) break;
+ }
+
+ if (ret) {
+ QMessageBox::information(
+ this, tr("Successful Operation"),
+ tr("Reload all the GnuPG's components successfully"));
+ } else {
+ QMessageBox::critical(
+ this, tr("Failed Operation"),
+ tr("Failed to reload all or one of the GnuPG's component(s)"));
+ }
}
void MainWindow::slot_restart_gpg_components(bool) {
- GpgFrontend::GpgAdvancedOperator::RestartGpgComponents(
- [=](int err, DataObjectPtr) {
- if (err >= 0) {
- QMessageBox::information(
- this, tr("Successful Operation"),
- tr("Restart all the GnuPG's components successfully"));
- } else {
- QMessageBox::critical(
- this, tr("Failed Operation"),
- tr("Failed to restart all or one of the GnuPG's component(s)"));
- }
- });
+ bool ret = true;
+ const auto size = GpgContext::GetAllChannelId().size();
+ for (auto i = 0; i < size; i++) {
+ ret = GpgAdvancedOperator::GetInstance().RestartGpgComponents();
+ if (!ret) break;
+ }
+
+ if (ret) {
+ QMessageBox::information(
+ this, tr("Successful Operation"),
+ tr("Restart all the GnuPG's components successfully"));
+ } else {
+ QMessageBox::critical(
+ this, tr("Failed Operation"),
+ tr("Failed to restart all or one of the GnuPG's component(s)"));
+ }
}
void MainWindow::slot_update_operations_menu_by_checked_keys(