aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gpg/GpgContext.cpp189
-rw-r--r--src/gpg/GpgContext.h35
-rw-r--r--src/gpg/GpgInfo.h4
-rw-r--r--src/gpg/function/BasicOperator.cpp6
-rw-r--r--src/gpg/function/GpgKeyOpera.cpp19
5 files changed, 153 insertions, 100 deletions
diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp
index a39918e2..ff483637 100644
--- a/src/gpg/GpgContext.cpp
+++ b/src/gpg/GpgContext.cpp
@@ -43,7 +43,7 @@ namespace GpgFrontend {
* Constructor
* Set up gpgme-context, set paths to app-run path
*/
-GpgContext::GpgContext(const GpgContextInitArgs& args) {
+GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) {
static bool _first = true;
if (_first) {
@@ -62,94 +62,153 @@ GpgContext::GpgContext(const GpgContextInitArgs& args) {
_ctx_ref = CtxRefHandler(_p_ctx);
if (args.gpg_alone) {
- info.AppPath = args.gpg_path;
+ 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());
+ info_.AppPath.c_str(),
+ info_.DatabasePath.c_str());
assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
}
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;
+ bool check_passed = false, find_openpgp = false, find_gpgconf = false,
+ find_cms = false;
+
while (engine_info != nullptr) {
- if (engine_info->protocol == GPGME_PROTOCOL_GPGCONF &&
- strcmp(engine_info->version, "1.0.0") != 0)
- find_gpgconf = true;
- 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 (!strcmp(engine_info->version, "1.0.0")) {
+ engine_info = engine_info->next;
+ continue;
}
- if (engine_info->protocol == GPGME_PROTOCOL_CMS &&
- strcmp(engine_info->version, "1.0.0") != 0)
- find_cms = true;
- if (engine_info->protocol == GPGME_PROTOCOL_ASSUAN) find_assuan = true;
+ DLOG(INFO) << gpgme_get_protocol_name(engine_info->protocol)
+ << std::string(engine_info->file_name == nullptr
+ ? "null"
+ : engine_info->file_name)
+ << std::string(engine_info->home_dir == nullptr
+ ? "null"
+ : engine_info->home_dir);
+
+ switch (engine_info->protocol) {
+ case GPGME_PROTOCOL_OpenPGP:
+ find_openpgp = true;
+ info_.AppPath = engine_info->file_name;
+ info_.GnupgVersion = engine_info->version;
+ break;
+ case GPGME_PROTOCOL_CMS:
+ find_cms = true;
+ info_.CMSPath = engine_info->file_name;
+ break;
+ case GPGME_PROTOCOL_GPGCONF:
+ find_gpgconf = true;
+ info_.GpgConfPath = engine_info->file_name;
+ break;
+ case GPGME_PROTOCOL_ASSUAN:
+ break;
+ case GPGME_PROTOCOL_G13:
+ break;
+ case GPGME_PROTOCOL_UISERVER:
+ break;
+ case GPGME_PROTOCOL_SPAWN:
+ break;
+ case GPGME_PROTOCOL_DEFAULT:
+ break;
+ case GPGME_PROTOCOL_UNKNOWN:
+ break;
+ }
engine_info = engine_info->next;
}
- if (find_gpgconf && find_openpgp && find_cms && find_assuan)
- check_pass = true;
+ // conditional check
+ if ((info_.GnupgVersion >= "2.0.0" && find_gpgconf && find_openpgp &&
+ find_cms) ||
+ (info_.GnupgVersion > "1.0.0" && find_gpgconf))
+ check_passed = true;
- if (!check_pass) {
+ if (!check_passed) {
this->good_ = false;
+ LOG(ERROR) << "Env check failed";
return;
} else {
- LOG(INFO) << "GnuPG version" << info.GnupgVersion;
-
- // Set Independent Database
- 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());
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
- }
-
- /** Setting the output type must be done at the beginning */
- /** think this means ascii-armor --> ? */
- gpgme_set_armor(*this, 1);
- // Speed up loading process
- gpgme_set_offline(*this, 1);
-
- 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));
- }
+ DLOG(INFO) << "gnupg version" << info_.GnupgVersion;
+ init_ctx();
good_ = true;
}
}
+void GpgContext::init_ctx() {
+ // Set Independent Database
+ if (info_.GnupgVersion <= "2.0.0" && args_.independent_database) {
+ info_.DatabasePath = args_.db_path;
+ DLOG(INFO) << "custom key db path" << info_.DatabasePath;
+ 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);
+ } else {
+ info_.DatabasePath = "default";
+ }
+
+ /** Setting the output type must be done at the beginning */
+ /** think this means ascii-armor --> ? */
+ gpgme_set_armor(*this, 1);
+ // Speed up loading process
+ gpgme_set_offline(*this, 1);
+
+ if (info_.GnupgVersion >= "2.0.0") {
+ 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 {
+ 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));
+ }
+
+ // for unit test
+ if (args_.test_mode) {
+ LOG(INFO) << "test mode";
+ if (info_.GnupgVersion >= "2.1.0") SetPassphraseCb(test_passphrase_cb);
+ gpgme_set_status_cb(*this, test_status_cb, nullptr);
+ }
+}
+
bool GpgContext::good() const { return good_; }
-void GpgContext::SetPassphraseCb(decltype(test_passphrase_cb) cb) const {
- gpgme_set_passphrase_cb(*this, cb, nullptr);
+void GpgContext::SetPassphraseCb(gpgme_passphrase_cb_t cb) const {
+ if (info_.GnupgVersion >= "2.1.0") {
+ if (gpgme_get_pinentry_mode(*this) != GPGME_PINENTRY_MODE_LOOPBACK) {
+ gpgme_set_pinentry_mode(*this, GPGME_PINENTRY_MODE_LOOPBACK);
+ }
+ gpgme_set_passphrase_cb(*this, cb, nullptr);
+ } else {
+ LOG(ERROR) << "Not supported for gnupg version" << info_.GnupgVersion;
+ }
+}
+
+gpgme_error_t GpgContext::test_passphrase_cb(void *opaque, const char *uid_hint,
+ const char *passphrase_info,
+ int last_was_bad, int fd) {
+ size_t res;
+ std::string pass = "abcdefg\n";
+ auto pass_len = pass.size();
+
+ size_t off = 0;
+
+ do {
+ res = gpgme_io_write(fd, &pass[off], pass_len - off);
+ if (res > 0) off += res;
+ } while (res > 0 && off != pass_len);
+
+ return off == pass_len ? 0 : gpgme_error_from_errno(errno);
+ return 0;
}
-std::string GpgContext::getGpgmeVersion() {
- return {gpgme_check_version(nullptr)};
+gpgme_error_t GpgContext::test_status_cb(void *hook, const char *keyword,
+ const char *args) {
+ LOG(INFO) << "keyword" << keyword;
+ return 0;
}
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/gpg/GpgContext.h b/src/gpg/GpgContext.h
index 887bb7a6..753e1090 100644
--- a/src/gpg/GpgContext.h
+++ b/src/gpg/GpgContext.h
@@ -33,10 +33,12 @@
namespace GpgFrontend {
struct GpgContextInitArgs {
+ // make no sense for gpg2
bool independent_database = false;
std::string db_path = {};
bool gpg_alone = false;
std::string gpg_path = {};
+ bool test_mode = false;
GpgContextInitArgs() = default;
};
@@ -55,14 +57,15 @@ class GpgContext : public SingletonFunctionObject<GpgContext> {
[[nodiscard]] bool good() const;
- [[nodiscard]] const GpgInfo& GetInfo() const { return info; }
-
- static std::string getGpgmeVersion();
+ [[nodiscard]] const GpgInfo& GetInfo() const { return info_; }
operator gpgme_ctx_t() const { return _ctx_ref.get(); }
private:
- GpgInfo info;
+ GpgInfo info_;
+ GpgContextInitArgs args_;
+
+ void init_ctx();
struct _ctx_ref_deleter {
void operator()(gpgme_ctx_t _ctx) {
@@ -78,28 +81,12 @@ class GpgContext : public SingletonFunctionObject<GpgContext> {
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;
- std::string pass = "abcdefg\n";
- auto pass_len = pass.size();
-
- size_t off = 0;
-
- (void)opaque;
- (void)uid_hint;
- (void)passphrase_info;
- (void)last_was_bad;
-
- do {
- res = gpgme_io_write(fd, &pass[off], pass_len - off);
- if (res > 0) off += res;
- } while (res > 0 && off != pass_len);
+ int last_was_bad, int fd);
- return off == pass_len ? 0 : gpgme_error_from_errno(errno);
- }
+ static gpgme_error_t test_status_cb(void* hook, const char* keyword,
+ const char* args);
- void SetPassphraseCb(decltype(test_passphrase_cb) func) const;
+ void SetPassphraseCb(gpgme_passphrase_cb_t func) const;
};
} // namespace GpgFrontend
diff --git a/src/gpg/GpgInfo.h b/src/gpg/GpgInfo.h
index 6ecb9b92..d651b2f6 100644
--- a/src/gpg/GpgInfo.h
+++ b/src/gpg/GpgInfo.h
@@ -40,6 +40,10 @@ class GpgInfo {
std::string DatabasePath;
std::string GnupgVersion;
+
+ std::string GpgConfPath;
+
+ std::string CMSPath;
};
#endif // GPGFRONTEND_ZH_CN_TS_GPGINFO_H
diff --git a/src/gpg/function/BasicOperator.cpp b/src/gpg/function/BasicOperator.cpp
index 56b7ca54..e52c091c 100644
--- a/src/gpg/function/BasicOperator.cpp
+++ b/src/gpg/function/BasicOperator.cpp
@@ -187,9 +187,11 @@ gpgme_error_t GpgFrontend::BasicOperator::EncryptSign(
void GpgFrontend::BasicOperator::SetSigners(KeyArgsList& keys) {
gpgme_signers_clear(ctx);
for (const GpgKey& key : keys) {
+ DLOG(INFO) << "key" << key.fpr();
if (key.CanSignActual()) {
- auto gpgmeError = gpgme_signers_add(ctx, gpgme_key_t(key));
- check_gpg_error(gpgmeError);
+ DLOG(INFO) << "signer";
+ auto error = gpgme_signers_add(ctx, gpgme_key_t(key));
+ check_gpg_error(error);
}
}
if (keys.size() != gpgme_signers_count(ctx))
diff --git a/src/gpg/function/GpgKeyOpera.cpp b/src/gpg/function/GpgKeyOpera.cpp
index 4df06875..4cbc1d0a 100644
--- a/src/gpg/function/GpgKeyOpera.cpp
+++ b/src/gpg/function/GpgKeyOpera.cpp
@@ -47,11 +47,13 @@ void GpgFrontend::GpgKeyOpera::DeleteKeys(
for (const auto& tmp : *key_ids) {
auto key = GpgKeyGetter::GetInstance().GetKey(tmp);
if (key.good()) {
- LOG(INFO) << "GpgKeyOpera DeleteKeys Get Key Good";
- err = check_gpg_error(gpgme_op_delete(ctx, gpgme_key_t(key), 1));
+ err = check_gpg_error(
+ gpgme_op_delete_ext(ctx, gpgme_key_t(key),
+ GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
- } else
- LOG(WARNING) << "GpgKeyOpera DeleteKeys get key failed" << key.fpr();
+ } else {
+ LOG(WARNING) << "GpgKeyOpera DeleteKeys get key failed" << tmp;
+ }
}
}
@@ -152,8 +154,7 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
const char* userid = userid_utf8.c_str();
auto algo_utf8 = params->getAlgo() + params->getKeySizeStr();
- LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateKey Params"
- << params->getAlgo() << params->getKeySizeStr();
+ LOG(INFO) << "params" << params->getAlgo() << params->getKeySizeStr();
const char* algo = algo_utf8.c_str();
unsigned long expires = 0;
@@ -176,14 +177,12 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
if (params->isNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->isNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
- LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateKey Args: " << userid
- << algo << expires << flags;
+ LOG(INFO) << "args: " << userid << algo << expires << flags;
err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags);
} else {
std::stringstream ss;
-
auto param_format =
boost::format{
"<GnupgKeyParms format=\"internal\">\n"
@@ -203,6 +202,8 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
ss << "</GnupgKeyParms>";
+ DLOG(INFO) << "params" << std::endl << ss.str();
+
err = gpgme_op_genkey(ctx, ss.str().c_str(), nullptr, nullptr);
}