aboutsummaryrefslogtreecommitdiffstats
path: root/src/ui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/widgets')
-rw-r--r--src/ui/widgets/ExportKeyPackageDialog.cpp165
-rw-r--r--src/ui/widgets/ExportKeyPackageDialog.h55
-rw-r--r--src/ui/widgets/KeyList.cpp62
-rw-r--r--src/ui/widgets/KeyList.h22
4 files changed, 298 insertions, 6 deletions
diff --git a/src/ui/widgets/ExportKeyPackageDialog.cpp b/src/ui/widgets/ExportKeyPackageDialog.cpp
new file mode 100644
index 00000000..b5eea82d
--- /dev/null
+++ b/src/ui/widgets/ExportKeyPackageDialog.cpp
@@ -0,0 +1,165 @@
+/**
+ * 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 "ExportKeyPackageDialog.h"
+
+#include <boost/format.hpp>
+
+#include "gpg/function/GpgKeyGetter.h"
+#include "gpg/function/GpgKeyImportExporter.h"
+#include "ui/aes/qaesencryption.h"
+#include "ui_ExportKeyPackageDialog.h"
+
+GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog(
+ KeyIdArgsListPtr key_ids, QWidget* parent)
+ : QDialog(parent),
+ ui(std::make_shared<Ui_exportKeyPackageDialog>()),
+ key_ids_(std::move(key_ids)),
+ mt(rd()) {
+ ui->setupUi(this);
+
+ generate_key_package_name();
+
+ connect(ui->gnerateNameButton, &QPushButton::clicked, this,
+ [=]() { generate_key_package_name(); });
+
+ connect(ui->setOutputPathButton, &QPushButton::clicked, this, [=]() {
+ auto file_name = QFileDialog::getSaveFileName(
+ this, _("Export Key Package"), ui->nameValueLabel->text() + ".gfepack",
+ QString(_("Key Package")) + " (*.gfepack);;All Files (*)");
+ ui->outputPathLabel->setText(file_name);
+ });
+
+ connect(ui->generatePassphraseButton, &QPushButton::clicked, this, [=]() {
+ passphrase_ = generate_passphrase(32);
+ auto file_name = QFileDialog::getSaveFileName(
+ this, _("Export Key Package Passphrase"),
+ ui->nameValueLabel->text() + ".key",
+ QString(_("Key File")) + " (*.key);;All Files (*)");
+ ui->passphraseValueLabel->setText(file_name);
+ write_buffer_to_file(file_name.toStdString(), passphrase_);
+ });
+
+ connect(ui->buttonBox, &QDialogButtonBox::accepted, this, [=]() {
+ if (ui->outputPathLabel->text().isEmpty()) {
+ QMessageBox::critical(
+ nullptr, _("Forbidden"),
+ _("Please select an output path before exporting."));
+ return;
+ }
+
+ if (ui->passphraseValueLabel->text().isEmpty()) {
+ QMessageBox::critical(
+ nullptr, _("Forbidden"),
+ _("Please generate a password to protect your key before exporting, "
+ "it is very important. Don't forget to back up your password in a "
+ "safe place."));
+ return;
+ }
+ auto key_id_exported = std::make_unique<KeyIdArgsList>();
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids_);
+ for (const auto& key : *keys) {
+ if (ui->noPublicKeyCheckBox->isChecked() && !key.is_private_key()) {
+ continue;
+ }
+ key_id_exported->push_back(key.id());
+ }
+
+ ByteArrayPtr key_export_data = nullptr;
+ if (!GpgKeyImportExporter::GetInstance().ExportKeys(
+ key_ids_, key_export_data,
+ ui->includeSecretKeyCheckBox->isChecked())) {
+ QMessageBox::critical(nullptr, _("Error"), _("Export Key(s) Failed."));
+ this->close();
+ return;
+ }
+
+ auto key = passphrase_;
+
+ QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB);
+ auto encoded = encryption.encode(key_export_data->data(), key.data());
+
+ write_buffer_to_file(ui->outputPathLabel->text().toStdString(),
+ encoded.toStdString());
+
+ QMessageBox::information(
+ this, _("Success"),
+ QString(_(
+ "The Key Package has been successfully generated and has been "
+ "protected by encryption algorithms. You can safely transfer your "
+ "Key Package.")) +
+ "<b>" +
+ _("But the key file cannot be leaked under any "
+ "circumstances. Please delete the Key Package and key file as "
+ "soon "
+ "as possible after completing the transfer operation") +
+ "</b>");
+ });
+
+ connect(ui->buttonBox, &QDialogButtonBox::rejected, this,
+ [=]() { this->close(); });
+
+ ui->nameLabel->setText(_("Key Package Name"));
+ ui->selectOutputPathLabel->setText(_("Output Path"));
+ ui->passphraseLabel->setText(_("Passphrase"));
+ ui->tipsLabel->setText(
+ _("Tips: You can use Key Package to safely and conveniently transfer "
+ "your public and private keys between devices."));
+ ui->generatePassphraseButton->setText(_("Generate and Save Passphrase"));
+ ui->gnerateNameButton->setText(_("Generate Key Package Name"));
+ ui->setOutputPathButton->setText(_("Select Output Path"));
+
+ ui->includeSecretKeyCheckBox->setText(
+ _("Include secret key (Think twice before acting)"));
+ ui->noPublicKeyCheckBox->setText(
+ _("Exclude keys that do not have a private key"));
+
+ setAttribute(Qt::WA_DeleteOnClose);
+ setWindowTitle(_("exportKeyPackageDialog"));
+}
+
+std::string GpgFrontend::UI::ExportKeyPackageDialog::generate_passphrase(
+ const int len) {
+ std::uniform_int_distribution<int> dist(999, 99999);
+ static const char alphanum[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+ std::string tmp_str;
+ tmp_str.reserve(len);
+
+ for (int i = 0; i < len; ++i) {
+ tmp_str += alphanum[dist(mt) % (sizeof(alphanum) - 1)];
+ }
+
+ return tmp_str;
+}
+
+void GpgFrontend::UI::ExportKeyPackageDialog::generate_key_package_name() {
+ std::uniform_int_distribution<int> dist(999, 99999);
+ auto file_string = boost::format("KeyPackage_%1%") % dist(mt);
+ ui->nameValueLabel->setText(file_string.str().c_str());
+ ui->outputPathLabel->clear();
+ ui->passphraseValueLabel->clear();
+}
diff --git a/src/ui/widgets/ExportKeyPackageDialog.h b/src/ui/widgets/ExportKeyPackageDialog.h
new file mode 100644
index 00000000..a254b453
--- /dev/null
+++ b/src/ui/widgets/ExportKeyPackageDialog.h
@@ -0,0 +1,55 @@
+/**
+ * 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_EXPORTKEYPACKAGEDIALOG_H
+#define GPGFRONTEND_EXPORTKEYPACKAGEDIALOG_H
+
+#include "GpgFrontendUI.h"
+
+class Ui_exportKeyPackageDialog;
+
+namespace GpgFrontend::UI {
+
+class ExportKeyPackageDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit ExportKeyPackageDialog(KeyIdArgsListPtr key_ids, QWidget* parent);
+
+ std::string generate_passphrase(const int len);
+
+ private:
+ std::shared_ptr<Ui_exportKeyPackageDialog> ui;
+ KeyIdArgsListPtr key_ids_;
+
+ std::random_device rd;
+ std::mt19937 mt;
+
+ std::string passphrase_;
+
+ void generate_key_package_name();
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_EXPORTKEYPACKAGEDIALOG_H
diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp
index 6dec19e7..02a8dd92 100644
--- a/src/ui/widgets/KeyList.cpp
+++ b/src/ui/widgets/KeyList.cpp
@@ -38,11 +38,11 @@ namespace GpgFrontend::UI {
int KeyList::key_list_id = 2048;
-KeyList::KeyList(bool menu, QWidget* parent)
+KeyList::KeyList(KeyMenuAbility::AbilityType menu_ability, QWidget* parent)
: QWidget(parent),
_m_key_list_id(key_list_id++),
ui(std::make_shared<Ui_KeyList>()),
- menu_status(menu) {
+ menu_ability_(menu_ability) {
init();
}
@@ -62,7 +62,11 @@ void KeyList::init() {
ui->setupUi(this);
- ui->menuWidget->setHidden(!menu_status);
+ ui->menuWidget->setHidden(!menu_ability_);
+ ui->refreshKeyListButton->setHidden(~menu_ability_ & KeyMenuAbility::REFRESH);
+ ui->syncButton->setHidden(~menu_ability_ & KeyMenuAbility::SYNC_PUBLIC_KEY);
+ ui->uncheckButton->setHidden(~menu_ability_ & KeyMenuAbility::UNCHECK_ALL);
+
ui->keyGroupTab->clear();
popupMenu = new QMenu(this);
@@ -73,6 +77,10 @@ void KeyList::init() {
SLOT(slotRefresh()));
connect(ui->refreshKeyListButton, &QPushButton::clicked, this,
&KeyList::slotRefresh);
+ connect(ui->uncheckButton, &QPushButton::clicked, this,
+ &KeyList::slotUncheckALL);
+ connect(ui->checkALLButton, &QPushButton::clicked, this,
+ &KeyList::slotCheckALL);
connect(ui->syncButton, &QPushButton::clicked, this,
&KeyList::slotSyncWithKeyServer);
connect(this, &KeyList::signalRefreshStatusBar, SignalStation::GetInstance(),
@@ -81,8 +89,16 @@ void KeyList::init() {
setAcceptDrops(true);
ui->refreshKeyListButton->setText(_("Refresh"));
+ ui->refreshKeyListButton->setToolTip(
+ _("Refresh the key list to synchronize changes."));
ui->syncButton->setText(_("Sync Public Key"));
- ui->syncButton->setToolTip(_("Sync public key with your default keyserver"));
+ ui->syncButton->setToolTip(_("Sync public key with your default keyserver."));
+ ui->uncheckButton->setText(_("Uncheck ALL"));
+ ui->uncheckButton->setToolTip(
+ _("Cancel all checked items in the current tab at once."));
+ ui->checkALLButton->setText(_("Check ALL"));
+ ui->checkALLButton->setToolTip(
+ _("Check all items in the current tab at once"));
}
void KeyList::addListGroupTab(
@@ -457,6 +473,32 @@ void KeyList::slotSyncWithKeyServer() {
});
}
+void KeyList::slotUncheckALL() {
+ auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget());
+ if (key_list == nullptr) return;
+ if (!mKeyTables.empty()) {
+ for (auto& key_table : mKeyTables) {
+ if (key_table.key_list == key_list) {
+ key_table.UncheckALL();
+ break;
+ }
+ }
+ }
+}
+
+void KeyList::slotCheckALL() {
+ auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget());
+ if (key_list == nullptr) return;
+ if (!mKeyTables.empty()) {
+ for (auto& key_table : mKeyTables) {
+ if (key_table.key_list == key_list) {
+ key_table.CheckALL();
+ break;
+ }
+ }
+ }
+}
+
KeyIdArgsListPtr& KeyTable::GetChecked() {
LOG(INFO) << "called";
if (checked_key_ids_ == nullptr)
@@ -597,4 +639,16 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) {
LOG(INFO) << "End";
}
+
+void KeyTable::UncheckALL() const {
+ for (int i = 0; i < key_list->rowCount(); i++) {
+ key_list->item(i, 0)->setCheckState(Qt::Unchecked);
+ }
+}
+
+void KeyTable::CheckALL() const {
+ for (int i = 0; i < key_list->rowCount(); i++) {
+ key_list->item(i, 0)->setCheckState(Qt::Checked);
+ }
+}
} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h
index 8d6fb600..4b41decd 100644
--- a/src/ui/widgets/KeyList.h
+++ b/src/ui/widgets/KeyList.h
@@ -53,6 +53,17 @@ struct KeyListColumn {
static constexpr InfoType FingerPrint = 1 << 5;
};
+struct KeyMenuAbility {
+ using AbilityType = unsigned int;
+
+ static constexpr AbilityType ALL = ~0;
+ static constexpr AbilityType NONE = 0;
+ static constexpr AbilityType REFRESH = 1 << 0;
+ static constexpr AbilityType SYNC_PUBLIC_KEY = 1 << 1;
+ static constexpr AbilityType UNCHECK_ALL = 1 << 3;
+ static constexpr AbilityType CHECK_ALL = 1 << 5;
+};
+
struct KeyTable {
QTableWidget* key_list;
KeyListRow::KeyType select_type;
@@ -76,6 +87,10 @@ struct KeyTable {
KeyIdArgsListPtr& GetChecked();
+ void UncheckALL() const;
+
+ void CheckALL() const;
+
void SetChecked(KeyIdArgsListPtr key_ids);
};
@@ -83,7 +98,8 @@ class KeyList : public QWidget {
Q_OBJECT
public:
- explicit KeyList(bool menu, QWidget* parent = nullptr);
+ explicit KeyList(KeyMenuAbility::AbilityType menu_ability,
+ QWidget* parent = nullptr);
void addListGroupTab(
const QString& name,
@@ -124,6 +140,8 @@ class KeyList : public QWidget {
private:
void init();
void importKeys(const QByteArray& inBuffer);
+ void slotUncheckALL();
+ void slotCheckALL();
static int key_list_id;
int _m_key_list_id;
@@ -135,7 +153,7 @@ class KeyList : public QWidget {
QMenu* popupMenu{};
GpgFrontend::KeyLinkListPtr _buffered_keys_list;
std::function<void(const GpgKey&, QWidget*)> mAction = nullptr;
- bool menu_status = false;
+ KeyMenuAbility::AbilityType menu_ability_ = KeyMenuAbility::ALL;
private slots: