aboutsummaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/GpgContext.cpp134
-rw-r--r--src/core/GpgContext.h2
-rw-r--r--src/core/GpgCoreInit.cpp89
-rw-r--r--src/core/function/ArchiveFileOperator.cpp15
-rw-r--r--src/core/function/CharsetOperator.cpp6
-rw-r--r--src/core/function/aes/aes_ssl_cbc.cpp4
-rw-r--r--src/core/model/GpgData.cpp3
-rw-r--r--src/core/thread/Task.cpp2
8 files changed, 187 insertions, 68 deletions
diff --git a/src/core/GpgContext.cpp b/src/core/GpgContext.cpp
index a5213134..f8dbebc6 100644
--- a/src/core/GpgContext.cpp
+++ b/src/core/GpgContext.cpp
@@ -40,8 +40,10 @@
#include "core/GpgModel.h"
#include "core/common/CoreCommonUtil.h"
#include "core/function/CoreSignalStation.h"
+#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgCommandExecutor.h"
#include "core/thread/TaskRunnerGetter.h"
+#include "spdlog/spdlog.h"
#include "thread/Task.h"
#ifdef _WIN32
@@ -58,20 +60,12 @@ GpgContext::GpgContext(int channel)
* Set up gpgme-context, set paths to app-run path
*/
GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) {
- static bool _first = true;
-
- if (_first) {
- /* Initialize the locale environment. */
- SPDLOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
- info_.GpgMEVersion = gpgme_check_version(nullptr);
- gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr));
-#ifdef LC_MESSAGES
- gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr));
-#endif
- _first = false;
- }
-
gpgme_ctx_t _p_ctx;
+
+ // get gpgme library version
+ info_.GpgMEVersion = gpgme_check_version(nullptr);
+
+ // create a new context
check_gpg_error(gpgme_new(&_p_ctx));
_ctx_ref = CtxRefHandler(_p_ctx);
@@ -83,6 +77,17 @@ GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) {
assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
}
+ // set context offline mode
+ SPDLOG_DEBUG("gpg context offline mode: {}", args_.offline_mode);
+ gpgme_set_offline(_ctx_ref.get(), args_.offline_mode ? 1 : 0);
+
+ // set option auto import missing key
+ // invalid at offline mode
+ SPDLOG_DEBUG("gpg context auto import missing key: {}", args_.offline_mode);
+ if (!args.offline_mode && args.auto_import_missing_key)
+ check_gpg_error(gpgme_set_ctx_flag(_ctx_ref.get(), "auto-key-import", "1"));
+
+ // get engine info
auto engine_info = gpgme_ctx_get_engine_info(*this);
// Check ENV before running
bool check_passed = false, find_openpgp = false, find_gpgconf = false,
@@ -219,8 +224,22 @@ void GpgContext::post_init_ctx() {
// preload info
auto &info = GetInfo();
- // listen passphrase input event
- SetPassphraseCb(custom_passphrase_cb);
+ auto &settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ bool use_pinentry_as_password_input_dialog = false;
+ try {
+ use_pinentry_as_password_input_dialog =
+ settings.lookup("general.use_pinentry_as_password_input_dialog");
+ } catch (...) {
+ SPDLOG_ERROR(
+ "setting operation error: use_pinentry_as_password_input_dialog");
+ }
+
+ // use custom qt dialog to replace pinentry
+ if (!use_pinentry_as_password_input_dialog) {
+ SetPassphraseCb(custom_passphrase_cb);
+ }
+
connect(this, &GpgContext::SignalNeedUserInputPassphrase,
CoreSignalStation::GetInstance(),
&CoreSignalStation::SignalNeedUserInputPassphrase);
@@ -372,6 +391,16 @@ const GpgInfo &GpgContext::GetInfo(bool refresh) {
auto component_name = info_split_list[0];
auto component_desc = info_split_list[1];
auto component_path = info_split_list[2];
+
+ boost::algorithm::trim(component_name);
+ boost::algorithm::trim(component_desc);
+ boost::algorithm::trim(component_path);
+
+#ifdef WINDOWS
+ // replace some special substrings on windows platform
+ boost::replace_all(component_path, "%3a", ":");
+#endif
+
auto binary_checksum = check_binary_chacksum(component_path);
SPDLOG_DEBUG(
@@ -386,13 +415,13 @@ const GpgInfo &GpgContext::GetInfo(bool refresh) {
version = info_.GnupgVersion;
}
if (component_name == "gpg-agent") {
- info_.GpgAgentPath = info_split_list[2];
+ info_.GpgAgentPath = component_path;
}
if (component_name == "dirmngr") {
- info_.DirmngrPath = info_split_list[2];
+ info_.DirmngrPath = component_path;
}
if (component_name == "keyboxd") {
- info_.KeyboxdPath = info_split_list[2];
+ info_.KeyboxdPath = component_path;
}
{
@@ -436,16 +465,25 @@ const GpgInfo &GpgContext::GetInfo(bool refresh) {
if (info_split_list.size() != 2) continue;
+ auto configuration_name = info_split_list[0];
+ auto configuration_value = info_split_list[1];
+ boost::algorithm::trim(configuration_name);
+ boost::algorithm::trim(configuration_value);
+
+#ifdef WINDOWS
+ // replace some special substrings on windows platform
+ boost::replace_all(configuration_value, "%3a", ":");
+#endif
+
// record gnupg home path
- if (info_split_list[0] == "homedir") {
+ if (configuration_name == "homedir") {
info_.GnuPGHomePath = info_split_list[1];
}
- auto configuration_name = info_split_list[0];
{
// try lock
std::unique_lock lock(info_.Lock);
- configurations_info[configuration_name] = {info_split_list[1]};
+ configurations_info[configuration_name] = {configuration_value};
}
}
});
@@ -489,12 +527,19 @@ const GpgInfo &GpgContext::GetInfo(bool refresh) {
if (info_split_list.size() != 6) continue;
auto configuration_name = info_split_list[0];
+ boost::algorithm::trim(configuration_name);
{
// try lock
std::unique_lock lock(info_.Lock);
options_info[configuration_name] = {
info_split_list[1], info_split_list[2], info_split_list[3],
info_split_list[4], info_split_list[5]};
+
+ boost::algorithm::trim(options_info[configuration_name][0]);
+ boost::algorithm::trim(options_info[configuration_name][1]);
+ boost::algorithm::trim(options_info[configuration_name][2]);
+ boost::algorithm::trim(options_info[configuration_name][3]);
+ boost::algorithm::trim(options_info[configuration_name][4]);
}
}
});
@@ -540,6 +585,7 @@ const GpgInfo &GpgContext::GetInfo(bool refresh) {
if (info_split_list.size() != 10) continue;
auto configuration_name = info_split_list[0];
+ boost::algorithm::trim(configuration_name);
{
// try lock
std::unique_lock lock(info_.Lock);
@@ -547,6 +593,25 @@ const GpgInfo &GpgContext::GetInfo(bool refresh) {
info_split_list[1], info_split_list[2], info_split_list[3],
info_split_list[4], info_split_list[5], info_split_list[6],
info_split_list[7], info_split_list[8], info_split_list[9]};
+
+ boost::algorithm::trim(
+ available_options_info[configuration_name][0]);
+ boost::algorithm::trim(
+ available_options_info[configuration_name][1]);
+ boost::algorithm::trim(
+ available_options_info[configuration_name][2]);
+ boost::algorithm::trim(
+ available_options_info[configuration_name][3]);
+ boost::algorithm::trim(
+ available_options_info[configuration_name][4]);
+ boost::algorithm::trim(
+ available_options_info[configuration_name][5]);
+ boost::algorithm::trim(
+ available_options_info[configuration_name][6]);
+ boost::algorithm::trim(
+ available_options_info[configuration_name][7]);
+ boost::algorithm::trim(
+ available_options_info[configuration_name][8]);
}
}
});
@@ -561,20 +626,33 @@ const GpgInfo &GpgContext::GetInfo(bool refresh) {
std::optional<std::string> GpgContext::check_binary_chacksum(
std::filesystem::path path) {
- QFile f(QString::fromStdString(path.u8string()));
- if (!f.open(QFile::ReadOnly)) return {};
+ // check file info and access rights
+ QFileInfo info(QString::fromStdString(path.u8string()));
+ if (!info.exists() || !info.isFile() || !info.isReadable()) {
+ SPDLOG_ERROR("get info for file {} error, exists: {}",
+ info.filePath().toStdString(), info.exists());
+ return {};
+ }
+
+ // open and read file
+ QFile f(info.filePath());
+ if (!f.open(QIODevice::ReadOnly)) {
+ SPDLOG_ERROR("open {} to calculate check sum error: {}", path.u8string(),
+ f.errorString().toStdString());
+ return {};
+ }
// read all data from file
auto buffer = f.readAll();
f.close();
- auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5);
+ auto hash_sha = QCryptographicHash(QCryptographicHash::Sha256);
// md5
- hash_md5.addData(buffer);
- auto md5 = hash_md5.result().toHex().toStdString();
- SPDLOG_DEBUG("md5 {}", md5);
+ hash_sha.addData(buffer);
+ auto sha = hash_sha.result().toHex().toStdString();
+ SPDLOG_DEBUG("checksum for file {} is {}", path.u8string(), sha);
- return md5.substr(0, 6);
+ return sha.substr(0, 6);
}
void GpgContext::_ctx_ref_deleter::operator()(gpgme_ctx_t _ctx) {
diff --git a/src/core/GpgContext.h b/src/core/GpgContext.h
index 384271a6..2ff87e6b 100644
--- a/src/core/GpgContext.h
+++ b/src/core/GpgContext.h
@@ -51,6 +51,8 @@ struct GpgContextInitArgs {
std::string gpg_path = {};
bool test_mode = false;
bool ascii = true;
+ bool offline_mode = false;
+ bool auto_import_missing_key = false;
GpgContextInitArgs() = default;
};
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp
index 840b2b87..9395bac7 100644
--- a/src/core/GpgCoreInit.cpp
+++ b/src/core/GpgCoreInit.cpp
@@ -36,6 +36,10 @@
#include "core/GpgContext.h"
#include "core/function/GlobalSettingStation.h"
#include "function/gpg/GpgAdvancedOperator.h"
+#include "spdlog/spdlog.h"
+#include "thread/Task.h"
+#include "thread/TaskRunner.h"
+#include "thread/TaskRunnerGetter.h"
namespace GpgFrontend {
@@ -93,12 +97,38 @@ void ShutdownCoreLoggingSystem() {
void ResetGpgFrontendCore() { reset_gpgfrontend_core(); }
void init_gpgfrontend_core() {
- // read from settings file
+ /* Initialize the locale environment. */
+ SPDLOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
+ // init gpgme subsystem
+ gpgme_check_version(nullptr);
+ gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr));
+#ifdef LC_MESSAGES
+ gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr));
+#endif
+
+ // get settings
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ // read settings
+ bool forbid_all_gnupg_connection = false;
+ try {
+ forbid_all_gnupg_connection =
+ settings.lookup("network.forbid_all_gnupg_connection");
+ } catch (...) {
+ SPDLOG_ERROR("setting operation error: forbid_all_gnupg_connection");
+ }
+
+ bool auto_import_missing_key = false;
+ try {
+ auto_import_missing_key =
+ settings.lookup("network.auto_import_missing_key");
+ } catch (...) {
+ SPDLOG_ERROR("setting operation error: auto_import_missing_key");
+ }
+ // read from settings file
bool use_custom_key_database_path = false;
try {
- auto& settings =
- GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings();
use_custom_key_database_path =
settings.lookup("general.use_custom_key_database_path");
} catch (...) {
@@ -110,8 +140,6 @@ void init_gpgfrontend_core() {
std::string custom_key_database_path;
try {
- auto& settings =
- GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings();
custom_key_database_path = static_cast<std::string>(
settings.lookup("general.custom_key_database_path"));
@@ -123,7 +151,7 @@ void init_gpgfrontend_core() {
custom_key_database_path);
// init default channel
- GpgFrontend::GpgContext::CreateInstance(
+ auto& default_ctx = GpgFrontend::GpgContext::CreateInstance(
GPGFRONTEND_DEFAULT_CHANNEL, [=]() -> std::unique_ptr<ChannelObject> {
GpgFrontend::GpgContextInitArgs args;
@@ -132,23 +160,46 @@ void init_gpgfrontend_core() {
args.db_path = custom_key_database_path;
}
- return std::unique_ptr<ChannelObject>(new GpgContext(args));
- });
-
- // init non-ascii channel
- GpgFrontend::GpgContext::CreateInstance(
- GPGFRONTEND_NON_ASCII_CHANNEL, [=]() -> std::unique_ptr<ChannelObject> {
- GpgFrontend::GpgContextInitArgs args;
- args.ascii = false;
-
- // set key database path
- if (use_custom_key_database_path && !custom_key_database_path.empty()) {
- args.db_path = custom_key_database_path;
- }
+ args.offline_mode = forbid_all_gnupg_connection;
+ args.auto_import_missing_key = auto_import_missing_key;
return std::unique_ptr<ChannelObject>(new GpgContext(args));
});
+ // exit if failed
+ if (!default_ctx.good()) {
+ SPDLOG_ERROR("default gpgme context init error, exit.");
+ QCoreApplication::exit();
+ };
+
+ // async init no-ascii channel
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG)
+ ->PostTask(
+ new Thread::Task([=](Thread::Task::DataObjectPtr data_obj) -> int {
+ // init non-ascii channel
+ auto& ctx = GpgFrontend::GpgContext::CreateInstance(
+ GPGFRONTEND_NON_ASCII_CHANNEL,
+ [=]() -> std::unique_ptr<ChannelObject> {
+ GpgFrontend::GpgContextInitArgs args;
+ args.ascii = false;
+
+ // set key database path
+ if (use_custom_key_database_path &&
+ !custom_key_database_path.empty()) {
+ args.db_path = custom_key_database_path;
+ }
+
+ args.offline_mode = forbid_all_gnupg_connection;
+ args.auto_import_missing_key = auto_import_missing_key;
+
+ return std::unique_ptr<ChannelObject>(new GpgContext(args));
+ });
+ if (!ctx.good()) SPDLOG_ERROR("no-ascii channel init error");
+
+ return ctx.good() ? 0 : -1;
+ }));
+
// try to restart all components
GpgFrontend::GpgAdvancedOperator::GetInstance().RestartGpgComponents();
}
diff --git a/src/core/function/ArchiveFileOperator.cpp b/src/core/function/ArchiveFileOperator.cpp
index 04c9326f..8aad0500 100644
--- a/src/core/function/ArchiveFileOperator.cpp
+++ b/src/core/function/ArchiveFileOperator.cpp
@@ -136,8 +136,6 @@ void GpgFrontend::ArchiveFileOperator::CreateArchive(
}
for (;;) {
- bool needcr = false;
-
entry = archive_entry_new();
r = archive_read_next_header2(disk, entry);
@@ -149,15 +147,6 @@ void GpgFrontend::ArchiveFileOperator::CreateArchive(
}
archive_read_disk_descend(disk);
-#ifdef WINDOWS
- auto entry_path =
- QString::fromStdWString(std::wstring(archive_entry_pathname_w(entry)))
- .toUtf8()
- .toStdString();
-#else
- auto entry_path = std::string(archive_entry_pathname_utf8(entry));
-#endif
-
SPDLOG_DEBUG("Adding: {} size: {} bytes: {} file type: {}",
archive_entry_pathname_utf8(entry),
archive_entry_size(entry), archive_entry_filetype(entry));
@@ -201,7 +190,6 @@ void GpgFrontend::ArchiveFileOperator::ExtractArchive(
struct archive *a;
struct archive *ext;
struct archive_entry *entry;
- int r;
a = archive_read_new();
ext = archive_write_disk_new();
@@ -241,8 +229,9 @@ void GpgFrontend::ArchiveFileOperator::ExtractArchive(
archive_error_string(a));
throw std::runtime_error("archive_read_open_filename() failed");
}
+
for (;;) {
- r = archive_read_next_header(a, &entry);
+ int r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_EOF) break;
if (r != ARCHIVE_OK) {
SPDLOG_ERROR("archive_read_next_header() failed: {}",
diff --git a/src/core/function/CharsetOperator.cpp b/src/core/function/CharsetOperator.cpp
index 0e40e317..72c5e72b 100644
--- a/src/core/function/CharsetOperator.cpp
+++ b/src/core/function/CharsetOperator.cpp
@@ -117,12 +117,10 @@ bool GpgFrontend::CharsetOperator::Convert2Utf8(const std::string &buffer,
if (status == U_BUFFER_OVERFLOW_ERROR) {
status = U_ZERO_ERROR;
- target_limit = target_capacity + 1;
out_buffer.clear();
out_buffer.resize(target_capacity);
- target_capacity =
- ucnv_convert(from_encode.c_str(), to_encode.c_str(), out_buffer.data(),
- out_buffer.size(), buffer.data(), buffer.size(), &status);
+ 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)) {
diff --git a/src/core/function/aes/aes_ssl_cbc.cpp b/src/core/function/aes/aes_ssl_cbc.cpp
index 88a54baa..3aa80ef5 100644
--- a/src/core/function/aes/aes_ssl_cbc.cpp
+++ b/src/core/function/aes/aes_ssl_cbc.cpp
@@ -59,7 +59,7 @@ 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 = (uint8_t *)malloc(c_len);
+ 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);
@@ -86,7 +86,7 @@ uint8_t *aes_256_cbc_encrypt(EVP_CIPHER_CTX *e, uint8_t *plaintext, int *len) {
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 = (uint8_t *)malloc(p_len);
+ 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);
diff --git a/src/core/model/GpgData.cpp b/src/core/model/GpgData.cpp
index 5aa95dc6..05f61a46 100644
--- a/src/core/model/GpgData.cpp
+++ b/src/core/model/GpgData.cpp
@@ -40,7 +40,8 @@ GpgFrontend::GpgData::GpgData() {
GpgFrontend::GpgData::GpgData(void* buffer, size_t size, bool copy) {
gpgme_data_t data;
- auto err = gpgme_data_new_from_mem(&data, (const char*)buffer, size, copy);
+ auto err = gpgme_data_new_from_mem(&data, static_cast<const char*>(buffer),
+ size, copy);
assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
data_ref_ = std::unique_ptr<struct gpgme_data, _data_ref_deleter>(data);
diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp
index f3c6ae86..7173b69e 100644
--- a/src/core/thread/Task.cpp
+++ b/src/core/thread/Task.cpp
@@ -218,7 +218,7 @@ void GpgFrontend::Thread::Task::DataObject::free_heap_ptr(Destructor *ptr) {
if (ptr->destroy != nullptr) {
ptr->destroy(ptr->p_obj);
}
- free((void *)ptr->p_obj);
+ free(const_cast<void *>(ptr->p_obj));
delete ptr;
}