aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/function
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/function')
-rw-r--r--src/core/function/ArchiveFileOperator.cpp411
-rw-r--r--src/core/function/ArchiveFileOperator.h54
-rw-r--r--src/core/function/CacheManager.cpp311
-rw-r--r--src/core/function/CacheManager.h157
-rw-r--r--src/core/function/CharsetOperator.cpp133
-rw-r--r--src/core/function/CoreSignalStation.cpp15
-rw-r--r--src/core/function/CoreSignalStation.h31
-rw-r--r--src/core/function/DataObjectOperator.cpp178
-rw-r--r--src/core/function/DataObjectOperator.h40
-rw-r--r--src/core/function/FileOperator.cpp124
-rw-r--r--src/core/function/FileOperator.h92
-rw-r--r--src/core/function/GlobalSettingStation.cpp230
-rw-r--r--src/core/function/GlobalSettingStation.h181
-rw-r--r--src/core/function/KeyPackageOperator.cpp186
-rw-r--r--src/core/function/KeyPackageOperator.h44
-rw-r--r--src/core/function/LoggerManager.cpp155
-rw-r--r--src/core/function/LoggerManager.h65
-rw-r--r--src/core/function/PassphraseGenerator.cpp24
-rw-r--r--src/core/function/PassphraseGenerator.h32
-rw-r--r--src/core/function/SecureMemoryAllocator.cpp63
-rw-r--r--src/core/function/SecureMemoryAllocator.h (renamed from src/core/function/CharsetOperator.h)37
-rw-r--r--src/core/function/aes/aes_ssl_cbc.cpp99
-rw-r--r--src/core/function/basic/ChannelObject.cpp (renamed from src/core/function/aes/aes_ssl.h)65
-rw-r--r--src/core/function/basic/ChannelObject.h98
-rw-r--r--src/core/function/basic/GpgFunctionObject.cpp105
-rw-r--r--src/core/function/basic/GpgFunctionObject.h194
-rw-r--r--src/core/function/basic/SingletonStorage.cpp133
-rw-r--r--src/core/function/basic/SingletonStorage.h90
-rw-r--r--src/core/function/basic/SingletonStorageCollection.cpp124
-rw-r--r--src/core/function/basic/SingletonStorageCollection.h79
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.cpp311
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.h47
-rw-r--r--src/core/function/gpg/GpgBasicOperator.cpp458
-rw-r--r--src/core/function/gpg/GpgBasicOperator.h140
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp369
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.h61
-rw-r--r--src/core/function/gpg/GpgContext.cpp339
-rw-r--r--src/core/function/gpg/GpgContext.h76
-rw-r--r--src/core/function/gpg/GpgFileOpera.cpp762
-rw-r--r--src/core/function/gpg/GpgFileOpera.h249
-rw-r--r--src/core/function/gpg/GpgKeyGetter.cpp286
-rw-r--r--src/core/function/gpg/GpgKeyGetter.h74
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.cpp269
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.h135
-rw-r--r--src/core/function/gpg/GpgKeyManager.cpp240
-rw-r--r--src/core/function/gpg/GpgKeyManager.h60
-rw-r--r--src/core/function/gpg/GpgKeyOpera.cpp604
-rw-r--r--src/core/function/gpg/GpgKeyOpera.h79
-rw-r--r--src/core/function/gpg/GpgUIDOperator.cpp62
-rw-r--r--src/core/function/gpg/GpgUIDOperator.h23
-rw-r--r--src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp115
-rw-r--r--src/core/function/result_analyse/GpgDecryptResultAnalyse.h22
-rw-r--r--src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp64
-rw-r--r--src/core/function/result_analyse/GpgEncryptResultAnalyse.h20
-rw-r--r--src/core/function/result_analyse/GpgResultAnalyse.cpp14
-rw-r--r--src/core/function/result_analyse/GpgResultAnalyse.h33
-rw-r--r--src/core/function/result_analyse/GpgSignResultAnalyse.cpp132
-rw-r--r--src/core/function/result_analyse/GpgSignResultAnalyse.h13
-rw-r--r--src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp244
-rw-r--r--src/core/function/result_analyse/GpgVerifyResultAnalyse.h22
60 files changed, 5477 insertions, 3396 deletions
diff --git a/src/core/function/ArchiveFileOperator.cpp b/src/core/function/ArchiveFileOperator.cpp
index 8aad0500..f1345f87 100644
--- a/src/core/function/ArchiveFileOperator.cpp
+++ b/src/core/function/ArchiveFileOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,7 +28,15 @@
#include "ArchiveFileOperator.h"
-int copy_data(struct archive *ar, struct archive *aw) {
+#include <archive.h>
+#include <archive_entry.h>
+#include <sys/fcntl.h>
+
+#include "core/utils/AsyncUtils.h"
+
+namespace GpgFrontend {
+
+auto CopyData(struct archive *ar, struct archive *aw) -> int {
int r;
const void *buff;
size_t size;
@@ -38,231 +46,218 @@ int copy_data(struct archive *ar, struct archive *aw) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF) return (ARCHIVE_OK);
if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_read_data_block() failed: {}",
- archive_error_string(ar));
+ GF_CORE_LOG_ERROR("archive_read_data_block() failed: {}",
+ archive_error_string(ar));
return (r);
}
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_write_data_block() failed: {}",
- archive_error_string(aw));
+ GF_CORE_LOG_ERROR("archive_write_data_block() failed: {}",
+ archive_error_string(aw));
return (r);
}
}
}
-void GpgFrontend::ArchiveFileOperator::CreateArchive(
- const std::filesystem::path &base_path,
- const std::filesystem::path &archive_path, int compress,
- const std::vector<std::filesystem::path> &files) {
- SPDLOG_DEBUG("CreateArchive: {}", archive_path.u8string());
-
- auto current_base_path_backup = QDir::currentPath();
- QDir::setCurrent(base_path.u8string().c_str());
-
- auto relative_archive_path =
- std::filesystem::relative(archive_path, base_path);
-
- std::vector<std::filesystem::path> relative_files;
- relative_files.reserve(files.size());
- for (const auto &file : files) {
- relative_files.push_back(std::filesystem::relative(file, base_path));
- }
-
- struct archive *a;
- struct archive_entry *entry;
- ssize_t len;
- int fd;
-
- SPDLOG_DEBUG("compress: {}", compress);
-
- a = archive_write_new();
- switch (compress) {
-#ifndef NO_BZIP2_CREATE
- case 'j':
- case 'y':
- archive_write_add_filter_bzip2(a);
- break;
-#endif
-#ifndef NO_COMPRESS_CREATE
- case 'Z':
- archive_write_add_filter_compress(a);
- break;
-#endif
-#ifndef NO_GZIP_CREATE
- case 'z':
- archive_write_add_filter_gzip(a);
- break;
-#endif
- default:
- archive_write_add_filter_none(a);
- break;
- }
- archive_write_set_format_ustar(a);
- archive_write_set_format_pax_restricted(a);
-
- auto u8_filename = relative_archive_path.u8string();
-
- if (!u8_filename.empty() && u8_filename == u8"-")
- throw std::runtime_error("cannot write to stdout");
-
-#ifdef WINDOWS
- archive_write_open_filename_w(a, relative_archive_path.wstring().c_str());
-#else
- archive_write_open_filename(a, u8_filename.c_str());
-#endif
-
- for (const auto &file : relative_files) {
- struct archive *disk = archive_read_disk_new();
-#ifndef NO_LOOKUP
- archive_read_disk_set_standard_lookup(disk);
-#endif
- int r;
-
- SPDLOG_DEBUG("reading file: {}", file.u8string());
-
-#ifdef WINDOWS
- r = archive_read_disk_open_w(disk, file.wstring().c_str());
-#else
- r = archive_read_disk_open(disk, file.u8string().c_str());
-#endif
-
- SPDLOG_DEBUG("read file done: {}", file.u8string());
-
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("{archive_read_disk_open() failed: {}",
- archive_error_string(disk));
- throw std::runtime_error("archive_read_disk_open() failed");
- }
+struct ArchiveReadClientData {
+ GFDataExchanger *ex;
+ std::array<std::byte, 1024> buf;
+ const std::byte *p_buf = buf.data();
+};
+
+auto ArchiveReadCallback(struct archive *, void *client_data,
+ const void **buffer) -> ssize_t {
+ auto *rdata = static_cast<ArchiveReadClientData *>(client_data);
+ *buffer = reinterpret_cast<const void *>(rdata->p_buf);
+ return rdata->ex->Read(rdata->buf.data(), rdata->buf.size());
+}
- for (;;) {
- entry = archive_entry_new();
- r = archive_read_next_header2(disk, entry);
-
- if (r == ARCHIVE_EOF) break;
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_read_next_header2() failed: {}",
- archive_error_string(disk));
- throw std::runtime_error("archive_read_next_header2() failed");
- }
- archive_read_disk_descend(disk);
-
- SPDLOG_DEBUG("Adding: {} size: {} bytes: {} file type: {}",
- archive_entry_pathname_utf8(entry),
- archive_entry_size(entry), archive_entry_filetype(entry));
-
- r = archive_write_header(a, entry);
- if (r < ARCHIVE_OK) {
- SPDLOG_ERROR("archive_write_header() failed: {}",
- archive_error_string(a));
- throw std::runtime_error("archive_write_header() failed");
- }
- if (r == ARCHIVE_FATAL) throw std::runtime_error("archive fatal");
- if (r > ARCHIVE_FAILED) {
- QByteArray buff;
-#ifdef WINDOWS
- FileOperator::ReadFile(
- QString::fromStdWString(archive_entry_sourcepath_w(entry)), buff);
-#else
- FileOperator::ReadFile(archive_entry_sourcepath(entry), buff);
-#endif
- archive_write_data(a, buff.data(), buff.size());
- }
- archive_entry_free(entry);
- }
- archive_read_close(disk);
- archive_read_free(disk);
- }
- archive_write_close(a);
- archive_write_free(a);
+auto ArchiveWriteCallback(struct archive *, void *client_data,
+ const void *buffer, size_t length) -> ssize_t {
+ auto *ex = static_cast<GFDataExchanger *>(client_data);
+ return ex->Write(static_cast<const std::byte *>(buffer), length);
+}
- QDir::setCurrent(current_base_path_backup);
+auto ArchiveCloseWriteCallback(struct archive *, void *client_data) -> int {
+ auto *ex = static_cast<GFDataExchanger *>(client_data);
+ ex->CloseWrite();
+ return 0;
}
-void GpgFrontend::ArchiveFileOperator::ExtractArchive(
- const std::filesystem::path &archive_path,
- const std::filesystem::path &base_path) {
- SPDLOG_DEBUG("ExtractArchive: {}", archive_path.u8string());
+void ArchiveFileOperator::NewArchive2DataExchanger(
+ const QString &target_directory, std::shared_ptr<GFDataExchanger> exchanger,
+ const OperationCallback &cb) {
+ RunIOOperaAsync(
+ [=](const DataObjectPtr &data_object) -> GFError {
+ std::array<char, 1024> buff{};
+ auto ret = 0;
+ const auto base_path = QDir(QDir(target_directory).absolutePath());
- auto current_base_path_backup = QDir::currentPath();
- QDir::setCurrent(base_path.u8string().c_str());
+ auto *archive = archive_write_new();
+ archive_write_add_filter_none(archive);
+ archive_write_set_format_pax_restricted(archive);
- struct archive *a;
- struct archive *ext;
- struct archive_entry *entry;
+ archive_write_open(archive, exchanger.get(), nullptr,
+ ArchiveWriteCallback, ArchiveCloseWriteCallback);
- a = archive_read_new();
- ext = archive_write_disk_new();
- archive_write_disk_set_options(ext, 0);
-#ifndef NO_BZIP2_EXTRACT
- archive_read_support_filter_bzip2(a);
-#endif
-#ifndef NO_GZIP_EXTRACT
- archive_read_support_filter_gzip(a);
-#endif
-#ifndef NO_COMPRESS_EXTRACT
- archive_read_support_filter_compress(a);
-#endif
-#ifndef NO_TAR_EXTRACT
- archive_read_support_format_tar(a);
-#endif
-#ifndef NO_CPIO_EXTRACT
- archive_read_support_format_cpio(a);
-#endif
-#ifndef NO_LOOKUP
- archive_write_disk_set_standard_lookup(ext);
-#endif
+ auto *disk = archive_read_disk_new();
+ archive_read_disk_set_standard_lookup(disk);
- auto filename = archive_path.u8string();
-
- if (!filename.empty() && filename == u8"-") {
- SPDLOG_ERROR("cannot read from stdin");
- }
#ifdef WINDOWS
- if (archive_read_open_filename_w(a, archive_path.wstring().c_str(), 10240) !=
- ARCHIVE_OK) {
+ auto r = archive_read_disk_open_w(
+ disk, target_directory.toStdWString().c_str());
#else
- if (archive_read_open_filename(a, archive_path.u8string().c_str(), 10240) !=
- ARCHIVE_OK) {
+ auto r = archive_read_disk_open(disk, target_directory.toUtf8());
#endif
- SPDLOG_ERROR("archive_read_open_filename() failed: {}",
- archive_error_string(a));
- throw std::runtime_error("archive_read_open_filename() failed");
- }
-
- for (;;) {
- int r = archive_read_next_header(a, &entry);
- if (r == ARCHIVE_EOF) break;
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_read_next_header() failed: {}",
- archive_error_string(a));
- throw std::runtime_error("archive_read_next_header() failed");
- }
- SPDLOG_DEBUG("Adding: {} size: {} bytes: {} file type: {}",
- archive_entry_pathname_utf8(entry), archive_entry_size(entry),
- archive_entry_filetype(entry));
- r = archive_write_header(ext, entry);
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_write_header() failed: {}",
- archive_error_string(ext));
- } else {
- r = copy_data(a, ext);
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("copy_data() failed: {}", archive_error_string(ext));
- }
- }
- }
- archive_read_close(a);
- archive_read_free(a);
- archive_write_close(ext);
- archive_write_free(ext);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_disk_open() failed: {}, abort...",
+ archive_error_string(disk));
+ archive_read_free(disk);
+ archive_write_free(archive);
+ return -1;
+ }
+
+ for (;;) {
+ auto *entry = archive_entry_new();
+ r = archive_read_next_header2(disk, entry);
+ if (r == ARCHIVE_EOF) break;
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_read_next_header2() failed, ret: {}, explain: {}", r,
+ archive_error_string(disk));
+ ret = -1;
+ break;
+ }
+
+ archive_read_disk_descend(disk);
+
+ // turn absolute path to relative path
+ archive_entry_set_pathname(
+ entry,
+ base_path.relativeFilePath(QString(archive_entry_pathname(entry)))
+ .toUtf8());
+
+ r = archive_write_header(archive, entry);
+ if (r < ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_write_header() failed, ret: {}, explain: {} ", r,
+ archive_error_string(archive));
+ continue;
+ }
+
+ if (r == ARCHIVE_FATAL) {
+ GF_CORE_LOG_ERROR(
+ "archive_write_header() failed, ret: {}, explain: {}, "
+ "abort ...",
+ r, archive_error_string(archive));
+ ret = -1;
+ break;
+ }
+
+ if (r > ARCHIVE_FAILED) {
+ auto fd = open(archive_entry_sourcepath(entry), O_RDONLY);
+ auto len = read(fd, buff.data(), buff.size());
+ while (len > 0) {
+ archive_write_data(archive, buff.data(), len);
+ len = read(fd, buff.data(), buff.size());
+ }
+ close(fd);
+ }
+ archive_entry_free(entry);
+ }
+
+ archive_read_free(disk);
+ archive_write_free(archive);
+ return ret;
+ },
+ cb, "archive_write_new");
+}
- QDir::setCurrent(current_base_path_backup);
+void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
+ std::shared_ptr<GFDataExchanger> ex, const QString &target_path,
+ const OperationCallback &cb) {
+ GF_CORE_LOG_INFO("target path: {}", target_path);
+ RunIOOperaAsync(
+ [=](const DataObjectPtr &data_object) -> GFError {
+ auto *archive = archive_read_new();
+ auto *ext = archive_write_disk_new();
+
+ auto r = archive_read_support_filter_all(archive);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_read_support_filter_all(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ r = archive_read_support_format_all(archive);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_read_support_format_all(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ auto rdata = ArchiveReadClientData{};
+ rdata.ex = ex.get();
+
+ r = archive_read_open(archive, &rdata, nullptr, ArchiveReadCallback,
+ nullptr);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_open(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ r = archive_write_disk_set_options(ext, 0);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_write_disk_set_options(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ for (;;) {
+ struct archive_entry *entry;
+ r = archive_read_next_header(archive, &entry);
+ if (r == ARCHIVE_EOF) break;
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_next_header(), ret: {}, reason: {}",
+ r, archive_error_string(archive));
+ break;
+ }
+
+ archive_entry_set_pathname(
+ entry,
+ (target_path + "/" + archive_entry_pathname(entry)).toUtf8());
+
+ r = archive_write_header(ext, entry);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_write_header(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ } else {
+ r = CopyData(archive, ext);
+ }
+ }
+
+ r = archive_read_free(archive);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_free(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ }
+ r = archive_write_free(ext);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_free(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ }
+
+ return 0;
+ },
+ cb, "archive_read_new");
}
-void GpgFrontend::ArchiveFileOperator::ListArchive(
- const std::filesystem::path &archive_path) {
+void ArchiveFileOperator::ListArchive(const QString &archive_path) {
struct archive *a;
struct archive_entry *entry;
int r;
@@ -270,14 +265,16 @@ void GpgFrontend::ArchiveFileOperator::ListArchive(
a = archive_read_new();
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
- r = archive_read_open_filename(a, archive_path.u8string().c_str(),
+ r = archive_read_open_filename(a, archive_path.toUtf8(),
10240); // Note 1
if (r != ARCHIVE_OK) return;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
- SPDLOG_DEBUG("File: {}", archive_entry_pathname(entry));
- SPDLOG_DEBUG("File Path: {}", archive_entry_pathname(entry));
+ GF_CORE_LOG_DEBUG("File: {}", archive_entry_pathname(entry));
+ GF_CORE_LOG_DEBUG("File Path: {}", archive_entry_pathname(entry));
archive_read_data_skip(a); // Note 2
}
r = archive_read_free(a); // Note 3
if (r != ARCHIVE_OK) return;
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/ArchiveFileOperator.h b/src/core/function/ArchiveFileOperator.h
index 4db5af5f..bfeec0c4 100644
--- a/src/core/function/ArchiveFileOperator.h
+++ b/src/core/function/ArchiveFileOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,40 +20,50 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ARCHIVEFILEOPERATOR_H
-#define GPGFRONTEND_ARCHIVEFILEOPERATOR_H
+#pragma once
#include "core/GpgFrontendCore.h"
-#include "core/function/FileOperator.h"
+#include "core/model/GFDataExchanger.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/utils/IOUtils.h"
namespace GpgFrontend {
-struct ArchiveStruct {
- struct archive *archive;
- struct archive_entry *entry;
- int fd;
- bool is_open;
- std::string name;
-};
-
class GPGFRONTEND_CORE_EXPORT ArchiveFileOperator {
public:
- static void ListArchive(const std::filesystem::path &archive_path);
+ /**
+ * @brief
+ *
+ * @param archive_path
+ */
+ static void ListArchive(const QString &archive_path);
- static void CreateArchive(const std::filesystem::path &base_path,
- const std::filesystem::path &archive_path,
- int compress,
- const std::vector<std::filesystem::path> &files);
+ /**
+ * @brief Create a Archive object
+ *
+ * @param base_path
+ * @param archive_path
+ * @param compress
+ * @param files
+ */
+ static void NewArchive2DataExchanger(const QString &target_directory,
+ std::shared_ptr<GFDataExchanger>,
+ const OperationCallback &cb);
- static void ExtractArchive(const std::filesystem::path &archive_path,
- const std::filesystem::path &base_path);
+ /**
+ * @brief
+ *
+ * @param archive_path
+ * @param base_path
+ */
+ static void ExtractArchiveFromDataExchanger(
+ std::shared_ptr<GFDataExchanger> fd, const QString &target_path,
+ const OperationCallback &cb);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ARCHIVEFILEOPERATOR_H
diff --git a/src/core/function/CacheManager.cpp b/src/core/function/CacheManager.cpp
index d9aead66..719c962d 100644
--- a/src/core/function/CacheManager.cpp
+++ b/src/core/function/CacheManager.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -29,119 +29,256 @@
#include "CacheManager.h"
#include <algorithm>
-#include <boost/format.hpp>
-#include <string>
+#include <shared_mutex>
+#include <utility>
-#include "function/DataObjectOperator.h"
-#include "spdlog/spdlog.h"
+#include "core/function/DataObjectOperator.h"
+#include "core/utils/MemoryUtils.h"
-GpgFrontend::CacheManager::CacheManager(int channel)
- : m_timer_(new QTimer(this)),
- SingletonFunctionObject<CacheManager>(channel) {
- connect(m_timer_, &QTimer::timeout, this, &CacheManager::flush_cache_storage);
- m_timer_->start(15000);
+namespace GpgFrontend {
- load_all_cache_storage();
-}
+template <typename Key, typename Value>
+class ThreadSafeMap {
+ public:
+ using MapType = std::map<Key, Value>;
+ using IteratorType = typename MapType::iterator;
-void GpgFrontend::CacheManager::SaveCache(std::string key,
- const nlohmann::json& value,
- bool flush) {
- auto data_object_key = get_data_object_key(key);
- cache_storage_.insert(key, value);
+ void insert(const Key& key, const Value& value) {
+ std::unique_lock lock(mutex_);
+ (*map_)[key] = value;
+ }
- if (std::find(key_storage_.begin(), key_storage_.end(), key) ==
- key_storage_.end()) {
- SPDLOG_DEBUG("register new key of cache", key);
- key_storage_.push_back(key);
+ auto get(const Key& key) -> std::optional<Value> {
+ std::shared_lock lock(mutex_);
+ auto it = map_->find(key);
+ if (it != map_->end()) {
+ return it->second;
+ }
+ return std::nullopt;
}
- if (flush) {
- flush_cache_storage();
+ auto exists(const Key& key) -> bool {
+ std::shared_lock lock(mutex_);
+ return map_->count(key) > 0;
}
-}
-nlohmann::json GpgFrontend::CacheManager::LoadCache(std::string key) {
- auto data_object_key = get_data_object_key(key);
+ auto begin() -> IteratorType { return map_mirror_->begin(); }
+
+ auto end() -> IteratorType { return map_mirror_->end(); }
- if (!cache_storage_.exists(key)) {
- cache_storage_.insert(key, load_cache_storage(key, {}));
+ auto mirror() -> ThreadSafeMap& {
+ std::shared_lock lock(mutex_);
+ *map_mirror_ = *map_;
+ return *this;
}
- auto cache = cache_storage_.get(key);
- if (cache)
- return *cache;
- else
- return {};
-}
+ auto remove(QString key) -> bool {
+ std::unique_lock lock(mutex_);
+ auto it = map_->find(key);
+ if (it != map_->end()) {
+ map_->erase(it);
+ return true;
+ }
+ return false;
+ }
-nlohmann::json GpgFrontend::CacheManager::LoadCache(
- std::string key, nlohmann::json default_value) {
- auto data_object_key = get_data_object_key(key);
- if (!cache_storage_.exists(key)) {
- cache_storage_.insert(key, load_cache_storage(key, default_value));
+ private:
+ std::unique_ptr<MapType, SecureObjectDeleter<MapType>> map_mirror_ =
+ std::move(SecureCreateUniqueObject<MapType>());
+ std::unique_ptr<MapType, SecureObjectDeleter<MapType>> map_ =
+ std::move(SecureCreateUniqueObject<MapType>());
+ mutable std::shared_mutex mutex_;
+};
+
+class CacheManager::Impl : public QObject {
+ Q_OBJECT
+ public:
+ Impl() : flush_timer_(new QTimer(this)) {
+ connect(flush_timer_, &QTimer::timeout, this,
+ &Impl::slot_flush_cache_storage);
+ flush_timer_->start(15000);
+
+ // load data from storage
+ load_all_cache_storage();
}
- auto cache = cache_storage_.get(key);
- if (cache)
- return *cache;
- else
- return {};
-}
+ void SaveDurableCache(QString key, const QJsonDocument& value, bool flush) {
+ auto data_object_key = get_data_object_key(key);
+ durable_cache_storage_.insert(key, value);
-std::string GpgFrontend::CacheManager::get_data_object_key(std::string key) {
- return (boost::format("__cache_data_%1%") % key).str();
-}
+ if (!key_storage_.contains(key)) {
+ GF_CORE_LOG_DEBUG("register new key of cache", key);
+ key_storage_.push_back(key);
+ }
-nlohmann::json GpgFrontend::CacheManager::load_cache_storage(
- std::string key, nlohmann::json default_value) {
- auto data_object_key = get_data_object_key(key);
- auto stored_data =
- GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(
- data_object_key);
+ if (flush) slot_flush_cache_storage();
+ }
- if (stored_data.has_value()) {
- return stored_data.value();
- } else {
- return default_value;
+ auto LoadDurableCache(const QString& key) -> QJsonDocument {
+ auto data_object_key = get_data_object_key(key);
+
+ if (!durable_cache_storage_.exists(key)) {
+ durable_cache_storage_.insert(key, load_cache_storage(key, {}));
+ }
+
+ auto cache = durable_cache_storage_.get(key);
+ if (cache.has_value()) return cache.value();
+ return {};
}
-}
-void GpgFrontend::CacheManager::flush_cache_storage() {
- for (auto cache : cache_storage_.mirror()) {
- auto key = get_data_object_key(cache.first);
- SPDLOG_DEBUG("save cache into filesystem, key {}, value size: {}", key,
- cache.second.size());
- GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(key,
- cache.second);
+ auto LoadDurableCache(const QString& key, QJsonDocument default_value)
+ -> QJsonDocument {
+ auto data_object_key = get_data_object_key(key);
+ if (!durable_cache_storage_.exists(key)) {
+ durable_cache_storage_.insert(
+ key, load_cache_storage(key, std::move(default_value)));
+ }
+
+ auto cache = durable_cache_storage_.get(key);
+ if (cache.has_value()) return cache.value();
+ return {};
}
- GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(drk_key_,
- key_storage_);
-}
-void GpgFrontend::CacheManager::register_cache_key(std::string key) {}
+ auto ResetDurableCache(const QString& key) -> bool {
+ auto data_object_key = get_data_object_key(key);
+ return durable_cache_storage_.remove(key);
+ }
+
+ void FlushCacheStorage() { this->slot_flush_cache_storage(); }
-void GpgFrontend::CacheManager::load_all_cache_storage() {
- SPDLOG_DEBUG("start to load all cache from file system");
- auto stored_data =
- GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(drk_key_);
+ void SaveCache(const QString& key, QString value) {
+ runtime_cache_storage_.insert(key, new QString(std::move(value)));
+ }
- // get cache data list from file system
- nlohmann::json registered_key_list;
- if (stored_data.has_value()) {
- registered_key_list = std::move(stored_data.value());
+ auto LoadCache(const QString& key) -> QString {
+ auto* value = runtime_cache_storage_.object(key);
+ if (value == nullptr) return {};
+ return *value;
}
- if (!registered_key_list.is_array()) {
+ void ResetCache(const QString& key) { runtime_cache_storage_.remove(key); }
+
+ private slots:
+
+ /**
+ * @brief
+ *
+ */
+ void slot_flush_cache_storage() {
+ for (const auto& cache : durable_cache_storage_.mirror()) {
+ auto key = get_data_object_key(cache.first);
+ GF_CORE_LOG_TRACE("save cache into filesystem, key {}", key);
+ GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
+ key, QJsonDocument(cache.second));
+ }
GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
- drk_key_, nlohmann::json::array());
- SPDLOG_ERROR("drk_key_ is not an array, abort.");
- return;
+ drk_key_, QJsonDocument(key_storage_));
}
- for (auto key : registered_key_list) {
- load_cache_storage(key, {});
+ private:
+ QCache<QString, QString> runtime_cache_storage_;
+ ThreadSafeMap<QString, QJsonDocument> durable_cache_storage_;
+ QJsonArray key_storage_;
+ QTimer* flush_timer_;
+ const QString drk_key_ = "__cache_manage_data_register_key_list";
+
+ /**
+ * @brief Get the data object key object
+ *
+ * @param key
+ * @return QString
+ */
+ static auto get_data_object_key(const QString& key) -> QString {
+ return QString("__cache_data_%1").arg(key);
}
- key_storage_ = registered_key_list;
-} \ No newline at end of file
+ /**
+ * @brief
+ *
+ * @param key
+ * @param default_value
+ * @return QJsonObject
+ */
+ static auto load_cache_storage(const QString& key,
+ QJsonDocument default_value) -> QJsonDocument {
+ auto data_object_key = get_data_object_key(key);
+ auto stored_data =
+ GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(
+ data_object_key);
+
+ if (stored_data.has_value()) return stored_data.value();
+ return default_value;
+ }
+
+ /**
+ * @brief
+ *
+ */
+ void load_all_cache_storage() {
+ GF_CORE_LOG_DEBUG("start to load all cache from file system");
+ auto stored_data =
+ GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(drk_key_);
+
+ // get cache data list from file system
+ QJsonArray registered_key_list;
+ if (stored_data->isArray()) {
+ registered_key_list = stored_data->array();
+ } else {
+ GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
+ drk_key_, QJsonDocument(QJsonArray()));
+ }
+
+ for (const auto& key : registered_key_list) {
+ load_cache_storage(key.toString(), {});
+ }
+
+ key_storage_ = registered_key_list;
+ }
+
+ /**
+ * @brief
+ *
+ * @param key
+ */
+ void register_cache_key(const QString& key) {}
+};
+
+CacheManager::CacheManager(int channel)
+ : SingletonFunctionObject<CacheManager>(channel),
+ p_(SecureCreateUniqueObject<Impl>()) {}
+
+CacheManager::~CacheManager() { p_->FlushCacheStorage(); }
+
+void CacheManager::SaveDurableCache(const QString& key,
+ const QJsonDocument& value, bool flush) {
+ p_->SaveDurableCache(key, value, flush);
+}
+
+auto CacheManager::LoadDurableCache(const QString& key) -> QJsonDocument {
+ return p_->LoadDurableCache(key);
+}
+
+auto CacheManager::LoadDurableCache(const QString& key,
+ QJsonDocument default_value)
+ -> QJsonDocument {
+ return p_->LoadDurableCache(key, std::move(default_value));
+}
+
+auto CacheManager::ResetDurableCache(const QString& key) -> bool {
+ return p_->ResetDurableCache(key);
+}
+
+void CacheManager::SaveCache(const QString& key, QString value) {
+ p_->SaveCache(key, std::move(value));
+}
+
+auto CacheManager::LoadCache(const QString& key) -> QString {
+ return p_->LoadCache(key);
+}
+
+void CacheManager::ResetCache(const QString& key) {
+ return p_->ResetCache(key);
+}
+} // namespace GpgFrontend
+
+#include "CacheManager.moc" \ No newline at end of file
diff --git a/src/core/function/CacheManager.h b/src/core/function/CacheManager.h
index 8234de2a..67e7fd75 100644
--- a/src/core/function/CacheManager.h
+++ b/src/core/function/CacheManager.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,94 +20,99 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_CACHEMANAGER_H
-#define GPGFRONTEND_CACHEMANAGER_H
+#pragma once
-#include <string>
-
-#include "core/GpgFunctionObject.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
-template <typename Key, typename Value>
-class ThreadSafeMap {
- public:
- using MapType = std::map<Key, Value>;
- using IteratorType = typename MapType::iterator;
-
- void insert(const Key& key, const Value& value) {
- std::unique_lock lock(mutex_);
- map_[key] = value;
- }
-
- std::optional<Value> get(const Key& key) {
- std::shared_lock lock(mutex_);
- auto it = map_.find(key);
- if (it != map_.end()) {
- return it->second;
- }
- return std::nullopt;
- }
-
- bool exists(const Key& key) {
- std::shared_lock lock(mutex_);
- return map_.count(key) > 0;
- }
-
- IteratorType begin() { return map_mirror_.begin(); }
-
- IteratorType end() { return map_mirror_.end(); }
-
- ThreadSafeMap& mirror() {
- std::shared_lock lock(mutex_);
- map_mirror_ = map_;
- return *this;
- }
-
- private:
- MapType map_mirror_;
- MapType map_;
- mutable std::shared_mutex mutex_;
-};
-
class GPGFRONTEND_CORE_EXPORT CacheManager
- : public QObject,
- public SingletonFunctionObject<CacheManager> {
- Q_OBJECT
+ : public SingletonFunctionObject<CacheManager> {
public:
- CacheManager(int channel = SingletonFunctionObject::GetDefaultChannel());
-
- void SaveCache(std::string key, const nlohmann::json& value,
- bool flush = false);
-
- nlohmann::json LoadCache(std::string key);
-
- nlohmann::json LoadCache(std::string key, nlohmann::json default_value);
+ /**
+ * @brief Construct a new Cache Manager object
+ *
+ * @param channel
+ */
+ explicit CacheManager(
+ int channel = SingletonFunctionObject::GetDefaultChannel());
+
+ /**
+ * @brief Destroy the Cache Manager object
+ *
+ */
+ ~CacheManager() override;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param value
+ */
+ void SaveCache(const QString& key, QString value);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param value
+ * @param flush
+ */
+ void SaveDurableCache(const QString& key, const QJsonDocument& value,
+ bool flush = false);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param value
+ */
+ auto LoadCache(const QString& key) -> QString;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @return QJsonDocument
+ */
+ auto LoadDurableCache(const QString& key) -> QJsonDocument;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param default_value
+ * @return QJsonDocument
+ */
+ auto LoadDurableCache(const QString& key, QJsonDocument default_value)
+ -> QJsonDocument;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @return auto
+ */
+ void ResetCache(const QString& key);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @return true
+ * @return false
+ */
+ auto ResetDurableCache(const QString& key) -> bool;
private:
- std::string get_data_object_key(std::string key);
-
- nlohmann::json load_cache_storage(std::string key,
- nlohmann::json default_value);
-
- void load_all_cache_storage();
-
- void flush_cache_storage();
-
- void register_cache_key(std::string key);
-
- ThreadSafeMap<std::string, nlohmann::json> cache_storage_;
- nlohmann::json key_storage_;
- QTimer* m_timer_;
- const std::string drk_key_ = "__cache_manage_data_register_key_list";
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend
-
-#endif
diff --git a/src/core/function/CharsetOperator.cpp b/src/core/function/CharsetOperator.cpp
deleted file mode 100644
index 72c5e72b..00000000
--- a/src/core/function/CharsetOperator.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "core/function/CharsetOperator.h"
-
-#include <spdlog/spdlog.h>
-#include <unicode/ucnv.h>
-#include <unicode/ucsdet.h>
-#include <unicode/ustring.h>
-#include <unicode/utypes.h>
-
-#include <cstddef>
-#include <memory>
-#include <string>
-
-GpgFrontend::CharsetOperator::CharsetInfo GpgFrontend::CharsetOperator::Detect(
- const std::string &buffer) {
- const UCharsetMatch *ucm;
- UErrorCode status = U_ZERO_ERROR;
- UCharsetDetector *csd = ucsdet_open(&status);
-
- status = U_ZERO_ERROR;
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to open charset detector: {}", u_errorName(status));
- return {"unknown", "unknown", 0};
- }
-
- SPDLOG_DEBUG("detecting charset buffer: {} bytes", buffer.size());
-
- status = U_ZERO_ERROR;
- ucsdet_setText(csd, buffer.data(), buffer.size(), &status);
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to set text to charset detector: {}",
- u_errorName(status));
- return {"unknown", "unknown", 0};
- }
-
- status = U_ZERO_ERROR;
- ucm = ucsdet_detect(csd, &status);
-
- if (U_FAILURE(status)) return {"unknown", "unknown", 0};
-
- status = U_ZERO_ERROR;
- const char *name = ucsdet_getName(ucm, &status);
- if (U_FAILURE(status)) return {"unknown", "unknown", 0};
-
- status = U_ZERO_ERROR;
- int confidence = ucsdet_getConfidence(ucm, &status);
- if (U_FAILURE(status)) return {name, "unknown", 0};
-
- status = U_ZERO_ERROR;
- const char *language = ucsdet_getLanguage(ucm, &status);
- if (U_FAILURE(status)) return {name, "unknown", confidence};
-
- SPDLOG_DEBUG("Detected charset: {} {} {}", name, language, confidence);
- return {name, language, confidence};
-}
-
-bool GpgFrontend::CharsetOperator::Convert2Utf8(const std::string &buffer,
- std::string &out_buffer,
- std::string from_charset_name) {
- UErrorCode status = U_ZERO_ERROR;
- const auto from_encode = std::string("utf-8");
- const auto to_encode = from_charset_name;
-
- SPDLOG_DEBUG("Converting buffer: {}", buffer.size());
-
- // test if the charset is supported
- UConverter *conv = ucnv_open(from_encode.c_str(), &status);
- ucnv_close(conv);
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to open converter: {}, from encode: {}",
- u_errorName(status), from_encode);
- return false;
- }
-
- // test if the charset is supported
- conv = ucnv_open(to_encode.c_str(), &status);
- ucnv_close(conv);
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to open converter: {}, to encode: {}",
- u_errorName(status), to_encode);
- return false;
- }
-
- status = U_ZERO_ERROR;
- int32_t target_limit = 0, target_capacity = 0;
-
- target_capacity =
- ucnv_convert(from_encode.c_str(), to_encode.c_str(), nullptr,
- target_limit, buffer.data(), buffer.size(), &status);
-
- if (status == U_BUFFER_OVERFLOW_ERROR) {
- status = U_ZERO_ERROR;
- out_buffer.clear();
- out_buffer.resize(target_capacity);
- ucnv_convert(from_encode.c_str(), to_encode.c_str(), out_buffer.data(),
- out_buffer.size(), buffer.data(), buffer.size(), &status);
- }
-
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to convert to utf-8: {}", u_errorName(status));
- return false;
- }
-
- SPDLOG_DEBUG("converted buffer: {} bytes", out_buffer.size());
- return true;
-} \ No newline at end of file
diff --git a/src/core/function/CoreSignalStation.cpp b/src/core/function/CoreSignalStation.cpp
index f78d417b..8cb84743 100644
--- a/src/core/function/CoreSignalStation.cpp
+++ b/src/core/function/CoreSignalStation.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -29,11 +29,12 @@
#include "core/function/CoreSignalStation.h"
std::unique_ptr<GpgFrontend::CoreSignalStation>
- GpgFrontend::CoreSignalStation::_instance = nullptr;
+ GpgFrontend::CoreSignalStation::instance = nullptr;
-GpgFrontend::CoreSignalStation* GpgFrontend::CoreSignalStation::GetInstance() {
- if (_instance == nullptr) {
- _instance = std::make_unique<CoreSignalStation>();
+auto GpgFrontend::CoreSignalStation::GetInstance()
+ -> GpgFrontend::CoreSignalStation* {
+ if (instance == nullptr) {
+ instance = std::make_unique<CoreSignalStation>();
}
- return _instance.get();
+ return instance.get();
}
diff --git a/src/core/function/CoreSignalStation.h b/src/core/function/CoreSignalStation.h
index 7497cab7..e0a11fa3 100644
--- a/src/core/function/CoreSignalStation.h
+++ b/src/core/function/CoreSignalStation.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,26 +20,27 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_CORESIGNALSTATION_H
-#define GPGFRONTEND_CORESIGNALSTATION_H
+#pragma once
#include "core/GpgFrontendCore.h"
namespace GpgFrontend {
+class GpgPassphraseContext;
+
/**
* @brief
*
*/
class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
Q_OBJECT
- static std::unique_ptr<CoreSignalStation> _instance;
+ static std::unique_ptr<CoreSignalStation> instance;
public:
/**
@@ -47,7 +48,7 @@ class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
*
* @return SignalStation*
*/
- static CoreSignalStation* GetInstance();
+ static auto GetInstance() -> CoreSignalStation*;
signals:
@@ -55,15 +56,25 @@ class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
* @brief
*
*/
- void SignalUserInputPassphraseDone(QString passparase);
+ void SignalNeedUserInputPassphrase(QSharedPointer<GpgPassphraseContext>);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalUserInputPassphraseCallback(QSharedPointer<GpgPassphraseContext>);
/**
* @brief
*
*/
- void SignalNeedUserInputPassphrase();
+ void SignalBadGnupgEnv(QString);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalGoodGnupgEnv();
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_CORESIGNALSTATION_H
diff --git a/src/core/function/DataObjectOperator.cpp b/src/core/function/DataObjectOperator.cpp
index 180cef30..cbf21f8e 100644
--- a/src/core/function/DataObjectOperator.cpp
+++ b/src/core/function/DataObjectOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -30,143 +30,131 @@
#include <qt-aes/qaesencryption.h>
-#include <boost/date_time.hpp>
-
-#include "core/function/FileOperator.h"
#include "core/function/PassphraseGenerator.h"
+#include "core/utils/IOUtils.h"
+
+namespace GpgFrontend {
-void GpgFrontend::DataObjectOperator::init_app_secure_key() {
- SPDLOG_DEBUG("initializing application secure key");
- FileOperator::WriteFileStd(app_secure_key_path_,
- PassphraseGenerator::GetInstance().Generate(256));
- std::filesystem::permissions(
- app_secure_key_path_,
- std::filesystem::perms::owner_read | std::filesystem::perms::owner_write);
+void DataObjectOperator::init_app_secure_key() {
+ GF_CORE_LOG_INFO("initializing application secure key...");
+ WriteFile(app_secure_key_path_,
+ PassphraseGenerator::GetInstance().Generate(256).toUtf8());
+ QFile::setPermissions(app_secure_key_path_,
+ QFileDevice::ReadOwner | QFileDevice::WriteOwner);
}
-GpgFrontend::DataObjectOperator::DataObjectOperator(int channel)
+DataObjectOperator::DataObjectOperator(int channel)
: SingletonFunctionObject<DataObjectOperator>(channel) {
- if (!is_directory(app_secure_path_)) create_directory(app_secure_path_);
-
- if (!exists(app_secure_key_path_)) {
- init_app_secure_key();
+ if (!QDir(app_secure_path_).exists()) QDir(app_secure_path_).mkpath(".");
+ if (!QFileInfo(app_secure_key_path_).exists()) init_app_secure_key();
+
+ QByteArray key;
+ if (!ReadFile(app_secure_key_path_, key)) {
+ GF_CORE_LOG_ERROR("failed to read app secure key file: {}",
+ app_secure_key_path_);
+ // unsafe mode
+ key = {};
}
- std::string key;
- if (!FileOperator::ReadFileStd(app_secure_key_path_.u8string(), key)) {
- SPDLOG_ERROR("failed to read app secure key file: {}",
- app_secure_key_path_.u8string());
- throw std::runtime_error("failed to read app secure key file");
- }
- hash_key_ = QCryptographicHash::hash(QByteArray::fromStdString(key),
- QCryptographicHash::Sha256);
- SPDLOG_DEBUG("app secure key loaded {} bytes", hash_key_.size());
+ hash_key_ = QCryptographicHash::hash(key, QCryptographicHash::Sha256);
- if (!exists(app_data_objs_path_)) create_directory(app_data_objs_path_);
+ if (!QDir(app_data_objs_path_).exists()) {
+ QDir(app_data_objs_path_).mkpath(".");
+ }
}
-std::string GpgFrontend::DataObjectOperator::SaveDataObj(
- const std::string& _key, const nlohmann::json& value) {
- std::string _hash_obj_key = {};
- if (_key.empty()) {
- _hash_obj_key =
+auto DataObjectOperator::SaveDataObj(const QString& key,
+ const QJsonDocument& value) -> QString {
+ QByteArray hash_obj_key;
+ if (key.isEmpty()) {
+ hash_obj_key =
QCryptographicHash::hash(
- hash_key_ + QByteArray::fromStdString(
- PassphraseGenerator::GetInstance().Generate(32) +
- to_iso_extended_string(
- boost::posix_time::second_clock::local_time())),
+ hash_key_ +
+ PassphraseGenerator::GetInstance().Generate(32).toUtf8() +
+ QDateTime::currentDateTime().toString().toUtf8(),
QCryptographicHash::Sha256)
- .toHex()
- .toStdString();
+ .toHex();
} else {
- _hash_obj_key =
- QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key),
- QCryptographicHash::Sha256)
- .toHex()
- .toStdString();
+ hash_obj_key = QCryptographicHash::hash(hash_key_ + key.toUtf8(),
+ QCryptographicHash::Sha256)
+ .toHex();
}
- const auto obj_path = app_data_objs_path_ / _hash_obj_key;
-
- QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
- QAESEncryption::Padding::ISO);
- auto encoded =
- encryption.encode(QByteArray::fromStdString(to_string(value)), hash_key_);
-
- SPDLOG_DEBUG("saving data object {} to {} , size: {} bytes", _hash_obj_key,
- obj_path.u8string(), encoded.size());
-
- FileOperator::WriteFileStd(obj_path.u8string(), encoded.toStdString());
+ const auto target_obj_path = app_data_objs_path_ + "/" + hash_obj_key;
+ auto encoded_data =
+ QAESEncryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO)
+ .encode(value.toJson(), hash_key_);
+ GF_CORE_LOG_TRACE("saving data object {} to disk {} , size: {} bytes",
+ hash_obj_key, target_obj_path, encoded_data.size());
+
+ // recreate if not exists
+ if (!QDir(app_data_objs_path_).exists()) {
+ QDir(app_data_objs_path_).mkpath(".");
+ }
- return _key.empty() ? _hash_obj_key : std::string();
+ if (!WriteFile(target_obj_path, encoded_data)) {
+ GF_CORE_LOG_ERROR("failed to write data object to disk: {}", key);
+ }
+ return key.isEmpty() ? hash_obj_key : QString();
}
-std::optional<nlohmann::json> GpgFrontend::DataObjectOperator::GetDataObject(
- const std::string& _key) {
+auto DataObjectOperator::GetDataObject(const QString& key)
+ -> std::optional<QJsonDocument> {
try {
- SPDLOG_DEBUG("get data object {}", _key);
- auto _hash_obj_key =
- QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key),
- QCryptographicHash::Sha256)
- .toHex()
- .toStdString();
-
- const auto obj_path = app_data_objs_path_ / _hash_obj_key;
-
- if (!std::filesystem::exists(obj_path)) {
- SPDLOG_ERROR("data object not found :{}", _key);
+ GF_CORE_LOG_TRACE("try to get data object from disk, key: {}", key);
+ auto hash_obj_key = QCryptographicHash::hash(hash_key_ + key.toUtf8(),
+ QCryptographicHash::Sha256)
+ .toHex();
+
+ const auto obj_path = app_data_objs_path_ + "/" + hash_obj_key;
+ if (!QFileInfo(obj_path).exists()) {
+ GF_CORE_LOG_WARN("data object not found from disk, key: {}", key);
return {};
}
- std::string buffer;
- if (!FileOperator::ReadFileStd(obj_path.u8string(), buffer)) {
- SPDLOG_ERROR("failed to read data object: {}", _key);
+ QByteArray encoded_data;
+ if (!ReadFile(obj_path, encoded_data)) {
+ GF_CORE_LOG_ERROR("failed to read data object from disk, key: {}", key);
return {};
}
- SPDLOG_DEBUG("data object found {}", _key);
-
- auto encoded = QByteArray::fromStdString(buffer);
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);
- SPDLOG_DEBUG("decrypting data object {} , hash key size: {}",
- encoded.size(), hash_key_.size());
-
- auto decoded =
- encryption.removePadding(encryption.decode(encoded, hash_key_));
-
- SPDLOG_DEBUG("data object decoded: {}", _key);
-
- return nlohmann::json::parse(decoded.toStdString());
+ auto decoded_data =
+ encryption.removePadding(encryption.decode(encoded_data, hash_key_));
+ GF_CORE_LOG_TRACE("data object has been decoded, key: {}, data: {}", key,
+ decoded_data);
+ return QJsonDocument::fromJson(decoded_data);
} catch (...) {
- SPDLOG_ERROR("failed to get data object: {}", _key);
+ GF_CORE_LOG_ERROR("failed to get data object, caught exception: {}", key);
return {};
}
}
-std::optional<nlohmann::json>
-GpgFrontend::DataObjectOperator::GetDataObjectByRef(const std::string& _ref) {
+auto DataObjectOperator::GetDataObjectByRef(const QString& _ref)
+ -> std::optional<QJsonDocument> {
if (_ref.size() != 64) return {};
try {
- const auto& _hash_obj_key = _ref;
- const auto obj_path = app_data_objs_path_ / _hash_obj_key;
+ const auto& hash_obj_key = _ref;
+ const auto obj_path = app_data_objs_path_ + "/" + hash_obj_key;
- if (!std::filesystem::exists(obj_path)) return {};
+ if (!QFileInfo(obj_path).exists()) return {};
- std::string buffer;
- if (!FileOperator::ReadFileStd(obj_path.u8string(), buffer)) return {};
- auto encoded = QByteArray::fromStdString(buffer);
+ QByteArray encoded_data;
+ if (!ReadFile(obj_path, encoded_data)) return {};
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);
- auto decoded =
- encryption.removePadding(encryption.decode(encoded, hash_key_));
+ auto decoded_data =
+ encryption.removePadding(encryption.decode(encoded_data, hash_key_));
- return nlohmann::json::parse(decoded.toStdString());
+ return QJsonDocument::fromJson(decoded_data);
} catch (...) {
return {};
}
}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/DataObjectOperator.h b/src/core/function/DataObjectOperator.h
index ae5dc62c..fedbd905 100644
--- a/src/core/function/DataObjectOperator.h
+++ b/src/core/function/DataObjectOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,18 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_DATAOBJECTOPERATOR_H
-#define GPGFRONTEND_DATAOBJECTOPERATOR_H
+#pragma once
+
+#include <optional>
-#include "core/GpgFunctionObject.h"
#include "core/function/GlobalSettingStation.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
@@ -45,11 +46,11 @@ class GPGFRONTEND_CORE_EXPORT DataObjectOperator
explicit DataObjectOperator(
int channel = SingletonFunctionObject::GetDefaultChannel());
- std::string SaveDataObj(const std::string &_key, const nlohmann::json &value);
+ auto SaveDataObj(const QString &_key, const QJsonDocument &value) -> QString;
- std::optional<nlohmann::json> GetDataObject(const std::string &_key);
+ auto GetDataObject(const QString &_key) -> std::optional<QJsonDocument>;
- std::optional<nlohmann::json> GetDataObjectByRef(const std::string &_ref);
+ auto GetDataObjectByRef(const QString &_ref) -> std::optional<QJsonDocument>;
private:
/**
@@ -60,21 +61,16 @@ class GPGFRONTEND_CORE_EXPORT DataObjectOperator
GlobalSettingStation &global_setting_station_ =
GlobalSettingStation::GetInstance(); ///< GlobalSettingStation
- std::filesystem::path app_secure_path_ =
- global_setting_station_.GetAppConfigPath() /
- "secure"; ///< Where sensitive information is stored
- std::filesystem::path app_secure_key_path_ =
- app_secure_path_ / "app.key"; ///< Where the key of data object is stored
- std::filesystem::path app_data_objs_path_ =
- global_setting_station_.GetAppDataPath() / "data_objs"; ///< Where data
- ///< object is
- ///< stored
+ QString app_secure_path_ =
+ global_setting_station_.GetAppDataPath() +
+ "/secure"; ///< Where sensitive information is stored
+ QString app_secure_key_path_ =
+ app_secure_path_ +
+ "/app.key"; ///< Where the key of data object is stored
+ QString app_data_objs_path_ =
+ global_setting_station_.GetAppDataPath() + "/data_objs";
- std::random_device rd_; ///< Random device
- std::mt19937 mt_ = std::mt19937(rd_()); ///< Mersenne twister
- QByteArray hash_key_; ///< Hash key
+ QByteArray hash_key_; ///< Hash key
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_DATAOBJECTOPERATOR_H
diff --git a/src/core/function/FileOperator.cpp b/src/core/function/FileOperator.cpp
deleted file mode 100644
index 41552246..00000000
--- a/src/core/function/FileOperator.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * 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 "FileOperator.h"
-
-bool GpgFrontend::FileOperator::ReadFile(const QString& file_name,
- QByteArray& data) {
- QFile file(file_name);
- if (!file.open(QIODevice::ReadOnly)) {
- SPDLOG_ERROR("failed to open file: {}", file_name.toStdString());
- return false;
- }
- data = file.readAll();
- file.close();
- return true;
-}
-
-bool GpgFrontend::FileOperator::WriteFile(const QString& file_name,
- const QByteArray& data) {
- QFile file(file_name);
- if (!file.open(QIODevice::WriteOnly)) {
- SPDLOG_ERROR("failed to open file: {}", file_name.toStdString());
- return false;
- }
- file.write(data);
- file.close();
- return true;
-}
-
-bool GpgFrontend::FileOperator::ReadFileStd(
- const std::filesystem::path& file_name, std::string& data) {
- QByteArray byte_data;
-#ifdef WINDOWS
- bool res = ReadFile(QString::fromStdU16String(file_name.u16string()).toUtf8(),
- byte_data);
-#else
- bool res = ReadFile(QString::fromStdString(file_name.u8string()).toUtf8(),
- byte_data);
-#endif
- data = byte_data.toStdString();
- return res;
-}
-
-bool GpgFrontend::FileOperator::WriteFileStd(
- const std::filesystem::path& file_name, const std::string& data) {
- return WriteFile(QString::fromStdString(file_name.u8string()).toUtf8(),
- QByteArray::fromStdString(data));
-}
-
-std::string GpgFrontend::FileOperator::CalculateHash(
- const std::filesystem::path& file_path) {
- // Returns empty QByteArray() on failure.
- QFileInfo info(QString::fromStdString(file_path.string()));
- std::stringstream ss;
-
- if (info.isFile() && info.isReadable()) {
- ss << "[#] " << _("File Hash Information") << std::endl;
- ss << " " << _("filename") << _(": ")
- << file_path.filename().u8string().c_str() << std::endl;
-
- QFile f(info.filePath());
- if (f.open(QFile::ReadOnly)) {
- // read all data
- auto buffer = f.readAll();
- ss << " " << _("file size(bytes)") << _(": ") << buffer.size()
- << std::endl;
-
- // md5
- auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5);
- hash_md5.addData(buffer);
- auto md5 = hash_md5.result().toHex().toStdString();
- SPDLOG_DEBUG("md5 {}", md5);
- ss << " "
- << "md5" << _(": ") << md5 << std::endl;
-
- // sha1
- auto hash_sha1 = QCryptographicHash(QCryptographicHash::Sha1);
- hash_sha1.addData(buffer);
- auto sha1 = hash_sha1.result().toHex().toStdString();
- SPDLOG_DEBUG("sha1 {}", sha1);
- ss << " "
- << "sha1" << _(": ") << sha1 << std::endl;
-
- // sha1
- auto hash_sha256 = QCryptographicHash(QCryptographicHash::Sha256);
- hash_sha256.addData(buffer);
- auto sha256 = hash_sha256.result().toHex().toStdString();
- SPDLOG_DEBUG("sha256 {}", sha256);
- ss << " "
- << "sha256" << _(": ") << sha256 << std::endl;
-
- ss << std::endl;
- }
- } else {
- ss << "[#] " << _("Error in Calculating File Hash ") << std::endl;
- }
-
- return ss.str();
-}
diff --git a/src/core/function/FileOperator.h b/src/core/function/FileOperator.h
deleted file mode 100644
index a727b1de..00000000
--- a/src/core/function/FileOperator.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * 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
- *
- */
-
-#ifndef GPGFRONTEND_FILEOPERATOR_H
-#define GPGFRONTEND_FILEOPERATOR_H
-
-#include "core/GpgFrontendCore.h"
-
-namespace GpgFrontend {
-
-/**
- * @brief provides file operations
- *
- */
-class GPGFRONTEND_CORE_EXPORT FileOperator {
- public:
- /**
- * @brief read file content using std struct
- *
- *
- * @param file_name file name
- * @param data data read from file
- * @return
- */
- static bool ReadFileStd(const std::filesystem::path &file_name,
- std::string &data);
-
- /**
- * @brief write file content using std struct
- *
- * @param file_name file name
- * @param data data to write to file
- * @return
- */
- static bool WriteFileStd(const std::filesystem::path &file_name,
- const std::string &data);
-
- /**
- * @brief read file content
- *
- * @param file_name file name
- * @param data data read from file
- * @return true if success
- * @return false if failed
- */
- static bool ReadFile(const QString &file_name, QByteArray &data);
-
- /**
- * @brief write file content
- *
- * @param file_name file name
- * @param data data to write to file
- * @return true if success
- * @return false if failed
- */
- static bool WriteFile(const QString &file_name, const QByteArray &data);
-
- /**
- * calculate the hash of a file
- * @param file_path
- * @return
- */
- static std::string CalculateHash(const std::filesystem::path &file_path);
-};
-} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_FILEOPERATOR_H
diff --git a/src/core/function/GlobalSettingStation.cpp b/src/core/function/GlobalSettingStation.cpp
index 6b743268..6969c15a 100644
--- a/src/core/function/GlobalSettingStation.cpp
+++ b/src/core/function/GlobalSettingStation.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,136 +28,148 @@
#include "GlobalSettingStation.h"
-#include "core/function/FileOperator.h"
+#include "core/module/ModuleManager.h"
+#include "core/utils/FilesystemUtils.h"
-void GpgFrontend::GlobalSettingStation::SyncSettings() noexcept {
- using namespace libconfig;
- try {
- ui_cfg_.writeFile(ui_config_path_.u8string().c_str());
- SPDLOG_DEBUG("updated ui configuration successfully written to {}",
- ui_config_path_.u8string());
+namespace GpgFrontend {
- } catch (const FileIOException &fioex) {
- SPDLOG_ERROR("i/o error while writing ui configuration file: {}",
- ui_config_path_.u8string());
- }
-}
+class GlobalSettingStation::Impl {
+ public:
+ /**
+ * @brief Construct a new Global Setting Station object
+ *
+ */
+ explicit Impl() noexcept {
+ GF_CORE_LOG_INFO("app path: {}", GetAppDir());
+ GF_CORE_LOG_INFO("app working path: {}", working_path_);
-GpgFrontend::GlobalSettingStation::GlobalSettingStation(int channel) noexcept
- : SingletonFunctionObject<GlobalSettingStation>(channel) {
- using namespace std::filesystem;
- using namespace libconfig;
-
- SPDLOG_INFO("app path: {}", app_path_.u8string());
- SPDLOG_INFO("app configure path: {}", app_configure_path_.u8string());
- SPDLOG_INFO("app data path: {}", app_data_path_.u8string());
- SPDLOG_INFO("app log path: {}", app_log_path_.u8string());
- SPDLOG_INFO("app locale path: {}", app_locale_path_.u8string());
- SPDLOG_INFO("app conf path: {}", ui_config_path_.u8string());
-
- SPDLOG_INFO("app log files total size: {}", GetLogFilesSize());
- SPDLOG_INFO("app data objects files total size: {}",
- GetDataObjectsFilesSize());
-
- if (!is_directory(app_configure_path_)) create_directory(app_configure_path_);
- if (!is_directory(app_data_path_)) create_directory(app_data_path_);
- if (!is_directory(app_log_path_)) create_directory(app_log_path_);
- if (!is_directory(ui_config_dir_path_)) create_directory(ui_config_dir_path_);
-
- if (!exists(ui_config_path_)) {
- try {
- this->ui_cfg_.writeFile(ui_config_path_.u8string().c_str());
- SPDLOG_DEBUG("user interface configuration successfully written to {}",
- ui_config_path_.u8string());
-
- } catch (const FileIOException &fioex) {
- SPDLOG_DEBUG(
- "i/o error while writing UserInterface configuration file {}",
- ui_config_path_.u8string());
- }
- } else {
- try {
- this->ui_cfg_.readFile(ui_config_path_.u8string().c_str());
- SPDLOG_DEBUG("user interface configuration successfully read from {}",
- ui_config_path_.u8string());
- } catch (const FileIOException &fioex) {
- SPDLOG_ERROR("i/o error while reading UserInterface configure file");
- } catch (const ParseException &pex) {
- SPDLOG_ERROR("parse error at {} : {} - {}", pex.getFile(), pex.getLine(),
- pex.getError());
+ auto portable_file_path = working_path_ + "/PORTABLE.txt";
+ if (QFileInfo(portable_file_path).exists()) {
+ GF_CORE_LOG_INFO(
+ "dectected portable mode, reconfiguring config and data path...");
+ Module::UpsertRTValue("core", "env.state.portable", 1);
+
+ app_data_path_ = working_path_;
+ app_log_path_ = app_data_path_ + "/logs";
+ app_data_objs_path_ = app_data_path_ + "/data_objs";
+
+ portable_mode_ = true;
}
+
+ GF_CORE_LOG_INFO("app data path: {}", app_data_path_);
+ GF_CORE_LOG_INFO("app log path: {}", app_log_path_);
+
+ GF_CORE_LOG_DEBUG("app log files total size: {}", GetLogFilesSize());
+ GF_CORE_LOG_DEBUG("app data objects files total size: {}",
+ GetDataObjectsFilesSize());
+
+ if (!QDir(app_data_path_).exists()) QDir(app_data_path_).mkpath(".");
+ if (!QDir(app_log_path_).exists()) QDir(app_log_path_).mkpath(".");
}
-}
-libconfig::Setting &
-GpgFrontend::GlobalSettingStation::GetUISettings() noexcept {
- return ui_cfg_.getRoot();
-}
+ [[nodiscard]] auto GetSettings() -> QSettings {
+ if (!portable_mode_) return QSettings();
+ return {app_portable_config_path_, QSettings::IniFormat};
+ }
-void GpgFrontend::GlobalSettingStation::init_app_secure_key() {}
+ [[nodiscard]] auto GetLogFilesSize() const -> QString {
+ return GetHumanFriendlyFileSize(GetFileSizeByPath(app_log_path_, "*.log"));
+ }
-int64_t GpgFrontend::GlobalSettingStation::get_files_size_at_path(
- std::filesystem::path path, std::string filename_pattern) const {
- auto dir = QDir(QString::fromStdString(path.u8string()));
- QFileInfoList fileList = dir.entryInfoList(
- QStringList() << QString::fromStdString(filename_pattern), QDir::Files);
- qint64 totalSize = 0;
+ [[nodiscard]] auto GetDataObjectsFilesSize() const -> QString {
+ return GetHumanFriendlyFileSize(
+ GetFileSizeByPath(app_data_objs_path_, "*"));
+ }
- for (const QFileInfo &fileInfo : fileList) {
- totalSize += fileInfo.size();
+ void ClearAllLogFiles() const {
+ DeleteAllFilesByPattern(app_log_path_, "*.log");
+ }
+
+ void ClearAllDataObjects() const {
+ DeleteAllFilesByPattern(app_data_objs_path_, "*");
+ }
+
+ /**
+ * @brief Get the App Dir object
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetAppDir() const -> QString {
+ return QCoreApplication::applicationDirPath();
}
- return totalSize;
-}
-std::string GpgFrontend::GlobalSettingStation::get_human_readable_size(
- int64_t size) const {
- double num = size;
- QStringList list;
- list << "KB"
- << "MB"
- << "GB"
- << "TB";
-
- QStringListIterator i(list);
- QString unit("bytes");
-
- while (num >= 1024.0 && i.hasNext()) {
- unit = i.next();
- num /= 1024.0;
+ /**
+ * @brief Get the App Data Path object
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetAppDataPath() const -> QString {
+ return app_data_path_;
}
- return (QString().setNum(num, 'f', 2) + " " + unit).toStdString();
+
+ /**
+ * @brief Get the Log Dir object
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetLogDir() const -> QString { return app_log_path_; }
+
+ private:
+ QString working_path_ = QDir::currentPath();
+
+ QString app_data_path_ = QString{QStandardPaths::writableLocation(
+ QStandardPaths::AppLocalDataLocation)}; ///< Program Data Location
+
+ QString app_log_path_ = app_data_path_ + "/logs"; ///< Program Data Location
+
+ QString app_data_objs_path_ =
+ app_data_path_ + "/data_objs"; ///< Object storage path
+
+ bool portable_mode_ = false; ///<
+ QString app_portable_config_path_ =
+ working_path_ + "/config.ini"; ///< take effect only in portable mode
+
+ /**
+ * @brief
+ *
+ */
+ void init_app_secure_key() {}
+};
+
+GlobalSettingStation::GlobalSettingStation(int channel) noexcept
+ : SingletonFunctionObject<GlobalSettingStation>(channel),
+ p_(SecureCreateUniqueObject<Impl>()) {}
+
+GlobalSettingStation::~GlobalSettingStation() noexcept = default;
+
+auto GlobalSettingStation::GetSettings() const -> QSettings {
+ return p_->GetSettings();
}
-std::string GpgFrontend::GlobalSettingStation::GetLogFilesSize() const {
- return get_human_readable_size(
- get_files_size_at_path(app_log_path_, "*.log"));
+auto GlobalSettingStation::GetAppDir() const -> QString {
+ return p_->GetAppDir();
}
-std::string GpgFrontend::GlobalSettingStation::GetDataObjectsFilesSize() const {
- return get_human_readable_size(
- get_files_size_at_path(app_data_objs_path_, "*"));
+auto GlobalSettingStation::GetAppDataPath() const -> QString {
+ return p_->GetAppDataPath();
}
-void GpgFrontend::GlobalSettingStation::ClearAllLogFiles() const {
- delete_all_files(app_log_path_, "*.log");
+[[nodiscard]] auto GlobalSettingStation::GetLogDir() const -> QString {
+ return p_->GetLogDir();
}
-void GpgFrontend::GlobalSettingStation::ClearAllDataObjects() const {
- delete_all_files(app_data_objs_path_, "*");
+auto GlobalSettingStation::GetLogFilesSize() const -> QString {
+ return p_->GetLogFilesSize();
}
-void GpgFrontend::GlobalSettingStation::delete_all_files(
- std::filesystem::path path, std::string filename_pattern) const {
- auto dir = QDir(QString::fromStdString(path.u8string()));
+auto GlobalSettingStation::GetDataObjectsFilesSize() const -> QString {
+ return p_->GetDataObjectsFilesSize();
+}
- // 使用name filters来只选取以.log结尾的文件
- QStringList logFiles = dir.entryList(
- QStringList() << QString::fromStdString(filename_pattern), QDir::Files);
+void GlobalSettingStation::ClearAllLogFiles() const { p_->ClearAllLogFiles(); }
- // 遍历并删除所有符合条件的文件
- for (const auto &file : logFiles) {
- QFile::remove(dir.absoluteFilePath(file));
- }
+void GlobalSettingStation::ClearAllDataObjects() const {
+ p_->ClearAllDataObjects();
}
-GpgFrontend::GlobalSettingStation::~GlobalSettingStation() noexcept = default;
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/GlobalSettingStation.h b/src/core/function/GlobalSettingStation.h
index 80780f4b..85ac57b4 100644
--- a/src/core/function/GlobalSettingStation.h
+++ b/src/core/function/GlobalSettingStation.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,26 +20,24 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GLOBALSETTINGSTATION_H
-#define GPGFRONTEND_GLOBALSETTINGSTATION_H
+#pragma once
-#include <filesystem>
-
-#include "GpgFrontendBuildInstallInfo.h"
-#include "core/GpgFrontendCore.h"
-#include "core/GpgFunctionObject.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
/**
- * @brief
+ * @class GlobalSettingStation
+ * @brief Singleton class for managing global settings in the application.
*
+ * This class handles reading and writing of global settings, as well as
+ * managing application directories and resource paths.
*/
class GPGFRONTEND_CORE_EXPORT GlobalSettingStation
: public SingletonFunctionObject<GlobalSettingStation> {
@@ -58,179 +56,60 @@ class GPGFRONTEND_CORE_EXPORT GlobalSettingStation
~GlobalSettingStation() noexcept override;
/**
- * @brief
- *
- * @return libconfig::Setting&
- */
- libconfig::Setting &GetUISettings() noexcept;
-
- /**
- * @brief
+ * @brief Get the Settings object
*
- * @return libconfig::Setting&
+ * @return QSettings
*/
- template <typename T>
- T LookupSettings(std::string path, T default_value) noexcept {
- T value = default_value;
- try {
- value = static_cast<T>(GetUISettings().lookup(path));
- } catch (...) {
- SPDLOG_WARN("setting not found: {}", path);
- }
- return value;
- }
+ [[nodiscard]] auto GetSettings() const -> QSettings;
/**
* @brief Get the App Dir object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetAppDir() const { return app_path_; }
-
- [[nodiscard]] std::filesystem::path GetAppDataPath() const {
- return app_data_path_;
- }
+ [[nodiscard]] auto GetAppDir() const -> QString;
/**
- * @brief Get the Log Dir object
- *
- * @return std::filesystem::path
+ * @brief Gets the application data directory.
+ * @return Path to the application data directory.
*/
- [[nodiscard]] std::filesystem::path GetLogDir() const {
- return app_log_path_;
- }
+ [[nodiscard]] auto GetAppDataPath() const -> QString;
/**
- * @brief Get the Standalone Database Dir object
- *
- * @return std::filesystem::path
- */
- [[nodiscard]] std::filesystem::path GetStandaloneDatabaseDir() const {
- auto db_path = app_configure_path_ / "db";
- if (!std::filesystem::exists(db_path)) {
- std::filesystem::create_directory(db_path);
- }
- return db_path;
- }
-
- [[nodiscard]] std::filesystem::path GetAppConfigPath() const {
- return app_configure_path_;
- }
-
- /**
- * @brief Get the Standalone Gpg Bin Dir object
+ * @brief Get the Log Dir object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetStandaloneGpgBinDir() const {
- return app_resource_path_ / "gpg1.4" / "gpg";
- }
+ [[nodiscard]] auto GetLogDir() const -> QString;
/**
- * @brief Get the Locale Dir object
+ * @brief Get the Log Files Size object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetLocaleDir() const {
- return app_locale_path_;
- }
+ [[nodiscard]] auto GetLogFilesSize() const -> QString;
/**
- * @brief Get the Resource Dir object
+ * @brief Get the Data Objects Files Size object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetResourceDir() const {
- return app_resource_path_;
- }
+ [[nodiscard]] auto GetDataObjectsFilesSize() const -> QString;
/**
- * @brief Get the Certs Dir object
+ * @brief clear all log files
*
- * @return std::filesystem::path
*/
- [[nodiscard]] std::filesystem::path GetCertsDir() const {
- return app_resource_path_ / "certs";
- }
-
- [[nodiscard]] std::string GetLogFilesSize() const;
-
- [[nodiscard]] std::string GetDataObjectsFilesSize() const;
-
void ClearAllLogFiles() const;
- void ClearAllDataObjects() const;
-
/**
- * @brief sync the settings to the file
+ * @brief clear all data objects
*
*/
- void SyncSettings() noexcept;
+ void ClearAllDataObjects() const;
private:
- std::filesystem::path app_path_ = QCoreApplication::applicationDirPath()
- .toStdString(); ///< Program Location
- std::filesystem::path app_data_path_ =
- QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
- .toStdString(); ///< Program Data Location
- std::filesystem::path app_log_path_ =
- app_data_path_ / "logs"; ///< Program Data Location
- std::filesystem::path app_data_objs_path_ =
- app_data_path_ / "data_objs"; ///< Object storage path
-
-#ifdef LINUX_INSTALL_BUILD
- std::filesystem::path app_resource_path_ =
- std::filesystem::path(APP_LOCALSTATE_PATH) /
- "gpgfrontend"; ///< Program Data Location
-#else
- std::filesystem::path app_resource_path_ =
- RESOURCE_DIR_BOOST_PATH(app_path_); ///< Program Data Location
-#endif
-
-#ifdef LINUX_INSTALL_BUILD
- std::filesystem::path app_locale_path_ =
- std::string(APP_LOCALE_PATH); ///< Program Data Location
-#else
- std::filesystem::path app_locale_path_ =
- app_resource_path_ / "locales"; ///< Program Data Location
-#endif
-
- std::filesystem::path app_configure_path_ =
- QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)
- .toStdString(); ///< Program Configure Location
- std::filesystem::path ui_config_dir_path_ =
- app_configure_path_ / "conf"; ///< Configure File Directory Location
- std::filesystem::path ui_config_path_ =
- ui_config_dir_path_ / "main.cfg"; ///< Main Configure File Location
-
- libconfig::Config ui_cfg_; ///< UI Configure File
-
- /**
- * @brief
- *
- */
- void init_app_secure_key();
-
- /**
- * @brief
- *
- */
- int64_t get_files_size_at_path(std::filesystem::path path,
- std::string filename_pattern) const;
-
- /**
- * @brief
- *
- */
- std::string get_human_readable_size(int64_t size) const;
-
- /**
- * @brief
- *
- */
- void delete_all_files(std::filesystem::path path,
- std::string filename_pattern) const;
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GLOBALSETTINGSTATION_H
diff --git a/src/core/function/KeyPackageOperator.cpp b/src/core/function/KeyPackageOperator.cpp
index 5c917ab8..d185b0ef 100644
--- a/src/core/function/KeyPackageOperator.cpp
+++ b/src/core/function/KeyPackageOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,92 +28,124 @@
#include "KeyPackageOperator.h"
-#include "FileOperator.h"
-#include "function/PassphraseGenerator.h"
-#include "function/gpg/GpgKeyGetter.h"
-#include "function/gpg/GpgKeyImportExporter.h"
-#include "qt-aes/qaesencryption.h"
+#include <qt-aes/qaesencryption.h>
+
+#include "core/function/KeyPackageOperator.h"
+#include "core/function/PassphraseGenerator.h"
+#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/model/GpgImportInformation.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/IOUtils.h"
namespace GpgFrontend {
-bool KeyPackageOperator::GeneratePassphrase(
- const std::filesystem::path& phrase_path, std::string& phrase) {
+auto KeyPackageOperator::GeneratePassphrase(const QString& phrase_path,
+ QString& phrase) -> bool {
phrase = PassphraseGenerator::GetInstance().Generate(256);
- SPDLOG_DEBUG("generated passphrase: {} bytes", phrase.size());
- return FileOperator::WriteFileStd(phrase_path, phrase);
+ GF_CORE_LOG_DEBUG("generated passphrase: {} bytes", phrase.size());
+ return WriteFile(phrase_path, phrase.toUtf8());
}
-bool KeyPackageOperator::GenerateKeyPackage(
- const std::filesystem::path& key_package_path,
- const std::string& key_package_name, KeyIdArgsListPtr& key_ids,
- std::string& phrase, bool secret) {
- SPDLOG_DEBUG("generating key package: {}", key_package_name);
-
- ByteArrayPtr key_export_data = nullptr;
- if (!GpgKeyImportExporter::GetInstance().ExportAllKeys(
- key_ids, key_export_data, secret)) {
- SPDLOG_ERROR("failed to export keys");
- return false;
- }
-
- auto key = QByteArray::fromStdString(phrase);
- auto data = QString::fromStdString(*key_export_data).toLocal8Bit().toBase64();
-
- auto hash_key = QCryptographicHash::hash(key, QCryptographicHash::Sha256);
- QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
- QAESEncryption::Padding::ISO);
- auto encoded = encryption.encode(data, hash_key);
-
- SPDLOG_DEBUG("writing key package: {}", key_package_name);
- return FileOperator::WriteFileStd(key_package_path, encoded.toStdString());
+void KeyPackageOperator::GenerateKeyPackage(const QString& key_package_path,
+ const QString& key_package_name,
+ const KeyArgsList& keys,
+ QString& phrase, bool secret,
+ const OperationCallback& cb) {
+ GF_CORE_LOG_DEBUG("generating key package: {}", key_package_name);
+
+ GpgKeyImportExporter::GetInstance().ExportAllKeys(
+ keys, secret, true, [=](GpgError err, const DataObjectPtr& data_obj) {
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ GF_LOG_ERROR("export keys error, reason: {}",
+ DescribeGpgErrCode(err).second);
+ cb(-1, data_obj);
+ return;
+ }
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GFBuffer>()) {
+ cb(-1, data_obj);
+ return;
+ }
+
+ auto gf_buffer = ExtractParams<GFBuffer>(data_obj, 0);
+
+ auto data = gf_buffer.ConvertToQByteArray().toBase64();
+ auto hash_key = QCryptographicHash::hash(phrase.toUtf8(),
+ QCryptographicHash::Sha256);
+ QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO);
+ auto encoded_data = encryption.encode(data, hash_key);
+ GF_CORE_LOG_DEBUG("writing key package, name: {}", key_package_name);
+
+ cb(WriteFile(key_package_path, encoded_data) ? 0 : -1,
+ TransferParams());
+ return;
+ });
}
-bool KeyPackageOperator::ImportKeyPackage(
- const std::filesystem::path& key_package_path,
- const std::filesystem::path& phrase_path,
- GpgFrontend::GpgImportInformation& import_info) {
- SPDLOG_DEBUG("importing key package: {]", key_package_path.u8string());
-
- std::string encrypted_data;
- FileOperator::ReadFileStd(key_package_path, encrypted_data);
-
- if (encrypted_data.empty()) {
- SPDLOG_ERROR("failed to read key package: {}", key_package_path.u8string());
- return false;
- };
-
- std::string passphrase;
- FileOperator::ReadFileStd(phrase_path, passphrase);
- SPDLOG_DEBUG("passphrase: {} bytes", passphrase.size());
- if (passphrase.size() != 256) {
- SPDLOG_ERROR("failed to read passphrase: {}", phrase_path.u8string());
- return false;
- }
-
- auto hash_key = QCryptographicHash::hash(
- QByteArray::fromStdString(passphrase), QCryptographicHash::Sha256);
- auto encoded = QByteArray::fromStdString(encrypted_data);
-
- QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
- QAESEncryption::Padding::ISO);
-
- auto decoded = encryption.removePadding(encryption.decode(encoded, hash_key));
- auto key_data = QByteArray::fromBase64(decoded);
-
- SPDLOG_DEBUG("key data size: {}", key_data.size());
- if (!key_data.startsWith(GpgConstants::PGP_PUBLIC_KEY_BEGIN) &&
- !key_data.startsWith(GpgConstants::PGP_PRIVATE_KEY_BEGIN)) {
- return false;
- }
-
- auto key_data_ptr = std::make_unique<ByteArray>(key_data.toStdString());
- import_info =
- GpgKeyImportExporter::GetInstance().ImportKey(std::move(key_data_ptr));
- return true;
+void KeyPackageOperator::ImportKeyPackage(const QString& key_package_path,
+ const QString& phrase_path,
+ const OperationCallback& cb) {
+ RunOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GFError {
+ GF_CORE_LOG_DEBUG("importing key package: {}", key_package_path);
+
+ QByteArray encrypted_data;
+ ReadFile(key_package_path, encrypted_data);
+
+ if (encrypted_data.isEmpty()) {
+ GF_CORE_LOG_ERROR("failed to read key package: {}", key_package_path);
+ return -1;
+ };
+
+ QByteArray passphrase;
+ ReadFile(phrase_path, passphrase);
+ if (passphrase.size() != 256) {
+ GF_CORE_LOG_ERROR("passphrase size mismatch: {}", phrase_path);
+ return -1;
+ }
+
+ auto hash_key =
+ QCryptographicHash::hash(passphrase, QCryptographicHash::Sha256);
+ auto encoded = encrypted_data;
+
+ QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO);
+
+ auto decoded =
+ encryption.removePadding(encryption.decode(encoded, hash_key));
+ auto key_data = QByteArray::fromBase64(decoded);
+ if (!key_data.startsWith(PGP_PUBLIC_KEY_BEGIN) &&
+ !key_data.startsWith(PGP_PRIVATE_KEY_BEGIN)) {
+ return -1;
+ }
+
+ auto import_info_ptr =
+ GpgKeyImportExporter::GetInstance().ImportKey(GFBuffer(key_data));
+ if (import_info_ptr == nullptr) return GPG_ERR_NO_DATA;
+
+ auto import_info = *import_info_ptr;
+ data_object->Swap({import_info});
+ return 0;
+ },
+ cb, "import_key_package");
}
-std::string KeyPackageOperator::GenerateKeyPackageName() {
+auto KeyPackageOperator::GenerateKeyPackageName() -> QString {
return generate_key_package_name();
}
+/**
+ * @brief generate key package name
+ *
+ * @return QString key package name
+ */
+auto KeyPackageOperator::generate_key_package_name() -> QString {
+ return QString("KeyPackage_%1")
+ .arg(QRandomGenerator::global()->bounded(999, 99999));
+}
+
} // namespace GpgFrontend
diff --git a/src/core/function/KeyPackageOperator.h b/src/core/function/KeyPackageOperator.h
index 00b0dbaa..252c7e00 100644
--- a/src/core/function/KeyPackageOperator.h
+++ b/src/core/function/KeyPackageOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYPACKAGEOPERATOR_H
-#define GPGFRONTEND_KEYPACKAGEOPERATOR_H
+#pragma once
-#include "core/GpgFrontendCore.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/typedef/CoreTypedef.h"
namespace GpgFrontend {
@@ -48,15 +47,15 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator {
* @return true if passphrase was generated and saved
* @return false if passphrase was not generated and saved
*/
- static bool GeneratePassphrase(const std::filesystem::path &phrase_path,
- std::string &phrase);
+ static auto GeneratePassphrase(const QString &phrase_path, QString &phrase)
+ -> bool;
/**
* @brief generate the name of the key package
*
- * @return std::string name of the key package
+ * @return QString name of the key package
*/
- static std::string GenerateKeyPackageName();
+ static auto GenerateKeyPackageName() -> QString;
/**
* @brief generate key package
@@ -69,10 +68,10 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator {
* @return true if key package was generated
* @return false if key package was not generated
*/
- static bool GenerateKeyPackage(const std::filesystem::path &key_package_path,
- const std::string &key_package_name,
- KeyIdArgsListPtr &key_ids, std::string &phrase,
- bool secret);
+ static void GenerateKeyPackage(const QString &key_package_path,
+ const QString &key_package_name,
+ const KeyArgsList &keys, QString &phrase,
+ bool secret, const OperationCallback &cb);
/**
* @brief import key package
@@ -83,25 +82,16 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator {
* @return true if key package was imported
* @return false if key package was not imported
*/
- static bool ImportKeyPackage(const std::filesystem::path &key_package_path,
- const std::filesystem::path &phrase_path,
- GpgFrontend::GpgImportInformation &import_info);
+ static void ImportKeyPackage(const QString &key_package_path,
+ const QString &phrase_path,
+ const OperationCallback &cb);
private:
/**
* @brief generate key package name
*
- * @return std::string key package name
+ * @return QString key package name
*/
- static std::string generate_key_package_name() {
- std::random_device rd_; ///< Random device
- auto mt_ = std::mt19937(rd_()); ///< Mersenne twister
-
- std::uniform_int_distribution<int> dist(999, 99999);
- auto file_string = boost::format("KeyPackage_%1%") % dist(mt_);
- return file_string.str();
- }
+ static auto generate_key_package_name() -> QString;
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_KEYPACKAGEOPERATOR_H
diff --git a/src/core/function/LoggerManager.cpp b/src/core/function/LoggerManager.cpp
new file mode 100644
index 00000000..c7088128
--- /dev/null
+++ b/src/core/function/LoggerManager.cpp
@@ -0,0 +1,155 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "LoggerManager.h"
+
+#include <spdlog/async.h>
+#include <spdlog/common.h>
+#include <spdlog/sinks/rotating_file_sink.h>
+#include <spdlog/sinks/stdout_color_sinks.h>
+
+#include "core/function/GlobalSettingStation.h"
+
+namespace GpgFrontend {
+
+std::shared_ptr<spdlog::logger> LoggerManager::default_logger = nullptr;
+spdlog::level::level_enum LoggerManager::default_log_level =
+ spdlog::level::debug;
+
+LoggerManager::LoggerManager(int channel)
+ : SingletonFunctionObject<LoggerManager>(channel) {
+ spdlog::init_thread_pool(1024, 2);
+ spdlog::flush_every(std::chrono::seconds(5));
+}
+
+LoggerManager::~LoggerManager() {
+#ifdef WINDOWS
+ // Under VisualStudio, this must be called before main finishes to workaround
+ // a known VS issue
+ spdlog::drop_all();
+ spdlog::shutdown();
+#endif
+
+ if (default_logger) default_logger = nullptr;
+}
+
+auto LoggerManager::GetLogger(const QString& id)
+ -> std::shared_ptr<spdlog::logger> {
+ auto m_it = logger_map_.find(id);
+ if (m_it == logger_map_.end()) return GetDefaultLogger();
+ return m_it->second;
+}
+
+auto LoggerManager::RegisterAsyncLogger(const QString& id,
+ spdlog::level::level_enum level)
+ -> std::shared_ptr<spdlog::logger> {
+ // get the log directory
+ auto log_file_path =
+ GlobalSettingStation::GetInstance().GetLogDir() + "/" + id + ".log";
+
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::stderr_color_sink_mt>());
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::rotating_file_sink_mt>(
+ log_file_path.toUtf8().constData(), 1048576 * 32, 8));
+
+ // logger
+ auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::async_logger>(
+ id.toStdString(), begin(sinks), end(sinks), spdlog::thread_pool());
+ logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+ // set the level of logger
+ logger->set_level(level);
+
+ // flush policy
+#ifdef DEBUG
+ logger->flush_on(spdlog::level::trace);
+#else
+ logger->flush_on(spdlog::level::err);
+#endif
+
+ logger_map_[id] = logger;
+ return logger;
+}
+
+auto LoggerManager::RegisterSyncLogger(const QString& id,
+ spdlog::level::level_enum level)
+ -> std::shared_ptr<spdlog::logger> {
+ // get the log directory
+ auto log_file_path =
+ GlobalSettingStation::GetInstance().GetLogDir() + "/" + id + ".log";
+
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::stderr_color_sink_mt>());
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::rotating_file_sink_mt>(
+ log_file_path.toUtf8().constData(), 1048576 * 32, 8));
+
+ // logger
+ auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::logger>(
+ id.toStdString(), begin(sinks), end(sinks));
+ logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+ // set the level of logger
+ logger->set_level(level);
+
+ logger_map_[id] = logger;
+ return logger;
+}
+
+auto LoggerManager::GetDefaultLogger() -> std::shared_ptr<spdlog::logger> {
+ if (default_logger == nullptr) {
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::stderr_color_sink_mt>());
+
+ // logger
+ auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::logger>(
+ "default", begin(sinks), end(sinks));
+ logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+ // set the level of logger
+ logger->set_level(default_log_level);
+ spdlog::set_default_logger(logger);
+ default_logger = logger;
+ }
+ return default_logger;
+}
+
+void LoggerManager::SetDefaultLogLevel(spdlog::level::level_enum level) {
+ default_log_level = level;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/LoggerManager.h b/src/core/function/LoggerManager.h
new file mode 100644
index 00000000..78fecc3c
--- /dev/null
+++ b/src/core/function/LoggerManager.h
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/basic/GpgFunctionObject.h"
+
+namespace spdlog {
+class logger;
+}
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT LoggerManager
+ : public SingletonFunctionObject<LoggerManager> {
+ public:
+ explicit LoggerManager(int channel);
+
+ ~LoggerManager() override;
+
+ auto RegisterAsyncLogger(const QString& id, spdlog::level::level_enum)
+ -> std::shared_ptr<spdlog::logger>;
+
+ auto RegisterSyncLogger(const QString& id, spdlog::level::level_enum)
+ -> std::shared_ptr<spdlog::logger>;
+
+ auto GetLogger(const QString& id) -> std::shared_ptr<spdlog::logger>;
+
+ static auto GetDefaultLogger() -> std::shared_ptr<spdlog::logger>;
+
+ static void SetDefaultLogLevel(spdlog::level::level_enum);
+
+ private:
+ static spdlog::level::level_enum default_log_level;
+ static std::shared_ptr<spdlog::logger> default_logger;
+
+ std::map<QString, std::shared_ptr<spdlog::logger>> logger_map_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/PassphraseGenerator.cpp b/src/core/function/PassphraseGenerator.cpp
index de963fa1..b7f1e877 100644
--- a/src/core/function/PassphraseGenerator.cpp
+++ b/src/core/function/PassphraseGenerator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,10 +20,30 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "PassphraseGenerator.h"
+
+namespace GpgFrontend {
+
+auto PassphraseGenerator::Generate(int len) -> QString {
+ auto file_string = QString("KeyPackage_%1")
+ .arg(QRandomGenerator::global()->bounded(999, 99999));
+ static const char kAlphanum[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+ QString tmp_str;
+ tmp_str.reserve(len);
+
+ for (int i = 0; i < len; ++i) {
+ tmp_str += kAlphanum[QRandomGenerator::global()->bounded(
+ static_cast<quint32>(sizeof(kAlphanum)))];
+ }
+ return tmp_str;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/PassphraseGenerator.h b/src/core/function/PassphraseGenerator.h
index a61356fe..2e5925b6 100644
--- a/src/core/function/PassphraseGenerator.h
+++ b/src/core/function/PassphraseGenerator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,15 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_PASSPHRASEGENERATOR_H
-#define GPGFRONTEND_PASSPHRASEGENERATOR_H
+#pragma once
-#include "core/GpgFrontendCore.h"
-#include "core/GpgFunctionObject.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
@@ -55,29 +53,13 @@ class GPGFRONTEND_CORE_EXPORT PassphraseGenerator
* @brief generate passphrase
*
* @param len length of the passphrase
- * @return std::string passphrase
+ * @return QString passphrase
*/
- std::string Generate(int len) {
- std::uniform_int_distribution<int> dist(999, 99999);
-
- auto file_string = boost::format("KeyPackage_%1%") % dist(mt_);
- static const char alphanum[] =
- "0123456789"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz";
- std::string tmp_str;
- tmp_str.reserve(len);
-
- for (int i = 0; i < len; ++i) {
- tmp_str += alphanum[dist(mt_) % (sizeof(alphanum) - 1)];
- }
- return tmp_str;
- }
+ auto Generate(int len) -> QString;
+ private:
std::random_device rd_; ///< Random device
std::mt19937 mt_ = std::mt19937(rd_()); ///< Mersenne twister
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_PASSPHRASEGENERATOR_H
diff --git a/src/core/function/SecureMemoryAllocator.cpp b/src/core/function/SecureMemoryAllocator.cpp
new file mode 100644
index 00000000..692c36c5
--- /dev/null
+++ b/src/core/function/SecureMemoryAllocator.cpp
@@ -0,0 +1,63 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SecureMemoryAllocator.h"
+
+#ifndef MACOS
+#include <mimalloc.h>
+#endif
+
+namespace GpgFrontend {
+
+auto SecureMemoryAllocator::Allocate(std::size_t size) -> void* {
+#ifndef MACOS
+ auto* addr = mi_malloc(size);
+#else
+ auto* addr = malloc(size);
+#endif
+ return addr;
+}
+
+auto SecureMemoryAllocator::Reallocate(void* ptr, std::size_t size) -> void* {
+#ifndef MACOS
+ auto* addr = mi_realloc(ptr, size);
+#else
+ auto* addr = realloc(ptr, size);
+#endif
+ return addr;
+}
+
+void SecureMemoryAllocator::Deallocate(void* p) {
+#ifndef MACOS
+ mi_free(p);
+#else
+ free(p);
+#endif
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/CharsetOperator.h b/src/core/function/SecureMemoryAllocator.h
index 41ce62f4..e9f1c1c3 100644
--- a/src/core/function/CharsetOperator.h
+++ b/src/core/function/SecureMemoryAllocator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,28 +20,41 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_CHARSETDETECTOR_H
-#define GPGFRONTEND_CHARSETDETECTOR_H
+#pragma once
-#include "core/GpgFrontendCore.h"
+#include <cstdint>
+#include <memory>
+
+#include "core/utils/LogUtils.h"
namespace GpgFrontend {
-class GPGFRONTEND_CORE_EXPORT CharsetOperator {
+class GPGFRONTEND_CORE_EXPORT SecureMemoryAllocator {
public:
- using CharsetInfo = std::tuple<std::string, std::string, int>;
+ static auto Allocate(std::size_t) -> void *;
+
+ static auto Reallocate(void *, std::size_t) -> void *;
- static CharsetInfo Detect(const std::string &buffer);
+ static void Deallocate(void *);
+};
- static bool Convert2Utf8(const std::string &buffer, std::string &out_buffer,
- std::string from_charset_name);
+template <typename T>
+struct SecureObjectDeleter {
+ void operator()(T *ptr) {
+ if (ptr) {
+ ptr->~T();
+ SecureMemoryAllocator::Deallocate(ptr);
+ }
+ }
};
-} // namespace GpgFrontend
-#endif // GPGFRONTEND_CHARSETDETECTOR_H
+template <typename T>
+using SecureUniquePtr = std::unique_ptr<T, SecureObjectDeleter<T>>;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/aes/aes_ssl_cbc.cpp b/src/core/function/aes/aes_ssl_cbc.cpp
deleted file mode 100644
index 3aa80ef5..00000000
--- a/src/core/function/aes/aes_ssl_cbc.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * AES encryption/decryption demo program using OpenSSL EVP apis
- * gcc -Wall openssl_aes.c -lcrypto
- * this is public domain code.
- * Saju Pillai ([email protected])
- **/
-
-#include "aes_ssl.h"
-
-namespace GpgFrontend::RawAPI {
-
-/**
- * @brief Create a 256 bit key and IV using the supplied key_data. salt can be
- * added for taste. Fills in the encryption and decryption ctx objects and
- * returns 0 on success
- *
- * @param key_data
- * @param key_data_len
- * @param salt
- * @param e_ctx
- * @param d_ctx
- * @return int
- */
-int aes_256_cbc_init(uint8_t *key_data, int key_data_len, uint8_t *salt,
- EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx) {
- int i, nrounds = 5;
- uint8_t key[32], iv[32];
-
- /*
- * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the
- * supplied key material. nrounds is the number of times the we hash the
- * material. More rounds are more secure but slower.
- */
- i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data,
- key_data_len, nrounds, key, iv);
- if (i != 32) {
- printf("Key size is %d bits - should be 256 bits\n", i);
- return -1;
- }
-
- EVP_CIPHER_CTX_init(e_ctx);
- EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
- EVP_CIPHER_CTX_init(d_ctx);
- EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv);
-
- return 0;
-}
-
-/**
- * @brief Encrypt *len bytes of data All data going in & out is considered
- * binary (uint8_t[])
- *
- * @param e
- * @param plaintext
- * @param len
- * @return uint8_t*
- */
-uint8_t *aes_256_cbc_encrypt(EVP_CIPHER_CTX *e, uint8_t *plaintext, int *len) {
- /* max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1
- * bytes */
- int c_len = *len + AES_BLOCK_SIZE, f_len = 0;
- auto *ciphertext = static_cast<uint8_t *>(malloc(c_len));
-
- /* allows reusing of 'e' for multiple encryption cycles */
- EVP_EncryptInit_ex(e, nullptr, nullptr, nullptr, nullptr);
-
- /* update ciphertext, c_len is filled with the length of ciphertext generated,
- *len is the size of plaintext in bytes */
- EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len);
-
- /* update ciphertext with the final remaining bytes */
- EVP_EncryptFinal_ex(e, ciphertext + c_len, &f_len);
-
- *len = c_len + f_len;
- return ciphertext;
-}
-
-/**
- * @brief Decrypt *len bytes of ciphertext
- *
- * @param e
- * @param ciphertext
- * @param len
- * @return uint8_t*
- */
-uint8_t *aes_256_cbc_decrypt(EVP_CIPHER_CTX *e, uint8_t *ciphertext, int *len) {
- /* plaintext will always be equal to or lesser than length of ciphertext*/
- int p_len = *len, f_len = 0;
- auto *plaintext = static_cast<uint8_t *>(malloc(p_len));
-
- EVP_DecryptInit_ex(e, nullptr, nullptr, nullptr, nullptr);
- EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len);
- EVP_DecryptFinal_ex(e, plaintext + p_len, &f_len);
-
- *len = p_len + f_len;
- return plaintext;
-}
-
-} // namespace GpgFrontend::RawAPI \ No newline at end of file
diff --git a/src/core/function/aes/aes_ssl.h b/src/core/function/basic/ChannelObject.cpp
index e75b68dd..18449ddb 100644
--- a/src/core/function/aes/aes_ssl.h
+++ b/src/core/function/basic/ChannelObject.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,55 +20,40 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_AES_SSL_H
-#define GPGFRONTEND_AES_SSL_H
+#include "ChannelObject.h"
-#include <openssl/aes.h>
-#include <openssl/evp.h>
+#include <iostream>
-#include "GpgFrontend.h"
+namespace GpgFrontend {
-namespace GpgFrontend::RawAPI {
+ChannelObject::ChannelObject() noexcept = default;
-/**
- * @brief
- *
- * @param key_data
- * @param key_data_len
- * @param salt
- * @param e_ctx
- * @param d_ctx
- * @return int
- */
-int aes_256_cbc_init(uint8_t *key_data, int key_data_len, uint8_t *salt,
- EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx);
+ChannelObject::ChannelObject(int channel, QString type)
+ : channel_(channel), type_(std::move(type)) {}
-/**
- * @brief
- *
- * @param e
- * @param plaintext
- * @param len
- * @return uint8_t*
- */
-uint8_t *aes_256_cbc_encrypt(EVP_CIPHER_CTX *e, uint8_t *plaintext, int *len);
+#ifdef DEBUG
+ChannelObject::~ChannelObject() noexcept {
+ // using iostream instead of spdlog bacause at this time spdlog may have
+ // already been destroyed.
+ QTextStream(stdout) << "releasing channel object: " << this->type_
+ << Qt::endl;
+}
+#else
+ChannelObject::~ChannelObject() noexcept = default;
+#endif
-/**
- * @brief
- *
- * @param e
- * @param ciphertext
- * @param len
- * @return uint8_t*
- */
-uint8_t *aes_256_cbc_decrypt(EVP_CIPHER_CTX *e, uint8_t *ciphertext, int *len);
+void ChannelObject::SetChannel(int channel) { this->channel_ = channel; }
+
+auto ChannelObject::GetChannel() const -> int { return channel_; }
-} // namespace GpgFrontend::RawAPI
+auto ChannelObject::GetDefaultChannel() -> int {
+ return kGpgFrontendDefaultChannel;
+}
-#endif // GPGFRONTEND_AES_SSL_H
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/ChannelObject.h b/src/core/function/basic/ChannelObject.h
new file mode 100644
index 00000000..27be55c4
--- /dev/null
+++ b/src/core/function/basic/ChannelObject.h
@@ -0,0 +1,98 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgConstants.h"
+#include "core/function/SecureMemoryAllocator.h"
+namespace GpgFrontend {
+
+/**
+ * @brief object which in channel system is called "channel"
+ *
+ */
+class GPGFRONTEND_CORE_EXPORT ChannelObject {
+ public:
+ /**
+ * @brief Construct a new Default Channel Object object
+ *
+ */
+ ChannelObject() noexcept;
+
+ /**
+ * @brief Destroy the Channel Object object
+ *
+ */
+ virtual ~ChannelObject() noexcept;
+
+ /**
+ * @brief Construct a new Channel Object object
+ *
+ * @param channel
+ */
+ explicit ChannelObject(int channel, QString type);
+
+ /**
+ * @brief Get the Default Channel object
+ *
+ * @return int
+ */
+ static auto GetDefaultChannel() -> int;
+
+ /**
+ * @brief Get the Channel object
+ *
+ * @return int
+ */
+ [[nodiscard]] auto GetChannel() const -> int;
+
+ /**
+ * @brief Set the Channel object
+ *
+ * @param channel
+ */
+ void SetChannel(int channel);
+
+ private:
+ int channel_ = kGpgFrontendDefaultChannel; ///< The channel id
+ QString type_;
+};
+
+template <typename Derived>
+auto ConvertToChannelObjectPtr(
+ std::unique_ptr<Derived, SecureObjectDeleter<Derived>> derivedPtr)
+ -> std::unique_ptr<ChannelObject, SecureObjectDeleter<ChannelObject>> {
+ static_assert(std::is_base_of_v<ChannelObject, Derived>,
+ "Derived must be a subclass of ChannelObject");
+
+ ChannelObject* base_ptr = derivedPtr.release();
+ return std::unique_ptr<ChannelObject, SecureObjectDeleter<ChannelObject>>(
+ base_ptr);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/GpgFunctionObject.cpp b/src/core/function/basic/GpgFunctionObject.cpp
new file mode 100644
index 00000000..e9e444f1
--- /dev/null
+++ b/src/core/function/basic/GpgFunctionObject.cpp
@@ -0,0 +1,105 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgFunctionObject.h"
+
+#include <map>
+#include <mutex>
+#include <typeinfo>
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/ChannelObject.h"
+
+struct FunctionObjectTypeLockInfo {
+ std::map<int, std::mutex> channel_lock_map;
+ std::mutex type_lock;
+};
+
+std::mutex g_function_object_mutex_map_lock;
+std::map<size_t, FunctionObjectTypeLockInfo> g_function_object_mutex_map;
+
+namespace GpgFrontend {
+auto GetGlobalFunctionObjectChannelLock(const std::type_info& type, int channel)
+ -> std::mutex& {
+ std::lock_guard<std::mutex> lock_guard(g_function_object_mutex_map_lock);
+ auto& channel_map = g_function_object_mutex_map[type.hash_code()];
+ return channel_map.channel_lock_map[channel];
+}
+
+auto GetGlobalFunctionObjectTypeLock(const std::type_info& type)
+ -> std::mutex& {
+ std::lock_guard<std::mutex> lock_guard(g_function_object_mutex_map_lock);
+ auto& channel_map = g_function_object_mutex_map[type.hash_code()];
+ return channel_map.type_lock;
+}
+
+/**
+ * @brief Get the Instance object
+ *
+ * @param channel
+ * @return T&
+ */
+auto GetChannelObjectInstance(const std::type_info& type, int channel)
+ -> ChannelObject* {
+ GF_DEFAULT_LOG_TRACE("try to get instance of type: {} at channel: {}",
+ type.name(), channel);
+
+ // lock this channel
+ std::lock_guard<std::mutex> guard(
+ GetGlobalFunctionObjectChannelLock(type, channel));
+
+ auto* p_storage =
+ SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
+ GF_DEFAULT_LOG_TRACE("get singleton storage result, p_storage: {}",
+ static_cast<void*>(p_storage));
+
+ auto* p_pbj =
+ static_cast<ChannelObject*>(p_storage->FindObjectInChannel(channel));
+ GF_DEFAULT_LOG_TRACE("find channel object result, channel {}, p_pbj: {}",
+ channel, static_cast<void*>(p_pbj));
+
+ return p_pbj;
+}
+
+auto CreateChannelObjectInstance(const std::type_info& type, int channel,
+ SecureUniquePtr<ChannelObject> channel_object)
+ -> ChannelObject* {
+ // lock this channel
+ std::lock_guard<std::mutex> guard(
+ GetGlobalFunctionObjectChannelLock(type, channel));
+
+ auto* p_storage =
+ SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
+ GF_DEFAULT_LOG_TRACE("create channel object, channel {}, type: {}", channel,
+ type.name());
+
+ // do create object of this channel
+ return p_storage->SetObjectInChannel(channel, std::move(channel_object));
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/GpgFunctionObject.h b/src/core/function/basic/GpgFunctionObject.h
new file mode 100644
index 00000000..1ea352b6
--- /dev/null
+++ b/src/core/function/basic/GpgFunctionObject.h
@@ -0,0 +1,194 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <mutex>
+#include <stdexcept>
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/function/basic/ChannelObject.h"
+#include "core/function/basic/SingletonStorage.h"
+#include "core/function/basic/SingletonStorageCollection.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+auto GPGFRONTEND_CORE_EXPORT GetChannelObjectInstance(
+ const std::type_info& type, int channel) -> ChannelObject*;
+
+auto GPGFRONTEND_CORE_EXPORT CreateChannelObjectInstance(
+ const std::type_info& type, int channel,
+ SecureUniquePtr<ChannelObject> channel_object) -> ChannelObject*;
+
+auto GPGFRONTEND_CORE_EXPORT
+GetGlobalFunctionObjectTypeLock(const std::type_info& type) -> std::mutex&;
+
+/**
+ * @brief
+ *
+ * @tparam T
+ */
+template <typename T>
+class SingletonFunctionObject : public ChannelObject {
+ public:
+ /**
+ * @brief prohibit copy
+ *
+ */
+ SingletonFunctionObject(const SingletonFunctionObject<T>&) = delete;
+
+ /**
+ * @brief prohibit copy
+ *
+ * @return SingletonFunctionObject&
+ */
+ auto operator=(const SingletonFunctionObject<T>&)
+ -> SingletonFunctionObject& = delete;
+
+ /**
+ * @brief Get the Instance object
+ *
+ * @param channel
+ * @return T&
+ */
+ static auto GetInstance(int channel = GpgFrontend::kGpgFrontendDefaultChannel)
+ -> T& {
+ static_assert(std::is_base_of_v<SingletonFunctionObject<T>, T>,
+ "T not derived from SingletonFunctionObject<T>");
+
+ const auto& type = typeid(T);
+ std::lock_guard<std::mutex> guard(GetGlobalFunctionObjectTypeLock(type));
+ auto* channel_object = GetChannelObjectInstance(type, channel);
+ if (channel_object == nullptr) {
+ channel_object = CreateChannelObjectInstance(
+ type, channel,
+ ConvertToChannelObjectPtr(SecureCreateUniqueObject<T>(channel)));
+ }
+ return *static_cast<T*>(channel_object);
+ }
+
+ /**
+ * @brief Create a Instance object
+ *
+ * @param channel
+ * @param factory
+ * @return T&
+ */
+ static auto CreateInstance(
+ int channel, const std::function<ChannelObjectPtr(void)>& factory) -> T& {
+ static_assert(std::is_base_of_v<SingletonFunctionObject<T>, T>,
+ "T not derived from SingletonFunctionObject<T>");
+
+ const auto& type = typeid(T);
+ std::lock_guard<std::mutex> guard(GetGlobalFunctionObjectTypeLock(type));
+ return *static_cast<T*>(
+ CreateChannelObjectInstance(type, channel, factory()));
+ }
+
+ /**
+ * @brief
+ *
+ * @param channel
+ * @return T&
+ */
+ static void ReleaseChannel(int channel) {
+ SingletonStorageCollection::GetInstance(false)
+ ->GetSingletonStorage(typeid(T))
+ ->ReleaseChannel(channel);
+ }
+
+ /**
+ * @brief Get the Default Channel object
+ *
+ * @return int
+ */
+ static auto GetDefaultChannel() -> int {
+ return ChannelObject::GetDefaultChannel();
+ }
+
+ /**
+ * @brief Get the Channel object
+ *
+ * @return int
+ */
+ [[nodiscard]] auto GetChannel() const -> int {
+ return ChannelObject::GetChannel();
+ }
+
+ /**
+ * @brief Get all the channel ids
+ *
+ * @return std::vector<int>
+ */
+ static auto GetAllChannelId() -> std::vector<int> {
+ return SingletonStorageCollection::GetInstance(false)
+ ->GetSingletonStorage(typeid(T))
+ ->GetAllChannelId();
+ }
+
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ */
+ SingletonFunctionObject(T&&) = delete;
+
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ */
+ SingletonFunctionObject(const T&) = delete;
+
+ /**
+ * @brief
+ *
+ */
+ void operator=(const T&) = delete;
+
+ protected:
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ */
+ SingletonFunctionObject() = default;
+
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ * @param channel
+ */
+ explicit SingletonFunctionObject(int channel)
+ : ChannelObject(channel, typeid(T).name()) {}
+
+ /**
+ * @brief Destroy the Singleton Function Object object
+ *
+ */
+ virtual ~SingletonFunctionObject() = default;
+};
+} // namespace GpgFrontend
diff --git a/src/core/function/basic/SingletonStorage.cpp b/src/core/function/basic/SingletonStorage.cpp
new file mode 100644
index 00000000..eab71e0f
--- /dev/null
+++ b/src/core/function/basic/SingletonStorage.cpp
@@ -0,0 +1,133 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SingletonStorage.h"
+
+#include <shared_mutex>
+
+#include "core/function/basic/ChannelObject.h"
+#include "utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+class SingletonStorage::Impl {
+ public:
+ void ReleaseChannel(int channel) {
+ decltype(instances_map_.end()) ins_it;
+ {
+ std::shared_lock<std::shared_mutex> lock(instances_mutex_);
+ ins_it = instances_map_.find(channel);
+ }
+ if (ins_it != instances_map_.end()) instances_map_.erase(ins_it);
+ }
+
+ auto FindObjectInChannel(int channel) -> GpgFrontend::ChannelObject* {
+ // read instances_map_
+ decltype(instances_map_.end()) ins_it;
+ {
+ std::shared_lock<std::shared_mutex> lock(instances_mutex_);
+ ins_it = instances_map_.find(channel);
+ if (ins_it == instances_map_.end()) {
+ GF_DEFAULT_LOG_TRACE("cannot find channel object, channel: {}",
+ channel);
+ return nullptr;
+ }
+ return ins_it->second.get();
+ }
+ }
+
+ auto GetAllChannelId() -> std::vector<int> {
+ std::vector<int> channels;
+ channels.reserve(instances_map_.size());
+ for (const auto& [key, value] : instances_map_) {
+ channels.push_back(key);
+ }
+ return channels;
+ }
+
+ auto SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
+ -> GpgFrontend::ChannelObject* {
+ GF_DEFAULT_LOG_TRACE(
+ "set channel object, type: {} in channel: {}, address: {}",
+ typeid(p_obj.get()).name(), channel, static_cast<void*>(p_obj.get()));
+
+ assert(p_obj != nullptr);
+ if (p_obj == nullptr) {
+ GF_DEFAULT_LOG_ERROR(
+ "cannot set a nullptr as a channel obejct of channel: {}", channel);
+ return nullptr;
+ }
+
+ p_obj->SetChannel(channel);
+ auto* raw_obj = p_obj.get();
+
+ {
+ GF_DEFAULT_LOG_TRACE(
+ "register channel object to instances map, "
+ "channel: {}, address: {}",
+ channel, static_cast<void*>(p_obj.get()));
+ std::unique_lock<std::shared_mutex> lock(instances_mutex_);
+ instances_map_[channel] = std::move(p_obj);
+ }
+
+ GF_DEFAULT_LOG_TRACE(
+ "set channel: {} success, current channel object address: {}", channel,
+ static_cast<void*>(raw_obj));
+ return raw_obj;
+ }
+
+ private:
+ std::shared_mutex instances_mutex_; ///< mutex for _instances_map
+ std::map<int, ChannelObjectPtr>
+ instances_map_; ///< map of singleton instances
+};
+
+SingletonStorage::SingletonStorage() noexcept
+ : p_(SecureCreateUniqueObject<Impl>()) {}
+
+SingletonStorage::~SingletonStorage() = default;
+
+void SingletonStorage::ReleaseChannel(int channel) {
+ p_->ReleaseChannel(channel);
+}
+
+auto SingletonStorage::FindObjectInChannel(int channel)
+ -> GpgFrontend::ChannelObject* {
+ return p_->FindObjectInChannel(channel);
+}
+
+auto SingletonStorage::GetAllChannelId() -> std::vector<int> {
+ return p_->GetAllChannelId();
+}
+
+auto SingletonStorage::SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
+ -> GpgFrontend::ChannelObject* {
+ return p_->SetObjectInChannel(channel, std::move(p_obj));
+}
+
+}; // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/SingletonStorage.h b/src/core/function/basic/SingletonStorage.h
new file mode 100644
index 00000000..0ef47443
--- /dev/null
+++ b/src/core/function/basic/SingletonStorage.h
@@ -0,0 +1,90 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/SecureMemoryAllocator.h"
+
+namespace GpgFrontend {
+
+class ChannelObject;
+
+using ChannelObjectPtr = SecureUniquePtr<ChannelObject>;
+
+class GPGFRONTEND_CORE_EXPORT SingletonStorage {
+ public:
+ /**
+ * @brief
+ *
+ */
+ SingletonStorage() noexcept;
+
+ /**
+ * @brief
+ *
+ */
+ ~SingletonStorage();
+
+ /**
+ * @brief
+ *
+ * @param channel
+ */
+ void ReleaseChannel(int channel);
+
+ /**
+ * @brief
+ *
+ * @param channel
+ * @return T*
+ */
+ auto FindObjectInChannel(int channel) -> ChannelObject*;
+
+ /**
+ * @brief Get all the channel ids
+ *
+ * @return std::vector<int>
+ */
+ auto GetAllChannelId() -> std::vector<int>;
+
+ /**
+ * @brief Set a new object in channel object
+ *
+ * @param channel
+ * @param p_obj
+ * @return T*
+ */
+ auto SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
+ -> ChannelObject*;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/SingletonStorageCollection.cpp b/src/core/function/basic/SingletonStorageCollection.cpp
new file mode 100644
index 00000000..c22b5242
--- /dev/null
+++ b/src/core/function/basic/SingletonStorageCollection.cpp
@@ -0,0 +1,124 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SingletonStorageCollection.h"
+
+#include <memory>
+#include <shared_mutex>
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/SingletonStorage.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+SecureUniquePtr<SingletonStorageCollection> global_instance = nullptr;
+
+class SingletonStorageCollection::Impl {
+ public:
+ /**
+ * @brief Get the Instance object
+ *
+ * @return SingletonStorageCollection*
+ */
+ static auto GetInstance(bool force_refresh) -> SingletonStorageCollection* {
+ if (force_refresh || global_instance == nullptr) {
+ global_instance = SecureCreateUniqueObject<SingletonStorageCollection>();
+ GF_DEFAULT_LOG_TRACE(
+ "a new global singleton storage collection created, address: {}",
+ static_cast<void*>(global_instance.get()));
+ }
+ return global_instance.get();
+ }
+
+ /**
+ * @brief Get the Instance object
+ *
+ * @return SingletonStorageCollection*
+ */
+ static void Destroy() { global_instance = nullptr; }
+
+ /**
+ * @brief Get the Singleton Storage object
+ *
+ * @param singleton_function_object
+ * @return SingletonStorage*
+ */
+ auto GetSingletonStorage(const std::type_info& type_id) -> SingletonStorage* {
+ const auto hash = type_id.hash_code();
+
+ while (true) {
+ decltype(storages_map_.end()) ins_it;
+ {
+ std::shared_lock<std::shared_mutex> lock(storages_mutex_);
+ ins_it = storages_map_.find(hash);
+ }
+ if (ins_it == storages_map_.end()) {
+ auto storage = SecureCreateUniqueObject<SingletonStorage>();
+ GF_DEFAULT_LOG_TRACE(
+ "hash: {} created, singleton storage address: {} type_name: {}",
+ hash, static_cast<void*>(storage.get()), type_id.name());
+
+ {
+ std::unique_lock<std::shared_mutex> lock(storages_mutex_);
+ storages_map_.insert({hash, std::move(storage)});
+ }
+ continue;
+ }
+ return ins_it->second.get();
+ }
+ }
+
+ private:
+ std::shared_mutex storages_mutex_; ///< mutex for storages_map_
+ std::map<size_t, SingletonStoragePtr> storages_map_;
+};
+
+SingletonStorageCollection::SingletonStorageCollection() noexcept
+ : p_(SecureCreateUniqueObject<Impl>()) {}
+
+SingletonStorageCollection::~SingletonStorageCollection() = default;
+
+auto GpgFrontend::SingletonStorageCollection::GetInstance(bool force_refresh)
+ -> GpgFrontend::SingletonStorageCollection* {
+ return Impl::GetInstance(force_refresh);
+}
+
+void SingletonStorageCollection::Destroy() {
+ GF_DEFAULT_LOG_TRACE(
+ "global singleton storage collection is about to destroy, address: {}",
+ static_cast<void*>(global_instance.get()));
+ return SingletonStorageCollection::Impl::Destroy();
+}
+
+auto SingletonStorageCollection::GetSingletonStorage(
+ const std::type_info& type_id) -> GpgFrontend::SingletonStorage* {
+ return p_->GetSingletonStorage(type_id);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/SingletonStorageCollection.h b/src/core/function/basic/SingletonStorageCollection.h
new file mode 100644
index 00000000..38ced83b
--- /dev/null
+++ b/src/core/function/basic/SingletonStorageCollection.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/SecureMemoryAllocator.h"
+
+namespace GpgFrontend {
+class SingletonStorage;
+
+using SingletonStoragePtr =
+ std::unique_ptr<SingletonStorage, SecureObjectDeleter<SingletonStorage>>;
+
+class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
+ public:
+ /**
+ * @brief
+ *
+ */
+ SingletonStorageCollection() noexcept;
+
+ /**
+ * @brief
+ *
+ */
+ ~SingletonStorageCollection();
+
+ /**
+ * @brief Get the Instance object
+ *
+ * @return SingletonStorageCollection*
+ */
+ static auto GetInstance(bool force_refresh) -> SingletonStorageCollection*;
+
+ /**
+ * @brief
+ *
+ */
+ static void Destroy();
+
+ /**
+ * @brief Get the Singleton Storage object
+ *
+ * @param singleton_function_object
+ * @return SingletonStorage*
+ */
+ auto GetSingletonStorage(const std::type_info&) -> SingletonStorage*;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgAdvancedOperator.cpp b/src/core/function/gpg/GpgAdvancedOperator.cpp
index 2a3bba42..3fc831ed 100644
--- a/src/core/function/gpg/GpgAdvancedOperator.cpp
+++ b/src/core/function/gpg/GpgAdvancedOperator.cpp
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2023. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * This file is part of GpgFrontend.
*
* GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,9 +20,10 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
//
@@ -32,152 +33,182 @@
#include "GpgAdvancedOperator.h"
#include "core/function/gpg/GpgCommandExecutor.h"
-#include "spdlog/spdlog.h"
-
-GpgFrontend::GpgAdvancedOperator::GpgAdvancedOperator(int channel)
- : SingletonFunctionObject(channel) {}
-
-bool GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--reload", "gpg-agent"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- SPDLOG_DEBUG("gpgconf reload exit code: {}", exit_code);
- success = true;
- }
- });
- return success;
+#include "core/module/ModuleManager.h"
+
+void GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache(
+ OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path, QStringList{"--reload", "gpg-agent"},
+ [=](int exit_code, const QString & /*p_out*/,
+ const QString & /*p_err*/) {
+ GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--reload"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
- return success;
+void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
+ OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path, QStringList{"--reload"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
- bool success = false;
-
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--verbose", "--kill", "all"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- return;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- if (!success) return false;
-
- success &= StartGpgAgent();
-
- success &= StartDirmngr();
-
- success &= StartKeyBoxd();
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path, QStringList{"--verbose", "--kill", "all"},
+ [=](int exit_code, const QString &p_out, const QString &p_err) {
+ GF_CORE_LOG_DEBUG("gpgconf --kill all command got exit code: {}",
+ exit_code);
+ bool success = true;
+ if (exit_code != 0) {
+ success = false;
+ GF_CORE_LOG_ERROR(
+ "gpgconf execute error, process stderr: {}, process stdout: {}",
+ p_err, p_out);
+ return;
+ }
+
+ GF_CORE_LOG_DEBUG("gpgconf --kill --all execute result: {}", success);
+ if (!success) {
+ GF_CORE_LOG_ERROR(
+ "restart all component after core initilized failed");
+ Module::UpsertRTValue(
+ "core", "gpg_advanced_operator.restart_gpg_components", false);
+ return;
+ }
+
+ StartGpgAgent([](int err, DataObjectPtr) {
+ if (err >= 0) {
+ Module::UpsertRTValue(
+ "core", "gpg_advanced_operator.restart_gpg_components", true);
+ return;
+ }
+ });
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::ResetConfigures() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--apply-defaults"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::ResetConfigures(OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path, QStringList{"--apply-defaults"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf apply-defaults exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartGpgAgent() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgAgentPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start gpg-agent successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("gpg-agent already started");
- } else {
- SPDLOG_ERROR(
- "gpg-agent execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartGpgAgent(OperationCallback cb) {
+ const auto gpg_agent_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.gpg_agent_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg agent path from rt: {}", gpg_agent_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (gpg_agent_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpg agent path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpg_agent_path, QStringList{"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartDirmngr() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().DirmngrPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start dirmngr successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("dirmngr already started");
- } else {
- SPDLOG_ERROR(
- "dirmngr execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartDirmngr(OperationCallback cb) {
+ const auto dirmngr_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.dirmngr_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg dirmngr path from rt: {}", dirmngr_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (dirmngr_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid dirmngr path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {dirmngr_path, QStringList{"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartKeyBoxd() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().KeyboxdPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start keyboxd successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("keyboxd already started");
- } else {
- SPDLOG_ERROR(
- "keyboxd execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartKeyBoxd(OperationCallback cb) {
+ const auto keyboxd_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.keyboxd_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg keyboxd path from rt: {}", keyboxd_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (keyboxd_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid keyboxd path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {keyboxd_path, QStringList{"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
diff --git a/src/core/function/gpg/GpgAdvancedOperator.h b/src/core/function/gpg/GpgAdvancedOperator.h
index 5325020a..d6b57095 100644
--- a/src/core/function/gpg/GpgAdvancedOperator.h
+++ b/src/core/function/gpg/GpgAdvancedOperator.h
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2023. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * This file is part of GpgFrontend.
*
* GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,42 +20,31 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
//
// Created by eric on 07.01.2023.
//
-#ifndef GPGFRONTEND_GPGADVANCEDOPERATOR_H
-#define GPGFRONTEND_GPGADVANCEDOPERATOR_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
+#include "core/typedef/CoreTypedef.h"
namespace GpgFrontend {
-class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
- : public SingletonFunctionObject<GpgAdvancedOperator> {
+class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator {
public:
/**
- * @brief Construct a new Basic Operator object
- *
- * @param channel Channel corresponding to the context
- */
- explicit GpgAdvancedOperator(
- int channel = SingletonFunctionObject::GetDefaultChannel());
-
- /**
* @brief
*
* @return true
* @return false
*/
- bool ClearGpgPasswordCache();
+ static void ClearGpgPasswordCache(OperationCallback);
/**
* @brief
@@ -63,7 +52,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool ReloadGpgComponents();
+ static void ReloadGpgComponents(OperationCallback);
/**
* @brief
@@ -71,7 +60,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool RestartGpgComponents();
+ static void RestartGpgComponents();
/**
* @brief
@@ -79,7 +68,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool ResetConfigures();
+ static void ResetConfigures(OperationCallback);
/**
* @brief
@@ -87,7 +76,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartGpgAgent();
+ static void StartGpgAgent(OperationCallback);
/**
* @brief
@@ -95,7 +84,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartDirmngr();
+ static void StartDirmngr(OperationCallback);
/**
* @brief
@@ -103,13 +92,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartKeyBoxd();
-
- private:
- GpgContext& ctx_ = GpgContext::GetInstance(
- SingletonFunctionObject::GetChannel()); ///< Corresponding context
+ static void StartKeyBoxd(OperationCallback);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGADVANCEDOPERATOR_H
diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp
index 71f84907..8b62aad0 100644
--- a/src/core/function/gpg/GpgBasicOperator.cpp
+++ b/src/core/function/gpg/GpgBasicOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,195 +28,389 @@
#include "GpgBasicOperator.h"
-#include <vector>
+#include <gpg-error.h>
-#include "GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/model/GpgDecryptResult.h"
+#include "core/model/GpgEncryptResult.h"
+#include "core/model/GpgSignResult.h"
+#include "core/model/GpgVerifyResult.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgBasicOperator::GpgBasicOperator(int channel)
+namespace GpgFrontend {
+
+GpgBasicOperator::GpgBasicOperator(int channel)
: SingletonFunctionObject<GpgBasicOperator>(channel) {}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Encrypt(
- KeyListPtr keys, GpgFrontend::BypeArrayRef in_buffer,
- GpgFrontend::ByteArrayPtr& out_buffer, GpgFrontend::GpgEncrResult& result) {
- // gpgme_encrypt_result_t e_result;
- gpgme_key_t recipients[keys->size() + 1];
+void GpgBasicOperator::Encrypt(const KeyArgsList& keys,
+ const GFBuffer& in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
- int index = 0;
- for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
- // Last entry data_in array has to be nullptr
- recipients[keys->size()] = nullptr;
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- gpgme_error_t err = check_gpg_error(gpgme_op_encrypt(
- ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
+}
- auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_));
- std::swap(result, temp_result);
+auto GpgBasicOperator::EncryptSync(const KeyArgsList& keys,
+ const GFBuffer& in_buffer, bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
- return err;
-}
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Decrypt(
- BypeArrayRef in_buffer, GpgFrontend::ByteArrayPtr& out_buffer,
- GpgFrontend::GpgDecrResult& result) {
- gpgme_error_t err;
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
- err = check_gpg_error(gpgme_op_decrypt(ctx_, data_in, data_out));
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
- auto temp_result = _new_result(gpgme_op_decrypt_result(ctx_));
- std::swap(result, temp_result);
+ return err;
+ },
+ "gpgme_op_encrypt", "2.1.0");
+}
- return err;
+void GpgBasicOperator::EncryptSymmetric(const GFBuffer& in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Verify(
- BypeArrayRef& in_buffer, ByteArrayPtr& sig_buffer,
- GpgVerifyResult& result) const {
- gpgme_error_t err;
+auto GpgBasicOperator::EncryptSymmetricSync(const GFBuffer& in_buffer,
+ bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ "gpgme_op_encrypt_symmetric", "2.1.0");
+}
- GpgData data_in(in_buffer.data(), in_buffer.size());
- GpgData data_out;
+void GpgBasicOperator::Decrypt(const GFBuffer& in_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
+}
- if (sig_buffer != nullptr && sig_buffer->size() > 0) {
- GpgData sig_data(sig_buffer->data(), sig_buffer->size());
- err = check_gpg_error(gpgme_op_verify(ctx_, sig_data, data_in, nullptr));
- } else
- err = check_gpg_error(gpgme_op_verify(ctx_, data_in, nullptr, data_out));
+auto GpgBasicOperator::DecryptSync(const GFBuffer& in_buffer)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ "gpgme_op_decrypt", "2.1.0");
+}
- auto temp_result = _new_result(gpgme_op_verify_result(ctx_));
- std::swap(result, temp_result);
+void GpgBasicOperator::Verify(const GFBuffer& in_buffer,
+ const GFBuffer& sig_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ if (!sig_buffer.Empty()) {
+ GpgData sig_data(sig_buffer);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_verify", "2.1.0");
+}
- return err;
+auto GpgBasicOperator::VerifySync(const GFBuffer& in_buffer,
+ const GFBuffer& sig_buffer)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ if (!sig_buffer.Empty()) {
+ GpgData sig_data(sig_buffer);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ "gpgme_op_verify", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Sign(
- KeyListPtr signers, BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- gpgme_sig_mode_t mode, GpgSignResult& result) {
- gpgme_error_t err;
+void GpgBasicOperator::Sign(const KeyArgsList& signers,
+ const GFBuffer& in_buffer, GpgSignMode mode,
+ bool ascii, const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (signers.empty()) return GPG_ERR_CANCELED;
- // Set Singers of this opera
- SetSigners(*signers);
+ GpgError err;
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ // Set Singers of this opera
+ SetSigners(signers, ascii);
- err = check_gpg_error(gpgme_op_sign(ctx_, data_in, data_out, mode));
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_sign(ctx, data_in, data_out, mode));
- auto temp_result = _new_result(gpgme_op_sign_result(ctx_));
+ data_object->Swap({GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_sign", "2.1.0");
+}
- std::swap(result, temp_result);
+auto GpgBasicOperator::SignSync(const KeyArgsList& signers,
+ const GFBuffer& in_buffer, GpgSignMode mode,
+ bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (signers.empty()) return GPG_ERR_CANCELED;
- return err;
+ GpgError err;
+
+ // Set Singers of this opera
+ SetSigners(signers, ascii);
+
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_sign(ctx, data_in, data_out, mode));
+
+ data_object->Swap({GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ "gpgme_op_sign", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgBasicOperator::DecryptVerify(
- BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgDecrResult& decrypt_result, GpgVerifyResult& verify_result) {
- gpgme_error_t err;
+void GpgBasicOperator::DecryptVerify(const GFBuffer& in_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
+}
- err = check_gpg_error(gpgme_op_decrypt_verify(ctx_, data_in, data_out));
+auto GpgBasicOperator::DecryptVerifySync(const GFBuffer& in_buffer)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_decr_result = _new_result(gpgme_op_decrypt_result(ctx_));
- std::swap(decrypt_result, temp_decr_result);
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
- auto temp_verify_result = _new_result(gpgme_op_verify_result(ctx_));
- std::swap(verify_result, temp_verify_result);
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
- return err;
+ return err;
+ },
+ "gpgme_op_decrypt_verify", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgBasicOperator::EncryptSign(
- KeyListPtr keys, KeyListPtr signers, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, GpgEncrResult& encr_result,
- GpgSignResult& sign_result) {
- gpgme_error_t err;
- SetSigners(*signers);
+void GpgBasicOperator::EncryptSign(const KeyArgsList& keys,
+ const KeyArgsList& signers,
+ const GFBuffer& in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty() || signers.empty()) return GPG_ERR_CANCELED;
- // gpgme_encrypt_result_t e_result;
- gpgme_key_t recipients[keys->size() + 1];
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
- // set key for user
- int index = 0;
- for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- // Last entry dataIn array has to be nullptr
- recipients[keys->size()] = nullptr;
+ SetSigners(signers, ascii);
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- // If the last parameter isnt 0, a private copy of data is made
- err = check_gpg_error(gpgme_op_encrypt_sign(
- ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
+}
+
+auto GpgBasicOperator::EncryptSignSync(const KeyArgsList& keys,
+ const KeyArgsList& signers,
+ const GFBuffer& in_buffer, bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty() || signers.empty()) return GPG_ERR_CANCELED;
+
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- auto temp_encr_result = _new_result(gpgme_op_encrypt_result(ctx_));
- swap(encr_result, temp_encr_result);
- auto temp_sign_result = _new_result(gpgme_op_sign_result(ctx_));
- swap(sign_result, temp_sign_result);
+ SetSigners(signers, ascii);
- return err;
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ "gpgme_op_encrypt_sign", "2.1.0");
}
-void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) {
- gpgme_signers_clear(ctx_);
+void GpgBasicOperator::SetSigners(const KeyArgsList& signers, bool ascii) {
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+
+ gpgme_signers_clear(ctx);
+
for (const GpgKey& key : signers) {
- SPDLOG_DEBUG("key fpr: {}", key.GetFingerprint());
+ GF_CORE_LOG_DEBUG("key fpr: {}", key.GetFingerprint());
if (key.IsHasActualSigningCapability()) {
- SPDLOG_DEBUG("signer");
- auto error = gpgme_signers_add(ctx_, gpgme_key_t(key));
- check_gpg_error(error);
+ GF_CORE_LOG_DEBUG("signer");
+ auto error = gpgme_signers_add(ctx, gpgme_key_t(key));
+ CheckGpgError(error);
}
}
- if (signers.size() != gpgme_signers_count(ctx_))
- SPDLOG_DEBUG("not all signers added");
+ if (signers.size() != gpgme_signers_count(ctx_.DefaultContext()))
+ GF_CORE_LOG_DEBUG("not all signers added");
}
-std::unique_ptr<GpgFrontend::KeyArgsList>
-GpgFrontend::GpgBasicOperator::GetSigners() {
- auto count = gpgme_signers_count(ctx_);
+auto GpgBasicOperator::GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList> {
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+
+ auto count = gpgme_signers_count(ctx);
auto signers = std::make_unique<std::vector<GpgKey>>();
- for (auto i = 0u; i < count; i++) {
- auto key = GpgKey(gpgme_signers_enum(ctx_, i));
+ for (auto i = 0U; i < count; i++) {
+ auto key = GpgKey(gpgme_signers_enum(ctx, i));
signers->push_back(GpgKey(std::move(key)));
}
return signers;
}
-
-gpg_error_t GpgFrontend::GpgBasicOperator::EncryptSymmetric(
- GpgFrontend::ByteArray& in_buffer, GpgFrontend::ByteArrayPtr& out_buffer,
- GpgFrontend::GpgEncrResult& result) {
- // deepcopy from ByteArray to GpgData
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
-
- gpgme_error_t err = check_gpg_error(gpgme_op_encrypt(
- ctx_, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
-
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
-
- // TODO(Saturneric): maybe a bug of gpgme
- if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
- auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_));
- std::swap(result, temp_result);
- }
-
- return err;
-}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgBasicOperator.h b/src/core/function/gpg/GpgBasicOperator.h
index 696ac9dc..37defb45 100644
--- a/src/core/function/gpg/GpgBasicOperator.h
+++ b/src/core/function/gpg/GpgBasicOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,20 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
-#define GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/model/GFBuffer.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -52,19 +53,18 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
int channel = SingletonFunctionObject::GetDefaultChannel());
/**
- * @brief Call the interface provided by gpgme for encryption operation
+ * @brief
*
- * All incoming data pointers out_buffer will be replaced with new valid
- * values
+ */
+ void Encrypt(const KeyArgsList&, const GFBuffer&, bool,
+ const GpgOperationCallback&);
+
+ /**
+ * @brief
*
- * @param keys list of public keys
- * @param in_buffer data that needs to be encrypted
- * @param out_buffer encrypted data
- * @param result the result of the operation
- * @return error code
*/
- gpg_error_t Encrypt(KeyListPtr keys, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, GpgEncrResult& result);
+ auto EncryptSync(const KeyArgsList&, const GFBuffer&, bool)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Call the interface provided by GPGME to symmetrical encryption
@@ -72,10 +72,21 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param in_buffer Data for encryption
* @param out_buffer Encrypted data
* @param result Encrypted results
- * @return gpg_error_t
+ * @return GpgError
+ */
+ void EncryptSymmetric(const GFBuffer& in_buffer, bool ascii,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_buffer
+ * @param ascii
+ * @param cb
+ * @return std::tuple<GpgError, DataObjectPtr>
*/
- gpg_error_t EncryptSymmetric(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgEncrResult& result);
+ auto EncryptSymmetricSync(const GFBuffer& in_buffer, bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
*
@@ -85,15 +96,25 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param keys List of public keys
* @param signers Private key for signatures
* @param in_buffer Data for operation
- * @param out_buffer Encrypted data
- * @param encr_result Encrypted results
- * @param sign_result Signature result
+ * @param ascii ascii mode
* @return
*/
- gpgme_error_t EncryptSign(KeyListPtr keys, KeyListPtr signers,
- BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgEncrResult& encr_result,
- GpgSignResult& sign_result);
+ void EncryptSign(const KeyArgsList& keys, const KeyArgsList& signers,
+ const GFBuffer& in_buffer, bool ascii,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param signers
+ * @param in_buffer
+ * @param ascii
+ * @param cb
+ */
+ auto EncryptSignSync(const KeyArgsList& keys, const KeyArgsList& signers,
+ const GFBuffer& in_buffer, bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Call the interface provided by gpgme for decryption operation
@@ -103,8 +124,15 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpgme_error_t Decrypt(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgDecrResult& result);
+ void Decrypt(const GFBuffer& in_buffer, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_buffer
+ */
+ auto DecryptSync(const GFBuffer& in_buffer)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Call the interface provided by gpgme to perform decryption and
@@ -116,9 +144,15 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param verify_result the result of the verifying operation
* @return error code
*/
- gpgme_error_t DecryptVerify(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgDecrResult& decrypt_result,
- GpgVerifyResult& verify_result);
+ void DecryptVerify(const GFBuffer& in_buffer, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_buffer
+ */
+ auto DecryptVerifySync(const GFBuffer& in_buffer)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Call the interface provided by gpgme for verification operation
@@ -128,8 +162,19 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpgme_error_t Verify(BypeArrayRef in_buffer, ByteArrayPtr& sig_buffer,
- GpgVerifyResult& result) const;
+ void Verify(const GFBuffer& in_buffer, const GFBuffer& sig_buffer,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_buffer
+ * @param sig_buffer
+ * @param cb
+ * @return std::tuple<GpgError, DataObjectPtr>
+ */
+ auto VerifySync(const GFBuffer& in_buffer, const GFBuffer& sig_buffer)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Call the interface provided by gpgme for signing operation
@@ -151,9 +196,22 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpg_error_t Sign(KeyListPtr signers, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode,
- GpgSignResult& result);
+ void Sign(const KeyArgsList& signers, const GFBuffer& in_buffer,
+ GpgSignMode mode, bool ascii, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param signers
+ * @param in_buffer
+ * @param mode
+ * @param ascii
+ * @param cb
+ * @return std::tuple<GpgError, DataObjectPtr>
+ */
+ auto SignSync(const KeyArgsList& signers, const GFBuffer& in_buffer,
+ GpgSignMode mode, bool ascii)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief Set the private key for signatures, this operation is a global
@@ -161,19 +219,17 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
*
* @param keys
*/
- void SetSigners(KeyArgsList& signers);
+ void SetSigners(const KeyArgsList& signers, bool ascii);
/**
* @brief Get a global signature private keys that has been set.
*
* @return Intelligent pointer pointing to the private key list
*/
- std::unique_ptr<KeyArgsList> GetSigners();
+ auto GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList>;
private:
GpgContext& ctx_ = GpgContext::GetInstance(
SingletonFunctionObject::GetChannel()); ///< Corresponding context
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
index 86c47c60..6d24f9bd 100644
--- a/src/core/function/gpg/GpgCommandExecutor.cpp
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,252 +20,231 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgCommandExecutor.h"
-#include "GpgFunctionObject.h"
+#include "core/model/DataObject.h"
+#include "core/module/Module.h"
+#include "core/thread/Task.h"
#include "core/thread/TaskRunnerGetter.h"
-GpgFrontend::GpgCommandExecutor::GpgCommandExecutor(int channel)
- : SingletonFunctionObject<GpgCommandExecutor>(channel) {}
+namespace GpgFrontend {
-void GpgFrontend::GpgCommandExecutor::Execute(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func) {
- SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size());
+auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
+ -> Thread::Task * {
+ const auto &cmd = context.cmd;
+ const auto &arguments = context.arguments;
+ const auto &interact_function = context.int_func;
+ const auto &cmd_executor_callback = context.cb_func;
- Thread::Task::TaskCallback result_callback =
- [](int rtn, Thread::Task::DataObjectPtr data_object) {
- SPDLOG_DEBUG("data object use count: {}", data_object.use_count());
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
+ const QString joined_argument = QStringList::fromVector(arguments).join(" ");
+
+ GF_CORE_LOG_DEBUG("building task: called cmd {} arguments size: {}", cmd,
+ arguments.size());
- auto exit_code = data_object->PopObject<int>();
- auto process_stdout = data_object->PopObject<std::string>();
- auto process_stderr = data_object->PopObject<std::string>();
- auto callback = data_object->PopObject<
- std::function<void(int, std::string, std::string)>>();
+ Thread::Task::TaskCallback result_callback =
+ [cmd, joined_argument](int /*rtn*/, const DataObjectPtr &data_object) {
+ GF_CORE_LOG_DEBUG(
+ "data object args count of cmd executor result callback: {}",
+ data_object->GetObjectSize());
+ if (!data_object->Check<int, QString, GpgCommandExecutorCallback>()) {
+ GF_CORE_LOG_ERROR("data object checking failed");
+ return;
+ }
+
+ auto exit_code = ExtractParams<int>(data_object, 0);
+ auto process_stdout = ExtractParams<QString>(data_object, 1);
+ auto callback =
+ ExtractParams<GpgCommandExecutorCallback>(data_object, 2);
// call callback
- callback(exit_code, process_stdout, process_stderr);
+ GF_CORE_LOG_DEBUG(
+ "calling custom callback from caller of cmd {} {}, "
+ "exit_code: {}",
+ cmd, joined_argument, exit_code);
+ callback(exit_code, process_stdout, {});
};
Thread::Task::TaskRunnable runner =
- [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int {
- SPDLOG_DEBUG("process runner called, data object size: {}",
- data_object->GetObjectSize());
+ [joined_argument](const DataObjectPtr &data_object) -> int {
+ GF_CORE_LOG_DEBUG("process runner called, data object size: {}",
+ data_object->GetObjectSize());
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
+ if (!data_object->Check<QString, QStringList, GpgCommandExecutorInteractor,
+ GpgCommandExecutorCallback>()) {
+ GF_CORE_LOG_ERROR("data object checking failed");
+ return -1;
+ }
// get arguments
- auto cmd = data_object->PopObject<std::string>();
- SPDLOG_DEBUG("get cmd: {}", cmd);
- auto arguments = data_object->PopObject<std::vector<std::string>>();
+ auto cmd = ExtractParams<QString>(data_object, 0);
+ auto arguments = ExtractParams<QStringList>(data_object, 1);
auto interact_func =
- data_object->PopObject<std::function<void(QProcess *)>>();
+ ExtractParams<GpgCommandExecutorInteractor>(data_object, 2);
+ auto callback = ExtractParams<GpgCommandExecutorCallback>(data_object, 3);
+ // create process
auto *cmd_process = new QProcess();
+ // move to current thread
+ //
+ cmd_process->moveToThread(QThread::currentThread());
+ // set process channel mode
+ // this is to make sure we can get all output from stdout and stderr
cmd_process->setProcessChannelMode(QProcess::MergedChannels);
+ cmd_process->setProgram(cmd);
+
+ // set arguments
+ QStringList q_arguments;
+ for (const auto &argument : arguments) {
+ q_arguments.append(argument);
+ }
+ cmd_process->setArguments(q_arguments);
- QObject::connect(cmd_process, &QProcess::started,
- []() -> void { SPDLOG_DEBUG("process started"); });
+ QObject::connect(
+ cmd_process, &QProcess::started, [cmd, joined_argument]() -> void {
+ GF_CORE_LOG_DEBUG(
+ "\n== Process Execute Started ==\nCommand: {}\nArguments: "
+ "{}\n========================",
+ cmd, joined_argument);
+ });
QObject::connect(
cmd_process, &QProcess::readyReadStandardOutput,
[interact_func, cmd_process]() { interact_func(cmd_process); });
- QObject::connect(cmd_process, &QProcess::errorOccurred,
- [=](QProcess::ProcessError error) {
- SPDLOG_ERROR("error in executing command: {} error: {}",
- cmd, error);
- });
QObject::connect(
- cmd_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
- [=](int, QProcess::ExitStatus status) {
- if (status == QProcess::NormalExit)
- SPDLOG_DEBUG(
- "proceess finished, succeed in executing command: {}, exit "
- "status: {}",
- cmd, status);
- else
- SPDLOG_ERROR(
- "proceess finished, error in executing command: {}, exit "
- "status: {}",
- cmd, status);
+ cmd_process, &QProcess::errorOccurred,
+ [=](QProcess::ProcessError error) {
+ GF_CORE_LOG_ERROR(
+ "caught error while executing command: {} {}, error: {}", cmd,
+ joined_argument, error);
});
- cmd_process->setProgram(QString::fromStdString(cmd));
-
- QStringList q_arguments;
- for (const auto &argument : arguments)
- q_arguments.append(QString::fromStdString(argument));
- cmd_process->setArguments(q_arguments);
-
- SPDLOG_DEBUG("process execute ready, cmd: {} {}", cmd,
- q_arguments.join(" ").toStdString());
+ GF_CORE_LOG_DEBUG(
+ "\n== Process Execute Ready ==\nCommand: {}\nArguments: "
+ "{}\n========================",
+ cmd, joined_argument);
cmd_process->start();
cmd_process->waitForFinished();
- std::string process_stdout =
- cmd_process->readAllStandardOutput().toStdString(),
- process_stderr =
- cmd_process->readAllStandardError().toStdString();
+ QString process_stdout = cmd_process->readAllStandardOutput();
int exit_code = cmd_process->exitCode();
+ GF_CORE_LOG_DEBUG(
+ "\n==== Process Execution Summary ====\n"
+ "Command: {}\n"
+ "Arguments: {}\n"
+ "Exit Code: {}\n"
+ "---- Standard Output ----\n"
+ "{}\n"
+ "===============================",
+ cmd, joined_argument, exit_code, process_stdout);
+
cmd_process->close();
cmd_process->deleteLater();
- // transfer result
- SPDLOG_DEBUG("runner append object");
- data_object->AppendObject(std::move(process_stderr));
- data_object->AppendObject(std::move(process_stdout));
- data_object->AppendObject(std::move(exit_code));
- SPDLOG_DEBUG("runner append object done");
-
+ data_object->Swap({exit_code, process_stdout, callback});
return 0;
};
- // data transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
- SPDLOG_DEBUG("executor append object");
- data_object->AppendObject(std::move(callback));
- data_object->AppendObject(std::move(interact_func));
- data_object->AppendObject(std::move(arguments));
- data_object->AppendObject(std::move(std::string{cmd}));
- SPDLOG_DEBUG("executor append object done");
-
- auto *process_task = new GpgFrontend::Thread::Task(
- std::move(runner), fmt::format("Execute/{}", cmd), data_object,
+ return new Thread::Task(
+ std::move(runner), QString("GpgCommamdExecutor(%1){%2}").arg(cmd),
+ TransferParams(cmd, arguments, interact_function, cmd_executor_callback),
std::move(result_callback));
+}
+
+void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
+ Thread::Task *task = BuildTaskFromExecCtx(context);
QEventLoop looper;
- QObject::connect(process_task, &Thread::Task::SignalTaskEnd, &looper,
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, &looper,
&QEventLoop::quit);
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(process_task);
-
+ Thread::TaskRunnerPtr target_task_runner = nullptr;
+
+ if (context.task_runner != nullptr) {
+ target_task_runner = context.task_runner;
+ } else {
+ target_task_runner =
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
+ }
+ target_task_runner->PostTask(task);
+
+ // to arvoid dead lock issue we need to check if current thread is the same as
+ // target thread. if it is, we can't call exec() because it will block the
+ // current thread.
+ GF_CORE_LOG_TRACE("blocking until gpg command finish...");
// block until task finished
// this is to keep reference vaild until task finished
looper.exec();
}
-void GpgFrontend::GpgCommandExecutor::ExecuteConcurrently(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func) {
- SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size());
-
- Thread::Task::TaskCallback result_callback =
- [](int rtn, Thread::Task::DataObjectPtr data_object) {
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
-
- auto exit_code = data_object->PopObject<int>();
- auto process_stdout = data_object->PopObject<std::string>();
- auto process_stderr = data_object->PopObject<std::string>();
- auto callback = data_object->PopObject<
- std::function<void(int, std::string, std::string)>>();
-
- // call callback
- callback(exit_code, process_stdout, process_stderr);
- };
-
- Thread::Task::TaskRunnable runner =
- [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int {
- SPDLOG_DEBUG("process runner called, data object size: {}",
- data_object->GetObjectSize());
-
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
-
- SPDLOG_DEBUG("runner pop object");
- // get arguments
- auto cmd = data_object->PopObject<std::string>();
- auto arguments = data_object->PopObject<std::vector<std::string>>();
- auto interact_func =
- data_object->PopObject<std::function<void(QProcess *)>>();
- SPDLOG_DEBUG("runner pop object done");
-
- auto *cmd_process = new QProcess();
- cmd_process->setProcessChannelMode(QProcess::MergedChannels);
-
- QObject::connect(cmd_process, &QProcess::started,
- []() -> void { SPDLOG_DEBUG("process started"); });
- QObject::connect(
- cmd_process, &QProcess::readyReadStandardOutput,
- [interact_func, cmd_process]() { interact_func(cmd_process); });
- QObject::connect(cmd_process, &QProcess::errorOccurred,
- [=](QProcess::ProcessError error) {
- SPDLOG_ERROR("error in executing command: {} error: {}",
- cmd, error);
- });
- QObject::connect(
- cmd_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
- [=](int, QProcess::ExitStatus status) {
- if (status == QProcess::NormalExit)
- SPDLOG_DEBUG(
- "proceess finished, succeed in executing command: {}, exit "
- "status: {}",
- cmd, status);
- else
- SPDLOG_ERROR(
- "proceess finished, error in executing command: {}, exit "
- "status: {}",
- cmd, status);
- });
-
- cmd_process->setProgram(QString::fromStdString(cmd));
- cmd_process->setProcessChannelMode(QProcess::SeparateChannels);
-
- QStringList q_arguments;
- for (const auto &argument : arguments)
- q_arguments.append(QString::fromStdString(argument));
- cmd_process->setArguments(q_arguments);
-
- SPDLOG_DEBUG("process start ready, cmd: {} {}", cmd,
- q_arguments.join(" ").toStdString());
-
- cmd_process->start();
- cmd_process->waitForFinished();
-
- std::string process_stdout =
- cmd_process->readAllStandardOutput().toStdString(),
- process_stderr =
- cmd_process->readAllStandardError().toStdString();
- int exit_code = cmd_process->exitCode();
-
- cmd_process->close();
- cmd_process->deleteLater();
-
- // transfer result
- SPDLOG_DEBUG("runner append object");
- data_object->AppendObject(std::move(process_stderr));
- data_object->AppendObject(std::move(process_stdout));
- data_object->AppendObject(std::move(exit_code));
- SPDLOG_DEBUG("runner append object done");
-
- return 0;
- };
+void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
+ for (auto &context : contexts) {
+ const auto &cmd = context.cmd;
+ GF_CORE_LOG_INFO("gpg concurrently called cmd {}", cmd);
+
+ Thread::Task *task = BuildTaskFromExecCtx(context);
+
+ if (context.task_runner != nullptr) {
+ context.task_runner->PostTask(task);
+ } else {
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
+ ->PostTask(task);
+ }
+ }
+}
- // data transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
- data_object->AppendObject(std::move(callback));
- data_object->AppendObject(std::move(interact_func));
- data_object->AppendObject(std::move(arguments));
- data_object->AppendObject(std::move(std::string{cmd}));
+void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
+ QEventLoop looper;
+ auto remaining_tasks = contexts.size();
+ Thread::TaskRunnerPtr target_task_runner = nullptr;
+
+ for (auto &context : contexts) {
+ const auto &cmd = context.cmd;
+ GF_CORE_LOG_DEBUG("gpg concurrently called cmd: {}", cmd);
+
+ Thread::Task *task = BuildTaskFromExecCtx(context);
+
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, [&]() {
+ --remaining_tasks;
+ GF_CORE_LOG_DEBUG("remaining tasks: {}", remaining_tasks);
+ if (remaining_tasks <= 0) {
+ GF_CORE_LOG_DEBUG("no remaining task, quit");
+ looper.quit();
+ }
+ });
+
+ if (context.task_runner != nullptr) {
+ target_task_runner = context.task_runner;
+ } else {
+ target_task_runner =
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
+ }
+
+ target_task_runner->PostTask(task);
+ }
+
+ GF_CORE_LOG_TRACE("blocking until concurrent gpg commands finish...");
+ // block until task finished
+ // this is to keep reference vaild until task finished
+ looper.exec();
+}
- auto *process_task = new GpgFrontend::Thread::Task(
- std::move(runner), fmt::format("ExecuteConcurrently/{}", cmd),
- data_object, std::move(result_callback), false);
+GpgCommandExecutor::ExecuteContext::ExecuteContext(
+ QString cmd, QStringList arguments, GpgCommandExecutorCallback callback,
+ Module::TaskRunnerPtr task_runner, GpgCommandExecutorInteractor int_func)
+ : cmd(std::move(cmd)),
+ arguments(std::move(arguments)),
+ cb_func(std::move(callback)),
+ int_func(std::move(int_func)),
+ task_runner(std::move(task_runner)) {}
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(process_task);
-}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgCommandExecutor.h b/src/core/function/gpg/GpgCommandExecutor.h
index da0e7a8b..ac52b295 100644
--- a/src/core/function/gpg/GpgCommandExecutor.h
+++ b/src/core/function/gpg/GpgCommandExecutor.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,39 +20,43 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
-#define GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
+#pragma once
-#ifndef WINDOWS
-#include <boost/process.hpp>
-#endif
-
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/thread/Task.h"
+#include "core/module/Module.h"
namespace GpgFrontend {
+using GpgCommandExecutorCallback = std::function<void(int, QString, QString)>;
+using GpgCommandExecutorInteractor = std::function<void(QProcess *)>;
+
/**
* @brief Extra commands related to GPG
*
*/
-class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
- : public SingletonFunctionObject<GpgCommandExecutor> {
+class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor {
public:
- /**
- * @brief Construct a new Gpg Command Executor object
- *
- * @param channel Corresponding context
- */
- explicit GpgCommandExecutor(
- int channel = SingletonFunctionObject::GetDefaultChannel());
+ struct GPGFRONTEND_CORE_EXPORT ExecuteContext {
+ QString cmd;
+ QStringList arguments;
+ GpgCommandExecutorCallback cb_func;
+ GpgCommandExecutorInteractor int_func;
+ Module::TaskRunnerPtr task_runner = nullptr;
+
+ ExecuteContext(
+ QString cmd, QStringList arguments,
+ GpgCommandExecutorCallback callback = [](int, const QString &,
+ const QString &) {},
+ Module::TaskRunnerPtr task_runner = nullptr,
+ GpgCommandExecutorInteractor int_func = [](QProcess *) {});
+ };
+
+ using ExecuteContexts = QList<ExecuteContext>;
/**
* @brief Excuting a command
@@ -60,22 +64,11 @@ class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
* @param arguments Command parameters
* @param interact_func Command answering function
*/
- void Execute(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback =
- [](int, std::string, std::string) {},
- std::function<void(QProcess *)> interact_func = [](QProcess *) {});
+ static void ExecuteSync(ExecuteContext);
- void ExecuteConcurrently(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func = [](QProcess *) {});
+ static void ExecuteConcurrentlyAsync(ExecuteContexts);
- private:
- GpgContext &ctx_ = GpgContext::GetInstance(
- SingletonFunctionObject::GetChannel()); ///< Corresponding context
+ static void ExecuteConcurrentlySync(ExecuteContexts);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
diff --git a/src/core/function/gpg/GpgContext.cpp b/src/core/function/gpg/GpgContext.cpp
new file mode 100644
index 00000000..6523386c
--- /dev/null
+++ b/src/core/function/gpg/GpgContext.cpp
@@ -0,0 +1,339 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "core/function/gpg/GpgContext.h"
+
+#include <gpg-error.h>
+#include <gpgme.h>
+
+#include <cassert>
+#include <mutex>
+
+#include "core/function/CoreSignalStation.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/model/GpgPassphraseContext.h"
+#include "core/module/ModuleManager.h"
+#include "core/utils/CacheUtils.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/MemoryUtils.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace GpgFrontend {
+
+class GpgContext::Impl {
+ public:
+ /**
+ * Constructor
+ * Set up gpgme-context, set paths to app-run path
+ */
+ Impl(GpgContext *parent, const GpgContextInitArgs &args)
+ : parent_(parent),
+ args_(args),
+ good_(default_ctx_initialize(args) && binary_ctx_initialize(args)) {}
+
+ ~Impl() {
+ if (ctx_ref_ != nullptr) {
+ gpgme_release(ctx_ref_);
+ }
+
+ if (binary_ctx_ref_ != nullptr) {
+ gpgme_release(binary_ctx_ref_);
+ }
+ }
+
+ [[nodiscard]] auto BinaryContext() const -> gpgme_ctx_t {
+ return binary_ctx_ref_;
+ }
+
+ [[nodiscard]] auto DefaultContext() const -> gpgme_ctx_t { return ctx_ref_; }
+
+ [[nodiscard]] auto Good() const -> bool { return good_; }
+
+ auto SetPassphraseCb(const gpgme_ctx_t &ctx, gpgme_passphrase_cb_t cb)
+ -> bool {
+ if (gpgme_get_pinentry_mode(ctx) != GPGME_PINENTRY_MODE_LOOPBACK) {
+ if (CheckGpgError(gpgme_set_pinentry_mode(
+ ctx, GPGME_PINENTRY_MODE_LOOPBACK)) != GPG_ERR_NO_ERROR) {
+ return false;
+ }
+ }
+ gpgme_set_passphrase_cb(ctx, cb, reinterpret_cast<void *>(parent_));
+ return true;
+ }
+
+ static auto TestPassphraseCb(void *opaque, const char *uid_hint,
+ const char *passphrase_info, int last_was_bad,
+ int fd) -> gpgme_error_t {
+ size_t res;
+ QString pass = "abcdefg\n";
+ auto passpahrase_size = pass.size();
+
+ size_t off = 0;
+
+ do {
+ res = gpgme_io_write(fd, &pass[off], passpahrase_size - off);
+ if (res > 0) off += res;
+ } while (res > 0 && off != passpahrase_size);
+
+ res += gpgme_io_write(fd, "\n", 1);
+ return res == passpahrase_size + 1
+ ? 0
+ : gpgme_error_from_errno(GPG_ERR_CANCELED);
+ }
+
+ static auto CustomPassphraseCb(void *hook, const char *uid_hint,
+ const char *passphrase_info, int prev_was_bad,
+ int fd) -> gpgme_error_t {
+ auto context_cache = GetCacheValue("PinentryContext");
+ bool ask_for_new = context_cache == "NEW_PASSPHRASE";
+ auto context =
+ QSharedPointer<GpgPassphraseContext>(new GpgPassphraseContext(
+ uid_hint != nullptr ? uid_hint : "",
+ passphrase_info != nullptr ? passphrase_info : "",
+ prev_was_bad != 0, ask_for_new));
+
+ GF_CORE_LOG_DEBUG(
+ "custom passphrase cb called, uid: {}, info: {}, last_was_bad: {}",
+ uid_hint == nullptr ? "<empty>" : QString{uid_hint},
+ passphrase_info == nullptr ? "<empty>" : QString{passphrase_info},
+ prev_was_bad);
+
+ QEventLoop looper;
+ QObject::connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalUserInputPassphraseCallback,
+ &looper, &QEventLoop::quit);
+
+ emit CoreSignalStation::GetInstance()->SignalNeedUserInputPassphrase(
+ context);
+ looper.exec();
+
+ ResetCacheValue("PinentryContext");
+ auto passphrase = context->GetPassphrase().toStdString();
+ auto passpahrase_size = passphrase.size();
+ GF_CORE_LOG_DEBUG("get passphrase from pinentry size: {}",
+ passpahrase_size);
+
+ size_t res = 0;
+ if (passpahrase_size > 0) {
+ size_t off = 0;
+ do {
+ res = gpgme_io_write(fd, &passphrase[off], passpahrase_size - off);
+ if (res > 0) off += res;
+ } while (res > 0 && off != passpahrase_size);
+ }
+
+ res += gpgme_io_write(fd, "\n", 1);
+
+ GF_CORE_LOG_DEBUG("custom passphrase cd is about to return, res: {}", res);
+ return res == passpahrase_size + 1
+ ? 0
+ : gpgme_error_from_errno(GPG_ERR_CANCELED);
+ }
+
+ static auto TestStatusCb(void *hook, const char *keyword, const char *args)
+ -> gpgme_error_t {
+ GF_CORE_LOG_DEBUG("keyword {}", keyword);
+ return GPG_ERR_NO_ERROR;
+ }
+
+ private:
+ GpgContext *parent_;
+ GpgContextInitArgs args_{}; ///<
+ gpgme_ctx_t ctx_ref_ = nullptr; ///<
+ gpgme_ctx_t binary_ctx_ref_ = nullptr; ///<
+ bool good_ = true;
+ std::mutex ctx_ref_lock_;
+ std::mutex binary_ctx_ref_lock_;
+
+ static auto set_ctx_key_list_mode(const gpgme_ctx_t &ctx) -> bool {
+ assert(ctx != nullptr);
+
+ const auto gpgme_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.version", QString{"0.0.0"});
+ GF_CORE_LOG_DEBUG("got gpgme version version from rt: {}", gpgme_version);
+
+ if (gpgme_get_keylist_mode(ctx) == 0) {
+ GF_CORE_LOG_ERROR(
+ "ctx is not a valid pointer, reported by gpgme_get_keylist_mode");
+ return false;
+ }
+
+ // set keylist mode
+ return CheckGpgError(gpgme_set_keylist_mode(
+ ctx, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_WITH_SECRET |
+ GPGME_KEYLIST_MODE_SIGS |
+ GPGME_KEYLIST_MODE_SIG_NOTATIONS |
+ GPGME_KEYLIST_MODE_WITH_TOFU)) == GPG_ERR_NO_ERROR;
+ }
+
+ static auto set_ctx_openpgp_engine_info(gpgme_ctx_t ctx) -> bool {
+ const auto app_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{});
+ const auto database_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.database_path", QString{});
+
+ GF_CORE_LOG_DEBUG("ctx set engine info, db path: {}, app path: {}",
+ database_path, app_path);
+
+ auto app_path_buffer = app_path.toUtf8();
+ auto database_path_buffer = database_path.toUtf8();
+
+ auto err = gpgme_ctx_set_engine_info(
+ ctx, gpgme_get_protocol(ctx),
+ app_path.isEmpty() ? nullptr : app_path_buffer,
+ database_path.isEmpty() ? nullptr : database_path_buffer);
+
+ assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
+
+ return true;
+ }
+
+ auto common_ctx_initialize(const gpgme_ctx_t &ctx,
+ const GpgContextInitArgs &args) -> bool {
+ assert(ctx != nullptr);
+
+ if (args.custom_gpgconf && !args.custom_gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_DEBUG("set custom gpgconf path: {}",
+ args.custom_gpgconf_path);
+ auto err =
+ gpgme_ctx_set_engine_info(ctx, GPGME_PROTOCOL_GPGCONF,
+ args.custom_gpgconf_path.toUtf8(), nullptr);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("set gpg context engine info error: {}",
+ DescribeGpgErrCode(err).second);
+ return false;
+ }
+ }
+
+ // set context offline mode
+ GF_CORE_LOG_DEBUG("gpg context offline mode: {}", args_.offline_mode);
+ gpgme_set_offline(ctx, args_.offline_mode ? 1 : 0);
+
+ // set option auto import missing key
+ // invalid at offline mode
+ GF_CORE_LOG_DEBUG("gpg context auto import missing key: {}",
+ args_.offline_mode);
+ if (!args.offline_mode && args.auto_import_missing_key) {
+ if (CheckGpgError(gpgme_set_ctx_flag(ctx, "auto-key-import", "1")) !=
+ GPG_ERR_NO_ERROR) {
+ return false;
+ }
+ }
+
+ if (!set_ctx_key_list_mode(ctx)) {
+ GF_CORE_LOG_DEBUG("set ctx key list mode failed");
+ return false;
+ }
+
+ // for unit test
+ if (args_.test_mode) {
+ if (!SetPassphraseCb(ctx, TestPassphraseCb)) {
+ GF_CORE_LOG_ERROR("set passphrase cb failed, test");
+ return false;
+ };
+ } else if (!args_.use_pinentry) {
+ if (!SetPassphraseCb(ctx, CustomPassphraseCb)) {
+ GF_CORE_LOG_DEBUG("set passphrase cb failed, custom");
+ return false;
+ }
+ }
+
+ // set custom gpg key db path
+ if (!args_.db_path.isEmpty()) {
+ Module::UpsertRTValue("core", "gpgme.ctx.database_path", args_.db_path);
+ }
+
+ if (!set_ctx_openpgp_engine_info(ctx)) {
+ GF_CORE_LOG_ERROR("set gpgme context openpgp engine info failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ auto binary_ctx_initialize(const GpgContextInitArgs &args) -> bool {
+ gpgme_ctx_t p_ctx;
+ if (auto err = CheckGpgError(gpgme_new(&p_ctx)); err != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("get new gpg context error: {}",
+ DescribeGpgErrCode(err).second);
+ return false;
+ }
+ assert(p_ctx != nullptr);
+ binary_ctx_ref_ = p_ctx;
+
+ if (!common_ctx_initialize(binary_ctx_ref_, args)) {
+ GF_CORE_LOG_ERROR("get new ctx failed, binary");
+ return false;
+ }
+
+ gpgme_set_armor(binary_ctx_ref_, 0);
+ return true;
+ }
+
+ auto default_ctx_initialize(const GpgContextInitArgs &args) -> bool {
+ gpgme_ctx_t p_ctx;
+ if (CheckGpgError(gpgme_new(&p_ctx)) != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("get new ctx failed, default");
+ return false;
+ }
+ assert(p_ctx != nullptr);
+ ctx_ref_ = p_ctx;
+
+ if (!common_ctx_initialize(ctx_ref_, args)) {
+ return false;
+ }
+
+ gpgme_set_armor(ctx_ref_, 1);
+ return true;
+ }
+};
+
+GpgContext::GpgContext(int channel)
+ : SingletonFunctionObject<GpgContext>(channel),
+ p_(SecureCreateUniqueObject<Impl>(this, GpgContextInitArgs{})) {}
+
+GpgContext::GpgContext(GpgContextInitArgs args, int channel)
+ : SingletonFunctionObject<GpgContext>(channel),
+ p_(SecureCreateUniqueObject<Impl>(this, args)) {}
+
+auto GpgContext::Good() const -> bool { return p_->Good(); }
+
+auto GpgContext::BinaryContext() -> gpgme_ctx_t { return p_->BinaryContext(); }
+
+auto GpgContext::DefaultContext() -> gpgme_ctx_t {
+ return p_->DefaultContext();
+}
+
+GpgContext::~GpgContext() = default;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgContext.h b/src/core/function/gpg/GpgContext.h
new file mode 100644
index 00000000..d473a341
--- /dev/null
+++ b/src/core/function/gpg/GpgContext.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/GpgFunctionObject.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+struct GpgContextInitArgs {
+ QString db_path = {}; ///<
+
+ bool test_mode = false; ///<
+ bool offline_mode = false; ///<
+ bool auto_import_missing_key = false; ///<
+
+ bool custom_gpgconf = false; ///<
+ QString custom_gpgconf_path; ///<
+
+ bool use_pinentry = false; ///<
+};
+
+/**
+ * @brief
+ *
+ */
+class GPGFRONTEND_CORE_EXPORT GpgContext
+ : public SingletonFunctionObject<GpgContext> {
+ public:
+ explicit GpgContext(int channel);
+
+ explicit GpgContext(GpgContextInitArgs args, int channel);
+
+ virtual ~GpgContext() override;
+
+ [[nodiscard]] auto Good() const -> bool;
+
+ auto BinaryContext() -> gpgme_ctx_t;
+
+ auto DefaultContext() -> gpgme_ctx_t;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp
index 30678cf0..94a08c76 100644
--- a/src/core/function/gpg/GpgFileOpera.cpp
+++ b/src/core/function/gpg/GpgFileOpera.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,235 +20,553 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgFileOpera.h"
-#include <memory>
-#include <string>
+#include "core/function/ArchiveFileOperator.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/model/GpgData.h"
+#include "core/model/GpgDecryptResult.h"
+#include "core/model/GpgEncryptResult.h"
+#include "core/model/GpgKey.h"
+#include "core/model/GpgSignResult.h"
+#include "core/model/GpgVerifyResult.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-#include "GpgBasicOperator.h"
-#include "GpgConstants.h"
-#include "function/FileOperator.h"
+namespace GpgFrontend {
-GpgFrontend::GpgFileOpera::GpgFileOpera(int channel)
+constexpr ssize_t kDataExchangerSize = 8192;
+
+GpgFileOpera::GpgFileOpera(int channel)
: SingletonFunctionObject<GpgFileOpera>(channel) {}
-GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile(
- KeyListPtr keys, const std::string& in_path, const std::string& out_path,
- GpgEncrResult& result, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer = nullptr;
-
- auto err = GpgBasicOperator::GetInstance(_channel).Encrypt(
- std::move(keys), in_buffer, out_buffer, result);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
-}
-
-GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile(
- const std::string& in_path, const std::string& out_path,
- GpgDecrResult& result) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer;
-
- auto err =
- GpgBasicOperator::GetInstance().Decrypt(in_buffer, out_buffer, result);
-
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
-}
-
-gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys,
- const std::string& in_path,
- const std::string& out_path,
- GpgSignResult& result,
- int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer;
-
- auto err = GpgBasicOperator::GetInstance(_channel).Sign(
- std::move(keys), in_buffer, out_buffer, GPGME_SIG_MODE_DETACH, result);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
-}
-
-gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile(
- const std::string& data_path, const std::string& sign_path,
- GpgVerifyResult& result, int _channel) {
-#ifdef WINDOWS
- auto data_path_std =
- std::filesystem::path(QString::fromStdString(data_path).toStdU16String());
- auto sign_path_std =
- std::filesystem::path(QString::fromStdString(sign_path).toStdU16String());
-#else
- auto data_path_std = std::filesystem::path(data_path);
- auto sign_path_std = std::filesystem::path(sign_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(data_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> sign_buffer = nullptr;
- if (!sign_path.empty()) {
- std::string sign_buffer_str;
- if (!FileOperator::ReadFileStd(sign_path_std, sign_buffer_str)) {
- throw std::runtime_error("read file error");
- }
- sign_buffer = std::make_unique<std::string>(sign_buffer_str);
- }
- auto err = GpgBasicOperator::GetInstance(_channel).Verify(
- in_buffer, sign_buffer, result);
- return err;
-}
-
-gpg_error_t GpgFrontend::GpgFileOpera::EncryptSignFile(
- KeyListPtr keys, KeyListPtr signer_keys, const std::string& in_path,
- const std::string& out_path, GpgEncrResult& encr_res,
- GpgSignResult& sign_res, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer = nullptr;
-
- auto err = GpgBasicOperator::GetInstance(_channel).EncryptSign(
- std::move(keys), std::move(signer_keys), in_buffer, out_buffer, encr_res,
- sign_res);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
-}
-
-gpg_error_t GpgFrontend::GpgFileOpera::DecryptVerifyFile(
- const std::string& in_path, const std::string& out_path,
- GpgDecrResult& decr_res, GpgVerifyResult& verify_res) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer = nullptr;
- auto err = GpgBasicOperator::GetInstance().DecryptVerify(
- in_buffer, out_buffer, decr_res, verify_res);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write file error");
- };
-
- return err;
-}
-unsigned int GpgFrontend::GpgFileOpera::EncryptFileSymmetric(
- const std::string& in_path, const std::string& out_path,
- GpgFrontend::GpgEncrResult& result, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer;
- auto err = GpgBasicOperator::GetInstance(_channel).EncryptSymmetric(
- in_buffer, out_buffer, result);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+void GpgFileOpera::EncryptFile(const KeyArgsList& keys, const QString& in_path,
+ bool ascii, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
}
+
+auto GpgFileOpera::EncryptFileSync(const KeyArgsList& keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
+
+ return err;
+ },
+ "gpgme_op_encrypt", "2.1.0");
+}
+
+void GpgFileOpera::EncryptDirectory(const KeyArgsList& keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ GF_CORE_LOG_DEBUG("encrypt directory start");
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
+
+ GF_CORE_LOG_DEBUG("encrypt directory finished, err: {}", err);
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 data exchanger operation, err: {}",
+ err);
+ });
+}
+
+void GpgFileOpera::DecryptFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))});
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
+}
+
+auto GpgFileOpera::DecryptFileSync(const QString& in_path,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))});
+
+ return err;
+ },
+ "gpgme_op_decrypt", "2.1.0");
+}
+
+void GpgFileOpera::DecryptArchive(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ ArchiveFileOperator::ExtractArchiveFromDataExchanger(
+ ex, out_path, [](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG(
+ "extract archive from data exchanger operation, err: {}", err);
+ });
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(ex);
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))});
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
+}
+
+void GpgFileOpera::SignFile(const KeyArgsList& keys, const QString& in_path,
+ bool ascii, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ // Set Singers of this opera
+ GpgBasicOperator::GetInstance().SetSigners(keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(
+ gpgme_op_sign(ctx, data_in, data_out, GPGME_SIG_MODE_DETACH));
+
+ data_object->Swap({
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_sign", "2.1.0");
+}
+
+auto GpgFileOpera::SignFileSync(const KeyArgsList& keys, const QString& in_path,
+ bool ascii, const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ // Set Singers of this opera
+ GpgBasicOperator::GetInstance().SetSigners(keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(
+ gpgme_op_sign(ctx, data_in, data_out, GPGME_SIG_MODE_DETACH));
+
+ data_object->Swap({
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ "gpgme_op_sign", "2.1.0");
+}
+
+void GpgFileOpera::VerifyFile(const QString& data_path,
+ const QString& sign_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(data_path, true);
+ GpgData data_out;
+ if (!sign_path.isEmpty()) {
+ GpgData sig_data(sign_path, true);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_verify", "2.1.0");
+}
+
+auto GpgFileOpera::VerifyFileSync(const QString& data_path,
+ const QString& sign_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(data_path, true);
+ GpgData data_out;
+ if (!sign_path.isEmpty()) {
+ GpgData sig_data(sign_path, true);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ "gpgme_op_verify", "2.1.0");
+}
+
+void GpgFileOpera::EncryptSignFile(const KeyArgsList& keys,
+ const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
+}
+
+auto GpgFileOpera::EncryptSignFileSync(const KeyArgsList& keys,
+ const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ "gpgme_op_encrypt_sign", "2.1.0");
+}
+
+void GpgFileOpera::EncryptSignDirectory(const KeyArgsList& keys,
+ const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii);
+
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ });
+}
+
+void GpgFileOpera::DecryptVerifyFile(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap({
+ GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
+}
+
+auto GpgFileOpera::DecryptVerifyFileSync(const QString& in_path,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap({
+ GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ "gpgme_op_decrypt_verify", "2.1.0");
+}
+
+void GpgFileOpera::DecryptVerifyArchive(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ ArchiveFileOperator::ExtractArchiveFromDataExchanger(
+ ex, out_path, [](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("extract archive from ex operation, err: {}", err);
+ });
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(ex);
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap({
+ GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
+}
+
+void GpgFileOpera::EncryptFileSymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
+}
+
+auto GpgFileOpera::EncryptFileSymmetricSync(const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ "gpgme_op_encrypt_symmetric", "2.1.0");
+}
+
+void GpgFileOpera::EncryptDerectorySymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ });
+}
+
+auto GpgFileOpera::EncryptDerectorySymmetricSync(const QString& in_path,
+ bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ });
+
+ return RunGpgOperaSync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ "gpgme_op_encrypt_symmetric", "2.1.0");
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgFileOpera.h b/src/core/function/gpg/GpgFileOpera.h
index dc81bc53..d7c2d44c 100644
--- a/src/core/function/gpg/GpgFileOpera.h
+++ b/src/core/function/gpg/GpgFileOpera.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,59 +20,123 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGFILEOPERA_H
-#define GPGFRONTEND_GPGFILEOPERA_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
- * @brief Executive files related to the basic operations that are provided by
- * GpgBasicOperator
+ * @brief Executive files related to the basic operations of GPG
+ *
* @class class: GpgBasicOperator
*/
class GPGFRONTEND_CORE_EXPORT GpgFileOpera
: public SingletonFunctionObject<GpgFileOpera> {
public:
+ /**
+ * @brief Construct a new Gpg File Opera object
+ *
+ * @param channel
+ */
explicit GpgFileOpera(
int channel = SingletonFunctionObject::GetDefaultChannel());
/**
- * @brief Encrypted file
+ * @brief Encrypted file with public key
*
* @param keys Used public key
* @param in_path The path where the enter file is located
* @param out_path The path where the output file is located
* @param result Encrypted results
- * @param _channel Channel in context
+ * @param channel Channel in context
* @return unsigned int error code
*/
- static unsigned int EncryptFile(KeyListPtr keys, const std::string& in_path,
- const std::string& out_path,
- GpgEncrResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void EncryptFile(const KeyArgsList& keys, const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @return std::tuple<GpgError, DataObjectPtr>
+ */
+ auto EncryptFileSync(const KeyArgsList& keys, const QString& in_path,
+ bool ascii, const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptDirectory(const KeyArgsList& keys, const QString& in_path,
+ bool ascii, const QString& out_path,
+ const GpgOperationCallback& cb);
/**
- * @brief 运用对称加密算法加密文件
+ * @brief Encrypted file symmetrically (with password)
*
* @param in_path
* @param out_path
* @param result
- * @param _channel
+ * @param channel
* @return unsigned int
*/
- static unsigned int EncryptFileSymmetric(
- const std::string& in_path, const std::string& out_path,
- GpgEncrResult& result, int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void EncryptFileSymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ auto EncryptFileSymmetricSync(const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptDerectorySymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ */
+ auto EncryptDerectorySymmetricSync(const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief
@@ -82,37 +146,77 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param result
* @return GpgError
*/
- static GpgError DecryptFile(const std::string& in_path,
- const std::string& out_path,
- GpgDecrResult& result);
+ void DecryptFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
*
+ * @param in_path
+ * @param out_path
+ * @param cb
+ * @return std::tuple<GpgError, DataObjectPtr>
+ */
+ auto DecryptFileSync(const QString& in_path, const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param out_path
+ * @param cb
+ */
+ void DecryptArchive(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief Sign file with private key
+ *
* @param keys
* @param in_path
* @param out_path
* @param result
- * @param _channel
+ * @param channel
+ * @return GpgError
+ */
+ void SignFile(const KeyArgsList& keys, const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @return std::tuple<GpgError, DataObjectPtr>
+ */
+ auto SignFileSync(const KeyArgsList& keys, const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief Verify file with public key
+ *
+ * @param data_path The path where the enter file is located
+ * @param sign_path The path where the signature file is located
+ * @param result Verify results
+ * @param channel Channel in context
* @return GpgError
*/
- static GpgError SignFile(KeyListPtr keys, const std::string& in_path,
- const std::string& out_path, GpgSignResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void VerifyFile(const QString& data_path, const QString& sign_path,
+ const GpgOperationCallback& cb);
/**
* @brief
*
* @param data_path
* @param sign_path
- * @param result
- * @param _channel
- * @return GpgError
+ * @return std::tuple<GpgError, DataObjectPtr>
*/
- static GpgError VerifyFile(const std::string& data_path,
- const std::string& sign_path,
- GpgVerifyResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ auto VerifyFileSync(const QString& data_path, const QString& sign_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief
@@ -120,18 +224,44 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param keys
* @param signer_keys
* @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptSignFile(const KeyArgsList& keys, const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param signer_keys
+ * @param in_path
+ * @param ascii
* @param out_path
- * @param encr_res
- * @param sign_res
- * @param _channel
- * @return GpgError
*/
- static GpgError EncryptSignFile(KeyListPtr keys, KeyListPtr signer_keys,
- const std::string& in_path,
- const std::string& out_path,
- GpgEncrResult& encr_res,
- GpgSignResult& sign_res,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ auto EncryptSignFileSync(const KeyArgsList& keys,
+ const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param signer_keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptSignDirectory(const KeyArgsList& keys,
+ const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
@@ -142,12 +272,31 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param verify_res
* @return GpgError
*/
- static GpgError DecryptVerifyFile(const std::string& in_path,
- const std::string& out_path,
- GpgDecrResult& decr_res,
- GpgVerifyResult& verify_res);
+ void DecryptVerifyFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param out_path
+ */
+ auto DecryptVerifyFileSync(const QString& in_path, const QString& out_path)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param out_path
+ * @param cb
+ */
+ void DecryptVerifyArchive(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ private:
+ GpgContext& ctx_ = GpgContext::GetInstance(
+ SingletonFunctionObject::GetChannel()); ///< Corresponding context
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGFILEOPERA_H
diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp
index ee6d2b09..4a35d3cd 100644
--- a/src/core/function/gpg/GpgKeyGetter.cpp
+++ b/src/core/function/gpg/GpgKeyGetter.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -32,136 +32,220 @@
#include <mutex>
#include <shared_mutex>
-#include <utility>
-#include "GpgConstants.h"
-#include "model/GpgKey.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgKeyGetter::GpgKeyGetter(int channel)
- : SingletonFunctionObject<GpgKeyGetter>(channel) {
- SPDLOG_DEBUG("called channel: {}", channel);
-}
+namespace GpgFrontend {
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr,
- bool use_cache) {
- // find in cache first
- if (use_cache) {
- auto key = get_key_in_cache(fpr);
- if (key.IsGood()) return key;
+class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
+ public:
+ explicit Impl(int channel)
+ : SingletonFunctionObject<GpgKeyGetter::Impl>(channel) {
+ GF_CORE_LOG_DEBUG("called channel: {}", channel);
}
- gpgme_key_t _p_key = nullptr;
- gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 1);
- if (_p_key == nullptr) {
- SPDLOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
- return GetPubkey(fpr);
- } else {
- return GpgKey(std::move(_p_key));
- }
-}
+ auto GetKey(const QString& fpr, bool use_cache) -> GpgKey {
+ // find in cache first
+ if (use_cache) {
+ auto key = get_key_in_cache(fpr);
+ if (key.IsGood()) return key;
+ }
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey(const std::string& fpr,
- bool use_cache) {
- // find in cache first
- if (use_cache) {
- auto key = get_key_in_cache(fpr);
- if (key.IsGood()) return key;
+ gpgme_key_t p_key = nullptr;
+ gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 1);
+ if (p_key == nullptr) {
+ GF_CORE_LOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
+ return GetPubkey(fpr, true);
+ }
+ return GpgKey(std::move(p_key));
}
- gpgme_key_t _p_key = nullptr;
- gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 0);
- if (_p_key == nullptr) SPDLOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
- return GpgKey(std::move(_p_key));
-}
+ auto GetPubkey(const QString& fpr, bool use_cache) -> GpgKey {
+ // find in cache first
+ if (use_cache) {
+ auto key = get_key_in_cache(fpr);
+ if (key.IsGood()) return key;
+ }
-GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() {
- // get the lock
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ gpgme_key_t p_key = nullptr;
+ gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 0);
+ if (p_key == nullptr)
+ GF_CORE_LOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
+ return GpgKey(std::move(p_key));
+ }
- auto keys_list = std::make_unique<GpgKeyLinkList>();
+ auto FetchKey() -> KeyLinkListPtr {
+ if (keys_search_cache_.empty()) {
+ FlushKeyCache();
+ }
- for (const auto& [key, value] : keys_cache_) {
- keys_list->push_back(value.Copy());
+ auto keys_list = std::make_unique<GpgKeyLinkList>();
+ {
+ // get the lock
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ for (const auto& key : keys_cache_) {
+ keys_list->push_back(key);
+ }
+ }
+ return keys_list;
}
- return keys_list;
-}
-void GpgFrontend::GpgKeyGetter::FlushKeyCache() {
- SPDLOG_DEBUG("called channel id: {}", GetChannel());
+ auto FlushKeyCache() -> bool {
+ GF_CORE_LOG_DEBUG("flush key channel called, channel: {}", GetChannel());
- // clear the keys cache
- keys_cache_.clear();
+ // clear the keys cache
+ keys_cache_.clear();
+ keys_search_cache_.clear();
- // init
- GpgError err = gpgme_op_keylist_start(ctx_, nullptr, 0);
+ // init
+ GpgError err = gpgme_op_keylist_start(ctx_.DefaultContext(), nullptr, 0);
- // for debug
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+ // for debug
+ assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
- // return when error
- if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return;
+ // return when error
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false;
- {
- // get the lock
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
- gpgme_key_t key;
- while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) {
- auto gpg_key = GpgKey(std::move(key));
-
- // detect if the key is in a smartcard
- // if so, try to get full information using gpgme_get_key()
- // this maybe a bug in gpgme
- if (gpg_key.IsHasCardKey()) {
- gpg_key = GetKey(gpg_key.GetId(), false);
+ {
+ // get the lock
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ gpgme_key_t key;
+ while ((err = gpgme_op_keylist_next(ctx_.DefaultContext(), &key)) ==
+ GPG_ERR_NO_ERROR) {
+ auto gpg_key = GpgKey(std::move(key));
+
+ // detect if the key is in a smartcard
+ // if so, try to get full information using gpgme_get_key()
+ // this maybe a bug in gpgme
+ if (gpg_key.IsHasCardKey()) {
+ gpg_key = GetKey(gpg_key.GetId(), false);
+ }
+
+ keys_cache_.push_back(gpg_key);
+ keys_search_cache_.insert(gpg_key.GetId(), gpg_key);
+ keys_search_cache_.insert(gpg_key.GetFingerprint(), gpg_key);
}
+ }
+
+ GF_CORE_LOG_DEBUG("flush key channel cache address: {} object address: {}",
+ static_cast<void*>(&keys_search_cache_),
+ static_cast<void*>(this));
+
+ // for debug
+ assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_EOF);
+
+ err = gpgme_op_keylist_end(ctx_.DefaultContext());
+ assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
- keys_cache_.insert({gpg_key.GetId(), std::move(gpg_key)});
+ GF_CORE_LOG_DEBUG("flush key channel done, channel: {}", GetChannel());
+ return true;
+ }
+
+ auto GetKeys(const KeyIdArgsListPtr& ids) -> KeyListPtr {
+ auto keys = std::make_unique<KeyArgsList>();
+ for (const auto& key_id : *ids) keys->emplace_back(GetKey(key_id, true));
+ return keys;
+ }
+
+ auto GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr {
+ // get the lock
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ auto keys_copy = std::make_unique<GpgKeyLinkList>();
+ for (const auto& key : *keys) keys_copy->emplace_back(key);
+ return keys_copy;
+ }
+
+ auto GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr {
+ // get the lock
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ auto keys_copy = std::make_unique<KeyArgsList>();
+ for (const auto& key : *keys) keys_copy->emplace_back(key);
+ return keys_copy;
+ }
+
+ private:
+ /**
+ * @brief Get the gpgme context object
+ *
+ */
+ GpgContext& ctx_ =
+ GpgContext::GetInstance(SingletonFunctionObject::GetChannel());
+
+ /**
+ * @brief shared mutex for the keys cache
+ *
+ */
+ mutable std::mutex ctx_mutex_;
+
+ /**
+ * @brief cache the keys with key id
+ *
+ */
+ QMap<QString, GpgKey> keys_search_cache_;
+
+ /**
+ * @brief
+ *
+ */
+ QList<GpgKey> keys_cache_;
+
+ /**
+ * @brief shared mutex for the keys cache
+ *
+ */
+ mutable std::mutex keys_cache_mutex_;
+
+ /**
+ * @brief Get the Key object
+ *
+ * @param id
+ * @return GpgKey
+ */
+ auto get_key_in_cache(const QString& key_id) -> GpgKey {
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ if (keys_search_cache_.find(key_id) != keys_search_cache_.end()) {
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ // return a copy of the key in cache
+ return keys_search_cache_[key_id];
}
+
+ // return a bad key
+ return {};
}
+};
- SPDLOG_DEBUG("cache address: {} object address: {}",
- static_cast<void*>(&keys_cache_), static_cast<void*>(this));
+GpgKeyGetter::GpgKeyGetter(int channel)
+ : SingletonFunctionObject<GpgKeyGetter>(channel),
+ p_(SecureCreateUniqueObject<Impl>(channel)) {
+ GF_CORE_LOG_DEBUG("called channel: {}", channel);
+}
- // for debug
- assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF);
+GpgKeyGetter::~GpgKeyGetter() = default;
- err = gpgme_op_keylist_end(ctx_);
- assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
+auto GpgKeyGetter::GetKey(const QString& key_id, bool use_cache) -> GpgKey {
+ return p_->GetKey(key_id, use_cache);
}
-GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys(
- const KeyIdArgsListPtr& ids) {
- auto keys = std::make_unique<KeyArgsList>();
- for (const auto& id : *ids) keys->emplace_back(GetKey(id));
- return keys;
+auto GpgKeyGetter::GetPubkey(const QString& key_id, bool use_cache) -> GpgKey {
+ return p_->GetPubkey(key_id, use_cache);
}
-GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
- const GpgFrontend::KeyLinkListPtr& keys) {
- // get the lock
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- auto keys_copy = std::make_unique<GpgKeyLinkList>();
- for (const auto& key : *keys) keys_copy->emplace_back(key.Copy());
- return keys_copy;
+auto GpgKeyGetter::FlushKeyCache() -> bool { return p_->FlushKeyCache(); }
+
+auto GpgKeyGetter::GetKeys(const KeyIdArgsListPtr& ids) -> KeyListPtr {
+ return p_->GetKeys(ids);
}
-GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
- const GpgFrontend::KeyListPtr& keys) {
- // get the lock
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- auto keys_copy = std::make_unique<KeyArgsList>();
- for (const auto& key : *keys) keys_copy->emplace_back(key.Copy());
- return keys_copy;
+auto GpgKeyGetter::GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr {
+ return p_->GetKeysCopy(keys);
}
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::get_key_in_cache(
- const std::string& id) {
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
- if (keys_cache_.find(id) != keys_cache_.end()) {
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- // return a copy of the key in cache
- return keys_cache_[id].Copy();
- }
- // return a bad key
- return GpgKey();
+auto GpgKeyGetter::GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr {
+ return p_->GetKeysCopy(keys);
}
+
+auto GpgKeyGetter::FetchKey() -> KeyLinkListPtr { return p_->FetchKey(); }
+
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyGetter.h b/src/core/function/gpg/GpgKeyGetter.h
index c96dbea7..91138623 100644
--- a/src/core/function/gpg/GpgKeyGetter.h
+++ b/src/core/function/gpg/GpgKeyGetter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
-#define GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+#pragma once
-#include <mutex>
-#include <vector>
-
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -50,8 +45,13 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
*
* @param channel
*/
- explicit GpgKeyGetter(
- int channel = SingletonFunctionObject::GetDefaultChannel());
+ explicit GpgKeyGetter(int channel = kGpgFrontendDefaultChannel);
+
+ /**
+ * @brief Destroy the Gpg Key Getter object
+ *
+ */
+ ~GpgKeyGetter();
/**
* @brief Get the Key object
@@ -59,7 +59,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param fpr
* @return GpgKey
*/
- GpgKey GetKey(const std::string& id, bool use_cache = true);
+ auto GetKey(const QString& key_id, bool use_cache = true) -> GpgKey;
/**
* @brief Get the Keys object
@@ -67,7 +67,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param ids
* @return KeyListPtr
*/
- KeyListPtr GetKeys(const KeyIdArgsListPtr& ids);
+ auto GetKeys(const KeyIdArgsListPtr& key_ids) -> KeyListPtr;
/**
* @brief Get the Pubkey object
@@ -75,20 +75,20 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param fpr
* @return GpgKey
*/
- GpgKey GetPubkey(const std::string& id, bool use_cache = true);
+ auto GetPubkey(const QString& key_id, bool use_cache = true) -> GpgKey;
/**
* @brief Get all the keys by receiving a linked list
*
* @return KeyLinkListPtr
*/
- KeyLinkListPtr FetchKey();
+ auto FetchKey() -> KeyLinkListPtr;
/**
* @brief flush the keys in the cache
*
*/
- void FlushKeyCache();
+ auto FlushKeyCache() -> bool;
/**
* @brief Get the Keys Copy object
@@ -96,7 +96,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param keys
* @return KeyListPtr
*/
- KeyListPtr GetKeysCopy(const KeyListPtr& keys);
+ auto GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr;
/**
* @brief Get the Keys Copy object
@@ -104,42 +104,10 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param keys
* @return KeyLinkListPtr
*/
- KeyLinkListPtr GetKeysCopy(const KeyLinkListPtr& keys);
+ auto GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr;
private:
- /**
- * @brief Get the gpgme context object
- *
- */
- GpgContext& ctx_ =
- GpgContext::GetInstance(SingletonFunctionObject::GetChannel());
-
- /**
- * @brief shared mutex for the keys cache
- *
- */
- mutable std::mutex ctx_mutex_;
-
- /**
- * @brief cache the keys with key id
- *
- */
- std::map<std::string, GpgKey> keys_cache_;
-
- /**
- * @brief shared mutex for the keys cache
- *
- */
- mutable std::mutex keys_cache_mutex_;
-
- /**
- * @brief Get the Key object
- *
- * @param id
- * @return GpgKey
- */
- GpgKey get_key_in_cache(const std::string& id);
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
diff --git a/src/core/function/gpg/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp
index 01349c94..ef8cb112 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.cpp
+++ b/src/core/function/gpg/GpgKeyImportExporter.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,79 +28,75 @@
#include "GpgKeyImportExporter.h"
-#include <memory>
+#include "core/GpgModel.h"
+#include "core/model/GpgImportInformation.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-#include "GpgConstants.h"
-#include "GpgKeyGetter.h"
+namespace GpgFrontend {
-GpgFrontend::GpgKeyImportExporter::GpgKeyImportExporter(int channel)
- : SingletonFunctionObject<GpgKeyImportExporter>(channel) {}
+GpgKeyImportExporter::GpgKeyImportExporter(int channel)
+ : SingletonFunctionObject<GpgKeyImportExporter>(channel),
+ ctx_(GpgContext::GetInstance(SingletonFunctionObject::GetChannel())) {}
/**
* Import key pair
* @param inBuffer input byte array
* @return Import information
*/
-GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExporter::ImportKey(
- StdBypeArrayPtr in_buffer) {
- if (in_buffer->empty()) return {};
+auto GpgKeyImportExporter::ImportKey(const GFBuffer& in_buffer)
+ -> std::shared_ptr<GpgImportInformation> {
+ if (in_buffer.Empty()) return {};
- GpgData data_in(in_buffer->data(), in_buffer->size());
- auto err = check_gpg_error(gpgme_op_import(ctx_, data_in));
+ GpgData data_in(in_buffer);
+ auto err = CheckGpgError(gpgme_op_import(ctx_.DefaultContext(), data_in));
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
gpgme_import_result_t result;
- result = gpgme_op_import_result(ctx_);
+ result = gpgme_op_import_result(ctx_.DefaultContext());
gpgme_import_status_t status = result->imports;
- auto import_info = std::make_unique<GpgImportInformation>(result);
+ auto import_info = SecureCreateSharedObject<GpgImportInformation>(result);
while (status != nullptr) {
- GpgImportedKey key;
+ GpgImportInformation::GpgImportedKey key;
key.import_status = static_cast<int>(status->status);
key.fpr = status->fpr;
- import_info->importedKeys.emplace_back(key);
+ import_info->imported_keys.emplace_back(key);
status = status->next;
}
-
- return *import_info;
+ return import_info;
}
/**
- * Export Key
- * @param uid_list key ids
- * @param out_buffer output byte array
+ * Export keys
+ * @param keys keys used
+ * @param outBuffer output byte array
* @return if success
*/
-bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
- ByteArrayPtr& out_buffer,
- bool secret) const {
- if (uid_list->empty()) return false;
+auto GpgKeyImportExporter::ExportKey(const GpgKey& key, bool secret, bool ascii,
+ bool shortest, bool ssh_mode) const
+ -> std::tuple<GpgError, GFBuffer> {
+ if (!key.IsGood()) return {GPG_ERR_CANCELED, {}};
- int _mode = 0;
- if (secret) _mode |= GPGME_EXPORT_MODE_SECRET;
+ int mode = 0;
+ if (secret) mode |= GPGME_EXPORT_MODE_SECRET;
+ if (shortest) mode |= GPGME_EXPORT_MODE_MINIMAL;
+ if (ssh_mode) mode |= GPGME_EXPORT_MODE_SSH;
- auto keys = GpgKeyGetter::GetInstance().GetKeys(uid_list);
- auto keys_array = new gpgme_key_t[keys->size() + 1];
+ std::vector<gpgme_key_t> keys_array;
- int index = 0;
- for (const auto& key : *keys) {
- keys_array[index++] = gpgme_key_t(key);
- }
- keys_array[index] = nullptr;
+ // Last entry data_in array has to be nullptr
+ keys_array.emplace_back(key);
+ keys_array.emplace_back(nullptr);
GpgData data_out;
- auto err = gpgme_op_export_keys(ctx_, keys_array, _mode, data_out);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false;
-
- delete[] keys_array;
-
- SPDLOG_DEBUG("export keys read_bytes: {}",
- gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
-
- swap(temp_out_buffer, out_buffer);
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
- return true;
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting a key finished, ascii: {}, read_bytes: {}", ascii,
+ gpgme_data_seek(data_out, 0, SEEK_END));
+ return {err, data_out.Read2GFBuffer()};
}
/**
@@ -109,114 +105,87 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
* @param outBuffer output byte array
* @return if success
*/
-bool GpgFrontend::GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys,
- ByteArrayPtr& out_buffer,
- bool secret) const {
- KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>();
- for (const auto& key : keys) key_ids->push_back(key.GetId());
- return ExportKeys(key_ids, out_buffer, secret);
+void GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, bool secret,
+ bool ascii, bool shortest, bool ssh_mode,
+ const GpgOperationCallback& cb) const {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
+
+ int mode = 0;
+ if (secret) mode |= GPGME_EXPORT_MODE_SECRET;
+ if (shortest) mode |= GPGME_EXPORT_MODE_MINIMAL;
+ if (ssh_mode) mode |= GPGME_EXPORT_MODE_SSH;
+
+ std::vector<gpgme_key_t> keys_array(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ keys_array.emplace_back(nullptr);
+
+ GpgData data_out;
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting keys finished, ascii: {}, read_bytes: {}",
+ ascii, gpgme_data_seek(data_out, 0, SEEK_END));
+
+ data_object->Swap({data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_export_keys", "2.1.0");
}
/**
- * Export all the keys both private and public keys
- * @param uid_list key ids
- * @param out_buffer output byte array
- * @return if success
- */
-bool GpgFrontend::GpgKeyImportExporter::ExportAllKeys(
- KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer, bool secret) const {
- bool result = true;
- result = ExportKeys(uid_list, out_buffer, false) & result;
-
- ByteArrayPtr temp_buffer;
- if (secret) {
- result = ExportKeys(uid_list, temp_buffer, true) & result;
- }
- out_buffer->append(*temp_buffer);
- return result;
-}
-
-/**
- * Export the secret key of a key pair(including subkeys)
- * @param key target key pair
+ * Export keys
+ * @param keys keys used
* @param outBuffer output byte array
- * @return if successful
+ * @return if success
*/
-bool GpgFrontend::GpgKeyImportExporter::ExportSecretKey(
- const GpgKey& key, ByteArrayPtr& out_buffer) const {
- SPDLOG_DEBUG("export secret key: {}", key.GetId().c_str());
-
- gpgme_key_t target_key[2] = {gpgme_key_t(key), nullptr};
-
- GpgData data_out;
- // export private key to outBuffer
- gpgme_error_t err = gpgme_op_export_keys(ctx_, target_key,
- GPGME_EXPORT_MODE_SECRET, data_out);
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
-
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportKey(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(), 0, data_out);
-
- SPDLOG_DEBUG("export keys read_bytes: {}",
- gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportKeyOpenSSH(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(), GPGME_EXPORT_MODE_SSH,
- data_out);
-
- SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportSecretKeyShortest(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(),
- GPGME_EXPORT_MODE_MINIMAL, data_out);
-
- SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+void GpgKeyImportExporter::ExportAllKeys(const KeyArgsList& keys, bool secret,
+ bool ascii,
+ const GpgOperationCallback& cb) const {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
+
+ int mode = 0;
+ std::vector<gpgme_key_t> keys_array(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ keys_array.emplace_back(nullptr);
+
+ GpgData data_out;
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting keys finished, ascii: {}, read_bytes: {}",
+ ascii, gpgme_data_seek(data_out, 0, SEEK_END));
+ auto buffer = data_out.Read2GFBuffer();
+
+ if (secret) {
+ int mode = 0;
+ mode |= GPGME_EXPORT_MODE_SECRET;
+
+ GpgData data_out_secret;
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode,
+ data_out_secret);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting secret keys finished, "
+ "ascii: {}, read_bytes: {}",
+ ascii, gpgme_data_seek(data_out_secret, 0, SEEK_END));
+ buffer.Append(data_out_secret.Read2GFBuffer());
+ }
+
+ data_object->Swap({buffer});
+ return err;
+ },
+ cb, "gpgme_op_export_keys", "2.1.0");
}
-GpgFrontend::GpgImportInformation::GpgImportInformation() = default;
-
-GpgFrontend::GpgImportInformation::GpgImportInformation(
- gpgme_import_result_t result) {
- if (result->unchanged) unchanged = result->unchanged;
- if (result->considered) considered = result->considered;
- if (result->no_user_id) no_user_id = result->no_user_id;
- if (result->imported) imported = result->imported;
- if (result->imported_rsa) imported_rsa = result->imported_rsa;
- if (result->unchanged) unchanged = result->unchanged;
- if (result->new_user_ids) new_user_ids = result->new_user_ids;
- if (result->new_sub_keys) new_sub_keys = result->new_sub_keys;
- if (result->new_signatures) new_signatures = result->new_signatures;
- if (result->new_revocations) new_revocations = result->new_revocations;
- if (result->secret_read) secret_read = result->secret_read;
- if (result->secret_imported) secret_imported = result->secret_imported;
- if (result->secret_unchanged) secret_unchanged = result->secret_unchanged;
- if (result->not_imported) not_imported = result->not_imported;
-}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyImportExporter.h b/src/core/function/gpg/GpgKeyImportExporter.h
index 6e90f436..d0724f7b 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.h
+++ b/src/core/function/gpg/GpgKeyImportExporter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,67 +20,22 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef _GPGKEYIMPORTEXPORTOR_H
-#define _GPGKEYIMPORTEXPORTOR_H
+#pragma once
-#include <string>
-
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/model/GFBuffer.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
-/**
- * @brief
- *
- */
-class GpgImportedKey {
- public:
- std::string fpr; ///<
- int import_status; ///<
-};
-
-typedef std::list<GpgImportedKey> GpgImportedKeyList; ///<
-
-/**
- * @brief
- *
- */
-class GPGFRONTEND_CORE_EXPORT GpgImportInformation {
- public:
- GpgImportInformation();
-
- /**
- * @brief Construct a new Gpg Import Information object
- *
- * @param result
- */
- explicit GpgImportInformation(gpgme_import_result_t result);
-
- int considered = 0; ///<
- int no_user_id = 0; ///<
- int imported = 0; ///<
- int imported_rsa = 0; ///<
- int unchanged = 0; ///<
- int new_user_ids = 0; ///<
- int new_sub_keys = 0; ///<
- int new_signatures = 0; ///<
- int new_revocations = 0; ///<
- int secret_read = 0; ///<
- int secret_imported = 0; ///<
- int secret_unchanged = 0; ///<
- int not_imported = 0; ///<
-
- GpgImportedKeyList importedKeys; ///<
-};
+class GpgImportInformation;
/**
* @brief
@@ -103,19 +58,19 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter
* @param inBuffer
* @return GpgImportInformation
*/
- GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer);
+ auto ImportKey(const GFBuffer&) -> std::shared_ptr<GpgImportInformation>;
/**
* @brief
*
- * @param uid_list
- * @param out_buffer
+ * @param key
* @param secret
- * @return true
- * @return false
+ * @param ascii
+ * @return std::tuple<GpgError, GFBuffer>
*/
- bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer,
- bool secret = false) const;
+ [[nodiscard]] auto ExportKey(const GpgKey& key, bool secret, bool ascii,
+ bool shortest, bool ssh_mode = false) const
+ -> std::tuple<GpgError, GFBuffer>;
/**
* @brief
@@ -126,67 +81,23 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter
* @return true
* @return false
*/
- bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer,
- bool secret = false) const;
+ void ExportKeys(const KeyArgsList& keys, bool secret, bool ascii,
+ bool shortest, bool ssh_mode,
+ const GpgOperationCallback& cb) const;
/**
* @brief
*
* @param keys
- * @param outBuffer
* @param secret
- * @return true
- * @return false
- */
- bool ExportAllKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer,
- bool secret) const;
-
- /**
- * @brief
- *
- * @param key
- * @param out_buffer
- * @return true
- * @return false
- */
- bool ExportKey(const GpgKey& key, ByteArrayPtr& out_buffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param out_buffer
- * @return true
- * @return false
+ * @param ascii
+ * @param cb
*/
- bool ExportKeyOpenSSH(const GpgKey& key, ByteArrayPtr& out_buffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param outBuffer
- * @return true
- * @return false
- */
- bool ExportSecretKey(const GpgKey& key, ByteArrayPtr& outBuffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param outBuffer
- * @return true
- * @return false
- */
- bool ExportSecretKeyShortest(const GpgKey& key,
- ByteArrayPtr& outBuffer) const;
+ void ExportAllKeys(const KeyArgsList& keys, bool secret, bool ascii,
+ const GpgOperationCallback& cb) const;
private:
- GpgContext& ctx_ =
- GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
+ GpgContext& ctx_;
};
} // namespace GpgFrontend
-
-#endif // _GPGKEYIMPORTEXPORTOR_H \ No newline at end of file
diff --git a/src/core/function/gpg/GpgKeyManager.cpp b/src/core/function/gpg/GpgKeyManager.cpp
index e556eec6..b5efe141 100644
--- a/src/core/function/gpg/GpgKeyManager.cpp
+++ b/src/core/function/gpg/GpgKeyManager.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,150 +28,146 @@
#include "GpgKeyManager.h"
-#include <boost/algorithm/string.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-#include <memory>
-#include <string>
-
-#include "GpgBasicOperator.h"
-#include "GpgKeyGetter.h"
-#include "spdlog/spdlog.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/utils/GpgUtils.h"
GpgFrontend::GpgKeyManager::GpgKeyManager(int channel)
: SingletonFunctionObject<GpgKeyManager>(channel) {}
-bool GpgFrontend::GpgKeyManager::SignKey(
+auto GpgFrontend::GpgKeyManager::SignKey(
const GpgFrontend::GpgKey& target, GpgFrontend::KeyArgsList& keys,
- const std::string& uid,
- const std::unique_ptr<boost::posix_time::ptime>& expires) {
- using namespace boost::posix_time;
-
- GpgBasicOperator::GetInstance().SetSigners(keys);
+ const QString& uid, const std::unique_ptr<QDateTime>& expires) -> bool {
+ GpgBasicOperator::GetInstance().SetSigners(keys, true);
unsigned int flags = 0;
unsigned int expires_time_t = 0;
- if (expires == nullptr)
+ if (expires == nullptr) {
flags |= GPGME_KEYSIGN_NOEXPIRE;
- else
- expires_time_t = to_time_t(*expires);
+ } else {
+ expires_time_t = expires->toSecsSinceEpoch();
+ }
- auto err = check_gpg_error(gpgme_op_keysign(
- ctx_, gpgme_key_t(target), uid.c_str(), expires_time_t, flags));
+ auto err = CheckGpgError(
+ gpgme_op_keysign(ctx_.DefaultContext(), static_cast<gpgme_key_t>(target),
+ uid.toUtf8(), expires_time_t, flags));
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgKeyManager::RevSign(
+auto GpgFrontend::GpgKeyManager::RevSign(
const GpgFrontend::GpgKey& key,
- const GpgFrontend::SignIdArgsListPtr& signature_id) {
+ const GpgFrontend::SignIdArgsListPtr& signature_id) -> bool {
auto& key_getter = GpgKeyGetter::GetInstance();
for (const auto& sign_id : *signature_id) {
auto signing_key = key_getter.GetKey(sign_id.first);
assert(signing_key.IsGood());
- auto err = check_gpg_error(gpgme_op_revsig(ctx_, gpgme_key_t(key),
- gpgme_key_t(signing_key),
- sign_id.second.c_str(), 0));
- if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return false;
+ auto err = CheckGpgError(
+ gpgme_op_revsig(ctx_.DefaultContext(), gpgme_key_t(key),
+ gpgme_key_t(signing_key), sign_id.second.toUtf8(), 0));
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false;
}
return true;
}
-bool GpgFrontend::GpgKeyManager::SetExpire(
- const GpgFrontend::GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
- std::unique_ptr<boost::posix_time::ptime>& expires) {
- using namespace boost::posix_time;
-
+auto GpgFrontend::GpgKeyManager::SetExpire(const GpgFrontend::GpgKey& key,
+ std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<QDateTime>& expires)
+ -> bool {
unsigned long expires_time = 0;
- if (expires != nullptr) expires_time = to_time_t(ptime(*expires));
+ if (expires != nullptr) expires_time = expires->toSecsSinceEpoch();
const char* sub_fprs = nullptr;
- if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().c_str();
+ if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().toUtf8();
- auto err = check_gpg_error(
- gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, sub_fprs, 0));
+ auto err = CheckGpgError(gpgme_op_setexpire(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key),
+ expires_time, sub_fprs, 0));
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
- int trust_level) {
+auto GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
+ int trust_level) -> bool {
if (trust_level < 0 || trust_level > 5) {
- SPDLOG_ERROR("illegal owner trust level: {}", trust_level);
+ GF_CORE_LOG_ERROR("illegal owner trust level: {}", trust_level);
}
- AutomatonNextStateHandler next_state_handler =
- [](AutomatonState state, std::string status, std::string args) {
- SPDLOG_DEBUG("next_state_handler state: {}, gpg_status: {}, args: {}",
- state, status, args);
- std::vector<std::string> tokens;
- boost::split(tokens, args, boost::is_any_of(" "));
-
- switch (state) {
- case AS_START:
- if (status == "GET_LINE" && args == "keyedit.prompt")
- return AS_COMMAND;
- return AS_ERROR;
- case AS_COMMAND:
- if (status == "GET_LINE" && args == "edit_ownertrust.value") {
- return AS_VALUE;
- }
- return AS_ERROR;
- case AS_VALUE:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- } else if (status == "GET_BOOL" &&
- args == "edit_ownertrust.set_ultimate.okay") {
- return AS_REALLY_ULTIMATE;
- }
- return AS_ERROR;
- case AS_REALLY_ULTIMATE:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- }
- return AS_ERROR;
- case AS_QUIT:
- if (status == "GET_LINE" && args == "keyedit.save.okay") {
- return AS_SAVE;
- }
- return AS_ERROR;
- case AS_ERROR:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- }
- return AS_ERROR;
- default:
- return AS_ERROR;
- };
- };
+ AutomatonNextStateHandler next_state_handler = [](AutomatonState state,
+ QString status,
+ QString args) {
+ GF_CORE_LOG_DEBUG("next_state_handler state: {}, gpg_status: {}, args: {}",
+ state, status, args);
+ auto tokens = args.split(' ');
+
+ switch (state) {
+ case AS_START:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_COMMAND;
+ }
+ return AS_ERROR;
+ case AS_COMMAND:
+ if (status == "GET_LINE" && args == "edit_ownertrust.value") {
+ return AS_VALUE;
+ }
+ return AS_ERROR;
+ case AS_VALUE:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ } else if (status == "GET_BOOL" &&
+ args == "edit_ownertrust.set_ultimate.okay") {
+ return AS_REALLY_ULTIMATE;
+ }
+ return AS_ERROR;
+ case AS_REALLY_ULTIMATE:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ }
+ return AS_ERROR;
+ case AS_QUIT:
+ if (status == "GET_LINE" && args == "keyedit.save.okay") {
+ return AS_SAVE;
+ }
+ return AS_ERROR;
+ case AS_ERROR:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ }
+ return AS_ERROR;
+ default:
+ return AS_ERROR;
+ };
+ };
AutomatonActionHandler action_handler =
[trust_level](AutomatonHandelStruct& handler, AutomatonState state) {
- SPDLOG_DEBUG("action_handler state: {}", state);
+ GF_CORE_LOG_DEBUG("action_handler state: {}", state);
switch (state) {
case AS_COMMAND:
- return std::string("trust");
+ return QString("trust");
case AS_VALUE:
handler.SetSuccess(true);
- return std::to_string(trust_level);
+ return QString::number(trust_level);
case AS_REALLY_ULTIMATE:
handler.SetSuccess(true);
- return std::string("Y");
+ return QString("Y");
case AS_QUIT:
- return std::string("quit");
+ return QString("quit");
case AS_SAVE:
handler.SetSuccess(true);
- return std::string("Y");
+ return QString("Y");
case AS_START:
case AS_ERROR:
- return std::string("");
+ return QString("");
default:
- return std::string("");
+ return QString("");
}
- return std::string("");
+ return QString("");
};
auto key_fpr = key.GetFingerprint();
@@ -180,49 +176,44 @@ bool GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
GpgData data_out;
- auto err = gpgme_op_interact(ctx_, gpgme_key_t(key), 0,
- GpgKeyManager::interactor_cb_fnc,
- (void*)&handel_struct, data_out);
- if (err != GPG_ERR_NO_ERROR) {
- SPDLOG_ERROR("fail to set owner trust level {} to key {}, err: {}",
- trust_level, key.GetId(), gpgme_strerror(err));
- }
-
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR &&
- handel_struct.Success();
+ auto err =
+ gpgme_op_interact(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), 0,
+ GpgKeyManager::interactor_cb_fnc,
+ static_cast<void*>(&handel_struct), data_out);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR && handel_struct.Success();
}
-gpgme_error_t GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
- const char* status,
- const char* args,
- int fd) {
- auto handle_struct = static_cast<AutomatonHandelStruct*>(handle);
- std::string status_s = status;
- std::string args_s = args;
- SPDLOG_DEBUG("cb start status: {}, args: {}, fd: {}, handle struct state: {}",
- status_s, args_s, fd, handle_struct->CuurentStatus());
+auto GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
+ const char* status,
+ const char* args, int fd)
+ -> gpgme_error_t {
+ auto* handle_struct = static_cast<AutomatonHandelStruct*>(handle);
+ QString status_s = status;
+ QString args_s = args;
+ GF_CORE_LOG_DEBUG(
+ "cb start status: {}, args: {}, fd: {}, handle struct state: {}",
+ status_s, args_s, fd, handle_struct->CuurentStatus());
if (status_s == "KEY_CONSIDERED") {
- std::vector<std::string> tokens;
- boost::split(tokens, args, boost::is_any_of(" "));
+ auto tokens = QString(args).split(' ');
if (tokens.empty() || tokens[0] != handle_struct->KeyFpr()) {
- SPDLOG_ERROR("handle struct key fpr {} mismatch token: {}, exit...",
- handle_struct->KeyFpr(), tokens[0]);
+ GF_CORE_LOG_ERROR("handle struct key fpr {} mismatch token: {}, exit...",
+ handle_struct->KeyFpr(), tokens[0]);
return -1;
}
return 0;
}
- if (status_s == "GOT_IT" || status_s.empty()) {
- SPDLOG_DEBUG("status GOT_IT, continue...");
+ if (status_s == "GOT_IT" || status_s.isEmpty()) {
+ GF_CORE_LOG_DEBUG("status GOT_IT, continue...");
return 0;
}
AutomatonState next_state = handle_struct->NextState(status_s, args_s);
if (next_state == AS_ERROR) {
- SPDLOG_DEBUG("handle struct next state caught error, skipping...");
+ GF_CORE_LOG_DEBUG("handle struct next state caught error, skipping...");
return GPG_ERR_FALSE;
}
@@ -233,10 +224,11 @@ gpgme_error_t GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
// set state and preform action
handle_struct->SetStatus(next_state);
Command cmd = handle_struct->Action();
- SPDLOG_DEBUG("handle struct action done, next state: {}, action cmd: {}",
- next_state, cmd);
- if (!cmd.empty()) {
- gpgme_io_write(fd, cmd.c_str(), cmd.size());
+ GF_CORE_LOG_DEBUG("handle struct action done, next state: {}, action cmd: {}",
+ next_state, cmd);
+ if (!cmd.isEmpty()) {
+ auto btye_array = cmd.toUtf8();
+ gpgme_io_write(fd, btye_array, btye_array.size());
gpgme_io_write(fd, "\n", 1);
} else if (status_s == "GET_LINE") {
// avoid trapping in this state
diff --git a/src/core/function/gpg/GpgKeyManager.h b/src/core/function/gpg/GpgKeyManager.h
index 62f7baca..8b4d41b2 100644
--- a/src/core/function/gpg/GpgKeyManager.h
+++ b/src/core/function/gpg/GpgKeyManager.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,19 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
-#define GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
+#pragma once
#include <functional>
-#include <string>
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -60,8 +58,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @param expires expire date and time of the signature
* @return if successful
*/
- bool SignKey(const GpgKey& target, KeyArgsList& keys, const std::string& uid,
- const std::unique_ptr<boost::posix_time::ptime>& expires);
+ auto SignKey(const GpgKey& target, KeyArgsList& keys, const QString& uid,
+ const std::unique_ptr<QDateTime>& expires) -> bool;
/**
* @brief
@@ -71,8 +69,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @return true
* @return false
*/
- bool RevSign(const GpgFrontend::GpgKey& key,
- const GpgFrontend::SignIdArgsListPtr& signature_id);
+ auto RevSign(const GpgFrontend::GpgKey& key,
+ const GpgFrontend::SignIdArgsListPtr& signature_id) -> bool;
/**
* @brief Set the Expire object
@@ -83,21 +81,21 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @return true
* @return false
*/
- bool SetExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
- std::unique_ptr<boost::posix_time::ptime>& expires);
+ auto SetExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<QDateTime>& expires) -> bool;
/**
* @brief
*
* @return
*/
- bool SetOwnerTrustLevel(const GpgKey& key, int trust_level);
+ auto SetOwnerTrustLevel(const GpgKey& key, int trust_level) -> bool;
private:
- static gpgme_error_t interactor_cb_fnc(void* handle, const char* status,
- const char* args, int fd);
+ static auto interactor_cb_fnc(void* handle, const char* status,
+ const char* args, int fd) -> gpgme_error_t;
- using Command = std::string;
+ using Command = QString;
using AutomatonState = enum {
AS_START,
AS_COMMAND,
@@ -113,35 +111,37 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
using AutomatonActionHandler =
std::function<Command(AutomatonHandelStruct&, AutomatonState)>;
using AutomatonNextStateHandler =
- std::function<AutomatonState(AutomatonState, std::string, std::string)>;
+ std::function<AutomatonState(AutomatonState, QString, QString)>;
struct AutomatonHandelStruct {
void SetStatus(AutomatonState next_state) { current_state_ = next_state; }
- AutomatonState CuurentStatus() { return current_state_; }
+ auto CuurentStatus() -> AutomatonState { return current_state_; }
void SetHandler(AutomatonNextStateHandler next_state_handler,
AutomatonActionHandler action_handler) {
- next_state_handler_ = next_state_handler;
- action_handler_ = action_handler;
+ next_state_handler_ = std::move(next_state_handler);
+ action_handler_ = std::move(action_handler);
}
- AutomatonState NextState(std::string gpg_status, std::string args) {
- return next_state_handler_(current_state_, gpg_status, args);
+ auto NextState(QString gpg_status, QString args) -> AutomatonState {
+ return next_state_handler_(current_state_, std::move(gpg_status),
+ std::move(args));
}
- Command Action() { return action_handler_(*this, current_state_); }
+ auto Action() -> Command { return action_handler_(*this, current_state_); }
void SetSuccess(bool success) { success_ = success; }
- bool Success() { return success_; }
+ [[nodiscard]] auto Success() const -> bool { return success_; }
- std::string KeyFpr() { return key_fpr_; }
+ auto KeyFpr() -> QString { return key_fpr_; }
- AutomatonHandelStruct(std::string key_fpr) : key_fpr_(key_fpr) {}
+ explicit AutomatonHandelStruct(QString key_fpr)
+ : key_fpr_(std::move(key_fpr)) {}
private:
AutomatonState current_state_ = AS_START;
AutomatonNextStateHandler next_state_handler_;
AutomatonActionHandler action_handler_;
bool success_ = false;
- std::string key_fpr_;
+ QString key_fpr_;
};
GpgContext& ctx_ =
@@ -149,5 +149,3 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp
index d5919cff..118f4784 100644
--- a/src/core/function/gpg/GpgKeyOpera.cpp
+++ b/src/core/function/gpg/GpgKeyOpera.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,38 +28,42 @@
#include "GpgKeyOpera.h"
-#include <boost/asio.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-#include <boost/format.hpp>
-#include <boost/process/async_pipe.hpp>
-#include <memory>
-#include <string>
-#include <vector>
+#include <gpg-error.h>
-#include "GpgCommandExecutor.h"
-#include "GpgKeyGetter.h"
-#include "core/GpgConstants.h"
-#include "core/GpgGenKeyInfo.h"
+#include <memory>
-GpgFrontend::GpgKeyOpera::GpgKeyOpera(int channel)
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgCommandExecutor.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/model/DataObject.h"
+#include "core/model/GpgGenKeyInfo.h"
+#include "core/model/GpgGenerateKeyResult.h"
+#include "core/module/ModuleManager.h"
+#include "core/typedef/GpgTypedef.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/GpgUtils.h"
+
+namespace GpgFrontend {
+
+GpgKeyOpera::GpgKeyOpera(int channel)
: SingletonFunctionObject<GpgKeyOpera>(channel) {}
/**
* Delete keys
* @param uidList key ids
*/
-void GpgFrontend::GpgKeyOpera::DeleteKeys(
- GpgFrontend::KeyIdArgsListPtr key_ids) {
+void GpgKeyOpera::DeleteKeys(GpgFrontend::KeyIdArgsListPtr key_ids) {
GpgError err;
for (const auto& tmp : *key_ids) {
auto key = GpgKeyGetter::GetInstance().GetKey(tmp);
if (key.IsGood()) {
- err = check_gpg_error(
- gpgme_op_delete_ext(ctx_, gpgme_key_t(key),
- GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
+ err = CheckGpgError(gpgme_op_delete_ext(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
} else {
- SPDLOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
+ GF_CORE_LOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
}
}
}
@@ -72,26 +76,24 @@ void GpgFrontend::GpgKeyOpera::DeleteKeys(
* @param expires date and time
* @return if successful
*/
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
- const GpgKey& key, const SubkeyId& subkey_fpr,
- std::unique_ptr<boost::posix_time::ptime>& expires) {
+auto GpgKeyOpera::SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<QDateTime>& expires) -> GpgError {
unsigned long expires_time = 0;
if (expires != nullptr) {
- using namespace boost::posix_time;
- using namespace std::chrono;
- expires_time =
- to_time_t(*expires) - system_clock::to_time_t(system_clock::now());
+ expires_time = QDateTime::currentDateTime().secsTo(*expires);
}
- SPDLOG_DEBUG(key.GetId(), subkey_fpr, expires_time);
-
GpgError err;
- if (key.GetFingerprint() == subkey_fpr || subkey_fpr.empty())
- err = gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, nullptr, 0);
- else
- err = gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time,
- subkey_fpr.c_str(), 0);
+ if (key.GetFingerprint() == subkey_fpr || subkey_fpr.isEmpty()) {
+ err =
+ gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ expires_time, nullptr, 0);
+ } else {
+ err =
+ gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ expires_time, subkey_fpr.toUtf8(), 0);
+ }
return err;
}
@@ -102,48 +104,52 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
* @param outputFileName out file name(path)
* @return the process doing this job
*/
-void GpgFrontend::GpgKeyOpera::GenerateRevokeCert(
- const GpgKey& key, const std::string& output_file_path) {
+void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key,
+ const QString& output_path) {
+ const auto app_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{});
// get all components
- GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().AppPath,
- {"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o",
- output_file_path, "--gen-revoke", key.GetFingerprint().c_str()},
- [=](int exit_code, const std::string& p_out, const std::string& p_err) {
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gnupg gen revoke execute error, process stderr: {}, process "
- "stdout: {}",
- p_err, p_out);
- } else {
- SPDLOG_DEBUG(
- "gnupg gen revoke exit_code: {}, process stdout size: {}",
- exit_code, p_out.size());
- }
- },
- [](QProcess* proc) -> void {
- // Code From Gpg4Win
- while (proc->canReadLine()) {
- const QString line = QString::fromUtf8(proc->readLine()).trimmed();
- SPDLOG_DEBUG("line: {}", line.toStdString());
- if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
- proc->write("y\n");
- } else if (line == QLatin1String("[GNUPG:] GET_LINE "
- "ask_revocation_reason.code")) {
- proc->write("0\n");
- } else if (line == QLatin1String("[GNUPG:] GET_LINE "
- "ask_revocation_reason.text")) {
- proc->write("\n");
- } else if (line == QLatin1String(
- "[GNUPG:] GET_BOOL openfile.overwrite.okay")) {
- // We asked before
- proc->write("y\n");
- } else if (line == QLatin1String("[GNUPG:] GET_BOOL "
- "ask_revocation_reason.okay")) {
- proc->write("y\n");
- }
- }
- });
+ GpgCommandExecutor::ExecuteSync(
+ {app_path,
+ QStringList{"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o",
+ output_path, "--gen-revoke", key.GetFingerprint()},
+ [=](int exit_code, const QString& p_out, const QString& p_err) {
+ if (exit_code != 0) {
+ GF_CORE_LOG_ERROR(
+ "gnupg gen revoke execute error, process stderr: {}, process "
+ "stdout: {}",
+ p_err, p_out);
+ } else {
+ GF_CORE_LOG_DEBUG(
+ "gnupg gen revoke exit_code: {}, process stdout size: {}",
+ exit_code, p_out.size());
+ }
+ },
+ nullptr,
+ [](QProcess* proc) -> void {
+ // Code From Gpg4Win
+ while (proc->canReadLine()) {
+ const QString line = QString::fromUtf8(proc->readLine()).trimmed();
+ GF_CORE_LOG_DEBUG("line: {}", line.toStdString());
+ if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
+ proc->write("y\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_LINE "
+ "ask_revocation_reason.code")) {
+ proc->write("0\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_LINE "
+ "ask_revocation_reason.text")) {
+ proc->write("\n");
+ } else if (line ==
+ QLatin1String(
+ "[GNUPG:] GET_BOOL openfile.overwrite.okay")) {
+ // We asked before
+ proc->write("y\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_BOOL "
+ "ask_revocation_reason.okay")) {
+ proc->write("y\n");
+ }
+ }
+ }});
}
/**
@@ -151,138 +157,366 @@ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert(
* @param params key generation args
* @return error information
*/
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
- const std::unique_ptr<GenKeyInfo>& params, GpgGenKeyResult& result) {
- auto userid_utf8 = params->GetUserid();
- const char* userid = userid_utf8.c_str();
- auto algo_utf8 = params->GetAlgo() + params->GetKeySizeStr();
-
- SPDLOG_DEBUG("params: {} {}", params->GetAlgo(), params->GetKeySizeStr());
-
- const char* algo = algo_utf8.c_str();
- unsigned long expires = 0;
- {
- using namespace boost::posix_time;
- using namespace std::chrono;
- expires = to_time_t(ptime(params->GetExpireTime())) -
- system_clock::to_time_t(system_clock::now());
- }
+void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
+ auto userid = params->GetUserid();
+ auto algo = params->GetAlgo() + params->GetKeySizeStr();
+
+ GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(),
+ params->GetKeySizeStr());
+
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("key generation args: {} {} {} {}", userid, algo,
+ expires, flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid.toUtf8(),
+ algo.toUtf8(), 0, expires, nullptr, flags);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{
+ gpgme_op_genkey_result(ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ }
- GpgError err;
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createkey", "2.1.0");
+}
- SPDLOG_DEBUG("ctx version, {}", ctx_.GetInfo(false).GnupgVersion);
+auto GpgKeyOpera::GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [=, &ctx = ctx_](const DataObjectPtr& data_object) -> GpgError {
+ auto userid = params->GetUserid();
+ auto algo = params->GetAlgo() + params->GetKeySizeStr();
+
+ GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(),
+ params->GetKeySizeStr());
+
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("key generation args: {} {} {} {}", userid, algo,
+ expires, flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid.toUtf8(),
+ algo.toUtf8(), 0, expires, nullptr, flags);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{
+ gpgme_op_genkey_result(ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ }
- if (ctx_.GetInfo(false).GnupgVersion >= "2.1.0") {
- unsigned int flags = 0;
+ return CheckGpgError(err);
+ },
+ "gpgme_op_createkey", "2.1.0");
+}
- if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
- if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
- if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
- if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
- if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
- if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+void GpgKeyOpera::GenerateSubkey(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
+ if (!params->IsSubKey()) return GPG_ERR_CANCELED;
+
+ GF_CORE_LOG_DEBUG("generate subkey algo {}, key size {}",
+ params->GetAlgo(), params->GetKeySizeStr());
+
+ auto algo = params->GetAlgo() + params->GetKeySizeStr();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
+ algo, expires, flags);
+ auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key),
+ algo.toUtf8(), 0, expires, flags);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ return err;
+ }
- SPDLOG_DEBUG("args: {}", userid, algo, expires, flags);
+ data_object->Swap({GpgGenerateKeyResult{
+ gpgme_op_genkey_result(ctx.DefaultContext())}});
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createsubkey", "2.1.13");
+}
- err = gpgme_op_createkey(ctx_, userid, algo, 0, expires, nullptr, flags);
+auto GpgKeyOpera::GenerateSubkeySync(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
+ if (!params->IsSubKey()) return GPG_ERR_CANCELED;
+
+ GF_CORE_LOG_DEBUG("generate subkey algo {} key size {}",
+ params->GetAlgo(), params->GetKeySizeStr());
+
+ auto algo = params->GetAlgo() + params->GetKeySizeStr();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires,
+ flags);
+
+ auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key),
+ algo.toUtf8(), 0, expires, flags);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ return err;
+ }
- } else {
- std::stringstream ss;
- auto param_format =
- boost::format{
- "<GnupgKeyParms format=\"internal\">\n"
- "Key-Type: %1%\n"
- "Key-Usage: sign\n"
- "Key-Length: %2%\n"
- "Name-Real: %3%\n"
- "Name-Comment: %4%\n"
- "Name-Email: %5%\n"} %
- params->GetAlgo() % params->GetKeyLength() % params->GetName() %
- params->GetComment() % params->GetEmail();
- ss << param_format;
-
- if (!params->IsNonExpired()) {
- auto date = params->GetExpireTime().date();
- ss << boost::format{"Expire-Date: %1%\n"} % to_iso_string(date);
- } else
- ss << boost::format{"Expire-Date: 0\n"};
- if (!params->IsNoPassPhrase())
- ss << boost::format{"Passphrase: %1%\n"} % params->GetPassPhrase();
-
- ss << "</GnupgKeyParms>";
-
- SPDLOG_DEBUG("params: {}", ss.str());
-
- err = gpgme_op_genkey(ctx_, ss.str().c_str(), nullptr, nullptr);
- }
+ data_object->Swap({GpgGenerateKeyResult{
+ gpgme_op_genkey_result(ctx.DefaultContext())}});
+ return CheckGpgError(err);
+ },
+ "gpgme_op_createsubkey", "2.1.13");
+}
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) {
- auto temp_result = _new_result(gpgme_op_genkey_result(ctx_));
- std::swap(temp_result, result);
- }
+void GpgKeyOpera::GenerateKeyWithSubkey(
+ const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&ctx = ctx_, params,
+ subkey_params](const DataObjectPtr& data_object) -> GpgError {
+ auto userid = params->GetUserid().toUtf8();
+ auto algo = (params->GetAlgo() + params->GetKeySizeStr()).toUtf8();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
+ flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
+ nullptr, flags);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ return err;
+ }
+
+ auto genkey_result =
+ GpgGenerateKeyResult{gpgme_op_genkey_result(ctx.DefaultContext())};
+
+ if (subkey_params == nullptr || !subkey_params->IsSubKey()) {
+ data_object->Swap({genkey_result});
+ return err;
+ }
+
+ auto key =
+ GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint());
+ if (!key.IsGood()) {
+ GF_CORE_LOG_ERROR("cannot get key which has been generate, fpr: {}",
+ genkey_result.GetFingerprint());
+ return err;
+ }
+
+ GF_CORE_LOG_DEBUG(
+ "try to generate subkey of key: {}, algo {} key size {}",
+ key.GetId(), subkey_params->GetAlgo(),
+ subkey_params->GetKeySizeStr());
+
+ algo = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr())
+ .toUtf8();
+ expires =
+ QDateTime::currentDateTime().secsTo(subkey_params->GetExpireTime());
+
+ flags = 0;
+ if (subkey_params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (subkey_params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (subkey_params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (subkey_params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (subkey_params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
+ algo, expires, flags);
+
+ err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), algo, 0,
+ expires, flags);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap(
+ {genkey_result, GpgGenerateKeyResult{gpgme_op_genkey_result(
+ ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({genkey_result, GpgGenerateKeyResult{}});
+ }
- return check_gpg_error(err);
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0");
}
-/**
- * Generate a new subkey of a certain key pair
- * @param key target key pair
- * @param params opera args
- * @return error info
- */
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey(
- const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params) {
- if (!params->IsSubKey()) return GPG_ERR_CANCELED;
-
- SPDLOG_DEBUG("generate subkey algo {} key size {}", params->GetAlgo(),
- params->GetKeySizeStr());
-
- auto algo_utf8 = (params->GetAlgo() + params->GetKeySizeStr());
- const char* algo = algo_utf8.c_str();
- unsigned long expires = 0;
- {
- using namespace boost::posix_time;
- using namespace std::chrono;
- expires = to_time_t(ptime(params->GetExpireTime())) -
- system_clock::to_time_t(system_clock::now());
- }
- unsigned int flags = 0;
+auto GpgKeyOpera::GenerateKeyWithSubkeySync(
+ const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params)
+ -> std::tuple<GpgError, DataObjectPtr> {
+ return RunGpgOperaSync(
+ [&ctx = ctx_, params,
+ subkey_params](const DataObjectPtr& data_object) -> GpgError {
+ auto userid = params->GetUserid().toUtf8();
+ auto algo = (params->GetAlgo() + params->GetKeySizeStr()).toUtf8();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
+ flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
+ nullptr, flags);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ return err;
+ }
+
+ auto genkey_result =
+ GpgGenerateKeyResult{gpgme_op_genkey_result(ctx.DefaultContext())};
- if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
- if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
- if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
- if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
- if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
- if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+ if (subkey_params == nullptr || !subkey_params->IsSubKey()) {
+ data_object->Swap({genkey_result});
+ return err;
+ }
- SPDLOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires, flags);
+ auto key =
+ GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint());
+ if (!key.IsGood()) {
+ GF_CORE_LOG_ERROR("cannot get key which has been generate, fpr: {}",
+ genkey_result.GetFingerprint());
+ return err;
+ }
+
+ GF_CORE_LOG_DEBUG(
+ "try to generate subkey of key: {}, algo {} key size {}",
+ key.GetId(), subkey_params->GetAlgo(),
+ subkey_params->GetKeySizeStr());
+
+ algo = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr())
+ .toUtf8();
+ expires =
+ QDateTime::currentDateTime().secsTo(subkey_params->GetExpireTime());
+
+ flags = 0;
+ if (subkey_params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (subkey_params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (subkey_params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (subkey_params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (subkey_params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
+ algo, expires, flags);
+
+ err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), algo, 0,
+ expires, flags);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap(
+ {genkey_result, GpgGenerateKeyResult{gpgme_op_genkey_result(
+ ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({genkey_result, GpgGenerateKeyResult{}});
+ }
- auto err =
- gpgme_op_createsubkey(ctx_, gpgme_key_t(key), algo, 0, expires, flags);
- return check_gpg_error(err);
+ return CheckGpgError(err);
+ },
+ "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyPassword(
- const GpgFrontend::GpgKey& key) {
- if (ctx_.GetInfo(false).GnupgVersion < "2.0.15") {
- SPDLOG_ERROR("operator not support");
- return GPG_ERR_NOT_SUPPORTED;
- }
- auto err = gpgme_op_passwd(ctx_, gpgme_key_t(key), 0);
- return check_gpg_error(err);
+void GpgKeyOpera::ModifyPassword(const GpgKey& key,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&key, &ctx = ctx_](const DataObjectPtr&) -> GpgError {
+ return gpgme_op_passwd(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), 0);
+ },
+ callback, "gpgme_op_passwd", "2.0.15");
}
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyTOFUPolicy(
- const GpgFrontend::GpgKey& key, gpgme_tofu_policy_t tofu_policy) {
- if (ctx_.GetInfo(false).GnupgVersion < "2.1.10") {
- SPDLOG_ERROR("operator not support");
+
+auto GpgKeyOpera::ModifyTOFUPolicy(const GpgKey& key,
+ gpgme_tofu_policy_t tofu_policy)
+ -> GpgError {
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"});
+ GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
+
+ if (CompareSoftwareVersion(gnupg_version, "2.1.10") < 0) {
+ GF_CORE_LOG_ERROR("operator not support");
return GPG_ERR_NOT_SUPPORTED;
}
- auto err = gpgme_op_tofu_policy(ctx_, gpgme_key_t(key), tofu_policy);
- return check_gpg_error(err);
+
+ auto err = gpgme_op_tofu_policy(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key), tofu_policy);
+ return CheckGpgError(err);
}
-void GpgFrontend::GpgKeyOpera::DeleteKey(const GpgFrontend::KeyId& key_id) {
+void GpgKeyOpera::DeleteKey(const GpgFrontend::KeyId& key_id) {
auto keys = std::make_unique<KeyIdArgsList>();
keys->push_back(key_id);
DeleteKeys(std::move(keys));
}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyOpera.h b/src/core/function/gpg/GpgKeyOpera.h
index 5446bd66..6ffe437c 100644
--- a/src/core/function/gpg/GpgKeyOpera.h
+++ b/src/core/function/gpg/GpgKeyOpera.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,18 +20,18 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef _GPGKEYOPERA_H
-#define _GPGKEYOPERA_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include <functional>
+
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
@@ -77,8 +77,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param expires
* @return GpgError
*/
- GpgError SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
- std::unique_ptr<boost::posix_time::ptime>& expires);
+ auto SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<QDateTime>& expires) -> GpgError;
/**
* @brief
@@ -86,8 +86,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param key
* @param output_file_name
*/
- void GenerateRevokeCert(const GpgKey& key,
- const std::string& output_file_name);
+ void GenerateRevokeCert(const GpgKey& key, const QString& output_path);
/**
* @brief
@@ -95,7 +94,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param key
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError ModifyPassword(const GpgKey& key);
+ void ModifyPassword(const GpgKey& key, const GpgOperationCallback&);
/**
* @brief
@@ -104,8 +103,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param tofu_policy
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError ModifyTOFUPolicy(const GpgKey& key,
- gpgme_tofu_policy_t tofu_policy);
+ auto ModifyTOFUPolicy(const GpgKey& key, gpgme_tofu_policy_t tofu_policy)
+ -> GpgFrontend::GpgError;
/**
* @brief
*
@@ -113,8 +112,16 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param result
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params,
- GpgGenKeyResult& result);
+ void GenerateKey(const std::shared_ptr<GenKeyInfo>&,
+ const GpgOperationCallback&);
+
+ /**
+ * @brief
+ *
+ * @param params
+ */
+ auto GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params)
+ -> std::tuple<GpgError, DataObjectPtr>;
/**
* @brief
@@ -123,13 +130,45 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param params
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError GenerateSubkey(
- const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params);
+ void GenerateSubkey(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback&);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param params
+ */
+ auto GenerateSubkeySync(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params)
+ -> std::tuple<GpgError, DataObjectPtr>;
+
+ /**
+ * @brief
+ *
+ * @param params
+ * @param subkey_params
+ * @param callback
+ */
+ void GenerateKeyWithSubkey(const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params,
+ const GpgOperationCallback& callback);
+
+ /**
+ * @brief
+ *
+ * @param params
+ * @param subkey_params
+ * @param callback
+ */
+ auto GenerateKeyWithSubkeySync(
+ const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params)
+ -> std::tuple<GpgError, DataObjectPtr>;
private:
GpgContext& ctx_ =
GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
};
} // namespace GpgFrontend
-
-#endif // _GPGKEYOPERA_H \ No newline at end of file
diff --git a/src/core/function/gpg/GpgUIDOperator.cpp b/src/core/function/gpg/GpgUIDOperator.cpp
index 7e7a711e..6c0373de 100644
--- a/src/core/function/gpg/GpgUIDOperator.cpp
+++ b/src/core/function/gpg/GpgUIDOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,44 +28,38 @@
#include "GpgUIDOperator.h"
-#include "boost/format.hpp"
+#include "core/GpgModel.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgUIDOperator::GpgUIDOperator(int channel)
+namespace GpgFrontend {
+
+GpgUIDOperator::GpgUIDOperator(int channel)
: SingletonFunctionObject<GpgUIDOperator>(channel) {}
-bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key,
- const std::string& uid) {
- auto err = gpgme_op_adduid(ctx_, gpgme_key_t(key), uid.c_str(), 0);
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- return true;
- else
- return false;
+auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& uid) -> bool {
+ auto err = gpgme_op_adduid(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key), uid.toUtf8(), 0);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::RevUID(const GpgFrontend::GpgKey& key,
- const std::string& uid) {
- auto err =
- check_gpg_error(gpgme_op_revuid(ctx_, gpgme_key_t(key), uid.c_str(), 0));
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- return true;
- else
- return false;
+auto GpgUIDOperator::RevUID(const GpgKey& key, const QString& uid) -> bool {
+ auto err = CheckGpgError(gpgme_op_revuid(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.toUtf8(), 0));
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::SetPrimaryUID(const GpgFrontend::GpgKey& key,
- const std::string& uid) {
- auto err = check_gpg_error(gpgme_op_set_uid_flag(
- ctx_, gpgme_key_t(key), uid.c_str(), "primary", nullptr));
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- return true;
- else
- return false;
+auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key, const QString& uid)
+ -> bool {
+ auto err = CheckGpgError(gpgme_op_set_uid_flag(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.toUtf8(),
+ "primary", nullptr));
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key,
- const std::string& name,
- const std::string& comment,
- const std::string& email) {
- SPDLOG_DEBUG("new uuid: {} {} {}", name, comment, email);
- auto uid = boost::format("%1%(%2%)<%3%>") % name % comment % email;
- return AddUID(key, uid.str());
+auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& name,
+ const QString& comment, const QString& email)
+ -> bool {
+ GF_CORE_LOG_DEBUG("new uuid: {} {} {}", name, comment, email);
+ return AddUID(key, QString("%1(%2)<%3>").arg(name).arg(comment).arg(email));
}
+
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgUIDOperator.h b/src/core/function/gpg/GpgUIDOperator.h
index c4a7d87b..b2cec8bc 100644
--- a/src/core/function/gpg/GpgUIDOperator.h
+++ b/src/core/function/gpg/GpgUIDOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
-#define GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
+#pragma once
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
@@ -54,7 +53,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid uid args(combine name&comment&email)
* @return if successful
*/
- bool AddUID(const GpgKey& key, const std::string& uid);
+ auto AddUID(const GpgKey& key, const QString& uid) -> bool;
/**
* create a new uid in certain key pair
@@ -64,8 +63,8 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param email
* @return
*/
- bool AddUID(const GpgKey& key, const std::string& name,
- const std::string& comment, const std::string& email);
+ auto AddUID(const GpgKey& key, const QString& name, const QString& comment,
+ const QString& email) -> bool;
/**
* Revoke(Delete) UID from certain key pair
@@ -73,7 +72,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid target uid
* @return if successful
*/
- bool RevUID(const GpgKey& key, const std::string& uid);
+ auto RevUID(const GpgKey& key, const QString& uid) -> bool;
/**
* Set one of a uid of a key pair as primary
@@ -81,7 +80,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid target uid
* @return if successful
*/
- bool SetPrimaryUID(const GpgKey& key, const std::string& uid);
+ auto SetPrimaryUID(const GpgKey& key, const QString& uid) -> bool;
private:
GpgContext& ctx_ =
@@ -89,5 +88,3 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp
index d3ec8d6e..5d0ce920 100644
--- a/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,70 +28,103 @@
#include "GpgDecryptResultAnalyse.h"
-#include "function/gpg/GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgKeyGetter.h"
GpgFrontend::GpgDecryptResultAnalyse::GpgDecryptResultAnalyse(
- GpgError m_error, GpgDecrResult m_result)
- : error_(m_error), result_(std::move(m_result)) {}
+ GpgError m_error, GpgDecryptResult m_result)
+ : error_(m_error), result_(m_result) {}
-void GpgFrontend::GpgDecryptResultAnalyse::do_analyse() {
- stream_ << "[#] " << _("Decrypt Operation");
+void GpgFrontend::GpgDecryptResultAnalyse::doAnalyse() {
+ auto *result = result_.GetRaw();
+
+ stream_ << "# " << tr("Decrypt Operation") << " ";
if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) {
- stream_ << "[" << _("Success") << "]" << std::endl;
+ stream_ << "- " << tr("Success") << " " << Qt::endl;
} else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
- if (result_ != nullptr && result_->unsupported_algorithm != nullptr) {
- stream_ << "------------>" << std::endl;
- stream_ << _("Unsupported Algo") << ": " << result_->unsupported_algorithm
- << std::endl;
+ stream_ << "- " << tr("Failed") << ": " << gpgme_strerror(error_)
+ << Qt::endl;
+ setStatus(-1);
+ if (result != nullptr && result->unsupported_algorithm != nullptr) {
+ stream_ << Qt::endl;
+ stream_ << "## " << tr("Unsupported Algo") << ": "
+ << result->unsupported_algorithm << Qt::endl;
}
}
- if (result_ != nullptr && result_->recipients != nullptr) {
- stream_ << "------------>" << std::endl;
- if (result_->file_name != nullptr) {
- stream_ << _("File Name") << ": " << result_->file_name << std::endl;
- stream_ << std::endl;
+ if (result != nullptr && result->recipients != nullptr) {
+ stream_ << Qt::endl;
+
+ stream_ << "## " << tr("Gernal State") << ": " << Qt::endl;
+
+ if (result->file_name != nullptr) {
+ stream_ << "- " << tr("File Name") << ": " << result->file_name
+ << Qt::endl;
+ }
+ stream_ << "- " << tr("MIME") << ": "
+ << (result->is_mime == 0 ? tr("false") : tr("true")) << Qt::endl;
+
+ stream_ << "- " << tr("Message Integrity Protection") << ": "
+ << (result->legacy_cipher_nomdc == 0 ? tr("true") : tr("false"))
+ << Qt::endl;
+ if (result->legacy_cipher_nomdc == 1) setStatus(0); /// < unsafe situation
+
+ if (result->symkey_algo != nullptr) {
+ stream_ << "- " << tr("Symmetric Encryption Algorithm") << ": "
+ << result->symkey_algo << Qt::endl;
+ }
+
+ if (result->session_key != nullptr) {
+ stream_ << "- " << tr("Session Key") << ": " << result->session_key
+ << Qt::endl;
}
- if (result_->is_mime) {
- stream_ << _("MIME") << ": " << _("true") << std::endl;
+
+ stream_ << "- " << tr("German Encryption Standards") << ": "
+ << (result->is_de_vs == 0 ? tr("false") : tr("true")) << Qt::endl;
+
+ stream_ << Qt::endl << Qt::endl;
+
+ auto *recipient = result->recipients;
+ auto index = 0;
+ if (recipient != nullptr) {
+ stream_ << "## " << tr("Recipient(s)") << ": " << Qt::endl << Qt::endl;
}
- auto recipient = result_->recipients;
- if (recipient != nullptr) stream_ << _("Recipient(s)") << ": " << std::endl;
while (recipient != nullptr) {
+ // check
+ if (recipient->keyid == nullptr) return;
+ stream_ << "### " << tr("Recipient") << " [" << ++index << "]: ";
print_recipient(stream_, recipient);
+ stream_ << Qt::endl
+ << "---------------------------------------" << Qt::endl
+ << Qt::endl;
recipient = recipient->next;
}
- stream_ << "<------------" << std::endl;
+
+ stream_ << Qt::endl;
}
- stream_ << std::endl;
+ stream_ << Qt::endl;
}
void GpgFrontend::GpgDecryptResultAnalyse::print_recipient(
- std::stringstream &stream, gpgme_recipient_t recipient) {
- // check
- if (recipient->keyid == nullptr) return;
-
- stream << " {>} " << _("Recipient") << ": ";
+ QTextStream &stream, gpgme_recipient_t recipient) {
auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(recipient->keyid);
if (key.IsGood()) {
- stream << key.GetName().c_str();
- if (!key.GetEmail().empty()) {
- stream << "<" << key.GetEmail().c_str() << ">";
- }
+ stream << key.GetName();
+ if (!key.GetComment().isEmpty()) stream << "(" << key.GetComment() << ")";
+ if (!key.GetEmail().isEmpty()) stream << "<" << key.GetEmail() << ">";
} else {
- stream << "<" << _("Unknown") << ">";
- set_status(0);
+ stream << "<" << tr("unknown") << ">";
+ setStatus(0);
}
- stream << std::endl;
+ stream << Qt::endl;
- stream << " " << _("Key ID") << ": " << recipient->keyid << std::endl;
- stream << " " << _("Public Key Algo") << ": "
- << gpgme_pubkey_algo_name(recipient->pubkey_algo) << std::endl;
+ stream << "- " << tr("Key ID") << ": " << recipient->keyid << Qt::endl;
+ stream << "- " << tr("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(recipient->pubkey_algo) << Qt::endl;
+ stream << "- " << tr("Status") << ": " << gpgme_strerror(recipient->status)
+ << Qt::endl;
}
diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.h b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h
index 1fc08d1f..c795e025 100644
--- a/src/core/function/result_analyse/GpgDecryptResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
-#define GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
-#include "core/GpgConstants.h"
+#include "core/model/GpgDecryptResult.h"
namespace GpgFrontend {
@@ -40,6 +39,7 @@ namespace GpgFrontend {
*/
class GPGFRONTEND_CORE_EXPORT GpgDecryptResultAnalyse
: public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Decrypt Result Analyse object
@@ -47,14 +47,14 @@ class GPGFRONTEND_CORE_EXPORT GpgDecryptResultAnalyse
* @param m_error
* @param m_result
*/
- explicit GpgDecryptResultAnalyse(GpgError m_error, GpgDecrResult m_result);
+ explicit GpgDecryptResultAnalyse(GpgError m_error, GpgDecryptResult m_result);
protected:
/**
* @brief
*
*/
- void do_analyse() final;
+ void doAnalyse() final;
private:
/**
@@ -63,12 +63,10 @@ class GPGFRONTEND_CORE_EXPORT GpgDecryptResultAnalyse
* @param stream
* @param recipient
*/
- void print_recipient(std::stringstream &stream, gpgme_recipient_t recipient);
+ void print_recipient(QTextStream &stream, gpgme_recipient_t recipient);
- GpgError error_; ///<
- GpgDecrResult result_; ///<
+ GpgError error_; ///<
+ GpgDecryptResult result_; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
index 21d37eab..a6b18b0a 100644
--- a/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,39 +28,53 @@
#include "GpgEncryptResultAnalyse.h"
-GpgFrontend::GpgEncryptResultAnalyse::GpgEncryptResultAnalyse(
- GpgError error, GpgEncrResult result)
- : error_(error), result_(std::move(result)) {}
+#include "core/model/GpgEncryptResult.h"
-void GpgFrontend::GpgEncryptResultAnalyse::do_analyse() {
- SPDLOG_DEBUG("start encrypt result analyse");
+namespace GpgFrontend {
- stream_ << "[#] " << _("Encrypt Operation") << " ";
+GpgEncryptResultAnalyse::GpgEncryptResultAnalyse(GpgError error,
+ GpgEncryptResult result)
+ : error_(error), result_(result) {}
- if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
- stream_ << "[" << _("Success") << "]" << std::endl;
- else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
+void GpgEncryptResultAnalyse::doAnalyse() {
+ stream_ << "# " << tr("Encrypt Operation") << " ";
+
+ if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) {
+ stream_ << "- " << tr("Success") << " " << Qt::endl;
+ } else {
+ stream_ << "- " << tr("Failed") << ": " << gpgme_strerror(error_)
+ << Qt::endl;
+ setStatus(-1);
}
- if (!~status_) {
- stream_ << "------------>" << std::endl;
- if (result_ != nullptr) {
- stream_ << _("Invalid Recipients") << ": " << std::endl;
- auto inv_reci = result_->invalid_recipients;
+ if ((~status_) == 0) {
+ stream_ << Qt::endl;
+
+ const auto *result = result_.GetRaw();
+
+ if (result != nullptr) {
+ stream_ << "## " << tr("Invalid Recipients") << ": " << Qt::endl
+ << Qt::endl;
+
+ auto *inv_reci = result->invalid_recipients;
+ auto index = 0;
+
while (inv_reci != nullptr) {
- stream_ << _("Fingerprint") << ": " << inv_reci->fpr << std::endl;
- stream_ << _("Reason") << ": " << gpgme_strerror(inv_reci->reason)
- << std::endl;
- stream_ << std::endl;
+ stream_ << "### " << tr("Recipients") << " " << ++index << ": "
+ << Qt::endl;
+ stream_ << "- " << tr("Fingerprint") << ": " << inv_reci->fpr
+ << Qt::endl;
+ stream_ << "- " << tr("Reason") << ": "
+ << gpgme_strerror(inv_reci->reason) << Qt::endl;
+ stream_ << Qt::endl << Qt::endl;
inv_reci = inv_reci->next;
}
}
- stream_ << "<------------" << std::endl;
+ stream_ << Qt::endl;
}
- stream_ << std::endl;
+ stream_ << Qt::endl;
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/result_analyse/GpgEncryptResultAnalyse.h b/src/core/function/result_analyse/GpgEncryptResultAnalyse.h
index 6811ef06..e9594628 100644
--- a/src/core/function/result_analyse/GpgEncryptResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgEncryptResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
-#define GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
-#include "core/GpgConstants.h"
+#include "core/model/GpgEncryptResult.h"
namespace GpgFrontend {
/**
@@ -39,6 +38,7 @@ namespace GpgFrontend {
*/
class GPGFRONTEND_CORE_EXPORT GpgEncryptResultAnalyse
: public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Encrypt Result Analyse object
@@ -46,19 +46,17 @@ class GPGFRONTEND_CORE_EXPORT GpgEncryptResultAnalyse
* @param error
* @param result
*/
- explicit GpgEncryptResultAnalyse(GpgError error, GpgEncrResult result);
+ explicit GpgEncryptResultAnalyse(GpgError error, GpgEncryptResult result);
protected:
/**
* @brief
*
*/
- void do_analyse() final;
+ void doAnalyse() final;
private:
- GpgError error_; ///<
- GpgEncrResult result_; ///<
+ GpgError error_; ///<
+ GpgEncryptResult result_; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgResultAnalyse.cpp b/src/core/function/result_analyse/GpgResultAnalyse.cpp
index 40ba4c3e..4c1f44e7 100644
--- a/src/core/function/result_analyse/GpgResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,19 +28,19 @@
#include "GpgResultAnalyse.h"
-const std::string GpgFrontend::GpgResultAnalyse::GetResultReport() const {
- return stream_.str();
+auto GpgFrontend::GpgResultAnalyse::GetResultReport() const -> const QString {
+ return *stream_.string();
}
-int GpgFrontend::GpgResultAnalyse::GetStatus() const { return status_; }
+auto GpgFrontend::GpgResultAnalyse::GetStatus() const -> int { return status_; }
-void GpgFrontend::GpgResultAnalyse::set_status(int m_status) {
+void GpgFrontend::GpgResultAnalyse::setStatus(int m_status) {
if (m_status < status_) status_ = m_status;
}
void GpgFrontend::GpgResultAnalyse::Analyse() {
if (!analysed_) {
- do_analyse();
+ doAnalyse();
analysed_ = true;
}
}
diff --git a/src/core/function/result_analyse/GpgResultAnalyse.h b/src/core/function/result_analyse/GpgResultAnalyse.h
index e609505f..9958b6a2 100644
--- a/src/core/function/result_analyse/GpgResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,21 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGRESULTANALYSE_H
-#define GPGFRONTEND_GPGRESULTANALYSE_H
+#pragma once
#include <sstream>
-#include <string>
-#include "core/GpgConstants.h"
+#include "core/typedef/GpgTypedef.h"
+
namespace GpgFrontend {
-class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse {
+class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse : public QObject {
+ Q_OBJECT
public:
/**
* @brief Construct a new Result Analyse object
@@ -45,16 +45,16 @@ class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse {
/**
* @brief Get the Result Report object
*
- * @return const std::string
+ * @return const QString
*/
- [[nodiscard]] const std::string GetResultReport() const;
+ [[nodiscard]] auto GetResultReport() const -> const QString;
/**
* @brief Get the Status object
*
* @return int
*/
- [[nodiscard]] int GetStatus() const;
+ [[nodiscard]] auto GetStatus() const -> int;
/**
* @brief
@@ -67,20 +67,19 @@ class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse {
* @brief
*
*/
- virtual void do_analyse() = 0;
+ virtual void doAnalyse() = 0;
/**
* @brief Set the status object
*
* @param m_status
*/
- void set_status(int m_status);
+ void setStatus(int m_status);
- std::stringstream stream_; ///<
- int status_ = 1; ///<
- bool analysed_ = false; ///<
+ QString buffer_;
+ QTextStream stream_ = QTextStream(&buffer_); ///<
+ int status_ = 1; ///<
+ bool analysed_ = false; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
index e4d1354f..bf429f38 100644
--- a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,88 +28,98 @@
#include "GpgSignResultAnalyse.h"
-#include "function/gpg/GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/utils/LocalizedUtils.h"
-GpgFrontend::GpgSignResultAnalyse::GpgSignResultAnalyse(GpgError error,
- GpgSignResult result)
+namespace GpgFrontend {
+
+GpgSignResultAnalyse::GpgSignResultAnalyse(GpgError error, GpgSignResult result)
: error_(error), result_(std::move(result)) {}
-void GpgFrontend::GpgSignResultAnalyse::do_analyse() {
- SPDLOG_DEBUG("start sign result analyse");
+void GpgSignResultAnalyse::doAnalyse() {
+ auto *result = this->result_.GetRaw();
- stream_ << "[#] " << _("Sign Operation") << " ";
+ stream_ << "# " << tr("Sign Operation") << " ";
- if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
- stream_ << "[" << _("Success") << "]" << std::endl;
- else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
+ if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) {
+ stream_ << "- " << tr("Success") << " " << Qt::endl;
+ } else {
+ stream_ << "- " << tr("Failed") << " " << gpgme_strerror(error_)
+ << Qt::endl;
+ setStatus(-1);
}
- if (result_ != nullptr &&
- (result_->signatures != nullptr || result_->invalid_signers != nullptr)) {
- SPDLOG_DEBUG("sign result analyse getting result");
- stream_ << "------------>" << std::endl;
- auto new_sign = result_->signatures;
+ if (result != nullptr &&
+ (result->signatures != nullptr || result->invalid_signers != nullptr)) {
+ stream_ << Qt::endl;
+ auto *new_sign = result->signatures;
+ auto index = 0;
while (new_sign != nullptr) {
- stream_ << "[>]" << _("New Signature") << ": " << std::endl;
-
- SPDLOG_DEBUG("signers fingerprint: ", new_sign->fpr);
-
- stream_ << " " << _("Sign Mode") << ": ";
- if (new_sign->type == GPGME_SIG_MODE_NORMAL)
- stream_ << _("Normal");
- else if (new_sign->type == GPGME_SIG_MODE_CLEAR)
- stream_ << _("Clear");
- else if (new_sign->type == GPGME_SIG_MODE_DETACH)
- stream_ << _("Detach");
+ stream_ << "## " << tr("New Signature") << " [" << ++index
+ << "]: " << Qt::endl;
+
+ stream_ << "- " << tr("Sign Mode") << ": ";
+ if (new_sign->type == GPGME_SIG_MODE_NORMAL) {
+ stream_ << tr("Normal");
+ } else if (new_sign->type == GPGME_SIG_MODE_CLEAR) {
+ stream_ << tr("Clear");
+ } else if (new_sign->type == GPGME_SIG_MODE_DETACH) {
+ stream_ << tr("Detach");
+ }
- stream_ << std::endl;
+ stream_ << Qt::endl;
- auto singerKey =
- GpgFrontend::GpgKeyGetter::GetInstance().GetKey(new_sign->fpr);
- if (singerKey.IsGood()) {
- stream_ << " " << _("Signer") << ": "
- << singerKey.GetUIDs()->front().GetUID() << std::endl;
+ auto singer_key = GpgKeyGetter::GetInstance().GetKey(new_sign->fpr);
+ if (singer_key.IsGood()) {
+ stream_ << "- " << tr("Signer") << ": "
+ << singer_key.GetUIDs()->front().GetUID() << Qt::endl;
} else {
- stream_ << " " << _("Signer") << ": "
- << "<unknown>" << std::endl;
+ stream_ << "- " << tr("Signer") << ": "
+ << "<unknown>" << Qt::endl;
}
- stream_ << " " << _("Public Key Algo") << ": "
- << gpgme_pubkey_algo_name(new_sign->pubkey_algo) << std::endl;
- stream_ << " " << _("Hash Algo") << ": "
- << gpgme_hash_algo_name(new_sign->hash_algo) << std::endl;
- stream_ << " " << _("Date") << "(" << _("UTC") << ")"
+ stream_ << "- " << tr("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(new_sign->pubkey_algo) << Qt::endl;
+ stream_ << "- " << tr("Hash Algo") << ": "
+ << gpgme_hash_algo_name(new_sign->hash_algo) << Qt::endl;
+ stream_ << "- " << tr("Date") << "(" << tr("UTC") << ")"
<< ": "
- << boost::posix_time::to_iso_extended_string(
- boost::posix_time::from_time_t(new_sign->timestamp))
- << std::endl;
+ << QDateTime::fromSecsSinceEpoch(new_sign->timestamp).toString()
+ << Qt::endl;
+ stream_ << "- " << tr("Date") << "(" << tr("Localized") << ")"
+ << ": " << GetFormatedDateByTimestamp(new_sign->timestamp)
+ << Qt::endl;
- stream_ << std::endl;
+ stream_ << Qt::endl
+ << "---------------------------------------" << Qt::endl
+ << Qt::endl;
new_sign = new_sign->next;
}
- SPDLOG_DEBUG("sign result analyse getting invalid signer");
+ auto *invalid_signer = result->invalid_signers;
+ stream_ << Qt::endl;
- auto invalid_signer = result_->invalid_signers;
-
- if (invalid_signer != nullptr)
- stream_ << _("Invalid Signers") << ": " << std::endl;
+ if (invalid_signer != nullptr) {
+ stream_ << "## " << tr("Invalid Signers") << ": " << Qt::endl;
+ }
+ index = 0;
while (invalid_signer != nullptr) {
- set_status(0);
- stream_ << "[>] " << _("Signer") << ": " << std::endl;
- stream_ << " " << _("Fingerprint") << ": " << invalid_signer->fpr
- << std::endl;
- stream_ << " " << _("Reason") << ": "
- << gpgme_strerror(invalid_signer->reason) << std::endl;
- stream_ << std::endl;
+ setStatus(0);
+ stream_ << "### " << tr("Signer") << " [" << ++index << "]: " << Qt::endl
+ << Qt::endl;
+ stream_ << "- " << tr("Fingerprint") << ": " << invalid_signer->fpr
+ << Qt::endl;
+ stream_ << "- " << tr("Reason") << ": "
+ << gpgme_strerror(invalid_signer->reason) << Qt::endl;
+ stream_ << "---------------------------------------" << Qt::endl;
invalid_signer = invalid_signer->next;
}
- stream_ << "<------------" << std::endl;
+ stream_ << Qt::endl;
}
-} \ No newline at end of file
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.h b/src/core/function/result_analyse/GpgSignResultAnalyse.h
index 43a78942..58a20417 100644
--- a/src/core/function/result_analyse/GpgSignResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgSignResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,16 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGSIGNRESULTANALYSE_H
-#define GPGFRONTEND_GPGSIGNRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
+#include "core/model/GpgSignResult.h"
namespace GpgFrontend {
@@ -38,6 +38,7 @@ namespace GpgFrontend {
*
*/
class GPGFRONTEND_CORE_EXPORT GpgSignResultAnalyse : public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Sign Result Analyse object
@@ -52,7 +53,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSignResultAnalyse : public GpgResultAnalyse {
* @brief
*
*/
- void do_analyse();
+ void doAnalyse() override;
private:
GpgError error_; ///<
@@ -61,5 +62,3 @@ class GPGFRONTEND_CORE_EXPORT GpgSignResultAnalyse : public GpgResultAnalyse {
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGSIGNRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
index b19db5b2..618275f9 100644
--- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,188 +28,200 @@
#include "GpgVerifyResultAnalyse.h"
-#include <boost/format.hpp>
-
#include "GpgFrontend.h"
-#include "core/GpgConstants.h"
-#include "function/gpg/GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/LocalizedUtils.h"
GpgFrontend::GpgVerifyResultAnalyse::GpgVerifyResultAnalyse(
GpgError error, GpgVerifyResult result)
- : error_(error), result_(std::move(result)) {}
+ : error_(error), result_(result) {}
-void GpgFrontend::GpgVerifyResultAnalyse::do_analyse() {
- SPDLOG_DEBUG("started");
+void GpgFrontend::GpgVerifyResultAnalyse::doAnalyse() {
+ auto *result = this->result_.GetRaw();
- stream_ << "[#] " << _("Verify Operation") << " ";
+ stream_ << "# " << tr("Verify Operation") << " ";
- if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
- stream_ << "[" << _("Success") << "]" << std::endl;
- else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
+ if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) {
+ stream_ << " - " << tr("Success") << " " << Qt::endl;
+ } else {
+ stream_ << " - " << tr("Failed") << ": " << gpgme_strerror(error_)
+ << Qt::endl;
+ setStatus(-1);
}
- if (result_ != nullptr && result_->signatures != nullptr) {
- stream_ << "------------>" << std::endl;
- auto sign = result_->signatures;
+ if (result != nullptr && result->signatures != nullptr) {
+ stream_ << Qt::endl;
+ auto *sign = result->signatures;
+
+ stream_ << "-> " << tr("Signed On") << "(" << tr("UTC") << ")"
+ << ": " << QDateTime::fromSecsSinceEpoch(sign->timestamp).toString()
+ << Qt::endl;
- stream_ << "[>] " << _("Signed On") << "(" << _("UTC") << ")"
- << " "
- << boost::posix_time::to_iso_extended_string(
- boost::posix_time::from_time_t(sign->timestamp))
- << std::endl;
+ stream_ << "-> " << tr("Signed On") << "(" << tr("Localized") << ")"
+ << ": " << GetFormatedDateByTimestamp(sign->timestamp) << Qt::endl;
- stream_ << std::endl << "[>] " << _("Signatures List") << ":" << std::endl;
+ stream_ << Qt::endl << "## " << tr("Signatures List") << ":" << Qt::endl;
+ stream_ << Qt::endl;
- bool canContinue = true;
+ bool can_continue = true;
int count = 1;
- while (sign && canContinue) {
- stream_ << boost::format(_("Signature [%1%]:")) % count++ << std::endl;
+ while ((sign != nullptr) && can_continue) {
+ stream_ << "### " << tr("Signature [%1]:").arg(count++) << Qt::endl;
+ stream_ << "- " << tr("Status") << ": ";
switch (gpg_err_code(sign->status)) {
case GPG_ERR_BAD_SIGNATURE:
- stream_ << _("A Bad Signature.") << std::endl;
+ stream_ << tr("A Bad Signature.") << Qt::endl;
print_signer(stream_, sign);
- stream_ << _("This Signature is invalid.") << std::endl;
- canContinue = false;
- set_status(-1);
+ stream_ << tr("This Signature is invalid.") << Qt::endl;
+ can_continue = false;
+ setStatus(-1);
break;
case GPG_ERR_NO_ERROR:
- stream_ << _("A") << " ";
- if (sign->summary & GPGME_SIGSUM_GREEN) {
- stream_ << _("Good") << " ";
+ stream_ << tr("A") << " ";
+ if ((sign->summary & GPGME_SIGSUM_GREEN) != 0) {
+ stream_ << tr("Good") << " ";
}
- if (sign->summary & GPGME_SIGSUM_RED) {
- stream_ << _("Bad") << " ";
+ if ((sign->summary & GPGME_SIGSUM_RED) != 0) {
+ stream_ << tr("Bad") << " ";
}
- if (sign->summary & GPGME_SIGSUM_SIG_EXPIRED) {
- stream_ << _("Expired") << " ";
+ if ((sign->summary & GPGME_SIGSUM_SIG_EXPIRED) != 0) {
+ stream_ << tr("Expired") << " ";
}
- if (sign->summary & GPGME_SIGSUM_KEY_MISSING) {
- stream_ << _("Missing Key's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_KEY_MISSING) != 0) {
+ stream_ << tr("Missing Key's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_KEY_REVOKED) {
- stream_ << _("Revoked Key's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_KEY_REVOKED) != 0) {
+ stream_ << tr("Revoked Key's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_KEY_EXPIRED) {
- stream_ << _("Expired Key's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_KEY_EXPIRED) != 0) {
+ stream_ << tr("Expired Key's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_CRL_MISSING) {
- stream_ << _("Missing CRL's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_CRL_MISSING) != 0) {
+ stream_ << tr("Missing CRL's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_VALID) {
- stream_ << _("Signature Fully Valid.") << std::endl;
+ if ((sign->summary & GPGME_SIGSUM_VALID) != 0) {
+ stream_ << tr("Signature Fully Valid.") << Qt::endl;
} else {
- stream_ << _("Signature Not Fully Valid.") << std::endl;
- stream_ << _("(May used a subkey to sign)") << std::endl;
+ stream_ << tr("Signature Not Fully Valid.") << Qt::endl;
+ stream_ << tr("(Adjust Trust Level to make it Fully Vaild)")
+ << Qt::endl;
}
- if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) {
- if (!print_signer(stream_, sign)) set_status(0);
+ if ((sign->status & GPGME_SIGSUM_KEY_MISSING) == 0U) {
+ if (!print_signer(stream_, sign)) setStatus(0);
} else {
- stream_ << _("Key is NOT present with ID 0x") << sign->fpr
- << std::endl;
+ stream_ << tr("Key is NOT present with ID 0x") << sign->fpr
+ << Qt::endl;
}
- set_status(1);
+ setStatus(1);
break;
case GPG_ERR_NO_PUBKEY:
- stream_ << _("A signature could NOT be verified due to a Missing Key")
- << std::endl;
- set_status(-2);
+ stream_
+ << tr("A signature could NOT be verified due to a Missing Key")
+ << Qt::endl;
+ setStatus(-2);
break;
case GPG_ERR_CERT_REVOKED:
- stream_ << _("A signature is valid but the key used to verify the "
- "signature has been revoked")
- << std::endl;
+ stream_ << tr("A signature is valid but the key used to verify the "
+ "signature has been revoked")
+ << Qt::endl;
if (!print_signer(stream_, sign)) {
- set_status(0);
+ setStatus(0);
}
- set_status(-1);
+ setStatus(-1);
break;
case GPG_ERR_SIG_EXPIRED:
- stream_ << _("A signature is valid but expired") << std::endl;
+ stream_ << tr("A signature is valid but expired") << Qt::endl;
if (!print_signer(stream_, sign)) {
- set_status(0);
+ setStatus(0);
}
- set_status(-1);
+ setStatus(-1);
break;
case GPG_ERR_KEY_EXPIRED:
- stream_ << _("A signature is valid but the key used to "
- "verify the signature has expired.")
- << std::endl;
+ stream_ << tr("A signature is valid but the key used to "
+ "verify the signature has expired.")
+ << Qt::endl;
if (!print_signer(stream_, sign)) {
- set_status(0);
+ setStatus(0);
}
break;
case GPG_ERR_GENERAL:
- stream_ << _("There was some other error which prevented "
- "the signature verification.")
- << std::endl;
+ stream_ << tr("There was some other error which prevented "
+ "the signature verification.")
+ << Qt::endl;
status_ = -1;
- canContinue = false;
+ can_continue = false;
break;
default:
- auto fpr = std::string(sign->fpr);
- stream_ << _("Error for key with fingerprint") << " "
- << GpgFrontend::beautify_fingerprint(fpr);
- set_status(-1);
+ auto fpr = QString(sign->fpr);
+ stream_ << tr("Error for key with fingerprint") << " "
+ << GpgFrontend::BeautifyFingerprint(fpr);
+ setStatus(-1);
}
- stream_ << std::endl;
+ stream_ << Qt::endl;
sign = sign->next;
}
- stream_ << "<------------" << std::endl;
+ stream_ << Qt::endl;
} else {
stream_
- << "[>] "
- << _("Could not find information that can be used for verification.")
- << std::endl;
- set_status(0);
+ << "-> "
+ << tr("Could not find information that can be used for verification.")
+ << Qt::endl;
+ setStatus(0);
return;
}
}
-bool GpgFrontend::GpgVerifyResultAnalyse::print_signer(
- std::stringstream &stream, gpgme_signature_t sign) {
- bool keyFound = true;
+auto GpgFrontend::GpgVerifyResultAnalyse::print_signer(QTextStream &stream,
+ gpgme_signature_t sign)
+ -> bool {
+ bool key_found = true;
auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(sign->fpr);
if (!key.IsGood()) {
- stream << " " << _("Signed By") << ": "
- << "<" << _("Unknown") << ">" << std::endl;
- set_status(0);
- keyFound = false;
+ stream << "- " << tr("Signed By") << ": "
+ << "<" << tr("Unknown") << ">" << Qt::endl;
+ setStatus(0);
+ key_found = false;
} else {
- stream << " " << _("Signed By") << ": "
- << key.GetUIDs()->front().GetUID() << std::endl;
+ stream << "- " << tr("Signed By") << ": " << key.GetUIDs()->front().GetUID()
+ << Qt::endl;
+ }
+ if (sign->pubkey_algo != 0U) {
+ stream << "- " << tr("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(sign->pubkey_algo) << Qt::endl;
+ }
+ if (sign->hash_algo != 0U) {
+ stream << "- " << tr("Hash Algo") << ": "
+ << gpgme_hash_algo_name(sign->hash_algo) << Qt::endl;
}
- if (sign->pubkey_algo)
- stream << " " << _("Public Key Algo") << ": "
- << gpgme_pubkey_algo_name(sign->pubkey_algo) << std::endl;
- if (sign->hash_algo)
- stream << " " << _("Hash Algo") << ": "
- << gpgme_hash_algo_name(sign->hash_algo) << std::endl;
- if (sign->timestamp)
- stream << " " << _("Date") << "(" << _("UTC") << ")"
- << ": "
- << boost::posix_time::to_iso_extended_string(
- boost::posix_time::from_time_t(sign->timestamp))
- << std::endl;
- stream << std::endl;
- return keyFound;
+ if (sign->timestamp != 0U) {
+ stream << "- " << tr("Date") << "(" << tr("UTC") << ")"
+ << ": " << QDateTime::fromSecsSinceEpoch(sign->timestamp).toString()
+ << Qt::endl;
+
+ stream << "- " << tr("Date") << "(" << tr("Localized") << ")"
+ << ": " << GetFormatedDateByTimestamp(sign->timestamp) << Qt::endl;
+ }
+ stream << Qt::endl;
+ return key_found;
}
-gpgme_signature_t GpgFrontend::GpgVerifyResultAnalyse::GetSignatures() const {
- if (result_)
- return result_->signatures;
- else
- return nullptr;
+auto GpgFrontend::GpgVerifyResultAnalyse::GetSignatures() const
+ -> gpgme_signature_t {
+ if (result_.IsGood()) {
+ return result_.GetRaw()->signatures;
+ }
+ return nullptr;
}
-GpgFrontend::GpgVerifyResult
-GpgFrontend::GpgVerifyResultAnalyse::TakeChargeOfResult() {
- return std::move(result_);
+
+auto GpgFrontend::GpgVerifyResultAnalyse::TakeChargeOfResult()
+ -> GpgFrontend::GpgVerifyResult {
+ return result_;
}
diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
index ce8e03ad..8aa2e41f 100644
--- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGVERIFYRESULTANALYSE_H
-#define GPGFRONTEND_GPGVERIFYRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
-#include "core/model/GpgKeySignature.h"
+#include "core/model/GpgVerifyResult.h"
namespace GpgFrontend {
/**
@@ -38,6 +37,7 @@ namespace GpgFrontend {
*
*/
class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Verify Result Analyse object
@@ -52,21 +52,21 @@ class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
*
* @return gpgme_signature_t
*/
- gpgme_signature_t GetSignatures() const;
+ auto GetSignatures() const -> gpgme_signature_t;
/**
* @brief
*
* @return GpgVerifyResult
*/
- GpgVerifyResult TakeChargeOfResult();
+ auto TakeChargeOfResult() -> GpgVerifyResult;
- private:
+ protected:
/**
* @brief
*
*/
- void do_analyse();
+ void doAnalyse() final;
private:
/**
@@ -77,12 +77,10 @@ class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
* @return true
* @return false
*/
- bool print_signer(std::stringstream &stream, gpgme_signature_t sign);
+ auto print_signer(QTextStream &stream, gpgme_signature_t sign) -> bool;
GpgError error_; ///<
GpgVerifyResult result_; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGVERIFYRESULTANALYSE_H