diff options
author | saturneric <[email protected]> | 2024-11-26 19:57:56 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2024-11-26 20:07:41 +0000 |
commit | 673a3a13fac0b41124760bf44244ba0bb039e09f (patch) | |
tree | e3ecaf4ad7882c32dc38292b7abdb5bbd58afbb6 | |
parent | fix: add ui status control for email operations (diff) | |
download | GpgFrontend-673a3a13fac0b41124760bf44244ba0bb039e09f.tar.gz GpgFrontend-673a3a13fac0b41124760bf44244ba0bb039e09f.zip |
feat: support eml data decryption
-rw-r--r-- | gpgfrontend.qrc | 1 | ||||
m--------- | modules | 0 | ||||
-rw-r--r-- | resource/lfs/icons/email-open.png | bin | 0 -> 7818 bytes | |||
-rw-r--r-- | src/ui/main_window/MainWindow.h | 30 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowSlotFunction.cpp | 140 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowSlotUI.cpp | 24 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowUI.cpp | 8 |
7 files changed, 198 insertions, 5 deletions
diff --git a/gpgfrontend.qrc b/gpgfrontend.qrc index d53dc1d3..4e904366 100644 --- a/gpgfrontend.qrc +++ b/gpgfrontend.qrc @@ -104,6 +104,7 @@ <file alias="database.png">resource/lfs/icons/database.png</file> <file alias="publish.png">resource/lfs/icons/publish.png</file> <file alias="email-check.png">resource/lfs/icons/email-check.png</file> + <file alias="email-open.png">resource/lfs/icons/email-open.png</file> </qresource> <qresource prefix="/test/key"> <file alias="pv1.key">resource/lfs/test/data/pv1.key</file> diff --git a/modules b/modules -Subproject 37bbb836f049e03b0bbdde20ac3d837b3667647 +Subproject 1ce0bca5a88b2a4e7d79892da907410f2ad0775 diff --git a/resource/lfs/icons/email-open.png b/resource/lfs/icons/email-open.png Binary files differnew file mode 100644 index 00000000..0176b698 --- /dev/null +++ b/resource/lfs/icons/email-open.png diff --git a/src/ui/main_window/MainWindow.h b/src/ui/main_window/MainWindow.h index e10efb9b..11c97884 100644 --- a/src/ui/main_window/MainWindow.h +++ b/src/ui/main_window/MainWindow.h @@ -172,6 +172,12 @@ class MainWindow : public GeneralMainWindow { void SlotVerifyEML(); /** + * @brief + * + */ + void SlotDecryptEML(); + + /** * @details decrypt and verify the text of currently active textedit-page * with the currently checked keys */ @@ -297,6 +303,12 @@ class MainWindow : public GeneralMainWindow { * @brief * */ + void SlotGeneralDecryptEMail(bool); + + /** + * @brief + * + */ void SlotGeneralVerifyEMail(bool); private slots: @@ -506,6 +518,20 @@ class MainWindow : public GeneralMainWindow { */ void slot_restart_gpg_components(bool); + /** + * @brief + * + * @param buffer + */ + void slot_decrypt_email_by_eml_data(const QByteArray& buffer); + + /** + * @brief + * + */ + void slot_decrypt_email_by_eml_data_result_helper( + const QMap<QString, QString>& p); + private: /** * @details Create actions for the main-menu and the context-menu of the @@ -654,7 +680,9 @@ class MainWindow : public GeneralMainWindow { QAction* import_key_from_file_act_{}; ///< QAction* import_key_from_clipboard_act_{}; ///< QAction* import_key_from_key_server_act_{}; ///< - QAction* verify_email_by_eml_data_act_{}; ///< + + QAction* verify_email_by_eml_data_act_{}; ///< + QAction* decrypt_email_by_eml_data_act_{}; QLabel* status_bar_icon_{}; ///< diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index e70fc8fa..c7579ff9 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -30,6 +30,8 @@ #include "core/function/gpg/GpgBasicOperator.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyImportExporter.h" +#include "core/function/result_analyse/GpgDecryptResultAnalyse.h" +#include "core/model/GpgDecryptResult.h" #include "core/module/ModuleManager.h" #include "core/typedef/GpgTypedef.h" #include "core/utils/CommonUtils.h" @@ -398,6 +400,57 @@ void MainWindow::slot_verify_email_by_eml_data(const QByteArray& buffer) { }); } +void MainWindow::slot_decrypt_email_by_eml_data(const QByteArray& buffer) { + Module::TriggerEvent( + "EMAIL_DECRYPT_EML_DATA", + { + {"eml_data", QString::fromLatin1(buffer.toBase64())}, + }, + [=](Module::EventIdentifier i, Module::Event::ListenerIdentifier ei, + Module::Event::Params p) { + LOG_D() << "EMAIL_DECRYPT_EML_DATA callback: " << i << ei; + if (p["ret"] != "0" || !p["err"].isEmpty()) { + LOG_E() << "An error occurred trying to decrypt email, " + << "error message: " << p["err"]; + + if (p["ret"] == "-2") { + QString detailed_error = p["err"]; + + QString info = + tr("# EML Data Error\n\n" + "The provided EML data does not conform to the " + "structure described in RFC 3156 and cannot be " + "validated.\n\n" + "Details: %1\n\n" + "What is EML Data?\n" + "EML is a file format used to represent email messages. " + "It typically contains the entire contents of an email, " + "including headers, " + "body text, attachments, and metadata. In order to validate " + "the email properly, it is necessary to provide the " + "complete, original EML " + "data.\n\n" + "For more information about the expected EML structure, " + "please refer to the RFC 3156 standard:\n" + "%2\n\n" + "Please ensure the EML data follows the standard and try " + "again.") + .arg(detailed_error) + .arg("https://www.rfc-editor.org/rfc/rfc3156.txt"); + slot_refresh_info_board(-2, info); + } + + return; + } + + if (p.contains("encrypted")) { + slot_decrypt_email_by_eml_data_result_helper(p); + } + + LOG_E() << "mime or signature data is missing"; + }); +} + void MainWindow::SlotVerifyEML() { if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) return; @@ -452,6 +505,8 @@ void MainWindow::slot_verify_email_by_eml_data_result_helper( const QMap<QString, QString>& p) { const auto mime = QByteArray::fromBase64(p["mime"].toLatin1()); const auto signature = QByteArray::fromBase64(p["signature"].toLatin1()); + const auto part_mime_content_hash = p["mime_hash"]; + const auto prm_micalg_value = p["micalg"]; auto timestamp = p.value("datetime", "-1").toLongLong(); auto datetime = tr("None"); @@ -460,7 +515,7 @@ void MainWindow::slot_verify_email_by_eml_data_result_helper( } QString email_info; - email_info.append("# Email Information\n\n"); + email_info.append("# E-Mail Information\n\n"); email_info.append(QString("- %1: %2\n") .arg(tr("From")) .arg(p.value("from", tr("Unknown")))); @@ -474,6 +529,15 @@ void MainWindow::slot_verify_email_by_eml_data_result_helper( email_info.append( QString("- %1: %2\n").arg(tr("BCC")).arg(p.value("bcc", tr("None")))); email_info.append(QString("- %1: %2\n").arg(tr("Date")).arg(datetime)); + + email_info.append("\n"); + email_info.append("# OpenPGP Information\n\n"); + email_info.append(QString("- %1: %2\n") + .arg(tr("Signed EML Data Hash (SHA1)")) + .arg(part_mime_content_hash)); + email_info.append(QString("- %1: %2\n") + .arg(tr("Message Integrity Check Algorithm")) + .arg(prm_micalg_value)); email_info.append("\n"); // set input buffer @@ -551,4 +615,78 @@ void MainWindow::slot_result_analyse_show_helper(const GpgResultAnalyse& r_a, r_a.GetResultReport() + r_b.GetResultReport()); } +void MainWindow::SlotDecryptEML() { + if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) return; + + auto buffer = edit_->CurPlainText().toLatin1(); + buffer = buffer.replace("\n", "\r\n"); + + // LOG_D() << "EML BUFFER: " << buffer; + + slot_decrypt_email_by_eml_data(buffer); +} + +void MainWindow::slot_decrypt_email_by_eml_data_result_helper( + const QMap<QString, QString>& p) { + const auto encrypted = QByteArray::fromBase64(p["encrypted"].toLatin1()); + + auto timestamp = p.value("datetime", "-1").toLongLong(); + auto datetime = tr("None"); + if (timestamp > 0) { + datetime = QLocale().toString(QDateTime::fromMSecsSinceEpoch(timestamp)); + } + + QString email_info; + email_info.append("# E-Mail Information\n\n"); + email_info.append(QString("- %1: %2\n") + .arg(tr("From")) + .arg(p.value("from", tr("Unknown")))); + email_info.append( + QString("- %1: %2\n").arg(tr("To")).arg(p.value("to", tr("Unknown")))); + email_info.append(QString("- %1: %2\n") + .arg(tr("Subject")) + .arg(p.value("subject", tr("None")))); + email_info.append( + QString("- %1: %2\n").arg(tr("CC")).arg(p.value("cc", tr("None")))); + email_info.append( + QString("- %1: %2\n").arg(tr("BCC")).arg(p.value("bcc", tr("None")))); + email_info.append(QString("- %1: %2\n").arg(tr("Date")).arg(datetime)); + + email_info.append("\n"); + + // data to transfer into task + auto buffer = GFBuffer(encrypted); + + CommonUtils::WaitForOpera( + this, tr("Decrypting"), [this, buffer](const OperaWaitingHd& hd) { + GpgFrontend::GpgBasicOperator::GetInstance( + m_key_list_->GetCurrentGpgContextChannel()) + .Decrypt(buffer, [this, hd](GpgError err, + const DataObjectPtr& data_obj) { + // stop waiting + hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr || + !data_obj->Check<GpgDecryptResult, GFBuffer>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + auto decrypt_result = + ExtractParams<GpgDecryptResult>(data_obj, 0); + auto out_buffer = ExtractParams<GFBuffer>(data_obj, 1); + auto result_analyse = GpgDecryptResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, + decrypt_result); + result_analyse.Analyse(); + slot_result_analyse_show_helper(result_analyse); + + if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { + edit_->SlotFillTextEditWithText( + out_buffer.ConvertToQByteArray()); + } + }); + }); +} + } // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index 4a460005..105a2374 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -80,7 +80,10 @@ void MainWindow::slot_switch_menu_control_mode(int index) { decrypt_act_->setDisabled(disable); decrypt_verify_act_->setDisabled(disable); - verify_email_by_eml_data_act_->setDisabled(disable); + if (Module::IsModuleActivate(kEmailModuleID)) { + verify_email_by_eml_data_act_->setDisabled(disable); + decrypt_email_by_eml_data_act_->setDisabled(disable); + } redo_act_->setDisabled(disable); undo_act_->setDisabled(disable); @@ -186,7 +189,10 @@ void MainWindow::SlotUpdateCryptoMenuStatus(unsigned int type) { decrypt_act_->setDisabled(true); decrypt_verify_act_->setDisabled(true); - verify_email_by_eml_data_act_->setDisabled(true); + if (Module::IsModuleActivate(kEmailModuleID)) { + verify_email_by_eml_data_act_->setDisabled(true); + decrypt_email_by_eml_data_act_->setDisabled(true); + } // gnupg operations if ((opera_type & MainWindow::OperationMenu::kVerify) != 0U) { @@ -209,7 +215,8 @@ void MainWindow::SlotUpdateCryptoMenuStatus(unsigned int type) { } // email operations - if ((opera_type & MainWindow::OperationMenu::kVerifyEMail) != 0U) { + if (Module::IsModuleActivate(kEmailModuleID) && + (opera_type & MainWindow::OperationMenu::kVerifyEMail) != 0U) { verify_email_by_eml_data_act_->setDisabled(false); } } @@ -369,4 +376,15 @@ void MainWindow::slot_restart_gpg_components(bool) { }); } +void MainWindow::SlotGeneralDecryptEMail(bool) { + // if (edit_->SlotCurPageFileTreeView() != nullptr) { + // const auto* file_tree_view = edit_->SlotCurPageFileTreeView(); + // const auto path = file_tree_view->GetSelected(); + + // const auto file_info = QFileInfo(path); + // if (file_info.isFile()) this->SlotFileVerify(path); + // } + if (edit_->SlotCurPageTextEdit() != nullptr) this->SlotDecryptEML(); +} + } // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp index e11d6374..9c2a5003 100644 --- a/src/ui/main_window/MainWindowUI.cpp +++ b/src/ui/main_window/MainWindowUI.cpp @@ -265,6 +265,12 @@ void MainWindow::create_actions() { ":/icons/email-check.png", tr("Verify RAW E-Mail Data (EML)")); connect(verify_email_by_eml_data_act_, &QAction::triggered, this, &MainWindow::SlotGeneralVerifyEMail); + + decrypt_email_by_eml_data_act_ = create_action( + "decrypt_email_by_eml_data", tr("Decrypt E-Mail"), + ":/icons/email-open.png", tr("Decrypt RAW E-Mail Data (EML)")); + connect(decrypt_email_by_eml_data_act_, &QAction::triggered, this, + &MainWindow::SlotGeneralDecryptEMail); } /* @@ -462,6 +468,7 @@ void MainWindow::create_menus() { if (Module::IsModuleActivate(kEmailModuleID)) { email_menu_ = menuBar()->addMenu(tr("E-Mail")); email_menu_->addAction(verify_email_by_eml_data_act_); + email_menu_->addAction(decrypt_email_by_eml_data_act_); } view_menu_ = menuBar()->addMenu(tr("View")); @@ -527,6 +534,7 @@ void MainWindow::create_tool_bars() { email_tool_bar_ = addToolBar(tr("E-Mail")); email_tool_bar_->setObjectName("emailToolBar"); email_tool_bar_->addAction(verify_email_by_eml_data_act_); + email_tool_bar_->addAction(decrypt_email_by_eml_data_act_); view_menu_->addAction(email_tool_bar_->toggleViewAction()); } |