aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gpg/GpgContext.cpp35
-rw-r--r--src/gpg/GpgContext.h31
-rw-r--r--src/gpg/GpgFunctionObject.h113
-rw-r--r--src/gpg/function/GpgKeyGetter.cpp1
-rw-r--r--src/gpg/function/GpgKeyGetter.h18
-rw-r--r--src/gpg/function/GpgKeyImportExportor.cpp64
-rw-r--r--src/gpg/function/GpgKeyImportExportor.h22
7 files changed, 208 insertions, 76 deletions
diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp
index a8c9a6de..c1911a17 100644
--- a/src/gpg/GpgContext.cpp
+++ b/src/gpg/GpgContext.cpp
@@ -23,9 +23,13 @@
*/
#include "gpg/GpgContext.h"
-#include "GpgConstants.h"
+#include <gpg-error.h>
+#include <gpgme.h>
#include <functional>
+#include <string>
+
+#include "GpgConstants.h"
#ifdef _WIN32
#include <windows.h>
@@ -39,7 +43,10 @@ namespace GpgFrontend {
* Constructor
* Set up gpgme-context, set paths to app-run path
*/
-GpgContext::GpgContext() {
+GpgContext::GpgContext(bool independent_database,
+ std::string db_path,
+ int channel)
+ : SingletonFunctionObject<GpgContext>(channel) {
static bool _first = true;
if (_first) {
@@ -57,25 +64,26 @@ GpgContext::GpgContext() {
check_gpg_error(gpgme_new(&_p_ctx));
_ctx_ref = CtxRefHandler(_p_ctx);
- LOG(INFO) << "GpgContext _ctx_ref Created";
+ DLOG(INFO) << "GpgContext _ctx_ref Created";
auto engineInfo = gpgme_ctx_get_engine_info(*this);
- LOG(INFO) << "GpgContext gpgme_ctx_get_engine_info Called";
+ DLOG(INFO) << "GpgContext gpgme_ctx_get_engine_info Called";
// Check ENV before running
bool check_pass = false, find_openpgp = false, find_gpgconf = false,
find_assuan = false, find_cms = false;
while (engineInfo != nullptr) {
- LOG(INFO) << gpgme_get_protocol_name(engineInfo->protocol) << " "
- << engineInfo->file_name << " " << engineInfo->version;
+ DLOG(INFO) << gpgme_get_protocol_name(engineInfo->protocol) << " "
+ << engineInfo->file_name << " " << engineInfo->version;
if (engineInfo->protocol == GPGME_PROTOCOL_GPGCONF &&
strcmp(engineInfo->version, "1.0.0") != 0)
find_gpgconf = true;
if (engineInfo->protocol == GPGME_PROTOCOL_OpenPGP &&
strcmp(engineInfo->version, "1.0.0") != 0)
- find_openpgp = true, info.AppPath = engineInfo->file_name;
+ find_openpgp = true, info.AppPath = engineInfo->file_name,
+ info.DatabasePath = "default";
if (engineInfo->protocol == GPGME_PROTOCOL_CMS &&
strcmp(engineInfo->version, "1.0.0") != 0)
find_cms = true;
@@ -87,11 +95,21 @@ GpgContext::GpgContext() {
if (find_gpgconf && find_openpgp && find_cms && find_assuan)
check_pass = true;
- LOG(INFO) << "GpgContext check_pass " << check_pass;
+ DLOG(INFO) << "GpgContext check_pass " << check_pass;
if (!check_pass) {
good_ = false;
return;
} else {
+ // Set Independent Database
+ if (independent_database) {
+ info.DatabasePath = db_path;
+ auto err = gpgme_ctx_set_engine_info(
+ _ctx_ref.get(), GPGME_PROTOCOL_OpenPGP, info.AppPath.c_str(),
+ info.DatabasePath.c_str());
+ assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+ DLOG(INFO) << "Set independent_database path" << db_path;
+ }
+
/** Setting the output type must be done at the beginning */
/** think this means ascii-armor --> ? */
gpgme_set_armor(*this, 1);
@@ -104,6 +122,7 @@ GpgContext::GpgContext() {
GPGME_KEYLIST_MODE_WITH_TOFU));
good_ = true;
}
+ DLOG(INFO) << "GpgContext init done ";
}
bool GpgContext::good() const {
diff --git a/src/gpg/GpgContext.h b/src/gpg/GpgContext.h
index 21fb5aee..0aa41f2f 100644
--- a/src/gpg/GpgContext.h
+++ b/src/gpg/GpgContext.h
@@ -35,21 +35,22 @@ namespace GpgFrontend {
* Custom Encapsulation of GpgME APIs
*/
class GpgContext : public SingletonFunctionObject<GpgContext> {
-
-public:
- GpgContext();
+ public:
+ GpgContext(bool independent_database = false,
+ std::string path = std::string(),
+ int channel = 0);
~GpgContext() override = default;
[[nodiscard]] bool good() const;
- [[nodiscard]] const GpgInfo &GetInfo() const { return info; }
+ [[nodiscard]] const GpgInfo& GetInfo() const { return info; }
static std::string getGpgmeVersion();
operator gpgme_ctx_t() const { return _ctx_ref.get(); }
-private:
+ private:
GpgInfo info;
struct _ctx_ref_deletor {
@@ -59,17 +60,17 @@ private:
}
};
- using CtxRefHandler =
- std::unique_ptr<struct gpgme_context, _ctx_ref_deletor>;
+ using CtxRefHandler = std::unique_ptr<struct gpgme_context, _ctx_ref_deletor>;
CtxRefHandler _ctx_ref = nullptr;
bool good_ = true;
-public:
- static gpgme_error_t test_passphrase_cb(void *opaque, const char *uid_hint,
- const char *passphrase_info,
- int last_was_bad, int fd) {
-
+ public:
+ static gpgme_error_t test_passphrase_cb(void* opaque,
+ const char* uid_hint,
+ const char* passphrase_info,
+ int last_was_bad,
+ int fd) {
LOG(INFO) << "test_passphrase_cb Called";
size_t res;
char pass[] = "abcdefg\n";
@@ -82,7 +83,7 @@ public:
(void)last_was_bad;
do {
- res = gpgme_io_write(fd, &pass[off], pass_len - off);
+ res = gpgme_io_write(fd, &pass[off], pass_len - off);
if (res > 0)
off += res;
} while (res > 0 && off != pass_len);
@@ -92,6 +93,6 @@ public:
void SetPassphraseCb(decltype(test_passphrase_cb) func) const;
};
-} // namespace GpgFrontend
+} // namespace GpgFrontend
-#endif // __SGPGMEPP_CONTEXT_H__
+#endif // __SGPGMEPP_CONTEXT_H__
diff --git a/src/gpg/GpgFunctionObject.h b/src/gpg/GpgFunctionObject.h
index 654f81d3..cb55cf92 100644
--- a/src/gpg/GpgFunctionObject.h
+++ b/src/gpg/GpgFunctionObject.h
@@ -25,44 +25,121 @@
#ifndef GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
#define GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
+#include <map>
#include <memory>
#include <mutex>
+#include <shared_mutex>
+#include <stdexcept>
+#include <string>
#include <easyloggingpp/easylogging++.h>
namespace GpgFrontend {
-template <typename T> class SingletonFunctionObject {
-public:
- static T &GetInstance() {
- LOG(INFO) << "SingletonFunctionObject GetInstance Calling "
- << typeid(T).name();
- std::lock_guard<std::mutex> guard(_instance_mutex);
- if (_instance == nullptr)
- _instance = std::make_unique<T>();
- return *_instance;
+
+template <typename T>
+class SingletonFunctionObject {
+ public:
+ static T& GetInstance(int channel = 0) {
+ DLOG(INFO) << "SingletonFunctionObject GetInstance Calling "
+ << typeid(T).name() << " channel " << channel;
+ if (!channel) {
+ std::lock_guard<std::mutex> guard(_instance_mutex);
+ if (_instance == nullptr)
+ _instance = std::make_unique<T>();
+ return *_instance;
+ } else {
+ // read _instances_map
+ decltype(_instances_map.end()) _it;
+ {
+ std::shared_lock lock(_instances_mutex);
+ _it = _instances_map.find(channel);
+ }
+ if (_it != _instances_map.end())
+ return *_it->second;
+ else
+ return CreateInstance(channel);
+ }
}
- SingletonFunctionObject(T &&) = delete;
+ static T& CreateInstance(int channel, std::unique_ptr<T> p_obj = nullptr) {
+ DLOG(INFO) << "SingletonFunctionObject CreateInstance Calling "
+ << typeid(T).name() << " channel " << channel;
+ if (!channel)
+ return *_instance;
+
+ // read _instances_map
+ decltype(_instances_map.end()) _it;
+ {
+ std::shared_lock lock(_instances_mutex);
+ _it = _instances_map.find(channel);
+ }
+ if (_it == _instances_map.end()) {
+ {
+ std::lock_guard<std::mutex> guard(_default_channel_mutex);
+ int tmp = channel;
+ std::swap(_default_channel, tmp);
+ if (p_obj == nullptr)
+ p_obj = std::make_unique<T>();
+ std::swap(_default_channel, tmp);
+ }
+ T* obj = p_obj.get();
+
+ // change _instances_map
+ {
+ std::unique_lock lock(_instances_mutex);
+ _instances_map.insert({channel, std::move(p_obj)});
+ }
+ return *obj;
+ } else {
+ return *_it->second;
+ }
+ }
+
+ static int GetDefaultChannel() { return _default_channel; }
+
+ int GetChannel() const { return channel_; }
+
+ SingletonFunctionObject(T&&) = delete;
+
+ SingletonFunctionObject(const T&) = delete;
- SingletonFunctionObject(const T &) = delete;
+ void operator=(const T&) = delete;
- void operator=(const T &) = delete;
+ protected:
+ SingletonFunctionObject() {}
-protected:
- SingletonFunctionObject() = default;
+ SingletonFunctionObject(int channel) : channel_(channel) {}
virtual ~SingletonFunctionObject() = default;
-private:
+ private:
+ int channel_ = _default_channel;
+ static int _default_channel;
+ static std::mutex _default_channel_mutex;
static std::mutex _instance_mutex;
+ static std::shared_mutex _instances_mutex;
static std::unique_ptr<T> _instance;
+ static std::map<int, std::unique_ptr<T>> _instances_map;
};
-template <typename T> std::mutex SingletonFunctionObject<T>::_instance_mutex;
+template <typename T>
+int SingletonFunctionObject<T>::_default_channel = 0;
+
+template <typename T>
+std::mutex SingletonFunctionObject<T>::_default_channel_mutex;
+
+template <typename T>
+std::mutex SingletonFunctionObject<T>::_instance_mutex;
+
+template <typename T>
+std::shared_mutex SingletonFunctionObject<T>::_instances_mutex;
template <typename T>
std::unique_ptr<T> SingletonFunctionObject<T>::_instance = nullptr;
-} // namespace GpgFrontend
+template <typename T>
+std::map<int, std::unique_ptr<T>> SingletonFunctionObject<T>::_instances_map;
+
+} // namespace GpgFrontend
-#endif // GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
+#endif // GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
diff --git a/src/gpg/function/GpgKeyGetter.cpp b/src/gpg/function/GpgKeyGetter.cpp
index 6d80088a..ab907ea7 100644
--- a/src/gpg/function/GpgKeyGetter.cpp
+++ b/src/gpg/function/GpgKeyGetter.cpp
@@ -32,6 +32,7 @@ GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr) {
gpgme_get_key(ctx, fpr.c_str(), &_p_key, 1);
if (_p_key == nullptr)
DLOG(WARNING) << "GpgKeyGetter GetKey _p_key Null";
+ assert(_p_key != nullptr);
return GpgKey(std::move(_p_key));
}
diff --git a/src/gpg/function/GpgKeyGetter.h b/src/gpg/function/GpgKeyGetter.h
index 3a291d2d..af22e2f2 100644
--- a/src/gpg/function/GpgKeyGetter.h
+++ b/src/gpg/function/GpgKeyGetter.h
@@ -32,19 +32,19 @@
namespace GpgFrontend {
class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter> {
+ public:
+ GpgKeyGetter() = default;
-public:
- GpgKey GetKey(const std::string &fpr);
+ GpgKey GetKey(const std::string& fpr);
- GpgKey GetPubkey(const std::string &fpr);
+ GpgKey GetPubkey(const std::string& fpr);
KeyListPtr FetchKey();
- GpgKeyGetter() = default;
-
-private:
- GpgContext &ctx = GpgContext::GetInstance();
+ private:
+ GpgContext& ctx =
+ GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel());
};
-} // namespace GpgFrontend
+} // namespace GpgFrontend
-#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
diff --git a/src/gpg/function/GpgKeyImportExportor.cpp b/src/gpg/function/GpgKeyImportExportor.cpp
index 2ee261b4..7a7af4c7 100644
--- a/src/gpg/function/GpgKeyImportExportor.cpp
+++ b/src/gpg/function/GpgKeyImportExportor.cpp
@@ -1,32 +1,62 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
#include "gpg/function/GpgKeyImportExportor.h"
+
#include "GpgConstants.h"
-#include <gpg-error.h>
/**
* Import key pair
* @param inBuffer input byte array
* @return Import information
*/
-GpgFrontend::GpgImportInformation
-GpgFrontend::GpgKeyImportExportor::ImportKey(StdBypeArrayPtr in_buffer) {
- LOG(INFO) << "ImportKey Called in_buffer Size " << in_buffer->size();
+GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExportor::ImportKey(
+ StdBypeArrayPtr in_buffer) {
+ DLOG(INFO) << "ImportKey called in_buffer Size " << in_buffer->size();
+
+ if (in_buffer->empty())
+ return GpgImportInformation();
+
GpgData data_in(in_buffer->data(), in_buffer->size());
+ DLOG(INFO) << "ImportKey gpgme_op_import";
auto err = check_gpg_error(gpgme_op_import(ctx, data_in));
assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
gpgme_import_result_t result;
-
+ DLOG(INFO) << "ImportKey gpgme_op_import_result";
result = gpgme_op_import_result(ctx);
gpgme_import_status_t status = result->imports;
auto import_info = std::make_unique<GpgImportInformation>(result);
- LOG(INFO) << "ImportKey import_information " << result->not_imported << " "
- << result->imported << " " << result->considered;
+ DLOG(INFO) << "ImportKey import_information " << result->not_imported << " "
+ << result->imported << " " << result->considered;
while (status != nullptr) {
GpgImportedKey key;
key.import_status = static_cast<int>(status->status);
key.fpr = status->fpr;
import_info->importedKeys.emplace_back(key);
status = status->next;
- LOG(INFO) << "ImportKey Fpr " << key.fpr << " Status " << key.import_status;
+ DLOG(INFO) << "ImportKey Fpr " << key.fpr << " Status "
+ << key.import_status;
}
return *import_info;
}
@@ -38,7 +68,8 @@ GpgFrontend::GpgKeyImportExportor::ImportKey(StdBypeArrayPtr in_buffer) {
* @return if success
*/
bool GpgFrontend::GpgKeyImportExportor::ExportKeys(
- KeyIdArgsListPtr &uid_list, BypeArrayPtr &out_buffer) const {
+ KeyIdArgsListPtr& uid_list,
+ BypeArrayPtr& out_buffer) const {
if (uid_list->empty())
return false;
@@ -49,8 +80,8 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeys(
auto err = gpgme_op_export(ctx, (*uid_list)[i].c_str(), 0, data_out);
assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
- LOG(INFO) << "exportKeys read_bytes"
- << gpgme_data_seek(data_out, 0, SEEK_END);
+ DLOG(INFO) << "exportKeys read_bytes"
+ << gpgme_data_seek(data_out, 0, SEEK_END);
auto temp_out_buffer = data_out.Read2Buffer();
std::swap(out_buffer, temp_out_buffer);
@@ -66,9 +97,10 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeys(
* @return if success
*/
bool GpgFrontend::GpgKeyImportExportor::ExportKeys(
- KeyArgsList &keys, BypeArrayPtr &out_buffer) const {
+ KeyArgsList& keys,
+ BypeArrayPtr& out_buffer) const {
KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>();
- for (const auto &key : keys)
+ for (const auto& key : keys)
key_ids->push_back(key.id());
return ExportKeys(key_ids, out_buffer);
}
@@ -80,9 +112,9 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeys(
* @return if successful
*/
bool GpgFrontend::GpgKeyImportExportor::ExportSecretKey(
- const GpgKey &key, BypeArrayPtr out_buffer) const {
-
- LOG(INFO) << "Export Secret Key" << key.id().c_str();
+ const GpgKey& key,
+ BypeArrayPtr out_buffer) const {
+ DLOG(INFO) << "Export Secret Key" << key.id().c_str();
gpgme_key_t target_key[2] = {gpgme_key_t(key), nullptr};
diff --git a/src/gpg/function/GpgKeyImportExportor.h b/src/gpg/function/GpgKeyImportExportor.h
index 455e59f8..2cdb4e80 100644
--- a/src/gpg/function/GpgKeyImportExportor.h
+++ b/src/gpg/function/GpgKeyImportExportor.h
@@ -25,6 +25,7 @@
#ifndef _GPGKEYIMPORTEXPORTOR_H
#define _GPGKEYIMPORTEXPORTOR_H
+#include <string>
#include "gpg/GpgConstants.h"
#include "gpg/GpgContext.h"
#include "gpg/GpgFunctionObject.h"
@@ -33,7 +34,7 @@
namespace GpgFrontend {
class GpgImportedKey {
-public:
+ public:
std::string fpr;
int import_status;
};
@@ -41,7 +42,7 @@ public:
typedef std::list<GpgImportedKey> GpgImportedKeyList;
class GpgImportInformation {
-public:
+ public:
GpgImportInformation() = default;
explicit GpgImportInformation(gpgme_import_result_t result) {
@@ -93,19 +94,20 @@ public:
class GpgKeyImportExportor
: public SingletonFunctionObject<GpgKeyImportExportor> {
-public:
+ public:
GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer);
- bool ExportKeys(KeyIdArgsListPtr &uid_list, BypeArrayPtr &out_buffer) const;
+ bool ExportKeys(KeyIdArgsListPtr& uid_list, BypeArrayPtr& out_buffer) const;
- bool ExportKeys(KeyArgsList &keys, BypeArrayPtr &outBuffer) const;
+ bool ExportKeys(KeyArgsList& keys, BypeArrayPtr& outBuffer) const;
- bool ExportSecretKey(const GpgKey &key, BypeArrayPtr outBuffer) const;
+ bool ExportSecretKey(const GpgKey& key, BypeArrayPtr outBuffer) const;
-private:
- GpgContext &ctx = GpgContext::GetInstance();
+ private:
+ GpgContext& ctx =
+ GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel());
};
-} // namespace GpgFrontend
+} // namespace GpgFrontend
-#endif // _GPGKEYIMPORTEXPORTOR_H \ No newline at end of file
+#endif // _GPGKEYIMPORTEXPORTOR_H \ No newline at end of file