aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp7
-rw-r--r--src/core/function/result_analyse/GpgVerifyResultAnalyse.h10
-rw-r--r--src/ui/UserInterfaceUtils.cpp117
-rw-r--r--src/ui/UserInterfaceUtils.h10
-rw-r--r--src/ui/main_window/MainWindowFileSlotFunction.cpp91
-rw-r--r--src/ui/main_window/MainWindowGpgOperaFunction.cpp118
6 files changed, 309 insertions, 44 deletions
diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
index b53ae9b8..9512189d 100644
--- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
@@ -126,6 +126,8 @@ void GpgFrontend::GpgVerifyResultAnalyse::doAnalyse() {
<< Qt::endl;
setStatus(-2);
print_signer_without_key(stream_, GpgSignature(sign));
+ unknown_signer_fpr_list_.push_back(
+ GpgSignature(sign).GetFingerprint());
break;
case GPG_ERR_CERT_REVOKED:
stream_ << tr("A signature is valid but the key used to verify the "
@@ -252,3 +254,8 @@ auto GpgFrontend::GpgVerifyResultAnalyse::TakeChargeOfResult()
-> GpgFrontend::GpgVerifyResult {
return result_;
}
+
+auto GpgFrontend::GpgVerifyResultAnalyse::GetUnknownSignatures() const
+ -> QList<QString> {
+ return unknown_signer_fpr_list_;
+}
diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
index 422cec43..b3e318b8 100644
--- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
@@ -53,7 +53,7 @@ class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
*
* @return gpgme_signature_t
*/
- auto GetSignatures() const -> gpgme_signature_t;
+ [[nodiscard]] auto GetSignatures() const -> gpgme_signature_t;
/**
* @brief
@@ -62,6 +62,13 @@ class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
*/
auto TakeChargeOfResult() -> GpgVerifyResult;
+ /**
+ * @brief Get the Unknown Signatures object
+ *
+ * @return QList<QString>
+ */
+ [[nodiscard]] auto GetUnknownSignatures() const -> QList<QString>;
+
protected:
/**
* @brief
@@ -92,6 +99,7 @@ class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
GpgError error_; ///<
GpgVerifyResult result_; ///<
+ QList<QString> unknown_signer_fpr_list_;
};
} // namespace GpgFrontend
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
index db54dd15..ba3c323b 100644
--- a/src/ui/UserInterfaceUtils.cpp
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -411,6 +411,67 @@ void CommonUtils::SlotImportKeyFromKeyServer(
return;
}
+ if (Module::IsModuleActivate(
+ "com.bktus.gpgfrontend.module.key_server_sync")) {
+ // LOOP
+ decltype(key_ids.size()) current_index = 1;
+ decltype(key_ids.size()) all_index = key_ids.size();
+
+ for (const auto &key_id : key_ids) {
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Network)
+ ->PostTask(new Thread::Task(
+ [=](const DataObjectPtr &data_obj) -> int {
+ Module::TriggerEvent(
+ "REQUEST_GET_PUBLIC_KEY_BY_KEY_ID",
+ {
+ {"key_id", QString(key_id)},
+ },
+ [key_id, channel, callback, current_index, all_index](
+ Module::EventIdentifier i,
+ Module::Event::ListenerIdentifier ei,
+ Module::Event::Params p) {
+ LOG_D()
+ << "REQUEST_GET_PUBLIC_KEY_BY_FINGERPRINT callback: "
+ << i << ei;
+
+ QString status;
+
+ if (p["ret"] != "0" || !p["error_msg"].isEmpty()) {
+ LOG_E()
+ << "An error occurred trying to get data from key:"
+ << key_id << "error message: " << p["error_msg"]
+ << "reply data: " << p["reply_data"];
+ status = p["error_msg"] + p["reply_data"];
+ } else if (p.contains("key_data")) {
+ const auto key_data = p["key_data"];
+ LOG_D() << "got key data of key " << key_id
+ << " from key server: " << key_data;
+
+ auto result = GpgKeyImportExporter::GetInstance(channel)
+ .ImportKey(GFBuffer(key_data));
+ if (result->imported == 1) {
+ status = tr("The key has been updated");
+ } else {
+ status = tr("No need to update the key");
+ }
+ }
+
+ callback(key_id, status, current_index, all_index);
+ });
+
+ return 0;
+ },
+ QString("key_%1_import_task").arg(key_id)));
+
+ // not too fast to hit rate limit
+ QThread::msleep(200);
+ current_index++;
+ }
+
+ return;
+ }
+
auto *thread =
QThread::create([target_keyserver, key_ids, callback, channel]() {
QUrl target_keyserver_url(target_keyserver);
@@ -594,4 +655,60 @@ void CommonUtils::ImportKeyFromKeyServer(int channel,
->PostTask(task);
}
+void CommonUtils::ImportKeyByKeyServerSyncModule(QWidget *parent, int channel,
+ const QList<QString> &fprs) {
+ if (!Module::IsModuleActivate(
+ "com.bktus.gpgfrontend.module.key_server_sync")) {
+ return;
+ }
+
+ auto all_key_data = QSharedPointer<QString>::create();
+ auto remaining_tasks = QSharedPointer<int>::create(fprs.size());
+
+ for (const auto &fpr : fprs) {
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Network)
+ ->PostTask(new Thread::Task(
+ [=](const DataObjectPtr &data_obj) -> int {
+ Module::TriggerEvent(
+ "REQUEST_GET_PUBLIC_KEY_BY_FINGERPRINT",
+ {
+ {"fingerprint", QString(fpr)},
+ },
+ [fpr, all_key_data, remaining_tasks, this, parent, channel](
+ Module::EventIdentifier i,
+ Module::Event::ListenerIdentifier ei,
+ Module::Event::Params p) {
+ LOG_D()
+ << "REQUEST_GET_PUBLIC_KEY_BY_FINGERPRINT callback: "
+ << i << ei;
+
+ if (p["ret"] != "0" || !p["error_msg"].isEmpty()) {
+ LOG_E()
+ << "An error occurred trying to get data from key:"
+ << fpr << "error message: " << p["error_msg"]
+ << "reply data: " << p["reply_data"];
+ } else if (p.contains("key_data")) {
+ const auto key_data = p["key_data"];
+ LOG_D() << "got key data of key " << fpr
+ << " from key server: " << key_data;
+
+ *all_key_data += key_data;
+ }
+
+ // it only uses one thread for these operations
+ // so that is no need for locking now
+ (*remaining_tasks)--;
+
+ if (*remaining_tasks == 0) {
+ this->SlotImportKeys(parent, channel,
+ all_key_data->toUtf8());
+ }
+ });
+
+ return 0;
+ },
+ QString("key_%1_import_task").arg(fpr)));
+ }
+}
} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h
index fd5de9de..650d049e 100644
--- a/src/ui/UserInterfaceUtils.h
+++ b/src/ui/UserInterfaceUtils.h
@@ -237,7 +237,7 @@ class CommonUtils : public QWidget {
*
* @param parent
*/
- void SlotImportKeyFromFile(QWidget* parentint, int channel);
+ void SlotImportKeyFromFile(QWidget* parent, int channel);
/**
* @brief
@@ -256,6 +256,14 @@ class CommonUtils : public QWidget {
/**
* @brief
*
+ * @param channel
+ */
+ void ImportKeyByKeyServerSyncModule(QWidget* parent, int channel,
+ const QList<QString>& fprs);
+
+ /**
+ * @brief
+ *
* @param ctx_channel
* @param key_ids
* @param callback
diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp
index 4b1eec9f..c85b616a 100644
--- a/src/ui/main_window/MainWindowFileSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp
@@ -34,6 +34,7 @@
#include "core/function/result_analyse/GpgEncryptResultAnalyse.h"
#include "core/function/result_analyse/GpgSignResultAnalyse.h"
#include "core/function/result_analyse/GpgVerifyResultAnalyse.h"
+#include "core/module/ModuleManager.h"
#include "core/utils/GpgUtils.h"
#include "core/utils/IOUtils.h"
#include "ui/UserInterfaceUtils.h"
@@ -554,14 +555,41 @@ void MainWindow::SlotFileVerify(const QString& path) {
process_result_analyse(edit_, info_board_, result_analyse);
- // pause this feature
- // if (result_analyse.GetStatus() == -2) {
- // import_unknown_key_from_keyserver(this, result_analyse);
- // }
- // pause this feature
- // if (result_analyse.GetStatus() >= 0) {
- // show_verify_details(this, info_board_, err, result);
- // }
+ if (!result_analyse.GetUnknownSignatures().isEmpty() &&
+ Module::IsModuleActivate(
+ "com.bktus.gpgfrontend.module.key_server_sync")) {
+ LOG_D() << "try to sync missing key info from server"
+ << result_analyse.GetUnknownSignatures();
+
+ QString fingerprint_list;
+ for (const auto& fingerprint :
+ result_analyse.GetUnknownSignatures()) {
+ fingerprint_list += fingerprint + "\n";
+ }
+
+ // Interaction with user
+ auto user_response = QMessageBox::question(
+ this, tr("Missing Keys"),
+ tr("Some signatures cannot be verified because the "
+ "corresponding keys are missing.\n\n"
+ "The following fingerprints are missing:\n%1\n\n"
+ "Would you like to fetch these keys from the key "
+ "server?")
+ .arg(fingerprint_list),
+ QMessageBox::Yes | QMessageBox::No);
+
+ if (user_response == QMessageBox::Yes) {
+ CommonUtils::GetInstance()
+ ->ImportKeyByKeyServerSyncModule(
+ this, m_key_list_->GetCurrentGpgContextChannel(),
+ result_analyse.GetUnknownSignatures());
+ } else {
+ QMessageBox::information(
+ this, tr("Verification Incomplete"),
+ tr("Verification was incomplete due to missing "
+ "keys. You can manually import the keys later."));
+ }
+ }
this->slot_refresh_current_file_view();
});
@@ -870,18 +898,43 @@ void MainWindow::SlotFileDecryptVerify(const QString& path) {
decrypt_result_analyse,
verify_result_analyse);
- // pause this feature
- // if (verify_result_analyse.GetStatus() == -2) {
- // import_unknown_key_from_keyserver(this,
- // verify_result_analyse);
- // }
- // pause this feature
- // if (verify_result_analyse.GetStatus() >= 0) {
- // show_verify_details(this, info_board_, err,
- // verify_result);
- // }
-
this->slot_refresh_current_file_view();
+
+ if (!verify_result_analyse.GetUnknownSignatures().isEmpty() &&
+ Module::IsModuleActivate(
+ "com.bktus.gpgfrontend.module.key_server_sync")) {
+ LOG_D() << "try to sync missing key info from server"
+ << verify_result_analyse.GetUnknownSignatures();
+
+ QString fingerprint_list;
+ for (const auto& fingerprint :
+ verify_result_analyse.GetUnknownSignatures()) {
+ fingerprint_list += fingerprint + "\n";
+ }
+
+ // Interaction with user
+ auto user_response = QMessageBox::question(
+ this, tr("Missing Keys"),
+ tr("Some signatures cannot be verified because the "
+ "corresponding keys are missing.\n\n"
+ "The following fingerprints are missing:\n%1\n\n"
+ "Would you like to fetch these keys from the key "
+ "server?")
+ .arg(fingerprint_list),
+ QMessageBox::Yes | QMessageBox::No);
+
+ if (user_response == QMessageBox::Yes) {
+ CommonUtils::GetInstance()
+ ->ImportKeyByKeyServerSyncModule(
+ this, m_key_list_->GetCurrentGpgContextChannel(),
+ verify_result_analyse.GetUnknownSignatures());
+ } else {
+ QMessageBox::information(
+ this, tr("Verification Incomplete"),
+ tr("Verification was incomplete due to missing "
+ "keys. You can manually import the keys later."));
+ }
+ }
});
});
}
diff --git a/src/ui/main_window/MainWindowGpgOperaFunction.cpp b/src/ui/main_window/MainWindowGpgOperaFunction.cpp
index 5069f600..b8935efb 100644
--- a/src/ui/main_window/MainWindowGpgOperaFunction.cpp
+++ b/src/ui/main_window/MainWindowGpgOperaFunction.cpp
@@ -35,6 +35,7 @@
#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 "ui/UserInterfaceUtils.h"
#include "ui/dialog/SignersPicker.h"
@@ -266,29 +267,65 @@ void MainWindow::SlotVerify() {
this, tr("Verifying"), [this, buffer](const OperaWaitingHd& hd) {
GpgFrontend::GpgBasicOperator::GetInstance(
m_key_list_->GetCurrentGpgContextChannel())
- .Verify(buffer, GFBuffer(),
- [this, hd](GpgError err, const DataObjectPtr& data_obj) {
- // stop waiting
- hd();
-
- if (CheckGpgError(err) == GPG_ERR_USER_1 ||
- data_obj == nullptr ||
- !data_obj->Check<GpgVerifyResult>()) {
- QMessageBox::critical(this, tr("Error"),
- tr("Unknown error occurred"));
- return;
- }
- auto verify_result =
- ExtractParams<GpgVerifyResult>(data_obj, 0);
-
- // analyse result
- auto result_analyse = GpgVerifyResultAnalyse(
- m_key_list_->GetCurrentGpgContextChannel(), err,
- verify_result);
- result_analyse.Analyse();
- process_result_analyse(edit_, info_board_,
- result_analyse);
- });
+ .Verify(
+ buffer, GFBuffer(),
+ [this, hd](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 ||
+ data_obj == nullptr ||
+ !data_obj->Check<GpgVerifyResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+ auto verify_result =
+ ExtractParams<GpgVerifyResult>(data_obj, 0);
+
+ // analyse result
+ auto result_analyse = GpgVerifyResultAnalyse(
+ m_key_list_->GetCurrentGpgContextChannel(), err,
+ verify_result);
+ result_analyse.Analyse();
+ process_result_analyse(edit_, info_board_, result_analyse);
+
+ if (!result_analyse.GetUnknownSignatures().isEmpty() &&
+ Module::IsModuleActivate(
+ "com.bktus.gpgfrontend.module.key_server_sync")) {
+ LOG_D() << "try to sync missing key info from server"
+ << result_analyse.GetUnknownSignatures();
+
+ QString fingerprint_list;
+ for (const auto& fingerprint :
+ result_analyse.GetUnknownSignatures()) {
+ fingerprint_list += fingerprint + "\n";
+ }
+
+ // Interaction with user
+ auto user_response = QMessageBox::question(
+ this, tr("Missing Keys"),
+ tr("Some signatures cannot be verified because the "
+ "corresponding keys are missing.\n\n"
+ "The following fingerprints are missing:\n%1\n\n"
+ "Would you like to fetch these keys from the key "
+ "server?")
+ .arg(fingerprint_list),
+ QMessageBox::Yes | QMessageBox::No);
+
+ if (user_response == QMessageBox::Yes) {
+ CommonUtils::GetInstance()
+ ->ImportKeyByKeyServerSyncModule(
+ this, m_key_list_->GetCurrentGpgContextChannel(),
+ result_analyse.GetUnknownSignatures());
+ } else {
+ QMessageBox::information(
+ this, tr("Verification Incomplete"),
+ tr("Verification was incomplete due to missing "
+ "keys. You can manually import the keys later."));
+ }
+ }
+ });
});
}
@@ -440,6 +477,41 @@ void MainWindow::SlotDecryptVerify() {
edit_->SlotFillTextEditWithText(
out_buffer.ConvertToQByteArray());
}
+
+ if (!verify_result_analyse.GetUnknownSignatures().isEmpty() &&
+ Module::IsModuleActivate(
+ "com.bktus.gpgfrontend.module.key_server_sync")) {
+ LOG_D() << "try to sync missing key info from server"
+ << verify_result_analyse.GetUnknownSignatures();
+
+ QString fingerprint_list;
+ for (const auto& fingerprint :
+ verify_result_analyse.GetUnknownSignatures()) {
+ fingerprint_list += fingerprint + "\n";
+ }
+
+ // Interaction with user
+ auto user_response = QMessageBox::question(
+ this, tr("Missing Keys"),
+ tr("Some signatures cannot be verified because the "
+ "corresponding keys are missing.\n\n"
+ "The following fingerprints are missing:\n%1\n\n"
+ "Would you like to fetch these keys from the key "
+ "server?")
+ .arg(fingerprint_list),
+ QMessageBox::Yes | QMessageBox::No);
+
+ if (user_response == QMessageBox::Yes) {
+ CommonUtils::GetInstance()->ImportKeyByKeyServerSyncModule(
+ this, m_key_list_->GetCurrentGpgContextChannel(),
+ verify_result_analyse.GetUnknownSignatures());
+ } else {
+ QMessageBox::information(
+ this, tr("Verification Incomplete"),
+ tr("Verification was incomplete due to missing "
+ "keys. You can manually import the keys later."));
+ }
+ }
});
});
}