diff options
Diffstat (limited to 'src')
23 files changed, 271 insertions, 122 deletions
diff --git a/src/gpg/GpgConstants.cpp b/src/gpg/GpgConstants.cpp index fd3c56b4..b047ffe3 100644 --- a/src/gpg/GpgConstants.cpp +++ b/src/gpg/GpgConstants.cpp @@ -215,6 +215,12 @@ GpgFrontend::GpgVerifyResult GpgFrontend::_new_result( return {result, _result_ref_deletor()}; } +GpgFrontend::GpgGenKeyResult GpgFrontend::_new_result( + gpgme_genkey_result_t&& result) { + gpgme_result_ref(result); + return {result, _result_ref_deletor()}; +} + void GpgFrontend::_result_ref_deletor::operator()(void* _result) { DLOG(INFO) << _("Called") << _result; if (_result != nullptr) gpgme_result_unref(_result); diff --git a/src/gpg/GpgConstants.h b/src/gpg/GpgConstants.h index 14895df7..3c0240d2 100644 --- a/src/gpg/GpgConstants.h +++ b/src/gpg/GpgConstants.h @@ -58,12 +58,14 @@ using GpgEncrResult = std::shared_ptr<struct _gpgme_op_encrypt_result>; using GpgDecrResult = std::shared_ptr<struct _gpgme_op_decrypt_result>; using GpgSignResult = std::shared_ptr<struct _gpgme_op_sign_result>; using GpgVerifyResult = std::shared_ptr<struct _gpgme_op_verify_result>; +using GpgGenKeyResult = std::shared_ptr<struct _gpgme_op_genkey_result>; // Convert from gpgme_xxx_result to GpgXXXResult GpgEncrResult _new_result(gpgme_encrypt_result_t&& result); GpgDecrResult _new_result(gpgme_decrypt_result_t&& result); GpgSignResult _new_result(gpgme_sign_result_t&& result); GpgVerifyResult _new_result(gpgme_verify_result_t&& result); +GpgGenKeyResult _new_result(gpgme_genkey_result_t&& result); // Error Info Printer GpgError check_gpg_error(GpgError err); diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp index d2b500e2..a39918e2 100644 --- a/src/gpg/GpgContext.cpp +++ b/src/gpg/GpgContext.cpp @@ -29,6 +29,7 @@ #include <functional> #include <string> +#include <utility> #include "GpgConstants.h" @@ -36,17 +37,13 @@ #include <windows.h> #endif -#define INT2VOIDP(i) (void*)(uintptr_t)(i) - namespace GpgFrontend { /** * Constructor * Set up gpgme-context, set paths to app-run path */ -GpgContext::GpgContext(bool independent_database, std::string db_path, - bool gpg_alone, std::string gpg_path, int channel) - : SingletonFunctionObject<GpgContext>(channel) { +GpgContext::GpgContext(const GpgContextInitArgs& args) { static bool _first = true; if (_first) { @@ -64,46 +61,57 @@ GpgContext::GpgContext(bool independent_database, std::string db_path, check_gpg_error(gpgme_new(&_p_ctx)); _ctx_ref = CtxRefHandler(_p_ctx); - if (gpg_alone) { - info.AppPath = gpg_path; + if (args.gpg_alone) { + info.AppPath = args.gpg_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); } - auto engineInfo = gpgme_ctx_get_engine_info(*this); + auto engine_info = gpgme_ctx_get_engine_info(*this); // Check ENV before running bool check_pass = false, find_openpgp = false, find_gpgconf = false, find_assuan = false, find_cms = false; - while (engineInfo != nullptr) { - if (engineInfo->protocol == GPGME_PROTOCOL_GPGCONF && - strcmp(engineInfo->version, "1.0.0") != 0) + while (engine_info != nullptr) { + if (engine_info->protocol == GPGME_PROTOCOL_GPGCONF && + strcmp(engine_info->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, - info.DatabasePath = "default", info.GnupgVersion = engineInfo->version; - if (engineInfo->protocol == GPGME_PROTOCOL_CMS && - strcmp(engineInfo->version, "1.0.0") != 0) + if (engine_info->protocol == GPGME_PROTOCOL_OpenPGP && + strcmp(engine_info->version, "1.0.0") != 0) { + find_openpgp = true; + info.AppPath = engine_info->file_name; + info.DatabasePath = "default", info.GnupgVersion = engine_info->version; + DLOG(INFO) << "OpenPGP" + << std::string(engine_info->file_name == nullptr + ? "null" + : engine_info->file_name) + << std::string(engine_info->home_dir == nullptr + ? "null" + : engine_info->home_dir); + } + + if (engine_info->protocol == GPGME_PROTOCOL_CMS && + strcmp(engine_info->version, "1.0.0") != 0) find_cms = true; - if (engineInfo->protocol == GPGME_PROTOCOL_ASSUAN) find_assuan = true; - engineInfo = engineInfo->next; + if (engine_info->protocol == GPGME_PROTOCOL_ASSUAN) find_assuan = true; + engine_info = engine_info->next; } if (find_gpgconf && find_openpgp && find_cms && find_assuan) check_pass = true; if (!check_pass) { - good_ = false; + this->good_ = false; return; } else { - LOG(INFO) << "Gnupg Version" << info.GnupgVersion; + LOG(INFO) << "GnuPG version" << info.GnupgVersion; // Set Independent Database - if (independent_database) { - info.DatabasePath = db_path; + if (args.independent_database) { + info.DatabasePath = args.db_path; + LOG(INFO) << "gpg custom database path" << info.DatabasePath; auto err = gpgme_ctx_set_engine_info( _ctx_ref.get(), GPGME_PROTOCOL_OpenPGP, info.AppPath.c_str(), info.DatabasePath.c_str()); @@ -116,10 +124,20 @@ GpgContext::GpgContext(bool independent_database, std::string db_path, // Speed up loading process gpgme_set_offline(*this, 1); - check_gpg_error(gpgme_set_keylist_mode( - *this, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_WITH_SECRET | - GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_SIG_NOTATIONS | - GPGME_KEYLIST_MODE_WITH_TOFU)); + if (info.GnupgVersion >= "2.0.0") { + LOG(INFO) << "Using GnuPG 2.x"; + check_gpg_error(gpgme_set_keylist_mode( + *this, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_WITH_SECRET | + GPGME_KEYLIST_MODE_SIGS | + GPGME_KEYLIST_MODE_SIG_NOTATIONS | + GPGME_KEYLIST_MODE_WITH_TOFU)); + } else { + LOG(INFO) << "Using GnuPG 1.x"; + check_gpg_error(gpgme_set_keylist_mode( + *this, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_SIGS | + GPGME_KEYLIST_MODE_SIG_NOTATIONS | + GPGME_KEYLIST_MODE_WITH_TOFU)); + } good_ = true; } } diff --git a/src/gpg/GpgContext.h b/src/gpg/GpgContext.h index da19bfd9..887bb7a6 100644 --- a/src/gpg/GpgContext.h +++ b/src/gpg/GpgContext.h @@ -32,14 +32,24 @@ namespace GpgFrontend { +struct GpgContextInitArgs { + bool independent_database = false; + std::string db_path = {}; + bool gpg_alone = false; + std::string gpg_path = {}; + + GpgContextInitArgs() = default; +}; + /** * Custom Encapsulation of GpgME APIs */ class GpgContext : public SingletonFunctionObject<GpgContext> { public: - explicit GpgContext(bool independent_database = false, - std::string path = std::string(), bool gpg_alone = false, - std::string gpg_path = std::string(), int channel = 0); + explicit GpgContext(const GpgContextInitArgs& args = {}); + + explicit GpgContext(int channel) + : SingletonFunctionObject<GpgContext>(channel) {} ~GpgContext() override = default; @@ -54,13 +64,13 @@ class GpgContext : public SingletonFunctionObject<GpgContext> { private: GpgInfo info; - struct _ctx_ref_deletor { + struct _ctx_ref_deleter { void operator()(gpgme_ctx_t _ctx) { if (_ctx != nullptr) gpgme_release(_ctx); } }; - using CtxRefHandler = std::unique_ptr<struct gpgme_context, _ctx_ref_deletor>; + using CtxRefHandler = std::unique_ptr<struct gpgme_context, _ctx_ref_deleter>; CtxRefHandler _ctx_ref = nullptr; bool good_ = true; diff --git a/src/gpg/GpgFunctionObject.h b/src/gpg/GpgFunctionObject.h index 6f1d60af..d81371d9 100644 --- a/src/gpg/GpgFunctionObject.h +++ b/src/gpg/GpgFunctionObject.h @@ -40,57 +40,52 @@ template <typename T> class SingletonFunctionObject { public: static T& GetInstance(int channel = 0) { - 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); - } + static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value, + "T not derived from SingletonFunctionObject<T>"); + + auto _p_pbj = find_object_in_channel(channel); + if (_p_pbj == nullptr) + return *set_object_in_channel(channel, std::make_unique<T>(channel)); + else + return *_p_pbj; + } + + static T& CreateInstance(int channel, + std::function<std::unique_ptr<T>(void)> factory) { + static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value, + "T not derived from SingletonFunctionObject<T>"); + + auto _p_pbj = find_object_in_channel(channel); + if (_p_pbj == nullptr) + return *set_object_in_channel(channel, std::move(factory())); + else + return *_p_pbj; } static T& CreateInstance(int channel, std::unique_ptr<T> p_obj = nullptr) { - if (!channel) return *_instance; + static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value, + "T not derived from SingletonFunctionObject<T>"); + + auto _p_pbj = find_object_in_channel(channel); + if (_p_pbj == nullptr) + return *set_object_in_channel(channel, std::move(p_obj)); + else + return *_p_pbj; + } - // read _instances_map + static T& ReleaseChannel(int channel) { 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; - } + if (_it != _instances_map.end()) _instances_map.erase(_it); + DLOG(INFO) << "channel" << channel << "released"; } static int GetDefaultChannel() { return _default_channel; } - int GetChannel() const { return channel_; } + [[nodiscard]] int GetChannel() const { return channel_; } SingletonFunctionObject(T&&) = delete; @@ -99,29 +94,53 @@ class SingletonFunctionObject { void operator=(const T&) = delete; protected: - SingletonFunctionObject() {} + SingletonFunctionObject() = default; - SingletonFunctionObject(int channel) : channel_(channel) {} + explicit SingletonFunctionObject(int channel) : channel_(channel) {} virtual ~SingletonFunctionObject() = default; + void SetChannel(int channel) { this->channel_ = channel; } + 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; + + static T* find_object_in_channel(int channel) { + // 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 nullptr; + else + return _it->second.get(); + } + } + + static T* set_object_in_channel(int channel, std::unique_ptr<T> p_obj) { + { + if (p_obj == nullptr) p_obj = std::make_unique<T>(); + T* obj = p_obj.get(); + obj->SetChannel(channel); + { + std::unique_lock lock(_instances_mutex); + _instances_map.insert({channel, std::move(p_obj)}); + } + return obj; + } + } }; 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> diff --git a/src/gpg/GpgGenKeyInfo.h b/src/gpg/GpgGenKeyInfo.h index 14290e17..cc679656 100644 --- a/src/gpg/GpgGenKeyInfo.h +++ b/src/gpg/GpgGenKeyInfo.h @@ -27,6 +27,7 @@ #include <boost/date_time.hpp> #include <boost/date_time/gregorian/greg_duration_types.hpp> +#include <boost/format.hpp> #include <string> #include <vector> @@ -34,7 +35,10 @@ namespace GpgFrontend { class GenKeyInfo { bool subKey = true; - std::string userid; + std::string name; + std::string email; + std::string comment; + std::string algo; int keySize = 2048; boost::posix_time::ptime expired = @@ -60,9 +64,23 @@ class GenKeyInfo { void setIsSubKey(bool m_sub_key) { GenKeyInfo::subKey = m_sub_key; } - [[nodiscard]] const std::string &getUserid() const { return userid; } + [[nodiscard]] std::string getUserid() const { + auto uid_format = boost::format("%1%(%2%)<%3%>") % this->name % + this->comment % this->email; + return uid_format.str(); + } + + void setName(const std::string &m_name) { this->name = m_name; } + + void setEmail(const std::string &m_email) { this->email = m_email; } + + void setComment(const std::string &m_comment) { this->comment = m_comment; } + + [[nodiscard]] std::string getName() const { return name; } + + [[nodiscard]] std::string getEmail() const { return email; } - void setUserid(const std::string &m_userid) { GenKeyInfo::userid = m_userid; } + [[nodiscard]] std::string getComment() const { return comment; } [[nodiscard]] const std::string &getAlgo() const { return algo; } diff --git a/src/gpg/function/BasicOperator.h b/src/gpg/function/BasicOperator.h index 4ea70eea..41bd9b7f 100644 --- a/src/gpg/function/BasicOperator.h +++ b/src/gpg/function/BasicOperator.h @@ -34,6 +34,10 @@ namespace GpgFrontend { class BasicOperator : public SingletonFunctionObject<BasicOperator> { public: + explicit BasicOperator( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<BasicOperator>(channel) {} + gpg_error_t Encrypt(KeyListPtr keys, BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, GpgEncrResult& result); @@ -65,7 +69,7 @@ class BasicOperator : public SingletonFunctionObject<BasicOperator> { private: GpgContext& ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel()); + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgCommandExecutor.h b/src/gpg/function/GpgCommandExecutor.h index f28caca8..dcdd318d 100644 --- a/src/gpg/function/GpgCommandExecutor.h +++ b/src/gpg/function/GpgCommandExecutor.h @@ -35,6 +35,9 @@ namespace GpgFrontend { class GpgCommandExecutor : public SingletonFunctionObject<GpgCommandExecutor> { public: + explicit GpgCommandExecutor( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgCommandExecutor>(channel) {} #ifndef WINDOWS void Execute(StringArgsRef arguments, @@ -44,7 +47,8 @@ class GpgCommandExecutor : public SingletonFunctionObject<GpgCommandExecutor> { #endif private: - GpgContext &ctx = GpgContext::GetInstance(); + GpgContext &ctx = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgFileOpera.h b/src/gpg/function/GpgFileOpera.h index 4aaf09f1..b7848440 100644 --- a/src/gpg/function/GpgFileOpera.h +++ b/src/gpg/function/GpgFileOpera.h @@ -33,6 +33,10 @@ namespace GpgFrontend { class GpgFileOpera : public SingletonFunctionObject<GpgFileOpera> { public: + explicit GpgFileOpera( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgFileOpera>(channel) {} + static GpgError EncryptFile(KeyListPtr keys, const std::string& path, GpgEncrResult& result); diff --git a/src/gpg/function/GpgKeyGetter.cpp b/src/gpg/function/GpgKeyGetter.cpp index 664aff56..3457a8a7 100644 --- a/src/gpg/function/GpgKeyGetter.cpp +++ b/src/gpg/function/GpgKeyGetter.cpp @@ -65,6 +65,8 @@ GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() { err = gpgme_op_keylist_end(ctx); + assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR); + return keys_list; } diff --git a/src/gpg/function/GpgKeyGetter.h b/src/gpg/function/GpgKeyGetter.h index 3af51815..fcd518d3 100644 --- a/src/gpg/function/GpgKeyGetter.h +++ b/src/gpg/function/GpgKeyGetter.h @@ -33,7 +33,9 @@ namespace GpgFrontend { class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter> { public: - GpgKeyGetter() = default; + explicit GpgKeyGetter( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgKeyGetter>(channel) {} GpgKey GetKey(const std::string& fpr); @@ -49,7 +51,7 @@ class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter> { private: GpgContext& ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel()); + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgKeyImportExportor.cpp b/src/gpg/function/GpgKeyImportExporter.cpp index 89d3b002..ca9b86d1 100644 --- a/src/gpg/function/GpgKeyImportExportor.cpp +++ b/src/gpg/function/GpgKeyImportExporter.cpp @@ -22,7 +22,7 @@ * */ -#include "gpg/function/GpgKeyImportExportor.h" +#include "gpg/function/GpgKeyImportExporter.h" #include "GpgConstants.h" @@ -31,7 +31,7 @@ * @param inBuffer input byte array * @return Import information */ -GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExportor::ImportKey( +GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExporter::ImportKey( StdBypeArrayPtr in_buffer) { if (in_buffer->empty()) return {}; @@ -60,7 +60,7 @@ GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExportor::ImportKey( * @param out_buffer output byte array * @return if success */ -bool GpgFrontend::GpgKeyImportExportor::ExportKeys( +bool GpgFrontend::GpgKeyImportExporter::ExportKeys( KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer) const { if (uid_list->empty()) return false; @@ -87,7 +87,7 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeys( * @param outBuffer output byte array * @return if success */ -bool GpgFrontend::GpgKeyImportExportor::ExportKeys( +bool GpgFrontend::GpgKeyImportExporter::ExportKeys( const KeyArgsList& keys, ByteArrayPtr& out_buffer) const { KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>(); for (const auto& key : keys) key_ids->push_back(key.id()); @@ -100,7 +100,7 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeys( * @param outBuffer output byte array * @return if successful */ -bool GpgFrontend::GpgKeyImportExportor::ExportSecretKey( +bool GpgFrontend::GpgKeyImportExporter::ExportSecretKey( const GpgKey& key, ByteArrayPtr& out_buffer) const { DLOG(INFO) << "Export Secret Key" << key.id().c_str(); @@ -117,7 +117,7 @@ bool GpgFrontend::GpgKeyImportExportor::ExportSecretKey( return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR; } -bool GpgFrontend::GpgKeyImportExportor::ExportKey( +bool GpgFrontend::GpgKeyImportExporter::ExportKey( const GpgFrontend::GpgKey& key, GpgFrontend::ByteArrayPtr& out_buffer) const { GpgData data_out; @@ -131,7 +131,7 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKey( return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR; } -bool GpgFrontend::GpgKeyImportExportor::ExportKeyOpenSSH( +bool GpgFrontend::GpgKeyImportExporter::ExportKeyOpenSSH( const GpgFrontend::GpgKey& key, GpgFrontend::ByteArrayPtr& out_buffer) const { GpgData data_out; @@ -145,7 +145,7 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeyOpenSSH( return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR; } -bool GpgFrontend::GpgKeyImportExportor::ExportSecretKeyShortest( +bool GpgFrontend::GpgKeyImportExporter::ExportSecretKeyShortest( const GpgFrontend::GpgKey& key, GpgFrontend::ByteArrayPtr& out_buffer) const { GpgData data_out; diff --git a/src/gpg/function/GpgKeyImportExportor.h b/src/gpg/function/GpgKeyImportExporter.h index ad43d539..b6c91303 100644 --- a/src/gpg/function/GpgKeyImportExportor.h +++ b/src/gpg/function/GpgKeyImportExporter.h @@ -79,9 +79,13 @@ class GpgImportInformation { GpgImportedKeyList importedKeys; }; -class GpgKeyImportExportor - : public SingletonFunctionObject<GpgKeyImportExportor> { +class GpgKeyImportExporter + : public SingletonFunctionObject<GpgKeyImportExporter> { public: + explicit GpgKeyImportExporter( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgKeyImportExporter>(channel) {} + GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer); bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer) const; @@ -99,7 +103,7 @@ class GpgKeyImportExportor private: GpgContext& ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel()); + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgKeyManager.h b/src/gpg/function/GpgKeyManager.h index 01254962..b2444e8d 100644 --- a/src/gpg/function/GpgKeyManager.h +++ b/src/gpg/function/GpgKeyManager.h @@ -33,6 +33,10 @@ namespace GpgFrontend { class GpgKeyManager : public SingletonFunctionObject<GpgKeyManager> { public: + explicit GpgKeyManager( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgKeyManager>(channel) {} + /** * Sign a key pair(actually a certain uid) * @param target target key pair @@ -50,7 +54,8 @@ class GpgKeyManager : public SingletonFunctionObject<GpgKeyManager> { std::unique_ptr<boost::posix_time::ptime>& expires); private: - GpgContext& ctx = GpgContext::GetInstance(); + GpgContext& ctx = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgKeyOpera.cpp b/src/gpg/function/GpgKeyOpera.cpp index 4bad303d..4df06875 100644 --- a/src/gpg/function/GpgKeyOpera.cpp +++ b/src/gpg/function/GpgKeyOpera.cpp @@ -26,6 +26,7 @@ #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> @@ -50,7 +51,7 @@ void GpgFrontend::GpgKeyOpera::DeleteKeys( err = check_gpg_error(gpgme_op_delete(ctx, gpgme_key_t(key), 1)); assert(gpg_err_code(err) == GPG_ERR_NO_ERROR); } else - LOG(WARNING) << "GpgKeyOpera DeleteKeys Get Key Bad"; + LOG(WARNING) << "GpgKeyOpera DeleteKeys get key failed" << key.fpr(); } } @@ -146,7 +147,7 @@ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert( * @return error information */ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey( - const std::unique_ptr<GenKeyInfo>& params) { + 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(); @@ -163,19 +164,53 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey( system_clock::to_time_t(system_clock::now()); } - unsigned int flags = 0; + GpgError err; - if (!params->isSubKey()) flags |= GPGME_CREATE_CERT; - if (params->isAllowEncryption()) flags |= GPGME_CREATE_ENCR; - if (params->isAllowSigning()) flags |= GPGME_CREATE_SIGN; - if (params->isAllowAuthentication()) flags |= GPGME_CREATE_AUTH; - if (params->isNonExpired()) flags |= GPGME_CREATE_NOEXPIRE; - if (params->isNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD; + if (ctx.GetInfo().GnupgVersion >= "2.1.0") { + 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; + + LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateKey Args: " << userid + << algo << expires << flags; + + err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags); - LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateKey Args: " << userid << algo - << expires << flags; + } else { + std::stringstream ss; + + auto param_format = + boost::format{ + "<GnupgKeyParms format=\"internal\">\n" + "Key-Type: %1%\n" + "Subkey-Type: %2%\n" + "Name-Real: %3%\n" + "Name-Comment: %4%\n" + "Name-Email: %5%\n"} % + params->getAlgo() % params->getKeySize() % params->getName() % + params->getComment() % params->getEmail(); + ss << param_format; + + if (!params->isNonExpired()) + ss << boost::format{"Expire-Date: %1%\n"} % expires; + if (!params->isNoPassPhrase()) + ss << boost::format{"Passphrase: %1%\n"} % params->getPassPhrase(); + + ss << "</GnupgKeyParms>"; + + err = gpgme_op_genkey(ctx, ss.str().c_str(), nullptr, nullptr); + } + + 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); + } - auto err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags); return check_gpg_error(err); } @@ -234,3 +269,9 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyTOFUPolicy( auto err = gpgme_op_tofu_policy(ctx, gpgme_key_t(key), tofu_policy); return check_gpg_error(err); } + +void GpgFrontend::GpgKeyOpera::DeleteKey(const GpgFrontend::KeyId& key_id) { + auto keys = std::make_unique<KeyIdArgsList>(); + keys->push_back(key_id); + DeleteKeys(std::move(keys)); +} diff --git a/src/gpg/function/GpgKeyOpera.h b/src/gpg/function/GpgKeyOpera.h index 7decfd79..73b8bdb5 100644 --- a/src/gpg/function/GpgKeyOpera.h +++ b/src/gpg/function/GpgKeyOpera.h @@ -33,8 +33,14 @@ namespace GpgFrontend { class GenKeyInfo; class GpgKeyOpera : public SingletonFunctionObject<GpgKeyOpera> { public: + explicit GpgKeyOpera( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgKeyOpera>(channel) {} + void DeleteKeys(KeyIdArgsListPtr key_ids); + void DeleteKey(const KeyId& key_id); + GpgError SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr, std::unique_ptr<boost::posix_time::ptime>& expires); @@ -46,13 +52,15 @@ class GpgKeyOpera : public SingletonFunctionObject<GpgKeyOpera> { GpgFrontend::GpgError ModifyTOFUPolicy(const GpgKey& key, gpgme_tofu_policy_t tofu_policy); - GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params); + GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params, + GpgGenKeyResult& result); GpgFrontend::GpgError GenerateSubkey( const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params); private: - GpgContext& ctx = GpgContext::GetInstance(); + GpgContext& ctx = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/UidOperator.h b/src/gpg/function/UidOperator.h index 7d5df254..d1a92b38 100644 --- a/src/gpg/function/UidOperator.h +++ b/src/gpg/function/UidOperator.h @@ -32,6 +32,10 @@ namespace GpgFrontend { class UidOperator : public SingletonFunctionObject<UidOperator> { public: + explicit UidOperator( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<UidOperator>(channel) {} + /** * create a new uid in certain key pair * @param key target key pair @@ -68,7 +72,8 @@ class UidOperator : public SingletonFunctionObject<UidOperator> { bool setPrimaryUID(const GpgKey& key, const std::string& uid); private: - GpgContext& ctx = GpgContext::GetInstance(); + GpgContext& ctx = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/ui/KeyImportDetailDialog.h b/src/ui/KeyImportDetailDialog.h index fe63baaa..a75d466d 100644 --- a/src/ui/KeyImportDetailDialog.h +++ b/src/ui/KeyImportDetailDialog.h @@ -25,7 +25,7 @@ #ifndef __KEYIMPORTDETAILSDIALOG_H__ #define __KEYIMPORTDETAILSDIALOG_H__ -#include <gpg/function/GpgKeyImportExportor.h> +#include <gpg/function/GpgKeyImportExporter.h> #include "gpg/GpgContext.h" #include "ui/GpgFrontendUI.h" diff --git a/src/ui/KeyMgmt.cpp b/src/ui/KeyMgmt.cpp index c03b8e6b..9f599461 100755 --- a/src/ui/KeyMgmt.cpp +++ b/src/ui/KeyMgmt.cpp @@ -27,7 +27,7 @@ #include <utility> #include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyImportExportor.h" +#include "gpg/function/GpgKeyImportExporter.h" #include "gpg/function/GpgKeyOpera.h" #include "ui/SignalStation.h" #include "ui/UserInterfaceUtils.h" @@ -150,9 +150,8 @@ KeyMgmt::KeyMgmt(QWidget* parent) : QMainWindow(parent) { connect(this, SIGNAL(signalKeyStatusUpdated()), SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh())); - connect(SignalStation::GetInstance(), - &SignalStation::signalRefreshStatusBar, this, - [=](const QString& message, int timeout) { + connect(SignalStation::GetInstance(), &SignalStation::signalRefreshStatusBar, + this, [=](const QString& message, int timeout) { statusBar()->showMessage(message, timeout); }); } diff --git a/src/ui/KeyServerImportDialog.cpp b/src/ui/KeyServerImportDialog.cpp index 844f2ae5..518b1b94 100644 --- a/src/ui/KeyServerImportDialog.cpp +++ b/src/ui/KeyServerImportDialog.cpp @@ -26,7 +26,7 @@ #include <utility> -#include "gpg/function/GpgKeyImportExportor.h" +#include "gpg/function/GpgKeyImportExporter.h" #include "ui/SignalStation.h" #include "ui/settings/GlobalSettingStation.h" diff --git a/src/ui/KeyUploadDialog.cpp b/src/ui/KeyUploadDialog.cpp index 52aa2bd3..ab4e139e 100644 --- a/src/ui/KeyUploadDialog.cpp +++ b/src/ui/KeyUploadDialog.cpp @@ -27,15 +27,14 @@ #include <algorithm> #include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyImportExportor.h" +#include "gpg/function/GpgKeyImportExporter.h" #include "ui/settings/GlobalSettingStation.h" namespace GpgFrontend::UI { KeyUploadDialog::KeyUploadDialog(const KeyIdArgsListPtr& keys_ids, QWidget* parent) - : QDialog(parent), - mKeys(GpgKeyGetter::GetInstance().GetKeys(keys_ids)) { + : QDialog(parent), mKeys(GpgKeyGetter::GetInstance().GetKeys(keys_ids)) { auto* pb = new QProgressBar(); pb->setRange(0, 0); pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); @@ -60,7 +59,6 @@ void KeyUploadDialog::slotUpload() { void KeyUploadDialog::uploadKeyToServer( const GpgFrontend::ByteArray& keys_data) { - std::string target_keyserver; if (target_keyserver.empty()) { try { diff --git a/src/ui/keypair_details/KeyPairDetailTab.cpp b/src/ui/keypair_details/KeyPairDetailTab.cpp index e4b9206a..8b5be042 100644 --- a/src/ui/keypair_details/KeyPairDetailTab.cpp +++ b/src/ui/keypair_details/KeyPairDetailTab.cpp @@ -25,7 +25,7 @@ #include "ui/keypair_details/KeyPairDetailTab.h" #include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyImportExportor.h" +#include "gpg/function/GpgKeyImportExporter.h" #include "gpg/function/GpgKeyOpera.h" #include "ui/SignalStation.h" #include "ui/UserInterfaceUtils.h" diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index 2dd3f842..5671d943 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -37,7 +37,7 @@ #include "gpg/function/BasicOperator.h" #include "gpg/function/GpgKeyGetter.h" -#include "gpg/function/GpgKeyImportExportor.h" +#include "gpg/function/GpgKeyImportExporter.h" #include "ui/UserInterfaceUtils.h" #include "ui/help/AboutDialog.h" #include "ui/settings/GlobalSettingStation.h" |