aboutsummaryrefslogtreecommitdiffstats
path: root/src/gpg/gpg_context/GpgContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/gpg/gpg_context/GpgContext.cpp324
1 files changed, 86 insertions, 238 deletions
diff --git a/src/gpg/gpg_context/GpgContext.cpp b/src/gpg/gpg_context/GpgContext.cpp
index a892603c..a9b83d92 100644
--- a/src/gpg/gpg_context/GpgContext.cpp
+++ b/src/gpg/gpg_context/GpgContext.cpp
@@ -23,10 +23,9 @@
*/
#include "gpg/GpgContext.h"
-#include "ui/WaitingDialog.h"
#include <functional>
-#include <unistd.h> /* contains read/write */
+#include <unistd.h> /* contains read/write */
#ifdef _WIN32
@@ -34,248 +33,97 @@
#endif
-#define INT2VOIDP(i) (void*)(uintptr_t)(i)
+#define INT2VOIDP(i) (void *)(uintptr_t)(i)
namespace GpgFrontend {
- /**
- * Constructor
- * Set up gpgme-context, set paths to app-run path
- */
- GpgContext::GpgContext() {
-
- gpgme_ctx_t _p_ctx;
- err = gpgme_new(&_p_ctx);
- check_gpg_error(err);
- _ctx_ref = CtxRefHandler(_p_ctx, [&](gpgme_ctx_t ctx) { gpgme_release(ctx); });
-
- gpgme_engine_info_t engineInfo;
- engineInfo = 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) {
- qDebug() << gpgme_get_protocol_name(engineInfo->protocol) << engineInfo->file_name << engineInfo->protocol
- << engineInfo->home_dir << 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;
- if (engineInfo->protocol == GPGME_PROTOCOL_CMS && strcmp(engineInfo->version, "1.0.0") != 0)
- find_cms = true;
- if (engineInfo->protocol == GPGME_PROTOCOL_ASSUAN)
- find_assuan = true;
- engineInfo = engineInfo->next;
- }
-
- if (find_gpgconf && find_openpgp && find_cms && find_assuan)
- check_pass = true;
-
- if (!check_pass) {
- good = false;
- return;
- } else good = true;
-
-
- /** 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);
- /** passphrase-callback */
- gpgme_set_passphrase_cb(*this, passphraseCb, this);
-
- 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);
-
- /** check if app is called with -d from command line */
- if (qApp->arguments().contains("-d")) {
- qDebug() << "gpgme_data_t debug on";
- debug = true;
- } else debug = false;
-
- slotRefreshKeyList();
- }
-
- bool GpgContext::isGood() const {
- return good;
- }
-
- /**
- * The Passphrase window, if not provided by env-Var GPG_AGENT_INFO
- * originally copied from http://basket.kde.org/ (kgpgme.cpp), but modified
- */
- gpgme_error_t GpgContext::passphraseCb(void *hook, const char *uid_hint,
- const char *passphrase_info,
- int last_was_bad, int fd) {
- auto *gpg = static_cast<GpgContext *>(hook);
- return gpg->passphrase(uid_hint, passphrase_info, last_was_bad, fd);
- }
-
- gpgme_error_t GpgContext::passphrase(const char *uid_hint,
- const char * /*passphrase_info*/,
- int last_was_bad, int fd) {
-
- gpgme_error_t returnValue = GPG_ERR_CANCELED;
- QString passwordDialogMessage;
- QString gpgHint = QString::fromUtf8(uid_hint);
- bool result;
-
-#ifdef _WIN32
- DWORD written;
- auto hd = INT2VOIDP(fd);
-#endif
-
- if (last_was_bad) {
- passwordDialogMessage += "<i> Wrong password. </i><br><br>\n\n";
- clearPasswordCache();
- }
-
- /** if uid provided */
- if (!gpgHint.isEmpty()) {
- // remove UID, leave only username & email
- gpgHint.remove(0, gpgHint.indexOf(" "));
- passwordDialogMessage += "<b> Enter Password for </b><br>" + gpgHint + "<br>";
- }
-
- if (mPasswordCache.isEmpty()) {
- QString password = QInputDialog::getText(QApplication::activeWindow(), "Enter Password",
- passwordDialogMessage, QLineEdit::Password,
- "", &result);
-
- if (result) mPasswordCache = password.toUtf8();
- } else result = true;
-
- if (result) {
-
-#ifndef _WIN32
- if (write(fd, mPasswordCache.data(), mPasswordCache.length()) == -1) qDebug() << "something is terribly broken";
-#else
- WriteFile(hd, mPasswordCache.data(), mPasswordCache.length(), &written, 0);
-#endif
- returnValue = GPG_ERR_NO_ERROR;
- }
-
-#ifndef _WIN32
- if (write(fd, "\n", 1) == -1) qDebug() << "something is terribly broken";
-#else
- WriteFile(hd, "\n", 1, &written, nullptr);
-
- /* program will hang on cancel if hd not closed */
- if (!result) CloseHandle(hd);
-#endif
-
- return returnValue;
- }
-
- /** also from kgpgme.cpp, seems to clear password from mem */
- void GpgContext::clearPasswordCache() {
- if (mPasswordCache.size() > 0) {
- mPasswordCache.fill('\0');
- mPasswordCache.truncate(0);
- }
- }
-
- // error-handling
- gpgme_error_t check_gpg_error(gpgme_error_t err, const QString &comment) {
- //if (gpgmeError != GPG_ERR_NO_ERROR && gpgmeError != GPG_ERR_CANCELED) {
- if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
- qDebug() << "[Error " << gpg_err_code(err)
- << "] Source: " << gpgme_strsource(err) << " Description: " << gpgme_strerror(err);
- }
- return err;
- }
-
- gpgme_error_t check_gpg_error(gpgme_error_t err) {
- //if (gpgmeError != GPG_ERR_NO_ERROR && gpgmeError != GPG_ERR_CANCELED) {
- if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
- qDebug() << "[Error " << gpg_err_code(err)
- << "] Source: " << gpgme_strsource(err) << " Description: " << gpgme_strerror(err);
- }
- return err;
- }
-
- /** return type should be gpgme_error_t*/
-
-
-
- /*
- * if there is no '\n' before the PGP-Begin-Block, but for example a whitespace,
- * GPGME doesn't recognise the Message as encrypted. This function adds '\n'
- * before the PGP-Begin-Block, if missing.
- */
- void GpgContext::preventNoDataErr(QByteArray *in) {
- int block_start = in->indexOf(GpgConstants::PGP_CRYPT_BEGIN);
- if (block_start > 0 && in->at(block_start - 1) != '\n') {
- in->insert(block_start, '\n');
- }
- block_start = in->indexOf(GpgConstants::PGP_SIGNED_BEGIN);
- if (block_start > 0 && in->at(block_start - 1) != '\n') {
- in->insert(block_start, '\n');
- }
- }
-
- /*
- * isSigned returns:
- * - 0, if text isn't signed at all
- * - 1, if text is partially signed
- * - 2, if text is completly signed
- */
- int GpgContext::textIsSigned(const QByteArray &text) {
- if (text.trimmed().startsWith(GpgConstants::PGP_SIGNED_BEGIN) &&
- text.trimmed().endsWith(GpgConstants::PGP_SIGNED_END))
- return 2;
- else if (text.contains(GpgConstants::PGP_SIGNED_BEGIN) && text.contains(GpgConstants::PGP_SIGNED_END))
- return 1;
-
- else return 0;
- }
-
- QString GpgContext::beautifyFingerprint(QString fingerprint) {
- uint len = fingerprint.length();
- if ((len > 0) && (len % 4 == 0))
- for (uint n = 0; 4 * (n + 1) < len; ++n) fingerprint.insert(static_cast<int>(5u * n + 4u), ' ');
- return fingerprint;
- }
-
- void GpgContext::slotRefreshKeyList() {
- qDebug() << "Refreshing Keys";
- this->fetch_keys();
- emit signalKeyInfoChanged();
- }
-
- QString GpgContext::getGpgmeVersion() {
- return {gpgme_check_version(nullptr)};
- }
-
- const GpgKeyList &GpgContext::getKeys() const {
- return mKeyList;
- }
-
- void GpgContext::slotUpdateKeyList(const QString &key_id) {
- auto it = mKeyMap.find(key_id);
- if (it != mKeyMap.end()) {
- gpgme_key_t new_key_ref;
-
- auto gpgmeErr = gpgme_get_key(*this, key_id.toUtf8().constData(), &new_key_ref, 0);
+/**
+ * Constructor
+ * Set up gpgme-context, set paths to app-run path
+ */
+GpgContext::GpgContext() {
+
+ gpgme_ctx_t _p_ctx;
+ auto err = gpgme_new(&_p_ctx);
+ check_gpg_error(err);
+ _ctx_ref =
+ CtxRefHandler(_p_ctx, [&](gpgme_ctx_t ctx) { gpgme_release(ctx); });
+
+ gpgme_engine_info_t engineInfo;
+ engineInfo = 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) {
+ qDebug() << gpgme_get_protocol_name(engineInfo->protocol)
+ << engineInfo->file_name << engineInfo->protocol
+ << engineInfo->home_dir << 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;
+ if (engineInfo->protocol == GPGME_PROTOCOL_CMS &&
+ strcmp(engineInfo->version, "1.0.0") != 0)
+ find_cms = true;
+ if (engineInfo->protocol == GPGME_PROTOCOL_ASSUAN)
+ find_assuan = true;
+ engineInfo = engineInfo->next;
+ }
+
+ if (find_gpgconf && find_openpgp && find_cms && find_assuan)
+ check_pass = true;
+
+ if (!check_pass) {
+ good_ = false;
+ return;
+ } else
+ good_ = true;
+
+ /** 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);
+
+ 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 (gpgme_err_code(gpgmeErr) == GPG_ERR_EOF) {
- gpgmeErr = gpgme_get_key(*this, key_id.toUtf8().constData(), &new_key_ref, 1);
+bool GpgContext::good() const { return good_; }
- if (gpgme_err_code(gpgmeErr) == GPG_ERR_EOF)
- throw std::runtime_error("key_id not found in key database");
- }
+/** also from kgpgme.cpp, seems to clear password from mem */
+void GpgContext::clearPasswordCache() {
+ if (mPasswordCache.size() > 0) {
+ mPasswordCache.fill('\0');
+ mPasswordCache.truncate(0);
+ }
+}
- if (new_key_ref != nullptr) {
- it->second = std::move(GpgKey(std::move(new_key_ref)));
- emit signalKeyInfoChanged();
- }
+/** return type should be gpgme_error_t*/
- }
- }
+/*
+ * if there is no '\n' before the PGP-Begin-Block, but for example a whitespace,
+ * GPGME doesn't recognise the Message as encrypted. This function adds '\n'
+ * before the PGP-Begin-Block, if missing.
+ */
+void GpgContext::preventNoDataErr(QByteArray *in) {
+ int block_start = in->indexOf(GpgConstants::PGP_CRYPT_BEGIN);
+ if (block_start > 0 && in->at(block_start - 1) != '\n') {
+ in->insert(block_start, '\n');
+ }
+ block_start = in->indexOf(GpgConstants::PGP_SIGNED_BEGIN);
+ if (block_start > 0 && in->at(block_start - 1) != '\n') {
+ in->insert(block_start, '\n');
+ }
+}
+std::string GpgContext::getGpgmeVersion() {
+ return {gpgme_check_version(nullptr)};
}
+
+} // namespace GpgFrontend