aboutsummaryrefslogtreecommitdiffstats
path: root/src/ui/main_window/MainWindowGpgOperaFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/main_window/MainWindowGpgOperaFunction.cpp')
-rw-r--r--src/ui/main_window/MainWindowGpgOperaFunction.cpp459
1 files changed, 407 insertions, 52 deletions
diff --git a/src/ui/main_window/MainWindowGpgOperaFunction.cpp b/src/ui/main_window/MainWindowGpgOperaFunction.cpp
index a2daa06b..8395c8f8 100644
--- a/src/ui/main_window/MainWindowGpgOperaFunction.cpp
+++ b/src/ui/main_window/MainWindowGpgOperaFunction.cpp
@@ -27,16 +27,10 @@
*/
#include "MainWindow.h"
-#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
-#include "core/function/result_analyse/GpgDecryptResultAnalyse.h"
-#include "core/function/result_analyse/GpgEncryptResultAnalyse.h"
-#include "core/function/result_analyse/GpgSignResultAnalyse.h"
-#include "core/function/result_analyse/GpgVerifyResultAnalyse.h"
-#include "core/model/DataObject.h"
-#include "core/model/GpgEncryptResult.h"
-#include "core/module/ModuleManager.h"
#include "core/utils/GpgUtils.h"
+#include "core/utils/IOUtils.h"
#include "ui/UserInterfaceUtils.h"
#include "ui/dialog/SignersPicker.h"
#include "ui/function/GpgOperaHelper.h"
@@ -46,22 +40,18 @@
namespace GpgFrontend::UI {
-void MainWindow::SlotEncrypt() {
- if (edit_->CurPageTextEdit() == nullptr) return;
-
- auto contexts = QSharedPointer<GpgOperaContextBasement>::create();
- contexts->ascii = true;
-
+auto MainWindow::encrypt_operation_key_validate(
+ const QSharedPointer<GpgOperaContextBasement>& contexts) -> bool {
auto key_ids = m_key_list_->GetChecked();
- // Symmetric Encrypt
+ // symmetric encryption
if (key_ids.isEmpty()) {
auto ret = QMessageBox::information(
this, tr("Symmetric Encryption"),
tr("No Key Selected. Do you want to encrypt with a "
"symmetric cipher using a passphrase?"),
QMessageBox::Ok | QMessageBox::Cancel);
- if (ret == QMessageBox::Cancel) return;
+ if (ret == QMessageBox::Cancel) return false;
contexts->keys = {};
} else {
@@ -69,9 +59,136 @@ void MainWindow::SlotEncrypt() {
key_ids,
[](const GpgKey& key) { return key.IsHasActualEncryptionCapability(); },
tr("The selected keypair cannot be used for encryption."));
- if (contexts->keys.empty()) return;
+ if (contexts->keys.empty()) return false;
+ }
+
+ return true;
+}
+
+auto MainWindow::sign_operation_key_validate(
+ const QSharedPointer<GpgOperaContextBasement>& contexts) -> bool {
+ auto* signers_picker =
+ new SignersPicker(m_key_list_->GetCurrentGpgContextChannel(), this);
+ QEventLoop loop;
+ connect(signers_picker, &SignersPicker::finished, &loop, &QEventLoop::quit);
+ loop.exec();
+
+ // return when canceled
+ if (!signers_picker->GetStatus()) return false;
+
+ auto signer_key_ids = signers_picker->GetCheckedSigners();
+ auto signer_keys =
+ GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel())
+ .GetKeys(signer_key_ids);
+ assert(std::all_of(signer_keys.begin(), signer_keys.end(),
+ [](const auto& key) { return key.IsGood(); }));
+
+ contexts->singer_keys = signer_keys;
+
+ return true;
+}
+
+auto MainWindow::check_read_file_paths_helper(const QStringList& paths)
+ -> bool {
+ QStringList invalid_files;
+ for (const auto& path : paths) {
+ auto result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(result)) {
+ invalid_files.append(path);
+ }
+ }
+
+ if (!invalid_files.empty()) {
+ QString error_file_names;
+ for (const auto& file_path : invalid_files) {
+ error_file_names += QFileInfo(file_path).fileName() + "\n";
+ }
+
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot read from the following files:\n\n%1")
+ .arg(error_file_names.trimmed()));
+ return false;
+ }
+
+ return true;
+}
+
+auto MainWindow::check_write_file_paths_helper(const QStringList& o_paths)
+ -> bool {
+ for (const auto& o_path : o_paths) {
+ if (QFile::exists(o_path)) {
+ auto out_file_name = tr("The target file %1 already exists, "
+ "do you need to overwrite it?")
+ .arg(QFileInfo(o_path).fileName());
+ auto ret = QMessageBox::warning(this, tr("Warning"), out_file_name,
+ QMessageBox::Ok | QMessageBox::Cancel);
+
+ if (ret == QMessageBox::Cancel) return false;
+ }
+ }
+
+ QStringList invalid_output_files;
+ for (const auto& path : o_paths) {
+ auto result = TargetFilePreCheck(path, false);
+ if (!std::get<0>(result)) {
+ invalid_output_files.append(path);
+ }
+ }
+
+ if (!invalid_output_files.empty()) {
+ QString error_file_names;
+ for (const auto& file_path : invalid_output_files) {
+ error_file_names += QFileInfo(file_path).fileName() + "\n";
+ }
+
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot write to the following files:\n\n%1")
+ .arg(error_file_names.trimmed()));
+ return false;
}
+ return true;
+}
+
+auto MainWindow::check_keys_helper(
+ const KeyIdArgsList& key_ids,
+ const std::function<bool(const GpgKey&)>& capability_check,
+ const QString& capability_err_string) -> GpgKeyList {
+ if (key_ids.empty()) {
+ QMessageBox::critical(
+ this, tr("No Key Checked"),
+ tr("Please check the key in the key toolbox on the right."));
+ return {};
+ }
+
+ auto keys =
+ GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel())
+ .GetKeys(key_ids);
+ assert(std::all_of(keys.begin(), keys.end(),
+ [](const auto& key) { return key.IsGood(); }));
+
+ // check key abilities
+ for (const auto& key : keys) {
+ if (!capability_check(key)) {
+ QMessageBox::critical(nullptr, tr("Invalid KeyPair"),
+ capability_err_string + "<br/><br/>" +
+ tr("For example the Following Key:") +
+ " <br/>" + key.GetUIDs()->front().GetUID());
+ return {};
+ }
+ }
+
+ return keys;
+}
+
+void MainWindow::SlotEncrypt() {
+ if (edit_->CurPageTextEdit() == nullptr) return;
+
+ auto contexts = QSharedPointer<GpgOperaContextBasement>::create();
+ contexts->ascii = true;
+
+ if (!encrypt_operation_key_validate(contexts)) return;
+
contexts->GetContextBuffer(0).append(GFBuffer(edit_->CurPlainText()));
GpgOperaHelper::BuildOperas(contexts, 0,
m_key_list_->GetCurrentGpgContextChannel(),
@@ -141,42 +258,13 @@ void MainWindow::SlotEncryptSign() {
contexts->ascii = true;
auto key_ids = m_key_list_->GetChecked();
+ contexts->keys = check_keys_helper(
+ key_ids,
+ [](const GpgKey& key) { return key.IsHasActualEncryptionCapability(); },
+ tr("The selected keypair cannot be used for encryption."));
+ if (contexts->keys.empty()) return;
- // Symmetric Encrypt
- if (key_ids.isEmpty()) {
- auto ret = QMessageBox::information(
- this, tr("Symmetric Encryption"),
- tr("No Key Selected. Do you want to encrypt with a "
- "symmetric cipher using a passphrase?"),
- QMessageBox::Ok | QMessageBox::Cancel);
- if (ret == QMessageBox::Cancel) return;
-
- contexts->keys = {};
- } else {
- contexts->keys = check_keys_helper(
- key_ids,
- [](const GpgKey& key) { return key.IsHasActualEncryptionCapability(); },
- tr("The selected keypair cannot be used for encryption."));
- if (contexts->keys.empty()) return;
- }
-
- auto* signers_picker =
- new SignersPicker(m_key_list_->GetCurrentGpgContextChannel(), this);
- QEventLoop loop;
- connect(signers_picker, &SignersPicker::finished, &loop, &QEventLoop::quit);
- loop.exec();
-
- // return when canceled
- if (!signers_picker->GetStatus()) return;
-
- auto signer_key_ids = signers_picker->GetCheckedSigners();
- auto signer_keys =
- GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel())
- .GetKeys(signer_key_ids);
- assert(std::all_of(signer_keys.begin(), signer_keys.end(),
- [](const auto& key) { return key.IsGood(); }));
-
- contexts->singer_keys = signer_keys;
+ if (!sign_operation_key_validate(contexts)) return;
contexts->GetContextBuffer(0).append(GFBuffer(edit_->CurPlainText()));
GpgOperaHelper::BuildOperas(contexts, 0,
@@ -204,4 +292,271 @@ void MainWindow::SlotDecryptVerify() {
}
}
+void MainWindow::SlotFileEncrypt(const QStringList& paths) {
+ auto contexts = QSharedPointer<GpgOperaContextBasement>::create();
+
+ bool const non_ascii_at_file_operation =
+ GetSettings().value("gnupg/non_ascii_at_file_operation", true).toBool();
+
+ contexts->ascii = !non_ascii_at_file_operation;
+
+ if (!encrypt_operation_key_validate(contexts)) return;
+
+ if (!check_read_file_paths_helper(paths)) return;
+
+ for (const auto& path : paths) {
+ QFileInfo info(path);
+ if (info.isDir()) {
+ contexts->GetContextPath(1).append(path);
+ contexts->GetContextOutPath(1).append(
+ SetExtensionOfOutputFileForArchive(path, kENCRYPT, contexts->ascii));
+ } else {
+ contexts->GetContextPath(0).append(path);
+ contexts->GetContextOutPath(0).append(
+ SetExtensionOfOutputFile(path, kENCRYPT, contexts->ascii));
+ }
+ }
+
+ if (!check_write_file_paths_helper(contexts->GetAllOutPath())) return;
+
+ GpgOperaHelper::BuildOperas(contexts, 0,
+ m_key_list_->GetCurrentGpgContextChannel(),
+ GpgOperaHelper::BuildOperasFileEncrypt);
+
+ GpgOperaHelper::BuildOperas(contexts, 1,
+ m_key_list_->GetCurrentGpgContextChannel(),
+ GpgOperaHelper::BuildOperasDirectoryEncrypt);
+
+ exec_operas_helper(tr("Encrypting"), contexts);
+}
+
+void MainWindow::SlotFileDecrypt(const QStringList& paths) {
+ auto contexts = QSharedPointer<GpgOperaContextBasement>::create();
+
+ contexts->ascii = true;
+
+ if (!check_read_file_paths_helper(paths)) return;
+
+ for (const auto& path : paths) {
+ QFileInfo info(path);
+ const auto extension = info.completeSuffix();
+
+ if (extension == "tar.gpg" || extension == "tar.asc") {
+ contexts->GetContextPath(1).append(path);
+ contexts->GetContextOutPath(1).append(
+ SetExtensionOfOutputFileForArchive(path, kDECRYPT, contexts->ascii));
+ } else {
+ contexts->GetContextPath(0).append(path);
+ contexts->GetContextOutPath(0).append(
+ SetExtensionOfOutputFile(path, kDECRYPT, contexts->ascii));
+ }
+ }
+
+ if (!check_write_file_paths_helper(contexts->GetAllOutPath())) return;
+
+ GpgOperaHelper::BuildOperas(contexts, 0,
+ m_key_list_->GetCurrentGpgContextChannel(),
+ GpgOperaHelper::BuildOperasFileDecrypt);
+
+ GpgOperaHelper::BuildOperas(contexts, 1,
+ m_key_list_->GetCurrentGpgContextChannel(),
+ GpgOperaHelper::BuildOperasArchiveDecrypt);
+
+ exec_operas_helper(tr("Decrypting"), contexts);
+}
+
+void MainWindow::SlotFileSign(const QStringList& paths) {
+ auto contexts = QSharedPointer<GpgOperaContextBasement>::create();
+
+ bool const non_ascii_at_file_operation =
+ GetSettings().value("gnupg/non_ascii_at_file_operation", true).toBool();
+
+ contexts->ascii = !non_ascii_at_file_operation;
+
+ auto key_ids = m_key_list_->GetChecked();
+ contexts->keys = check_keys_helper(
+ key_ids,
+ [](const GpgKey& key) { return key.IsHasActualSigningCapability(); },
+ tr("The selected key contains a key that does not actually have a "
+ "sign usage."));
+ if (contexts->keys.empty()) return;
+
+ if (!check_read_file_paths_helper(paths)) return;
+
+ for (const auto& path : paths) {
+ QFileInfo info(path);
+ contexts->GetContextPath(0).append(path);
+ contexts->GetContextOutPath(0).append(
+ SetExtensionOfOutputFile(path, kSIGN, contexts->ascii));
+ }
+
+ if (!check_write_file_paths_helper(contexts->GetAllOutPath())) return;
+
+ GpgOperaHelper::BuildOperas(contexts, 0,
+ m_key_list_->GetCurrentGpgContextChannel(),
+ GpgOperaHelper::BuildOperasFileSign);
+
+ exec_operas_helper(tr("Signing"), contexts);
+}
+
+void MainWindow::SlotFileVerify(const QStringList& paths) {
+ auto contexts = QSharedPointer<GpgOperaContextBasement>::create();
+
+ if (!check_read_file_paths_helper(paths)) return;
+
+ for (const auto& path : paths) {
+ QFileInfo info(path);
+
+ QString sign_file_path = path;
+ QString data_file_path;
+
+ bool const possible_singleton_target =
+ info.suffix() == "gpg" || info.suffix() == "pgp";
+ if (possible_singleton_target) {
+ swap(data_file_path, sign_file_path);
+ } else {
+ data_file_path = info.path() + "/" + info.completeBaseName();
+ }
+
+ auto data_file_info = QFileInfo(data_file_path);
+ if (!possible_singleton_target && !data_file_info.exists()) {
+ bool ok;
+ QString const text = QInputDialog::getText(
+ this, tr("File to be Verified"),
+ tr("Please provide An ABSOLUTE Path \n"
+ "If Data And Signature is COMBINED within a single file, "
+ "KEEP THIS EMPTY: "),
+ QLineEdit::Normal, data_file_path, &ok);
+
+ if (!ok) return;
+
+ data_file_path = text.isEmpty() ? data_file_path : text;
+ data_file_info = QFileInfo(data_file_path);
+ }
+
+ contexts->GetContextPath(0).append(sign_file_path);
+ contexts->GetContextOutPath(0).append(data_file_path);
+ }
+
+ GpgOperaHelper::BuildOperas(contexts, 0,
+ m_key_list_->GetCurrentGpgContextChannel(),
+ GpgOperaHelper::BuildOperasFileVerify);
+
+ exec_operas_helper(tr("Verifying"), contexts);
+
+ if (!contexts->unknown_fprs.isEmpty()) {
+ slot_verifying_unknown_signature_helper(contexts->unknown_fprs);
+ }
+}
+
+void MainWindow::SlotFileEncryptSign(const QStringList& paths) {
+ auto contexts = QSharedPointer<GpgOperaContextBasement>::create();
+
+ bool const non_ascii_at_file_operation =
+ GetSettings().value("gnupg/non_ascii_at_file_operation", true).toBool();
+
+ contexts->ascii = !non_ascii_at_file_operation;
+
+ auto key_ids = m_key_list_->GetChecked();
+ contexts->keys = check_keys_helper(
+ key_ids,
+ [](const GpgKey& key) { return key.IsHasActualEncryptionCapability(); },
+ tr("The selected keypair cannot be used for encryption."));
+ if (contexts->keys.empty()) return;
+
+ if (!sign_operation_key_validate(contexts)) return;
+
+ if (!check_read_file_paths_helper(paths)) return;
+
+ for (const auto& path : paths) {
+ QFileInfo info(path);
+ if (info.isDir()) {
+ contexts->GetContextPath(1).append(path);
+ contexts->GetContextOutPath(1).append(
+ SetExtensionOfOutputFileForArchive(path, kENCRYPT, contexts->ascii));
+ } else {
+ contexts->GetContextPath(0).append(path);
+ contexts->GetContextOutPath(0).append(
+ SetExtensionOfOutputFile(path, kENCRYPT, contexts->ascii));
+ }
+ }
+
+ if (!check_write_file_paths_helper(contexts->GetAllOutPath())) return;
+
+ GpgOperaHelper::BuildOperas(contexts, 0,
+ m_key_list_->GetCurrentGpgContextChannel(),
+ GpgOperaHelper::BuildOperasFileEncryptSign);
+
+ GpgOperaHelper::BuildOperas(contexts, 1,
+ m_key_list_->GetCurrentGpgContextChannel(),
+ GpgOperaHelper::BuildOperasDirectoryEncryptSign);
+
+ exec_operas_helper(tr("Encrypting and Signing"), contexts);
+}
+
+void MainWindow::SlotFileDecryptVerify(const QStringList& paths) {
+ auto contexts = QSharedPointer<GpgOperaContextBasement>::create();
+
+ contexts->ascii = true;
+
+ if (!check_read_file_paths_helper(paths)) return;
+
+ for (const auto& path : paths) {
+ QFileInfo info(path);
+ const auto extension = info.completeSuffix();
+
+ if (extension == "tar.gpg" || extension == "tar.asc") {
+ contexts->GetContextPath(1).append(path);
+ contexts->GetContextOutPath(1).append(
+ SetExtensionOfOutputFileForArchive(path, kDECRYPT, contexts->ascii));
+ } else {
+ contexts->GetContextPath(0).append(path);
+ contexts->GetContextOutPath(0).append(
+ SetExtensionOfOutputFile(path, kDECRYPT, contexts->ascii));
+ }
+ }
+
+ if (!check_write_file_paths_helper(contexts->GetAllOutPath())) return;
+
+ GpgOperaHelper::BuildOperas(contexts, 0,
+ m_key_list_->GetCurrentGpgContextChannel(),
+ GpgOperaHelper::BuildOperasFileDecryptVerify);
+
+ GpgOperaHelper::BuildOperas(contexts, 1,
+ m_key_list_->GetCurrentGpgContextChannel(),
+ GpgOperaHelper::BuildOperasArchiveDecryptVerify);
+
+ exec_operas_helper(tr("Decrypting and Verifying"), contexts);
+
+ if (!contexts->unknown_fprs.isEmpty()) {
+ slot_verifying_unknown_signature_helper(contexts->unknown_fprs);
+ }
+};
+
+void MainWindow::SlotFileVerifyEML(const QString& path) {
+ auto check_result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot read from file: %1").arg(path));
+ return;
+ }
+
+ QFileInfo file_info(path);
+ if (file_info.size() > static_cast<qint64>(1024 * 1024 * 32)) {
+ QMessageBox::warning(this, tr("EML File Too Large"),
+ tr("The EML file \"%1\" is larger than 32MB and "
+ "will not be opened.")
+ .arg(file_info.fileName()));
+ return;
+ }
+
+ QFile eml_file(path);
+ if (!eml_file.open(QIODevice::ReadOnly)) return;
+ auto buffer = eml_file.readAll();
+
+ // LOG_D() << "EML BUFFER (FILE): " << buffer;
+
+ slot_verify_email_by_eml_data(buffer);
+}
+
} // namespace GpgFrontend::UI \ No newline at end of file