diff options
author | Saturneric <[email protected]> | 2021-06-09 19:02:41 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2021-06-09 19:02:41 +0000 |
commit | 7d000da3e8c8a65b43174b5be2edcd4c1bd6c27e (patch) | |
tree | 698f2ace3c49453768bf3c85e97069d65700e950 /src/gpg/GpgContext.cpp | |
parent | Adjust the output of analysis results. (diff) | |
download | GpgFrontend-7d000da3e8c8a65b43174b5be2edcd4c1bd6c27e.tar.gz GpgFrontend-7d000da3e8c8a65b43174b5be2edcd4c1bd6c27e.zip |
Do not clear the text when the decryption operation fails.
Add decrypt and verify operation.
Change the icon further.
Fix the function of importing from the key server.
Signed-off-by: Saturneric <[email protected]>
Diffstat (limited to 'src/gpg/GpgContext.cpp')
-rw-r--r-- | src/gpg/GpgContext.cpp | 244 |
1 files changed, 145 insertions, 99 deletions
diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp index bd1aa013..a6be9c3c 100644 --- a/src/gpg/GpgContext.cpp +++ b/src/gpg/GpgContext.cpp @@ -26,6 +26,7 @@ #include "ui/keygen/KeygenThread.h" #include <unistd.h> /* contains read/write */ +#include <Mime.h> #ifdef _WIN32 #include <windows.h> @@ -381,7 +382,7 @@ namespace GpgME { gpgme_key_t recipients[keys.count() + 1]; int index = 0; - for(const auto& key : keys) { + for (const auto &key : keys) { recipients[index++] = key.key_refer; } @@ -412,12 +413,43 @@ namespace GpgME { gpgme_data_release(dataOut); } - if(result != nullptr) { + if (result != nullptr) { *result = gpgme_op_encrypt_result(mCtx); } return err; } + + /** + * if this is mime, split text and attachments... + * message contains only text afterwards + */ + void parseMime(QByteArray *message) { + + QString pText; + bool show_ma_dock = false; + + Mime *mime = new Mime(message); + for(MimePart tmp : mime->parts()) { + if (tmp.header.getValue("Content-Type") == "text/plain" && tmp.header.getValue("Content-Transfer-Encoding") != "base64") { + QByteArray body; + if (tmp.header.getValue("Content-Transfer-Encoding") == "quoted-printable") { + Mime::quotedPrintableDecode(tmp.body, body); + } else { + body = tmp.body; + } + pText.append(QString(body)); + } else { + // TODO + show_ma_dock = true; + } + } + *message = pText.toUtf8(); + if (show_ma_dock) { + // TODO + } + } + /** Decrypt QByteAarray, return QByteArray * mainly from http://basket.kde.org/ (kgpgme.cpp) */ @@ -425,47 +457,21 @@ namespace GpgME { GpgContext::decrypt(const QByteArray &inBuffer, QByteArray *outBuffer, gpgme_decrypt_result_t *result) { gpgme_data_t dataIn = nullptr, dataOut = nullptr; gpgme_decrypt_result_t m_result = nullptr; - QString errorString; outBuffer->resize(0); - if (mCtx) { + if (mCtx != nullptr) { err = gpgme_data_new_from_mem(&dataIn, inBuffer.data(), inBuffer.size(), 1); - checkErr(err); - if (!err) { + if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) { err = gpgme_data_new(&dataOut); - checkErr(err); - if (!err) { + if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) { err = gpgme_op_decrypt(mCtx, dataIn, dataOut); - checkErr(err); - - if (gpg_err_code(err) == GPG_ERR_DECRYPT_FAILED) { - errorString.append(gpgErrString(err)).append("<br>"); - m_result = gpgme_op_decrypt_result(mCtx); - checkErr(m_result->recipients->status); - errorString.append(gpgErrString(m_result->recipients->status)).append("<br>"); - errorString.append( - tr("<br>No private key with id %1 present dataIn keyring").arg( - m_result->recipients->keyid)); - } else { - errorString.append(gpgErrString(err)).append("<br>"); - } - - if (!err) { - m_result = gpgme_op_decrypt_result(mCtx); - if (m_result->unsupported_algorithm) { - QMessageBox::critical(0, tr("Unsupported algorithm"), m_result->unsupported_algorithm); - } else { - err = readToBuffer(dataOut, outBuffer); - checkErr(err); - } + m_result = gpgme_op_decrypt_result(mCtx); + if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) { + err = readToBuffer(dataOut, outBuffer); } } } } - if (gpg_err_code(err) != GPG_ERR_NO_ERROR && gpg_err_code(err) != GPG_ERR_CANCELED) { - QMessageBox::critical(nullptr, tr("Error decrypting:"), errorString); - return false; - } if (!settings.value("general/rememberPassword").toBool()) { clearPasswordCache(); @@ -478,7 +484,29 @@ namespace GpgME { gpgme_data_release(dataOut); } - if(result != nullptr) { + /* + * 1) is it mime (content-type:) + * 2) parse header + * 2) choose action depending on content-type + */ + if (Mime::isMime(outBuffer)) { + Header header = Mime::getHeader(outBuffer); + // is it multipart, is multipart-parsing enabled + if (header.getValue("Content-Type") == "multipart/mixed" + && settings.value("mime/parseMime").toBool()) { + parseMime(outBuffer); + } else if (header.getValue("Content-Type") == "text/plain" + && settings.value("mime/parseQP").toBool()) { + if (header.getValue("Content-Transfer-Encoding") == "quoted-printable") { + auto *decoded = new QByteArray(); + Mime::quotedPrintableDecode(*outBuffer, *decoded); + //TODO: remove header + outBuffer = decoded; + } + } + } + + if (result != nullptr) { *result = m_result; } return err; @@ -682,7 +710,7 @@ namespace GpgME { m_result = gpgme_op_verify_result(mCtx); - if(result != nullptr) { + if (result != nullptr) { *result = m_result; } @@ -709,7 +737,9 @@ namespace GpgME { verify_result = gpgme_op_verify_result (mCtx); */ //} - gpg_error_t GpgContext::sign(const QVector<GpgKey>& keys, const QByteArray &inBuffer, QByteArray *outBuffer, bool detached, gpgme_sign_result_t *result) { + gpg_error_t + GpgContext::sign(const QVector<GpgKey> &keys, const QByteArray &inBuffer, QByteArray *outBuffer, bool detached, + gpgme_sign_result_t *result) { gpgme_error_t gpgmeError; gpgme_data_t dataIn, dataOut; @@ -763,7 +793,7 @@ namespace GpgME { m_result = gpgme_op_sign_result(mCtx); - if(result != nullptr) { + if (result != nullptr) { *result = m_result; } @@ -835,8 +865,8 @@ namespace GpgME { if (key.fpr == fpr) { return key; } else { - for(auto &subkey : key.subKeys) { - if(subkey.fpr == fpr) { + for (auto &subkey : key.subKeys) { + if (subkey.fpr == fpr) { return key; } } @@ -848,9 +878,9 @@ namespace GpgME { /** * note: is_private_key status is not returned */ - const GpgKey & GpgContext::getKeyById(const QString &id) { + const GpgKey &GpgContext::getKeyById(const QString &id) { - for(const auto &key : mKeyList) { + for (const auto &key : mKeyList) { if (key.id == id) { return key; } else { @@ -884,7 +914,7 @@ namespace GpgME { auto gpgmeError = gpgme_op_keysign(mCtx, target.key_refer, uid.toUtf8().constData(), expires_time_t, flags); - if(gpgmeError == GPG_ERR_NO_ERROR) { + if (gpgmeError == GPG_ERR_NO_ERROR) { emit signalKeyUpdated(target.id); return true; } else { @@ -923,22 +953,22 @@ namespace GpgME { } } - void GpgContext::slotUpdateKeyList(QString key_id) { + void GpgContext::slotUpdateKeyList(const QString &key_id) { auto it = mKeyMap.find(key_id); if (it != mKeyMap.end()) { gpgme_key_t new_key_refer; auto gpgmeErr = gpgme_get_key(mCtx, key_id.toUtf8().constData(), &new_key_refer, 0); - if(gpgme_err_code(gpgmeErr) == GPG_ERR_EOF) { + if (gpgme_err_code(gpgmeErr) == GPG_ERR_EOF) { gpgmeErr = gpgme_get_key(mCtx, key_id.toUtf8().constData(), &new_key_refer, 1); - if(gpgme_err_code(gpgmeErr) == GPG_ERR_EOF) { + if (gpgme_err_code(gpgmeErr) == GPG_ERR_EOF) { throw std::runtime_error("key_id not found in key database"); } } - if(new_key_refer != nullptr) { + if (new_key_refer != nullptr) { it.value()->swapKeyRefer(new_key_refer); emit signalKeyInfoChanged(); } @@ -949,11 +979,10 @@ namespace GpgME { bool GpgContext::addUID(const GpgKey &key, const GpgUID &uid) { QString userid = QString("%1 (%3) <%2>").arg(uid.name, uid.email, uid.comment); auto gpgmeError = gpgme_op_adduid(mCtx, key.key_refer, userid.toUtf8().constData(), 0); - if(gpgmeError == GPG_ERR_NO_ERROR) { + if (gpgmeError == GPG_ERR_NO_ERROR) { emit signalKeyUpdated(key.id); return true; - } - else { + } else { checkErr(gpgmeError); return false; } @@ -962,11 +991,10 @@ namespace GpgME { bool GpgContext::revUID(const GpgKey &key, const GpgUID &uid) { auto gpgmeError = gpgme_op_revuid(mCtx, key.key_refer, uid.uid.toUtf8().constData(), 0); - if(gpgmeError == GPG_ERR_NO_ERROR) { + if (gpgmeError == GPG_ERR_NO_ERROR) { emit signalKeyUpdated(key.id); return true; - } - else { + } else { checkErr(gpgmeError); return false; } @@ -975,11 +1003,10 @@ namespace GpgME { bool GpgContext::setPrimaryUID(const GpgKey &key, const GpgUID &uid) { auto gpgmeError = gpgme_op_set_uid_flag(mCtx, key.key_refer, uid.uid.toUtf8().constData(), "primary", nullptr); - if(gpgmeError == GPG_ERR_NO_ERROR) { + if (gpgmeError == GPG_ERR_NO_ERROR) { emit signalKeyUpdated(key.id); return true; - } - else { + } else { checkErr(gpgmeError); return false; } @@ -990,13 +1017,12 @@ namespace GpgME { auto signing_key = getKeyById(signature.keyid); auto gpgmeError = gpgme_op_revsig(mCtx, key.key_refer, - signing_key.key_refer, - signature.uid.toUtf8().constData(), 0); - if(gpg_err_code(gpgmeError) == GPG_ERR_NO_ERROR) { + signing_key.key_refer, + signature.uid.toUtf8().constData(), 0); + if (gpg_err_code(gpgmeError) == GPG_ERR_NO_ERROR) { emit signalKeyUpdated(key.id); return true; - } - else { + } else { checkErr(gpgmeError); return false; } @@ -1004,7 +1030,7 @@ namespace GpgME { bool GpgContext::generateSubkey(const GpgKey &key, GenKeyInfo *params) { - if(!params->isSubKey()) { + if (!params->isSubKey()) { return false; } @@ -1038,11 +1064,10 @@ namespace GpgME { auto gpgmeError = gpgme_op_createsubkey(mCtx, key.key_refer, algo, 0, expires, flags); - if(gpgmeError == GPG_ERR_NO_ERROR) { + if (gpgmeError == GPG_ERR_NO_ERROR) { emit signalKeyUpdated(key.id); return true; - } - else { + } else { checkErr(gpgmeError); return false; } @@ -1050,33 +1075,33 @@ namespace GpgME { bool GpgContext::setExpire(const GpgKey &key, const GpgSubKey *subkey, QDateTime *expires) { unsigned long expires_time = 0; - if(expires != nullptr) { + if (expires != nullptr) { qDebug() << "Expire Datetime" << expires->toString(); expires_time = QDateTime::currentDateTime().secsTo(*expires); } const char *subfprs = nullptr; - if(subkey != nullptr) { + if (subkey != nullptr) { subfprs = subkey->fpr.toUtf8().constData(); } auto gpgmeError = gpgme_op_setexpire(mCtx, key.key_refer, expires_time, subfprs, 0); - if(gpgmeError == GPG_ERR_NO_ERROR) { + if (gpgmeError == GPG_ERR_NO_ERROR) { emit signalKeyUpdated(key.id); return true; - } - else { + } else { checkErr(gpgmeError); return false; } } bool GpgContext::checkIfKeyCanSign(const GpgKey &key) { - if(std::any_of(key.subKeys.begin(), key.subKeys.end(), [] (const GpgSubKey &subkey) -> bool { + if (std::any_of(key.subKeys.begin(), key.subKeys.end(), [](const GpgSubKey &subkey) -> bool { return subkey.secret && subkey.can_sign && !subkey.disabled && !subkey.revoked && !subkey.expired; - })) return true; + })) + return true; return false; } @@ -1085,16 +1110,18 @@ namespace GpgME { } bool GpgContext::checkIfKeyCanAuth(const GpgKey &key) { - if(std::any_of(key.subKeys.begin(), key.subKeys.end(), [] (const GpgSubKey &subkey) -> bool { + if (std::any_of(key.subKeys.begin(), key.subKeys.end(), [](const GpgSubKey &subkey) -> bool { return subkey.secret && subkey.can_authenticate && !subkey.disabled && !subkey.revoked && !subkey.expired; - })) return true; + })) + return true; return false; } bool GpgContext::checkIfKeyCanEncr(const GpgKey &key) { - if(std::any_of(key.subKeys.begin(), key.subKeys.end(), [] (const GpgSubKey &subkey) -> bool { + if (std::any_of(key.subKeys.begin(), key.subKeys.end(), [](const GpgSubKey &subkey) -> bool { return subkey.can_encrypt && !subkey.disabled && !subkey.revoked && !subkey.expired; - })) return true; + })) + return true; return false; } @@ -1103,11 +1130,6 @@ namespace GpgME { gpgme_data_t dataIn = nullptr, dataOut = nullptr; outBuffer->resize(0); - if (keys.count() == 0) { - QMessageBox::critical(nullptr, tr("No Key Selected"), tr("No Key Selected")); - return false; - } - setSigners(keys); //gpgme_encrypt_result_t e_result; @@ -1115,25 +1137,25 @@ namespace GpgME { /* set key for user */ int index = 0; - for(const auto &key : keys) { + for (const auto &key : keys) { recipients[index++] = key.key_refer; } //Last entry dataIn array has to be nullptr recipients[keys.count()] = nullptr; //If the last parameter isnt 0, a private copy of data is made - if (mCtx) { + if (mCtx != nullptr) { err = gpgme_data_new_from_mem(&dataIn, inBuffer.data(), inBuffer.size(), 1); - checkErr(err); - if (!err) { + if (gpg_err_code(err) == GPG_ERR_NO_ERROR) { err = gpgme_data_new(&dataOut); - checkErr(err); - if (!err) { + if (gpg_err_code(err) == GPG_ERR_NO_ERROR) { err = gpgme_op_encrypt_sign(mCtx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, dataIn, dataOut); - checkErr(err); - if (!err) { + if (encr_result != nullptr) + *encr_result = gpgme_op_encrypt_result(mCtx); + if (sign_result != nullptr) + *sign_result = gpgme_op_sign_result(mCtx); + if (gpg_err_code(err) == GPG_ERR_NO_ERROR) { err = readToBuffer(dataOut, outBuffer); - checkErr(err); } } } @@ -1145,19 +1167,43 @@ namespace GpgME { gpgme_data_release(dataOut); } - if(encr_result != nullptr) { - *encr_result = gpgme_op_encrypt_result(mCtx); - } - if(sign_result != nullptr) { - *sign_result = gpgme_op_sign_result(mCtx); - } - return err; } -} - + gpgme_error_t + GpgContext::decryptVerify(const QByteArray &inBuffer, QByteArray *outBuffer, gpgme_decrypt_result_t *decrypt_result, + gpgme_verify_result_t *verify_result) { + gpgme_data_t dataIn = nullptr, dataOut = nullptr; + outBuffer->resize(0); + if (mCtx != nullptr) { + err = gpgme_data_new_from_mem(&dataIn, inBuffer.data(), inBuffer.size(), 1); + if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) { + err = gpgme_data_new(&dataOut); + if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) { + err = gpgme_op_decrypt_verify(mCtx, dataIn, dataOut); + if (decrypt_result != nullptr) + *decrypt_result = gpgme_op_decrypt_result(mCtx); + if (verify_result != nullptr) + *verify_result = gpgme_op_verify_result(mCtx); + if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) { + err = readToBuffer(dataOut, outBuffer); + } + } + } + } + if (!settings.value("general/rememberPassword").toBool()) { + clearPasswordCache(); + } + if (dataIn) { + gpgme_data_release(dataIn); + } + if (dataOut) { + gpgme_data_release(dataOut); + } + return err; + } +}
\ No newline at end of file |