diff options
author | Saturneric <[email protected]> | 2021-12-06 15:58:23 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2021-12-06 15:58:43 +0000 |
commit | 97d13004e4f1cb33941a9be57c7e7662e223890b (patch) | |
tree | 6bf2466046379fd8ac2a0e9ca3605e15dce4672d /src | |
parent | Merge branch 'develop' of github.com:saturneric/GpgFrontend into develop-ci (diff) | |
download | GpgFrontend-97d13004e4f1cb33941a9be57c7e7662e223890b.tar.gz GpgFrontend-97d13004e4f1cb33941a9be57c7e7662e223890b.zip |
Improve UI & Functions
Diffstat (limited to 'src')
41 files changed, 761 insertions, 215 deletions
diff --git a/src/gpg/GpgConstants.cpp b/src/gpg/GpgConstants.cpp index 5688287e..e3de1d06 100644 --- a/src/gpg/GpgConstants.cpp +++ b/src/gpg/GpgConstants.cpp @@ -77,12 +77,15 @@ gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err, std::string GpgFrontend::beautify_fingerprint( GpgFrontend::BypeArrayConstRef fingerprint) { - auto _fingerprint = fingerprint; - unsigned len = fingerprint.size(); - if ((len > 0) && (len % 4 == 0)) - for (unsigned n = 0; 4 * (n + 1) < len; ++n) - _fingerprint.insert(static_cast<int>(5u * n + 4u), " "); - return fingerprint; + auto len = fingerprint.size(); + std::stringstream out; + decltype(len) count = 0; + while (count < len) { + if (count && !(count % 5)) out << " "; + out << fingerprint[count]; + count++; + } + return out.str(); } // trim from start (in place) diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp index 5d901c3f..b35615a6 100644 --- a/src/gpg/GpgContext.cpp +++ b/src/gpg/GpgContext.cpp @@ -76,7 +76,7 @@ GpgContext::GpgContext(bool independent_database, std::string db_path, if (engineInfo->protocol == GPGME_PROTOCOL_OpenPGP && strcmp(engineInfo->version, "1.0.0") != 0) find_openpgp = true, info.AppPath = engineInfo->file_name, - info.DatabasePath = "default"; + info.DatabasePath = "default", info.GnupgVersion = engineInfo->version; if (engineInfo->protocol == GPGME_PROTOCOL_CMS && strcmp(engineInfo->version, "1.0.0") != 0) find_cms = true; @@ -91,6 +91,8 @@ GpgContext::GpgContext(bool independent_database, std::string db_path, good_ = false; return; } else { + LOG(INFO) << "Gnupg Version" << info.GnupgVersion; + // Set Independent Database if (independent_database) { info.DatabasePath = db_path; diff --git a/src/gpg/GpgInfo.h b/src/gpg/GpgInfo.h index 27e13112..6ecb9b92 100644 --- a/src/gpg/GpgInfo.h +++ b/src/gpg/GpgInfo.h @@ -38,6 +38,8 @@ class GpgInfo { std::string AppPath; std::string DatabasePath; + + std::string GnupgVersion; }; #endif // GPGFRONTEND_ZH_CN_TS_GPGINFO_H diff --git a/src/gpg/GpgModel.h b/src/gpg/GpgModel.h index 3e07427c..af094bf5 100644 --- a/src/gpg/GpgModel.h +++ b/src/gpg/GpgModel.h @@ -25,13 +25,13 @@ #ifndef GPGFRONTEND_ZH_CN_TS_GPGMODEL_H #define GPGFRONTEND_ZH_CN_TS_GPGMODEL_H -#include "GpgConstants.h" - #include <list> #include <utility> +#include "GpgConstants.h" #include "gpg/model/GpgData.h" #include "gpg/model/GpgKey.h" +#include "gpg/model/GpgSignature.h" namespace GpgFrontend { diff --git a/src/gpg/function/GpgKeyImportExportor.cpp b/src/gpg/function/GpgKeyImportExportor.cpp index f4b88c60..d8812839 100644 --- a/src/gpg/function/GpgKeyImportExportor.cpp +++ b/src/gpg/function/GpgKeyImportExportor.cpp @@ -33,11 +33,12 @@ */ GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExportor::ImportKey( StdBypeArrayPtr in_buffer) { - if (in_buffer->empty()) return GpgImportInformation(); + if (in_buffer->empty()) return {}; GpgData data_in(in_buffer->data(), in_buffer->size()); auto err = check_gpg_error(gpgme_op_import(ctx, data_in)); - assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); + if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {}; + gpgme_import_result_t result; result = gpgme_op_import_result(ctx); gpgme_import_status_t status = result->imports; @@ -49,6 +50,7 @@ GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExportor::ImportKey( import_info->importedKeys.emplace_back(key); status = status->next; } + return *import_info; } @@ -64,11 +66,11 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeys( // Alleviate another crash problem caused by an unknown array out-of-bounds // access + auto all_success = true; for (size_t i = 0; i < uid_list->size(); i++) { GpgData data_out; auto err = gpgme_op_export(ctx, (*uid_list)[i].c_str(), 0, data_out); - assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); - + if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) all_success = false; DLOG(INFO) << "exportKeys read_bytes" << gpgme_data_seek(data_out, 0, SEEK_END); @@ -76,7 +78,7 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeys( std::swap(out_buffer, temp_out_buffer); } - return true; + return all_success; } /** @@ -105,7 +107,6 @@ bool GpgFrontend::GpgKeyImportExportor::ExportSecretKey( gpgme_key_t target_key[2] = {gpgme_key_t(key), nullptr}; GpgData data_out; - // export private key to outBuffer gpgme_error_t err = gpgme_op_export_keys(ctx, target_key, GPGME_EXPORT_MODE_SECRET, data_out); @@ -115,3 +116,17 @@ bool GpgFrontend::GpgKeyImportExportor::ExportSecretKey( return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR; } + +bool GpgFrontend::GpgKeyImportExportor::ExportKey( + const GpgFrontend::GpgKey& key, + GpgFrontend::ByteArrayPtr& out_buffer) const { + GpgData data_out; + auto err = gpgme_op_export(ctx, key.id().c_str(), 0, data_out); + + DLOG(INFO) << "exportKeys read_bytes" + << gpgme_data_seek(data_out, 0, SEEK_END); + + auto temp_out_buffer = data_out.Read2Buffer(); + std::swap(out_buffer, temp_out_buffer); + return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR; +} diff --git a/src/gpg/function/GpgKeyImportExportor.h b/src/gpg/function/GpgKeyImportExportor.h index bceb87ef..35a237ba 100644 --- a/src/gpg/function/GpgKeyImportExportor.h +++ b/src/gpg/function/GpgKeyImportExportor.h @@ -88,6 +88,8 @@ class GpgKeyImportExportor bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer) const; + bool ExportKey(const GpgKey& key, ByteArrayPtr& out_buffer) const; + bool ExportSecretKey(const GpgKey& key, ByteArrayPtr& outBuffer) const; private: diff --git a/src/gpg/function/GpgKeyOpera.cpp b/src/gpg/function/GpgKeyOpera.cpp index c60f9157..d0172a31 100644 --- a/src/gpg/function/GpgKeyOpera.cpp +++ b/src/gpg/function/GpgKeyOpera.cpp @@ -214,4 +214,23 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey( auto err = gpgme_op_createsubkey(ctx, gpgme_key_t(key), algo, 0, expires, flags); return check_gpg_error(err); -}
\ No newline at end of file +} + +GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyPassword( + const GpgFrontend::GpgKey& key) { + if (ctx.GetInfo().GnupgVersion < "2.0.15") { + LOG(ERROR) << _("operator not support"); + return GPG_ERR_NOT_SUPPORTED; + } + auto err = gpgme_op_passwd(ctx, gpgme_key_t(key), 0); + return check_gpg_error(err); +} +GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyTOFUPolicy( + const GpgFrontend::GpgKey& key, gpgme_tofu_policy_t tofu_policy) { + if (ctx.GetInfo().GnupgVersion < "2.1.10") { + LOG(ERROR) << _("operator not support"); + return GPG_ERR_NOT_SUPPORTED; + } + auto err = gpgme_op_tofu_policy(ctx, gpgme_key_t(key), tofu_policy); + return check_gpg_error(err); +} diff --git a/src/gpg/function/GpgKeyOpera.h b/src/gpg/function/GpgKeyOpera.h index 71e2de8b..568a125d 100644 --- a/src/gpg/function/GpgKeyOpera.h +++ b/src/gpg/function/GpgKeyOpera.h @@ -41,6 +41,11 @@ class GpgKeyOpera : public SingletonFunctionObject<GpgKeyOpera> { static void GenerateRevokeCert(const GpgKey& key, const std::string& output_file_name); + GpgFrontend::GpgError ModifyPassword(const GpgKey& key); + + GpgFrontend::GpgError ModifyTOFUPolicy(const GpgKey& key, + gpgme_tofu_policy_t tofu_policy); + GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params); GpgFrontend::GpgError GenerateSubkey( diff --git a/src/gpg/model/GpgSignature.cpp b/src/gpg/model/GpgSignature.cpp new file mode 100644 index 00000000..c8509edf --- /dev/null +++ b/src/gpg/model/GpgSignature.cpp @@ -0,0 +1,28 @@ +/** + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#include "GpgSignature.h" + +GpgFrontend::GpgSignature::GpgSignature(gpgme_signature_t sig) + : _signature_ref(sig, [&](gpgme_signature_t signature) {}) {} diff --git a/src/gpg/model/GpgSignature.h b/src/gpg/model/GpgSignature.h new file mode 100644 index 00000000..347cceb1 --- /dev/null +++ b/src/gpg/model/GpgSignature.h @@ -0,0 +1,86 @@ +/** + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_GPGSIGNATURE_H +#define GPGFRONTEND_GPGSIGNATURE_H + +#include <boost/date_time/gregorian/greg_date.hpp> +#include <boost/date_time/posix_time/conversion.hpp> + +#include "gpg/GpgConstants.h" + +namespace GpgFrontend { +class GpgSignature { + public: + [[nodiscard]] gpgme_validity_t validity() const { + return _signature_ref->validity; + } + + [[nodiscard]] gpgme_error_t status() const { return _signature_ref->status; } + + [[nodiscard]] gpgme_error_t summary() const { + return _signature_ref->summary; + } + + [[nodiscard]] std::string pubkey_algo() const { + return gpgme_pubkey_algo_name(_signature_ref->pubkey_algo); + } + + [[nodiscard]] std::string hash_algo() const { + return gpgme_hash_algo_name(_signature_ref->hash_algo); + } + + [[nodiscard]] boost::gregorian::date create_time() const { + return boost::posix_time::from_time_t(_signature_ref->timestamp).date(); + } + [[nodiscard]] boost::gregorian::date expire_time() const { + return boost::posix_time::from_time_t(_signature_ref->exp_timestamp).date(); + } + + [[nodiscard]] std::string fpr() const { return _signature_ref->fpr; } + + GpgSignature() = default; + + ~GpgSignature() = default; + + explicit GpgSignature(gpgme_signature_t sig); + + GpgSignature(GpgSignature &&) noexcept = default; + + GpgSignature(const GpgSignature &) = delete; + + GpgSignature &operator=(GpgSignature &&) noexcept = default; + + GpgSignature &operator=(const GpgSignature &) = delete; + + private: + using KeySignatrueRefHandler = + std::unique_ptr<struct _gpgme_signature, + std::function<void(gpgme_signature_t)>>; + + KeySignatrueRefHandler _signature_ref = nullptr; +}; +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGSIGNATURE_H diff --git a/src/gpg/model/GpgSubKey.h b/src/gpg/model/GpgSubKey.h index 5f65c507..3ee93a0c 100644 --- a/src/gpg/model/GpgSubKey.h +++ b/src/gpg/model/GpgSubKey.h @@ -21,6 +21,7 @@ * by Saturneric<[email protected]> starting on May 12, 2021. * */ + #ifndef GPGFRONTEND_GPGSUBKEY_H #define GPGFRONTEND_GPGSUBKEY_H diff --git a/src/gpg/model/GpgTOFUInfo.cpp b/src/gpg/model/GpgTOFUInfo.cpp new file mode 100644 index 00000000..0f18a1c2 --- /dev/null +++ b/src/gpg/model/GpgTOFUInfo.cpp @@ -0,0 +1,28 @@ +/** + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#include "GpgTOFUInfo.h" + +GpgFrontend::GpgTOFUInfo::GpgTOFUInfo(gpgme_tofu_info_t tofu_info) + : _tofu_info_ref(tofu_info, [&](gpgme_tofu_info_t tofu_info) {}) {} diff --git a/src/gpg/model/GpgTOFUInfo.h b/src/gpg/model/GpgTOFUInfo.h new file mode 100644 index 00000000..3d1e379d --- /dev/null +++ b/src/gpg/model/GpgTOFUInfo.h @@ -0,0 +1,89 @@ +/** + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_GPGTOFU_H +#define GPGFRONTEND_GPGTOFU_H + +#include "gpg/GpgConstants.h" + +namespace GpgFrontend { + +class GpgTOFUInfo { + public: + [[nodiscard]] unsigned validity() const { return _tofu_info_ref->validity; } + + [[nodiscard]] unsigned policy() const { return _tofu_info_ref->policy; } + + [[nodiscard]] unsigned long sign_count() const { + return _tofu_info_ref->signcount; + } + + [[nodiscard]] unsigned long encr_count() const { + return _tofu_info_ref->encrcount; + } + + [[nodiscard]] unsigned long sign_first() const { + return _tofu_info_ref->signfirst; + } + + [[nodiscard]] unsigned long sign_last() const { + return _tofu_info_ref->signlast; + } + + [[nodiscard]] unsigned long encr_last() const { + return _tofu_info_ref->encrlast; + } + + [[nodiscard]] std::string description() const { + return _tofu_info_ref->description; + } + + GpgTOFUInfo() = default; + + explicit GpgTOFUInfo(gpgme_tofu_info_t tofu_info); + + GpgTOFUInfo(GpgTOFUInfo&& o) noexcept { + swap(_tofu_info_ref, o._tofu_info_ref); + } + + GpgTOFUInfo(const GpgTOFUInfo&) = delete; + + GpgTOFUInfo& operator=(GpgTOFUInfo&& o) noexcept { + swap(_tofu_info_ref, o._tofu_info_ref); + return *this; + }; + + GpgTOFUInfo& operator=(const GpgTOFUInfo&) = delete; + + private: + using SubkeyRefHandler = + std::unique_ptr<struct _gpgme_tofu_info, + std::function<void(gpgme_tofu_info_t)>>; + + SubkeyRefHandler _tofu_info_ref = nullptr; +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_GPGTOFU_H diff --git a/src/gpg/model/GpgUID.h b/src/gpg/model/GpgUID.h index 66dba321..8cac4cf7 100644 --- a/src/gpg/model/GpgUID.h +++ b/src/gpg/model/GpgUID.h @@ -26,6 +26,7 @@ #define GPGFRONTEND_GPGUID_H #include "GpgKeySignature.h" +#include "GpgTOFUInfo.h" namespace GpgFrontend { @@ -43,6 +44,16 @@ class GpgUID { [[nodiscard]] bool invalid() const { return _uid_ref->invalid; } + [[nodiscard]] std::unique_ptr<std::vector<GpgTOFUInfo>> tofu_infos() const { + auto infos = std::make_unique<std::vector<GpgTOFUInfo>>(); + auto info_next = _uid_ref->tofu; + while (info_next != nullptr) { + infos->push_back(GpgTOFUInfo(info_next)); + info_next = info_next->next; + } + return infos; + } + [[nodiscard]] std::unique_ptr<std::vector<GpgKeySignature>> signatures() const { auto sigs = std::make_unique<std::vector<GpgKeySignature>>(); diff --git a/src/gpg/result_analyse/VerifyResultAnalyse.cpp b/src/gpg/result_analyse/VerifyResultAnalyse.cpp index 74d2d204..3901b6c8 100644 --- a/src/gpg/result_analyse/VerifyResultAnalyse.cpp +++ b/src/gpg/result_analyse/VerifyResultAnalyse.cpp @@ -200,3 +200,7 @@ gpgme_signature_t GpgFrontend::VerifyResultAnalyse::GetSignatures() { else return nullptr; } +GpgFrontend::GpgVerifyResult +GpgFrontend::VerifyResultAnalyse::TakeChargeOfResult() { + return std::move(result); +} diff --git a/src/gpg/result_analyse/VerifyResultAnalyse.h b/src/gpg/result_analyse/VerifyResultAnalyse.h index 51ce17ac..abd8f72e 100644 --- a/src/gpg/result_analyse/VerifyResultAnalyse.h +++ b/src/gpg/result_analyse/VerifyResultAnalyse.h @@ -36,6 +36,8 @@ class VerifyResultAnalyse : public ResultAnalyse { gpgme_signature_t GetSignatures(); + GpgVerifyResult TakeChargeOfResult(); + private: void do_analyse(); diff --git a/src/main.cpp b/src/main.cpp index ee542ff0..983d062b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,6 +38,7 @@ int main(int argc, char* argv[]) { // Qt App QApplication app(argc, argv); + QApplication::setWindowIcon(QIcon(":gpgfrontend.png")); // logging system init_logging(); @@ -65,7 +66,7 @@ int main(int argc, char* argv[]) { #endif /** - * internationalisation. loop to restart mainwindow + * internationalisation. loop to restart main window * with changed translation when settings change. */ int return_from_event_loop_code; diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index b80da2ec..f4b00d22 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -6,6 +6,7 @@ aux_source_directory(./main_window UI_SOURCE) aux_source_directory(./help UI_SOURCE) aux_source_directory(./settings UI_SOURCE) aux_source_directory(./function UI_SOURCE) +aux_source_directory(./details UI_SOURCE) if (SMTP_SUPPORT) message(STATUS "Build SMTP Support") diff --git a/src/ui/FileEncryptionDialog.cpp b/src/ui/FileEncryptionDialog.cpp index 137d8555..aeba6497 100755 --- a/src/ui/FileEncryptionDialog.cpp +++ b/src/ui/FileEncryptionDialog.cpp @@ -267,7 +267,7 @@ void FileEncryptionDialog::slotExecuteAction() { GpgVerifyResult result = nullptr; auto error = BasicOperator::GetInstance().Verify(in_data, sign_data, result); - new VerifyDetailsDialog(this, mKeyList, error, std::move(result)); + new VerifyDetailsDialog(this, error, std::move(result)); return; } diff --git a/src/ui/FileEncryptionDialog.h b/src/ui/FileEncryptionDialog.h index 613f84e7..b09bb8db 100755 --- a/src/ui/FileEncryptionDialog.h +++ b/src/ui/FileEncryptionDialog.h @@ -25,9 +25,9 @@ #ifndef __FILEENCRYPTIONDIALOG_H__ #define __FILEENCRYPTIONDIALOG_H__ -#include "VerifyDetailsDialog.h" #include "gpg/GpgContext.h" #include "ui/GpgFrontendUI.h" +#include "ui/details/VerifyDetailsDialog.h" #include "ui/widgets/KeyList.h" namespace GpgFrontend::UI { diff --git a/src/ui/KeyServerImportDialog.cpp b/src/ui/KeyServerImportDialog.cpp index 17db7d65..2b814693 100644 --- a/src/ui/KeyServerImportDialog.cpp +++ b/src/ui/KeyServerImportDialog.cpp @@ -196,7 +196,7 @@ void KeyServerImportDialog::createKeysTable() { void KeyServerImportDialog::setMessage(const QString& text, bool error) { if (mAutomatic) return; - + message->setText(text); if (error) { icon->setPixmap( @@ -527,34 +527,24 @@ KeyServerImportDialog::KeyServerImportDialog(QWidget* parent) : QDialog(parent), mAutomatic(true) { setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); - message = new QLabel; - message->setFixedHeight(24); - icon = new QLabel; - icon->setFixedHeight(24); - // Network Waiting waitingBar = new QProgressBar(); waitingBar->setVisible(false); waitingBar->setRange(0, 0); - waitingBar->setFixedHeight(24); - waitingBar->setFixedWidth(200); + waitingBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + waitingBar->setTextVisible(false); // Layout for messagebox - auto* messageLayout = new QHBoxLayout; - messageLayout->addWidget(icon); - messageLayout->addWidget(message); - messageLayout->addWidget(waitingBar); - messageLayout->addStretch(); + auto* layout = new QHBoxLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + layout->addWidget(waitingBar); keyServerComboBox = createComboBox(); - auto* mainLayout = new QGridLayout; - - mainLayout->addLayout(messageLayout, 0, 0, 1, 3); - - this->setLayout(mainLayout); - this->setWindowTitle(_("Upload Keys from Keyserver")); - this->setFixedSize(200, 42); + this->setLayout(layout); + this->setWindowTitle(_("Update Keys from Keyserver")); + this->setFixedSize(240, 42); this->setModal(true); } diff --git a/src/ui/KeyServerImportDialog.h b/src/ui/KeyServerImportDialog.h index 67571f2f..508fb42d 100644 --- a/src/ui/KeyServerImportDialog.h +++ b/src/ui/KeyServerImportDialog.h @@ -38,7 +38,7 @@ class KeyServerImportDialog : public QDialog { public: KeyServerImportDialog(bool automatic, QWidget* parent); - KeyServerImportDialog(QWidget* parent); + explicit KeyServerImportDialog(QWidget* parent); void slotImport(const KeyIdArgsListPtr& keys); diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index f4eb70a8..839abb98 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -361,8 +361,6 @@ class MainWindow : public QMainWindow { QToolBar* keyToolBar{}; /** Toolbar holding key operations */ QToolButton* importButton{}; /** Toolbutton for import dropdown menu in toolbar */ - QToolButton* fileEncButton{}; /** Toolbutton for file cryption dropdown menu - in toolbar */ QDockWidget* keyListDock{}; /** Encrypt Dock*/ QDockWidget* attachmentDock{}; /** Attachment Dock */ QDockWidget* infoBoardDock{}; diff --git a/src/ui/details/SignatureDetailsDialog.cpp b/src/ui/details/SignatureDetailsDialog.cpp new file mode 100644 index 00000000..b9ab6b78 --- /dev/null +++ b/src/ui/details/SignatureDetailsDialog.cpp @@ -0,0 +1,25 @@ +/** + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#include "SignatureDetailsDialog.h" diff --git a/src/ui/details/SignatureDetailsDialog.h b/src/ui/details/SignatureDetailsDialog.h new file mode 100644 index 00000000..ea69d1f2 --- /dev/null +++ b/src/ui/details/SignatureDetailsDialog.h @@ -0,0 +1,35 @@ +/** + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_SIGNATUREDETAILSDIALOG_H +#define GPGFRONTEND_SIGNATUREDETAILSDIALOG_H +#include "ui/GpgFrontendUI.h" + +class SignatureDetailsDialog : public QDialog { + Q_OBJECT + public: + +}; + +#endif // GPGFRONTEND_SIGNATUREDETAILSDIALOG_H diff --git a/src/ui/VerifyDetailsDialog.cpp b/src/ui/details/VerifyDetailsDialog.cpp index 1ad9d996..c03feea5 100644 --- a/src/ui/VerifyDetailsDialog.cpp +++ b/src/ui/details/VerifyDetailsDialog.cpp @@ -22,19 +22,16 @@ * */ -#include "ui/VerifyDetailsDialog.h" +#include "VerifyDetailsDialog.h" #include <boost/format.hpp> namespace GpgFrontend::UI { -VerifyDetailsDialog::VerifyDetailsDialog(QWidget* parent, KeyList* keyList, - GpgError error, GpgVerifyResult result) - : QDialog(parent), - mKeyList(keyList), - mResult(std::move(result)), - error(error) { - this->setWindowTitle(_("Signature Details")); +VerifyDetailsDialog::VerifyDetailsDialog(QWidget* parent, GpgError error, + GpgVerifyResult result) + : QDialog(parent), mResult(std::move(result)), error(error) { + this->setWindowTitle(_("Signatures Details")); mainLayout = new QHBoxLayout(); this->setLayout(mainLayout); @@ -86,7 +83,8 @@ void VerifyDetailsDialog::slotRefresh() { } // Add information box for every single key while (sign) { - auto* sign_box = new VerifyKeyDetailBox(this, mKeyList, sign); + GpgSignature signature(sign); + auto* sign_box = new VerifyKeyDetailBox(signature, this); sign = sign->next; mVboxLayout->addWidget(sign_box); } diff --git a/src/ui/VerifyDetailsDialog.h b/src/ui/details/VerifyDetailsDialog.h index 3de4a56f..5de648f6 100644 --- a/src/ui/VerifyDetailsDialog.h +++ b/src/ui/details/VerifyDetailsDialog.h @@ -34,8 +34,8 @@ namespace GpgFrontend::UI { class VerifyDetailsDialog : public QDialog { Q_OBJECT public: - explicit VerifyDetailsDialog(QWidget* parent, KeyList* keyList, - GpgError error, GpgVerifyResult result); + explicit VerifyDetailsDialog(QWidget* parent, GpgError error, + GpgVerifyResult result); private slots: diff --git a/src/ui/keypair_details/KeyPairDetailTab.cpp b/src/ui/keypair_details/KeyPairDetailTab.cpp index f88e9edc..3e1ec319 100644 --- a/src/ui/keypair_details/KeyPairDetailTab.cpp +++ b/src/ui/keypair_details/KeyPairDetailTab.cpp @@ -26,6 +26,7 @@ #include "gpg/function/GpgKeyGetter.h" #include "gpg/function/GpgKeyImportExportor.h" +#include "gpg/function/GpgKeyOpera.h" #include "ui/SignalStation.h" #include "ui/UserInterfaceUtils.h" #include "ui/WaitingDialog.h" @@ -33,8 +34,6 @@ namespace GpgFrontend::UI { KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent) : QWidget(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) { - keyid = mKey.id(); - ownerBox = new QGroupBox(_("Owner")); keyBox = new QGroupBox(_("Master Key")); fingerprintBox = new QGroupBox(_("Fingerprint")); @@ -117,8 +116,8 @@ KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent) keyBox->setLayout(vboxKD); mvbox->addWidget(keyBox); - fingerPrintVarLabel = - new QLabel(beautifyFingerprint(QString::fromStdString(mKey.fpr()))); + fingerPrintVarLabel = new QLabel(beautify_fingerprint(mKey.fpr()).c_str()); + fingerPrintVarLabel->setWordWrap(false); fingerPrintVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); fingerPrintVarLabel->setStyleSheet("margin-left: 0; margin-right: 5;"); auto* hboxFP = new QHBoxLayout(); @@ -137,49 +136,68 @@ KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent) mvbox->addWidget(fingerprintBox); mvbox->addStretch(); - if (mKey.is_private_key()) { - auto* privKeyBox = new QGroupBox(_("Operations")); - auto* vboxPK = new QVBoxLayout(); + auto* opera_key_box = new QGroupBox(_("Operations")); + auto* vbox_p_k = new QVBoxLayout(); + + auto export_h_box_layout = new QHBoxLayout(); + vbox_p_k->addLayout(export_h_box_layout); - auto* exportButton = + auto* export_public_button = new QPushButton(_("Export Public Key")); + export_h_box_layout->addWidget(export_public_button); + connect(export_public_button, SIGNAL(clicked()), this, + SLOT(slotExportPublicKey())); + + if (mKey.is_private_key()) { + auto* export_private_button = new QPushButton(_("Export Private Key (Include Subkey)")); - vboxPK->addWidget(exportButton); - connect(exportButton, SIGNAL(clicked()), this, + connect(export_private_button, SIGNAL(clicked()), this, SLOT(slotExportPrivateKey())); + export_h_box_layout->addWidget(export_private_button); if (mKey.has_master_key()) { - auto* editExpiresButton = + auto* edit_expires_button = new QPushButton(_("Modify Expiration Datetime (Master Key)")); - vboxPK->addWidget(editExpiresButton); - connect(editExpiresButton, SIGNAL(clicked()), this, + connect(edit_expires_button, SIGNAL(clicked()), this, SLOT(slotModifyEditDatetime())); - - auto hBoxLayout = new QHBoxLayout(); - auto* keyServerOperaButton = - new QPushButton(_("Key Server Operation (Pubkey)")); - keyServerOperaButton->setStyleSheet("text-align:center;"); - - auto* revokeCertGenButton = - new QPushButton(_("Generate Revoke Certificate")); - connect(revokeCertGenButton, SIGNAL(clicked()), this, - SLOT(slotGenRevokeCert())); - - hBoxLayout->addWidget(keyServerOperaButton); - hBoxLayout->addWidget(revokeCertGenButton); - - vboxPK->addLayout(hBoxLayout); - connect(keyServerOperaButton, SIGNAL(clicked()), this, - SLOT(slotModifyEditDatetime())); - - // Set Menu - createKeyServerOperaMenu(); - keyServerOperaButton->setMenu(keyServerOperaMenu); + auto* edit_password_button = new QPushButton(_("Modify Password")); + connect(edit_password_button, SIGNAL(clicked()), this, + SLOT(slotModifyPassword())); + + auto edit_h_box_layout = new QHBoxLayout(); + edit_h_box_layout->addWidget(edit_expires_button); + edit_h_box_layout->addWidget(edit_password_button); + vbox_p_k->addLayout(edit_h_box_layout); } + } - privKeyBox->setLayout(vboxPK); - mvbox->addWidget(privKeyBox); + auto advance_h_box_layout = new QHBoxLayout(); + auto* key_server_opera_button = + new QPushButton(_("Key Server Operation (Pubkey)")); + key_server_opera_button->setStyleSheet("text-align:center;"); + connect(key_server_opera_button, SIGNAL(clicked()), this, + SLOT(slotModifyEditDatetime())); + // Set Menu + createKeyServerOperaMenu(); + key_server_opera_button->setMenu(keyServerOperaMenu); + advance_h_box_layout->addWidget(key_server_opera_button); + + if (mKey.is_private_key() && mKey.has_master_key()) { + auto* revoke_cert_gen_button = + new QPushButton(_("Generate Revoke Certificate")); + connect(revoke_cert_gen_button, SIGNAL(clicked()), this, + SLOT(slotGenRevokeCert())); + advance_h_box_layout->addWidget(revoke_cert_gen_button); } + auto* modify_tofu_button = new QPushButton(_("Modify TOFU Policy")); + connect(modify_tofu_button, SIGNAL(clicked()), this, + SLOT(slotModifyTOFUPolicy())); + + vbox_p_k->addLayout(advance_h_box_layout); + opera_key_box->setLayout(vbox_p_k); + mvbox->addWidget(opera_key_box); + vbox_p_k->addWidget(modify_tofu_button); + if ((mKey.expired()) || (mKey.revoked())) { auto* expBox = new QHBoxLayout(); QPixmap pixmap(":warning.png"); @@ -214,6 +232,30 @@ KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent) setLayout(mvbox); } +void KeyPairDetailTab::slotExportPublicKey() { + ByteArrayPtr keyArray = nullptr; + + if (!GpgKeyImportExportor::GetInstance().ExportKey(mKey, keyArray)) { + QMessageBox::critical(this, _("Error"), + _("An error occurred during the export operation.")); + return; + } + auto fileString = + mKey.name() + " " + mKey.email() + "(" + mKey.id() + ")_pub.asc"; + auto fileName = + QFileDialog::getSaveFileName( + this, _("Export Key To File"), QString::fromStdString(fileString), + QString(_("Key Files")) + " (*.asc *.txt);;All Files (*)") + .toStdString(); + + if (!write_buffer_to_file(fileName, *keyArray)) { + QMessageBox::critical( + this, _("Export Error"), + QString(_("Couldn't open %1 for writing")).arg(fileName.c_str())); + return; + } +} + void KeyPairDetailTab::slotExportPrivateKey() { // Show a information box with explanation about private key int ret = QMessageBox::information( @@ -234,14 +276,8 @@ void KeyPairDetailTab::slotExportPrivateKey() { _("An error occurred during the export operation.")); return; } - - auto key = GpgKeyGetter::GetInstance().GetKey(keyid); - if (!key.good()) { - QMessageBox::critical(nullptr, _("Error"), _("Key Not Found.")); - return; - } auto fileString = - key.name() + " " + key.email() + "(" + key.id() + ")_secret.asc"; + mKey.name() + " " + mKey.email() + "(" + mKey.id() + ")_secret.asc"; auto fileName = QFileDialog::getSaveFileName( this, _("Export Key To File"), QString::fromStdString(fileString), @@ -250,21 +286,13 @@ void KeyPairDetailTab::slotExportPrivateKey() { if (!write_buffer_to_file(fileName, *keyArray)) { QMessageBox::critical( - nullptr, _("Export Error"), + this, _("Export Error"), QString(_("Couldn't open %1 for writing")).arg(fileName.c_str())); return; } } } -QString KeyPairDetailTab::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 KeyPairDetailTab::slotCopyFingerprint() { QString fpr = fingerPrintVarLabel->text().trimmed().replace(" ", QString()); QClipboard* cb = QApplication::clipboard(); @@ -322,9 +350,7 @@ void KeyPairDetailTab::slotRefreshKeyInfo() { createdVarLabel->setText(keyCreateTimeVal); algorithmVarLabel->setText(keyAlgoVal); - auto key_fpr = mKey.fpr(); - fingerPrintVarLabel->setText( - QString::fromStdString(beautify_fingerprint(key_fpr))); + fingerPrintVarLabel->setText(beautify_fingerprint(mKey.fpr()).c_str()); } void KeyPairDetailTab::createKeyServerOperaMenu() { @@ -333,9 +359,11 @@ void KeyPairDetailTab::createKeyServerOperaMenu() { auto* uploadKeyPair = new QAction(_("Upload Key Pair to Key Server"), this); connect(uploadKeyPair, SIGNAL(triggered()), this, SLOT(slotUploadKeyToServer())); + if (!mKey.is_private_key()) uploadKeyPair->setDisabled(true); + auto* updateKeyPair = new QAction(_("Update Key Pair"), this); connect(updateKeyPair, SIGNAL(triggered()), this, - SLOT(slotUpdateKeyToServer())); + SLOT(slotUpdateKeyFromServer())); keyServerOperaMenu->addAction(uploadKeyPair); keyServerOperaMenu->addAction(updateKeyPair); @@ -349,7 +377,7 @@ void KeyPairDetailTab::slotUploadKeyToServer() { dialog->slotUpload(); } -void KeyPairDetailTab::slotUpdateKeyToServer() { +void KeyPairDetailTab::slotUpdateKeyFromServer() { auto keys = std::make_unique<KeyIdArgsList>(); keys->push_back(mKey.id()); auto* dialog = new KeyServerImportDialog(this); @@ -403,4 +431,43 @@ void KeyPairDetailTab::slotRefreshKey() { this->slotRefreshKeyInfo(); } +void KeyPairDetailTab::slotModifyPassword() { + auto err = GpgKeyOpera::GetInstance().ModifyPassword(mKey); + if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) { + QMessageBox::critical(this, _("Not Successful"), + QString(_("Modify password not successfully."))); + } +} + +void KeyPairDetailTab::slotModifyTOFUPolicy() { + QStringList items; + items << _("Policy Auto") << _("Policy Good") << _("Policy Bad") + << _("Policy Ask") << _("Policy Unknown"); + + bool ok; + QString item = QInputDialog::getItem( + this, _("Modify TOFU Policy(Default is Auto)"), + _("Policy for the Key Pair:"), items, 0, false, &ok); + if (ok && !item.isEmpty()) { + LOG(INFO) << "selected policy" << item.toStdString(); + gpgme_tofu_policy_t tofu_policy = GPGME_TOFU_POLICY_AUTO; + if (item == _("Policy Auto")) { + tofu_policy = GPGME_TOFU_POLICY_AUTO; + } else if (item == _("Policy Good")) { + tofu_policy = GPGME_TOFU_POLICY_GOOD; + } else if (item == _("Policy Bad")) { + tofu_policy = GPGME_TOFU_POLICY_BAD; + } else if (item == _("Policy Ask")) { + tofu_policy = GPGME_TOFU_POLICY_ASK; + } else if (item == _("Policy Unknown")) { + tofu_policy = GPGME_TOFU_POLICY_UNKNOWN; + } + auto err = GpgKeyOpera::GetInstance().ModifyTOFUPolicy(mKey, tofu_policy); + if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) { + QMessageBox::critical(this, _("Not Successful"), + QString(_("Modify TOFU policy not successfully."))); + } + } +} + } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyPairDetailTab.h b/src/ui/keypair_details/KeyPairDetailTab.h index 782696ac..534014e5 100644 --- a/src/ui/keypair_details/KeyPairDetailTab.h +++ b/src/ui/keypair_details/KeyPairDetailTab.h @@ -36,22 +36,17 @@ namespace GpgFrontend::UI { class KeyPairDetailTab : public QWidget { Q_OBJECT - /** - * @details Return QString with a space inserted at every fourth character - * - * @param fingerprint The fingerprint to be beautified - */ - static QString beautifyFingerprint(QString fingerprint); - void createKeyServerOperaMenu(); private slots: /** - * @details Export the key to a file, which is choosen in a file dialog + * @details Export the key to a file, which is chosen in a file dialog */ void slotExportPrivateKey(); + void slotExportPublicKey(); + /** * @details Copy the fingerprint to clipboard */ @@ -59,19 +54,21 @@ class KeyPairDetailTab : public QWidget { void slotModifyEditDatetime(); + void slotModifyPassword(); + void slotRefreshKeyInfo(); void slotUploadKeyToServer(); - void slotUpdateKeyToServer(); + void slotUpdateKeyFromServer(); void slotGenRevokeCert(); void slotRefreshKey(); - private: - std::string keyid; /** The id of the key the details should be shown for */ + void slotModifyTOFUPolicy(); + private: GpgKey mKey; QGroupBox* ownerBox; /** Groupbox containing owner information */ diff --git a/src/ui/keypair_details/KeyPairUIDTab.cpp b/src/ui/keypair_details/KeyPairUIDTab.cpp index 3d56699a..11055df3 100644 --- a/src/ui/keypair_details/KeyPairUIDTab.cpp +++ b/src/ui/keypair_details/KeyPairUIDTab.cpp @@ -28,6 +28,7 @@ #include "gpg/function/GpgKeyManager.h" #include "gpg/function/UidOperator.h" #include "ui/SignalStation.h" +#include "ui/widgets/TOFUInfoPage.h" namespace GpgFrontend::UI { @@ -53,31 +54,47 @@ KeyPairUIDTab::KeyPairUIDTab(const std::string& key_id, QWidget* parent) uidButtonsLayout->addWidget(addUIDButton, 0, 1); uidButtonsLayout->addWidget(manageUIDButton, 0, 2); - auto gridLayout = new QGridLayout(); + auto grid_layout = new QGridLayout(); - gridLayout->addWidget(uidList, 0, 0); - gridLayout->addLayout(uidButtonsLayout, 1, 0); - gridLayout->setContentsMargins(0, 10, 0, 0); + grid_layout->addWidget(uidList, 0, 0); + grid_layout->addLayout(uidButtonsLayout, 1, 0); + grid_layout->setContentsMargins(0, 10, 0, 0); - auto uidGroupBox = new QGroupBox(); - uidGroupBox->setLayout(gridLayout); - uidGroupBox->setTitle(_("UIDs")); + auto uid_group_box = new QGroupBox(); + uid_group_box->setLayout(grid_layout); + uid_group_box->setTitle(_("UIDs")); - auto signGridLayout = new QGridLayout(); - signGridLayout->addWidget(sigList, 0, 0); - signGridLayout->setContentsMargins(0, 10, 0, 0); + auto tofu_group_box = new QGroupBox(); + auto tofu_vbox_layout = new QVBoxLayout(); + tofu_group_box->setLayout(tofu_vbox_layout); + tofu_group_box->setTitle(_("TOFU")); +#if !defined(RELEASE) + tofuTabs = new QTabWidget(this); + tofu_vbox_layout->addWidget(tofuTabs); +#endif - auto signGroupBox = new QGroupBox(); - signGroupBox->setLayout(signGridLayout); - signGroupBox->setTitle(_("Signature of Selected UID")); + auto sign_grid_layout = new QGridLayout(); + sign_grid_layout->addWidget(sigList, 0, 0); + sign_grid_layout->setContentsMargins(0, 10, 0, 0); + + auto sign_group_box = new QGroupBox(); + sign_group_box->setLayout(sign_grid_layout); + sign_group_box->setTitle(_("Signature of Selected UID")); auto vboxLayout = new QVBoxLayout(); - vboxLayout->addWidget(uidGroupBox); - vboxLayout->addWidget(signGroupBox); + vboxLayout->addWidget(uid_group_box); +#if !defined(RELEASE) + // Function needed testing + vboxLayout->addWidget(tofu_group_box); +#endif + vboxLayout->addWidget(sign_group_box); + vboxLayout->setContentsMargins(0, 0, 0, 0); connect(addUIDButton, SIGNAL(clicked(bool)), this, SLOT(slotAddUID())); connect(uidList, SIGNAL(itemSelectionChanged()), this, + SLOT(slotRefreshTOFUInfo())); + connect(uidList, SIGNAL(itemSelectionChanged()), this, SLOT(slotRefreshSigList())); // Key Database Refresh @@ -189,6 +206,32 @@ void KeyPairUIDTab::slotRefreshUIDList() { } slotRefreshSigList(); + slotRefreshTOFUInfo(); +} + +void KeyPairUIDTab::slotRefreshTOFUInfo() { + if (this->tofuTabs == nullptr) return; + + int uidRow = 0; + tofuTabs->clear(); + for (const auto& uid : buffered_uids) { + // Only Show Selected UID Signatures + if (!uidList->item(uidRow++, 0)->isSelected()) { + continue; + } + auto tofu_infos = uid.tofu_infos(); + LOG(INFO) << "tofu info size" << tofu_infos->size(); + if (tofu_infos->empty()) { + tofuTabs->hide(); + } else { + tofuTabs->show(); + } + int index = 1; + for (const auto& tofu_info : *tofu_infos) { + tofuTabs->addTab(new TOFUInfoPage(tofu_info, this), + QString(_("TOFU %1")).arg(index++)); + } + } } void KeyPairUIDTab::slotRefreshSigList() { @@ -329,7 +372,7 @@ void KeyPairUIDTab::slotDelUID() { "</b><br/><br/>" + keynames + +"<br/>" + _("The action can not be undone."), QMessageBox::No | QMessageBox::Yes); - + if (ret == QMessageBox::Yes) { for (const auto& uid : *selected_uids) { LOG(INFO) << "KeyPairUIDTab::slotDelUID UID" << uid; @@ -423,9 +466,9 @@ void KeyPairUIDTab::contextMenuEvent(QContextMenuEvent* event) { uidPopupMenu->exec(event->globalPos()); } - if (!sigList->selectedItems().isEmpty()) { - signPopupMenu->exec(event->globalPos()); - } + // if (!sigList->selectedItems().isEmpty()) { + // signPopupMenu->exec(event->globalPos()); + // } } void KeyPairUIDTab::slotAddSignSingle() { @@ -528,6 +571,7 @@ void KeyPairUIDTab::slotDelSign() { void KeyPairUIDTab::slotRefreshKey() { this->mKey = GpgKeyGetter::GetInstance().GetKey(this->mKey.id()); this->slotRefreshUIDList(); + this->slotRefreshTOFUInfo(); this->slotRefreshSigList(); } diff --git a/src/ui/keypair_details/KeyPairUIDTab.h b/src/ui/keypair_details/KeyPairUIDTab.h index 6dece8d5..823935d4 100644 --- a/src/ui/keypair_details/KeyPairUIDTab.h +++ b/src/ui/keypair_details/KeyPairUIDTab.h @@ -45,6 +45,7 @@ class KeyPairUIDTab : public QWidget { GpgKey mKey; QTableWidget* uidList{}; QTableWidget* sigList{}; + QTabWidget* tofuTabs{}; QMenu* manageSelectedUIDMenu{}; QMenu* uidPopupMenu{}; QMenu* signPopupMenu{}; @@ -71,6 +72,8 @@ class KeyPairUIDTab : public QWidget { void slotRefreshUIDList(); + void slotRefreshTOFUInfo(); + void slotRefreshSigList(); void slotAddSign(); diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index e05c6e13..f328c45a 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -39,6 +39,7 @@ #include "gpg/function/GpgKeyGetter.h" #include "gpg/function/GpgKeyImportExportor.h" #include "ui/UserInterfaceUtils.h" +#include "ui/help/AboutDialog.h" #include "ui/widgets/SignersPicker.h" namespace GpgFrontend::UI { @@ -244,17 +245,21 @@ void MainWindow::slotVerify() { }); if (!if_error) { - auto resultAnalyse = VerifyResultAnalyse(error, std::move(result)); - resultAnalyse.analyse(); - process_result_analyse(edit, infoBoard, resultAnalyse); - - // if (resultAnalyse->getStatus() >= 0) { - // infoBoard->resetOptionActionsMenu(); - // infoBoard->addOptionalAction( - // "Show Verify Details", [this, error, result]() { - // VerifyDetailsDialog(this, mCtx, mKeyList, error, result); - // }); - // } + auto result_analyse = VerifyResultAnalyse(error, std::move(result)); + result_analyse.analyse(); + process_result_analyse(edit, infoBoard, result_analyse); + + if (result_analyse.getStatus() >= 0) { + // take out result + auto _result = result_analyse.TakeChargeOfResult(); + auto _result_ptr = _result.get(); + _result.reset(nullptr); + infoBoard->resetOptionActionsMenu(); + infoBoard->addOptionalAction( + "Show Verify Details", [this, error, _result_ptr]() { + VerifyDetailsDialog(this, error, GpgVerifyResult(_result_ptr)); + }); + } } } @@ -423,8 +428,8 @@ void MainWindow::slotDecryptVerify() { decrypt_res.analyse(); verify_res.analyse(); process_result_analyse(edit, infoBoard, decrypt_res, verify_res); - - edit->slotFillTextEditWithText(QString::fromStdString(*decrypted)); + if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) + edit->slotFillTextEditWithText(QString::fromStdString(*decrypted)); // if (verify_res.getStatus() >= 0) { // infoBoard->resetOptionActionsMenu(); @@ -507,6 +512,12 @@ void MainWindow::slotVersionUpgrade(const QString& currentVersion, QString(_("GpgFrontend Upgradeable (New Version: %1).")) .arg(latestVersion), 30000); + auto update_button = new QPushButton("Update GpgFrontend", this); + connect(update_button, &QPushButton::clicked, [=]() { + auto* about_dialog = new AboutDialog(2, this); + about_dialog->show(); + }); + statusBar()->addPermanentWidget(update_button, 0); } else if (currentVersion > latestVersion) { QMessageBox::warning( this, _("Unreleased Version"), diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index 35eb74ac..9a7c7b83 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -111,7 +111,6 @@ void MainWindow::slotOpenSettingsDialog() { this->setIconSize(QSize(icon_width, icon_height)); importButton->setIconSize(QSize(icon_width, icon_height)); - fileEncButton->setIconSize(QSize(icon_width, icon_height)); // Iconstyle @@ -119,7 +118,6 @@ void MainWindow::slotOpenSettingsDialog() { auto button_style = static_cast<Qt::ToolButtonStyle>(icon_style); this->setToolButtonStyle(button_style); importButton->setToolButtonStyle(button_style); - fileEncButton->setToolButtonStyle(button_style); // restart mainwindow if necessary if (getRestartNeeded()) { diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp index b56472e4..7ceaffa2 100644 --- a/src/ui/main_window/MainWindowUI.cpp +++ b/src/ui/main_window/MainWindowUI.cpp @@ -453,15 +453,15 @@ void MainWindow::createToolBars() { void MainWindow::createStatusBar() { auto* statusBarBox = new QWidget(); auto* statusBarBoxLayout = new QHBoxLayout(); - QPixmap* pixmap; + // QPixmap* pixmap; // icon which should be shown if there are files in attachments-folder - pixmap = new QPixmap(":statusbar_icon.png"); - statusBarIcon = new QLabel(); - statusBar()->addWidget(statusBarIcon); - - statusBarIcon->setPixmap(*pixmap); - statusBar()->insertPermanentWidget(0, statusBarIcon, 0); + // pixmap = new QPixmap(":statusbar_icon.png"); + // statusBarIcon = new QLabel(); + // statusBar()->addWidget(statusBarIcon); + // + // statusBarIcon->setPixmap(*pixmap); + // statusBar()->insertPermanentWidget(0, statusBarIcon, 0); statusBar()->showMessage(_("Ready"), 2000); statusBarBox->setLayout(statusBarBoxLayout); } diff --git a/src/ui/settings/SettingsDialog.cpp b/src/ui/settings/SettingsDialog.cpp index fcef70c7..1fbfb8db 100644 --- a/src/ui/settings/SettingsDialog.cpp +++ b/src/ui/settings/SettingsDialog.cpp @@ -105,6 +105,8 @@ void SettingsDialog::slotSetRestartNeeded(bool needed) { } void SettingsDialog::slotAccept() { + LOG(INFO) << "called"; + generalTab->applySettings(); #ifdef SMTP_SUPPORT sendMailTab->applySettings(); @@ -115,9 +117,12 @@ void SettingsDialog::slotAccept() { advancedTab->applySettings(); #endif + LOG(INFO) << "apply done"; + // write settings to filesystem GlobalSettingStation::GetInstance().Sync(); + LOG(INFO) << "restart needed" << getRestartNeeded(); if (getRestartNeeded()) { emit signalRestartNeeded(true); } @@ -131,7 +136,7 @@ QHash<QString, QString> SettingsDialog::listLanguages() { auto locale_path = GlobalSettingStation::GetInstance().GetLocaleDir(); - auto locale_dir = QDir(QString::fromStdString(locale_path.string()) ); + auto locale_dir = QDir(QString::fromStdString(locale_path.string())); QStringList file_names = locale_dir.entryList(QStringList("*")); for (int i = 0; i < file_names.size(); ++i) { diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp index 0f3a1f74..2409edd7 100644 --- a/src/ui/widgets/InfoBoardWidget.cpp +++ b/src/ui/widgets/InfoBoardWidget.cpp @@ -49,19 +49,22 @@ InfoBoardWidget::InfoBoardWidget(QWidget* parent, KeyList* keyList) auto* actionButtonMenu = new QWidget(); actionButtonMenu->setContentsMargins(0, 0, 0, 0); actionButtonMenu->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); - actionButtonMenu->setFixedHeight(36); + actionButtonMenu->setFixedHeight(40); actionButtonLayout = new QHBoxLayout(); - actionButtonLayout->setContentsMargins(5, 5, 5, 5); + actionButtonLayout->setContentsMargins(0, 0, 0, 0); actionButtonLayout->setSpacing(0); - actionButtonMenu->setLayout(actionButtonLayout); - auto label = new QLabel(_("Optional Actions")); + auto* label = new QLabel(_("Board Actions")); label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); label->setContentsMargins(0, 0, 0, 0); + mButtonGroup = new QButtonGroup(this); - actionButtonLayout->addWidget(label); + auto* bottom_layout = new QHBoxLayout(this); + bottom_layout->addWidget(label); actionButtonLayout->addStretch(); + bottom_layout->addLayout(actionButtonLayout); + actionButtonMenu->setLayout(bottom_layout); QFrame* line; line = new QFrame(this); diff --git a/src/ui/widgets/InfoBoardWidget.h b/src/ui/widgets/InfoBoardWidget.h index 3c43f733..b7239adb 100644 --- a/src/ui/widgets/InfoBoardWidget.h +++ b/src/ui/widgets/InfoBoardWidget.h @@ -27,7 +27,7 @@ #include "EditorPage.h" #include "gpg/result_analyse/VerifyResultAnalyse.h" -#include "ui/VerifyDetailsDialog.h" +#include "ui/details/VerifyDetailsDialog.h" namespace GpgFrontend::UI { @@ -102,6 +102,7 @@ class InfoBoardWidget : public QWidget { nullptr}; /** TreeView associated to the notification */ QHBoxLayout* actionButtonLayout; + QButtonGroup* mButtonGroup; void deleteWidgetsInLayout(QLayout* layout, int start_index = 0); }; diff --git a/src/ui/widgets/TOFUInfoPage.cpp b/src/ui/widgets/TOFUInfoPage.cpp new file mode 100644 index 00000000..a1f76d7a --- /dev/null +++ b/src/ui/widgets/TOFUInfoPage.cpp @@ -0,0 +1,43 @@ +/** + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#include "TOFUInfoPage.h" + +GpgFrontend::UI::TOFUInfoPage::TOFUInfoPage( + const GpgFrontend::GpgTOFUInfo &tofu_info, QWidget *parent) + : QWidget(parent) { + auto grid_layout = new QGridLayout(); + + grid_layout->addWidget(new QLabel(QString(_("Key ID")) + ": "), 0, 0); + grid_layout->addWidget(new QLabel(QString(_("Algorithm")) + ": "), 1, 0); + grid_layout->addWidget(new QLabel(QString(_("Key Size")) + ": "), 2, 0); + grid_layout->addWidget(new QLabel(QString(_("Nominal Usage")) + ": "), 3, 0); + grid_layout->addWidget(new QLabel(QString(_("Actual Usage")) + ": "), 4, 0); + grid_layout->addWidget(new QLabel(QString(_("Expires on")) + ": "), 5, 0); + grid_layout->addWidget(new QLabel(QString(_("Last Update")) + ": "), 6, 0); + grid_layout->addWidget(new QLabel(QString(_("Secret Key Existence")) + ": "), + 7, 0); + + setLayout(grid_layout); +} diff --git a/src/ui/widgets/TOFUInfoPage.h b/src/ui/widgets/TOFUInfoPage.h new file mode 100644 index 00000000..29f004d1 --- /dev/null +++ b/src/ui/widgets/TOFUInfoPage.h @@ -0,0 +1,42 @@ +/** + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_TOFUINFOPAGE_H +#define GPGFRONTEND_TOFUINFOPAGE_H + +#include "gpg/GpgModel.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { +class TOFUInfoPage : public QWidget { + Q_OBJECT + public: + explicit TOFUInfoPage(const GpgTOFUInfo &tofu_info, + QWidget *parent = nullptr); + + private: +}; +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_TOFUINFOPAGE_H diff --git a/src/ui/widgets/VerifyKeyDetailBox.cpp b/src/ui/widgets/VerifyKeyDetailBox.cpp index cd5b6641..3975ac93 100644 --- a/src/ui/widgets/VerifyKeyDetailBox.cpp +++ b/src/ui/widgets/VerifyKeyDetailBox.cpp @@ -28,19 +28,19 @@ namespace GpgFrontend::UI { -VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget* parent, KeyList* keyList, - gpgme_signature_t signature) - : QGroupBox(parent), mKeyList(keyList), fpr(signature->fpr) { +VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature, + QWidget* parent) + : QGroupBox(parent), fpr(signature.fpr()) { auto* vbox = new QVBoxLayout(); - switch (gpg_err_code(signature->status)) { + switch (gpg_err_code(signature.status())) { case GPG_ERR_NO_PUBKEY: { this->setTitle("A Error Signature"); auto* importButton = new QPushButton(_("Import from keyserver")); connect(importButton, SIGNAL(clicked()), this, SLOT(slotImportFormKeyserver())); - this->setTitle(QString(_("Key not present with id 0x")) + signature->fpr); + this->setTitle(QString(_("Key not present with id 0x")) + fpr.c_str()); auto grid = new QGridLayout(); @@ -60,9 +60,9 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget* parent, KeyList* keyList, vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (signature->fpr != nullptr) { + if (!signature.fpr().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - QString(signature->fpr))); + signature.fpr().c_str())); } } break; @@ -76,9 +76,9 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget* parent, KeyList* keyList, vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (signature->fpr != nullptr) { + if (!signature.fpr().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - QString(signature->fpr))); + signature.fpr().c_str())); } } break; @@ -92,9 +92,9 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget* parent, KeyList* keyList, vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (signature->fpr != nullptr) { + if (!signature.fpr().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - QString(signature->fpr))); + signature.fpr().c_str())); } } break; @@ -110,9 +110,9 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget* parent, KeyList* keyList, vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (signature->fpr != nullptr) { + if (!signature.fpr().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - QString(signature->fpr))); + signature.fpr().c_str())); } } break; @@ -126,9 +126,9 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget* parent, KeyList* keyList, vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (signature->fpr != nullptr) { + if (!signature.fpr().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - QString(signature->fpr))); + signature.fpr().c_str())); } } break; @@ -141,9 +141,9 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget* parent, KeyList* keyList, vbox->addLayout(gird); } else { vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); - if (signature->fpr != nullptr) { + if (!signature.fpr().empty()) { vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + - QString(signature->fpr))); + signature.fpr().c_str())); } } break; @@ -155,22 +155,14 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget* parent, KeyList* keyList, void VerifyKeyDetailBox::slotImportFormKeyserver() { auto* importDialog = new KeyServerImportDialog(false, this); auto key_ids = std::make_unique<KeyIdArgsList>(); - key_ids->push_back(fpr.toStdString()); + key_ids->push_back(fpr); importDialog->slotImport(key_ids); } -QString VerifyKeyDetailBox::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; -} - QGridLayout* VerifyKeyDetailBox::createKeyInfoGrid( - gpgme_signature_t& signature) { + const GpgSignature& signature) { auto grid = new QGridLayout(); - GpgKey key = GpgKeyGetter::GetInstance().GetKey(signature->fpr); + GpgKey key = GpgKeyGetter::GetInstance().GetKey(fpr); if (!key.good()) return nullptr; grid->addWidget(new QLabel(QString(_("Signer Name")) + ":"), 0, 0); @@ -181,9 +173,9 @@ QGridLayout* VerifyKeyDetailBox::createKeyInfoGrid( grid->addWidget(new QLabel(QString::fromStdString(key.name())), 0, 1); grid->addWidget(new QLabel(QString::fromStdString(key.email())), 1, 1); - grid->addWidget(new QLabel(beautifyFingerprint(signature->fpr)), 2, 1); + grid->addWidget(new QLabel(beautify_fingerprint(fpr).c_str()), 2, 1); - if (signature->summary & GPGME_SIGSUM_VALID) { + if (signature.summary() & GPGME_SIGSUM_VALID) { grid->addWidget(new QLabel(_("Fully Valid")), 3, 1); } else { grid->addWidget(new QLabel(_("NOT Fully Valid")), 3, 1); @@ -192,29 +184,29 @@ QGridLayout* VerifyKeyDetailBox::createKeyInfoGrid( QString flags; QTextStream textStream(&flags); - if (signature->summary & GPGME_SIGSUM_GREEN) { + if (signature.summary() & GPGME_SIGSUM_GREEN) { textStream << _("Good") << " "; } - if (signature->summary & GPGME_SIGSUM_RED) { + if (signature.summary() & GPGME_SIGSUM_RED) { textStream << _("Bad") << " "; } - if (signature->summary & GPGME_SIGSUM_SIG_EXPIRED) { + if (signature.summary() & GPGME_SIGSUM_SIG_EXPIRED) { textStream << _("Expired") << " "; } - if (signature->summary & GPGME_SIGSUM_KEY_MISSING) { + if (signature.summary() & GPGME_SIGSUM_KEY_MISSING) { textStream << _("Missing Key") << " "; } - if (signature->summary & GPGME_SIGSUM_KEY_REVOKED) { + if (signature.summary() & GPGME_SIGSUM_KEY_REVOKED) { textStream << _("Revoked Key") << " "; } - if (signature->summary & GPGME_SIGSUM_KEY_EXPIRED) { + if (signature.summary() & GPGME_SIGSUM_KEY_EXPIRED) { textStream << _("Expired Key") << " "; } - if (signature->summary & GPGME_SIGSUM_CRL_MISSING) { + if (signature.summary() & GPGME_SIGSUM_CRL_MISSING) { textStream << _("Missing CRL") << " "; } - grid->addWidget(new QLabel(_(flags.toUtf8().constData())), 4, 1); + grid->addWidget(new QLabel(flags.toStdString().c_str()), 4, 1); return grid; } diff --git a/src/ui/widgets/VerifyKeyDetailBox.h b/src/ui/widgets/VerifyKeyDetailBox.h index c1b26bb2..b01d628d 100644 --- a/src/ui/widgets/VerifyKeyDetailBox.h +++ b/src/ui/widgets/VerifyKeyDetailBox.h @@ -33,21 +33,16 @@ namespace GpgFrontend::UI { class VerifyKeyDetailBox : public QGroupBox { Q_OBJECT public: - explicit VerifyKeyDetailBox(QWidget* parent, KeyList* mKeyList, - gpgme_signature_t signature); + explicit VerifyKeyDetailBox(const GpgSignature& signature, QWidget* parent); private slots: void slotImportFormKeyserver(); private: - KeyList* mKeyList; + QGridLayout* createKeyInfoGrid(const GpgSignature& signature); - static QString beautifyFingerprint(QString fingerprint); - - static QGridLayout* createKeyInfoGrid(gpgme_signature_t& signature); - - QString fpr; + std::string fpr; }; } // namespace GpgFrontend::UI |