diff options
author | Saturneric <[email protected]> | 2023-02-07 07:16:45 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2023-02-07 07:16:45 +0000 |
commit | a49c6605244d656d4a4b72e95fbbcbe83372d363 (patch) | |
tree | ba28d451a0c78041f36e0e8be7ca30114ddce4ef | |
parent | feat: add a custom pinentry hook for sandbox mode in macOS (diff) | |
download | GpgFrontend-a49c6605244d656d4a4b72e95fbbcbe83372d363.tar.gz GpgFrontend-a49c6605244d656d4a4b72e95fbbcbe83372d363.zip |
feat: use custom password dialog now
-rw-r--r-- | src/core/GpgContext.cpp | 86 | ||||
-rw-r--r-- | src/core/GpgContext.h | 22 | ||||
-rw-r--r-- | src/core/common/CoreCommonUtil.cpp | 19 | ||||
-rw-r--r-- | src/core/common/CoreCommonUtil.h | 24 | ||||
-rw-r--r-- | src/core/function/CoreSignalStation.cpp | 39 | ||||
-rw-r--r-- | src/core/function/CoreSignalStation.h | 69 | ||||
-rw-r--r-- | src/core/thread/TaskRunner.cpp | 6 | ||||
-rw-r--r-- | src/core/thread/TaskRunner.h | 9 | ||||
-rw-r--r-- | src/main.cpp | 19 | ||||
-rw-r--r-- | src/ui/SignalStation.h | 12 | ||||
-rw-r--r-- | src/ui/UserInterfaceUtils.cpp | 29 | ||||
-rw-r--r-- | src/ui/UserInterfaceUtils.h | 24 | ||||
-rw-r--r-- | src/ui/dialog/key_generate/KeygenDialog.cpp | 30 | ||||
-rw-r--r-- | src/ui/dialog/key_generate/KeygenDialog.h | 1 |
14 files changed, 361 insertions, 28 deletions
diff --git a/src/core/GpgContext.cpp b/src/core/GpgContext.cpp index 82e9394d..e7b360e8 100644 --- a/src/core/GpgContext.cpp +++ b/src/core/GpgContext.cpp @@ -30,9 +30,17 @@ #include <gpg-error.h> #include <gpgme.h> +#include <unistd.h> -#include "GpgConstants.h" +#include <string> + +#include "core/GpgConstants.h" +#include "core/GpgModel.h" +#include "core/common/CoreCommonUtil.h" +#include "core/function/CoreSignalStation.h" #include "core/function/gpg/GpgCommandExecutor.h" +#include "core/thread/TaskRunnerGetter.h" +#include "thread/Task.h" #ifdef _WIN32 #include <windows.h> @@ -85,7 +93,7 @@ GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) { } SPDLOG_INFO( - "engine info: {} {} {} {}", + "gpg context engine info: {} {} {} {}", gpgme_get_protocol_name(engine_info->protocol), std::string(engine_info->file_name == nullptr ? "null" : engine_info->file_name), @@ -149,12 +157,19 @@ GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) { return; } else { SPDLOG_INFO("gnupg version {}", info_.GnupgVersion); - init_ctx(); + // async, init context + Thread::TaskRunnerGetter::GetInstance() + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG) + ->PostTask(new Thread::Task([=](Thread::Task::DataObjectPtr) -> int { + post_init_ctx(); + return 0; + })); + good_ = true; } } -void GpgContext::init_ctx() { +void GpgContext::post_init_ctx() { // Set Independent Database if (info_.GnupgVersion <= "2.0.0" && args_.independent_database) { info_.DatabasePath = args_.db_path; @@ -198,10 +213,14 @@ void GpgContext::init_ctx() { gpgme_set_status_cb(*this, test_status_cb, nullptr); } -#if defined(RELEASE) && defined(MACOS) - // running in sandbox + // preload info + auto info = GetInfo(); + + // listen passphrase input event SetPassphraseCb(custom_passphrase_cb); -#endif + connect(this, &GpgContext::SignalNeedUserInputPassphrase, + CoreSignalStation::GetInstance(), + &CoreSignalStation::SignalNeedUserInputPassphrase); } bool GpgContext::good() const { return good_; } @@ -238,8 +257,36 @@ gpgme_error_t GpgContext::custom_passphrase_cb(void *opaque, const char *uid_hint, const char *passphrase_info, int last_was_bad, int fd) { - // TODO - return 0; + if (last_was_bad > 3) { + SPDLOG_WARN("failure_counts is over three times"); + return gpgme_error_from_errno(GPG_ERR_CANCELED); + } + + std::string passphrase = + CoreCommonUtil::GetInstance()->GetTempCacheValue("__key_passphrase"); + // no pawword is an error situation + if (passphrase.empty()) { + // user input passphrase + SPDLOG_DEBUG("might need user to input passparase"); + passphrase = GpgContext::GetInstance().need_user_input_passphrase(); + if (passphrase.empty()) { + gpgme_io_write(fd, "\n", 1); + return gpgme_error_from_errno(GPG_ERR_CANCELED); + } + } + + // the user must at least write a newline character before returning from the + // callback. + passphrase = passphrase.append("\n"); + auto passpahrase_size = passphrase.size(); + + size_t off = 0, res = 0; + do { + res = gpgme_io_write(fd, &passphrase[off], passpahrase_size - off); + if (res > 0) off += res; + } while (res > 0 && off != passpahrase_size); + + return off == passpahrase_size ? 0 : gpgme_error_from_errno(GPG_ERR_CANCELED); } gpgme_error_t GpgContext::test_status_cb(void *hook, const char *keyword, @@ -248,6 +295,27 @@ gpgme_error_t GpgContext::test_status_cb(void *hook, const char *keyword, return GPG_ERR_NO_ERROR; } +std::string GpgContext::need_user_input_passphrase() { + emit SignalNeedUserInputPassphrase(); + + std::string final_passphrase; + bool input_done = false; + SPDLOG_DEBUG("loop start to wait from user"); + connect(CoreSignalStation::GetInstance(), + &CoreSignalStation::SignalUserInputPassphraseDone, this, + [&](QString passphrase) { + SPDLOG_DEBUG("SignalUserInputPassphraseDone emitted"); + final_passphrase = passphrase.toStdString(); + input_done = true; + }); + while (!input_done) { + SPDLOG_DEBUG("loppe still waiting..."); + sleep(1); + } + SPDLOG_DEBUG("lopper end"); + return final_passphrase; +} + const GpgInfo &GpgContext::GetInfo(bool refresh) { if (!extend_info_loaded_ || refresh) { GpgCommandExecutor::GetInstance().Execute( diff --git a/src/core/GpgContext.h b/src/core/GpgContext.h index bc4b615b..b25fcf15 100644 --- a/src/core/GpgContext.h +++ b/src/core/GpgContext.h @@ -29,6 +29,8 @@ #ifndef __SGPGMEPP_CONTEXT_H__ #define __SGPGMEPP_CONTEXT_H__ +#include <string> + #include "GpgConstants.h" #include "GpgFunctionObject.h" #include "GpgInfo.h" @@ -57,7 +59,9 @@ struct GpgContextInitArgs { * */ class GPGFRONTEND_CORE_EXPORT GpgContext - : public SingletonFunctionObject<GpgContext> { + : public QObject, + public SingletonFunctionObject<GpgContext> { + Q_OBJECT public: /** * @brief Construct a new Gpg Context object @@ -110,7 +114,14 @@ class GPGFRONTEND_CORE_EXPORT GpgContext * @brief * */ - void init_ctx(); + void post_init_ctx(); + + /** + * @brief + * + * @return std::string + */ + std::string need_user_input_passphrase(); /** * @brief @@ -125,6 +136,13 @@ class GPGFRONTEND_CORE_EXPORT GpgContext CtxRefHandler _ctx_ref = nullptr; ///< bool good_ = true; ///< + signals: + /** + * @brief + * + */ + void SignalNeedUserInputPassphrase(); + public: /** * @brief diff --git a/src/core/common/CoreCommonUtil.cpp b/src/core/common/CoreCommonUtil.cpp index a19994a6..54400e24 100644 --- a/src/core/common/CoreCommonUtil.cpp +++ b/src/core/common/CoreCommonUtil.cpp @@ -26,6 +26,8 @@ #include "CoreCommonUtil.h"
+#include <string>
+
namespace GpgFrontend {
std::unique_ptr<CoreCommonUtil> CoreCommonUtil::instance_ = nullptr; ///<
@@ -37,4 +39,21 @@ CoreCommonUtil *CoreCommonUtil::GetInstance() { }
return instance_.get();
}
+
+void CoreCommonUtil::SetTempCacheValue(const std::string key,
+ const std::string value) {
+ temp_cache_[key] = value;
+}
+
+std::string CoreCommonUtil::GetTempCacheValue(const std::string key) {
+ std::string temp_cache_value;
+ std::swap(temp_cache_value, temp_cache_[key]);
+ return temp_cache_value;
+}
+
+void CoreCommonUtil::ResetTempCacheValue(const std::string key) {
+ std::string temp_cache_value;
+ std::swap(temp_cache_value, temp_cache_[key]);
+}
+
} // namespace GpgFrontend
diff --git a/src/core/common/CoreCommonUtil.h b/src/core/common/CoreCommonUtil.h index 3762c4f0..6cbf6405 100644 --- a/src/core/common/CoreCommonUtil.h +++ b/src/core/common/CoreCommonUtil.h @@ -27,6 +27,8 @@ #ifndef GPGFRONTEND_CORECOMMONUTIL_H
#define GPGFRONTEND_CORECOMMONUTIL_H
+#include <string>
+
#include "core/GpgFrontendCore.h"
namespace GpgFrontend {
@@ -46,6 +48,27 @@ class GPGFRONTEND_CORE_EXPORT CoreCommonUtil : public QObject { */
CoreCommonUtil() = default;
+ /**
+ * @brief set a temp cache under a certain key
+ *
+ */
+ void SetTempCacheValue(const std::string, const std::string);
+
+ /**
+ * @brief after get the temp cache, its value will be imediately ease in
+ * storage
+ *
+ * @return std::string
+ */
+ std::string GetTempCacheValue(const std::string);
+
+ /**
+ * @brief imediately ease temp cache in storage
+ *
+ * @return std::string
+ */
+ void ResetTempCacheValue(const std::string);
+
signals:
/**
@@ -56,6 +79,7 @@ class GPGFRONTEND_CORE_EXPORT CoreCommonUtil : public QObject { private:
static std::unique_ptr<CoreCommonUtil> instance_; ///<
+ std::map<std::string, std::string> temp_cache_; //<
};
} // namespace GpgFrontend
diff --git a/src/core/function/CoreSignalStation.cpp b/src/core/function/CoreSignalStation.cpp new file mode 100644 index 00000000..f78d417b --- /dev/null +++ b/src/core/function/CoreSignalStation.cpp @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2021 Saturneric + * + * 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. + * + * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "core/function/CoreSignalStation.h" + +std::unique_ptr<GpgFrontend::CoreSignalStation> + GpgFrontend::CoreSignalStation::_instance = nullptr; + +GpgFrontend::CoreSignalStation* GpgFrontend::CoreSignalStation::GetInstance() { + if (_instance == nullptr) { + _instance = std::make_unique<CoreSignalStation>(); + } + return _instance.get(); +} diff --git a/src/core/function/CoreSignalStation.h b/src/core/function/CoreSignalStation.h new file mode 100644 index 00000000..7497cab7 --- /dev/null +++ b/src/core/function/CoreSignalStation.h @@ -0,0 +1,69 @@ +/** + * Copyright (C) 2021 Saturneric + * + * 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. + * + * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef GPGFRONTEND_CORESIGNALSTATION_H +#define GPGFRONTEND_CORESIGNALSTATION_H + +#include "core/GpgFrontendCore.h" + +namespace GpgFrontend { + +/** + * @brief + * + */ +class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject { + Q_OBJECT + static std::unique_ptr<CoreSignalStation> _instance; + + public: + /** + * @brief Get the Instance object + * + * @return SignalStation* + */ + static CoreSignalStation* GetInstance(); + + signals: + + /** + * @brief + * + */ + void SignalUserInputPassphraseDone(QString passparase); + + /** + * @brief + * + */ + void SignalNeedUserInputPassphrase(); +}; + +} // namespace GpgFrontend + +#endif // GPGFRONTEND_CORESIGNALSTATION_H diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 7be38f76..c4296852 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -58,6 +58,12 @@ void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) { quit(); } +void GpgFrontend::Thread::TaskRunner::PostScheduleTask(Task* task, + size_t seconds) { + if (task == nullptr) return; + // TODO +} + [[noreturn]] void GpgFrontend::Thread::TaskRunner::run() { SPDLOG_TRACE("called, thread id: {}", QThread::currentThreadId()); while (true) { diff --git a/src/core/thread/TaskRunner.h b/src/core/thread/TaskRunner.h index 565c123c..6a5e00a5 100644 --- a/src/core/thread/TaskRunner.h +++ b/src/core/thread/TaskRunner.h @@ -27,6 +27,7 @@ #ifndef GPGFRONTEND_TASKRUNNER_H #define GPGFRONTEND_TASKRUNNER_H +#include <cstddef> #include <mutex> #include <queue> @@ -66,6 +67,14 @@ class GPGFRONTEND_CORE_EXPORT TaskRunner : public QThread { */ void PostTask(Task* task); + /** + * @brief + * + * @param task + * @param seconds + */ + void PostScheduleTask(Task* task, size_t seconds); + private: std::queue<Task*> tasks; ///< The task queue std::map<std::string, Task*> pending_tasks_; ///< The pending tasks diff --git a/src/main.cpp b/src/main.cpp index 52a20334..01964f6a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -151,14 +151,21 @@ int main(int argc, char* argv[]) { return_from_event_loop_code = CRASH_CODE; } - SPDLOG_INFO("restart loop refresh"); + SPDLOG_INFO("restart loop refresh, event loop code: {}", + return_from_event_loop_code); } while (return_from_event_loop_code == RESTART_CODE); - // reset core - GpgFrontend::ResetGpgFrontendCore(); - - // log for debug - SPDLOG_INFO("deep restart or cash loop refresh"); + if (return_from_event_loop_code == DEEP_RESTART_CODE || + return_from_event_loop_code == CRASH_CODE) { + // reset core + GpgFrontend::ResetGpgFrontendCore(); + // log for debug + SPDLOG_INFO("deep restart or cash loop refresh"); + } else { + // log for debug + SPDLOG_INFO("need to close application, event loop code: {}", + return_from_event_loop_code); + } // deep restart mode } while (return_from_event_loop_code == DEEP_RESTART_CODE || diff --git a/src/ui/SignalStation.h b/src/ui/SignalStation.h index eb7b3f74..48651f1b 100644 --- a/src/ui/SignalStation.h +++ b/src/ui/SignalStation.h @@ -79,6 +79,18 @@ class SignalStation : public QObject { * @param timeout */ void SignalRefreshStatusBar(const QString& message, int timeout); + + /** + * @brief + * + */ + void SignalUserInputPassphraseDone(QString passparase); + + /** + * @brief + * + */ + void SignalNeedUserInputPassphrase(); }; } // namespace GpgFrontend::UI diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp index b84c1ad2..72ebe6f6 100644 --- a/src/ui/UserInterfaceUtils.cpp +++ b/src/ui/UserInterfaceUtils.cpp @@ -28,16 +28,19 @@ #include "UserInterfaceUtils.h" +#include <string> #include <utility> #include <vector> #include "core/common/CoreCommonUtil.h" +#include "core/function/CoreSignalStation.h" #include "core/function/FileOperator.h" #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/thread/Task.h" #include "core/thread/TaskRunner.h" #include "core/thread/TaskRunnerGetter.h" +#include "spdlog/spdlog.h" #include "ui/SignalStation.h" #include "ui/dialog/WaitingDialog.h" #include "ui/struct/SettingsObject.h" @@ -157,6 +160,9 @@ CommonUtils::CommonUtils() : QWidget(nullptr) { connect(this, &CommonUtils::SignalKeyDatabaseRefreshDone, SignalStation::GetInstance(), &SignalStation::SignalKeyDatabaseRefreshDone); + connect(this, &CommonUtils::SignalUserInputPassphraseDone, + CoreSignalStation::GetInstance(), + &CoreSignalStation::SignalUserInputPassphraseDone); // directly connect to SignalKeyStatusUpdated // to avoid the delay of signal emitting @@ -165,6 +171,10 @@ CommonUtils::CommonUtils() : QWidget(nullptr) { &SignalStation::SignalKeyDatabaseRefresh, this, &CommonUtils::slot_update_key_status); + connect(CoreSignalStation::GetInstance(), + &CoreSignalStation::SignalNeedUserInputPassphrase, this, + &CommonUtils::slot_popup_passphrase_input_dialog); + connect(this, &CommonUtils::SignalGnupgNotInstall, this, []() { QMessageBox::critical( nullptr, _("ENV Loading Failed"), @@ -409,4 +419,23 @@ void CommonUtils::slot_update_key_status() { refresh_task); } +void CommonUtils::slot_popup_passphrase_input_dialog() { + SPDLOG_INFO("called"); + + auto *dialog = new QInputDialog(QApplication::activeWindow(), Qt::Dialog); + dialog->setModal(true); + dialog->setWindowTitle(_("Password Input Dialog")); + dialog->setInputMode(QInputDialog::TextInput); + dialog->setTextEchoMode(QLineEdit::Password); + dialog->setLabelText("Please Input The Password"); + dialog->resize(600, 80); + dialog->exec(); + + QString password = dialog->textValue(); + dialog->deleteLater(); + + // send signal + emit SignalUserInputPassphraseDone(password); +} + } // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h index d11ae9a2..7761de7b 100644 --- a/src/ui/UserInterfaceUtils.h +++ b/src/ui/UserInterfaceUtils.h @@ -163,6 +163,18 @@ class CommonUtils : public QWidget { */ void SignalKeyDatabaseRefreshDone(); + /** + * @brief + * + */ + void SignalNeedUserInputPassphrase(); + + /** + * @brief + * + */ + void SignalUserInputPassphraseDone(QString passphrase); + public slots: /** * @brief @@ -220,10 +232,8 @@ class CommonUtils : public QWidget { * @param arguments * @param interact_func */ - void SlotExecuteCommand( - const std::string& cmd, - const QStringList& arguments, - const std::function<void(QProcess*)>& interact_func); + void SlotExecuteCommand(const std::string& cmd, const QStringList& arguments, + const std::function<void(QProcess*)>& interact_func); private slots: @@ -233,6 +243,12 @@ class CommonUtils : public QWidget { */ void slot_update_key_status(); + /** + * @brief + * + */ + void slot_popup_passphrase_input_dialog(); + private: static std::unique_ptr<CommonUtils> instance_; ///< }; diff --git a/src/ui/dialog/key_generate/KeygenDialog.cpp b/src/ui/dialog/key_generate/KeygenDialog.cpp index 3fd2a357..5cd6e664 100644 --- a/src/ui/dialog/key_generate/KeygenDialog.cpp +++ b/src/ui/dialog/key_generate/KeygenDialog.cpp @@ -28,6 +28,7 @@ #include "KeygenDialog.h" +#include "core/common/CoreCommonUtil.h" #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgKeyOpera.h" #include "dialog/WaitingDialog.h" @@ -110,6 +111,10 @@ void KeyGenDialog::slot_key_gen_accept() { error_stream << " " << _("Expiration time too long.") << std::endl; } + if (passphrase_edit_->isEnabled() && passphrase_edit_->text().size() == 0) { + error_stream << " " << _("Password is empty.") << std::endl; + } + auto err_string = error_stream.str(); if (err_string.empty()) { @@ -129,6 +134,11 @@ void KeyGenDialog::slot_key_gen_accept() { boost::posix_time::from_time_t(date_edit_->dateTime().toTime_t())); } + if (!gen_key_info_->IsNoPassPhrase()) { + CoreCommonUtil::GetInstance()->SetTempCacheValue( + "__key_passphrase", this->passphrase_edit_->text().toStdString()); + } + GpgGenKeyResult result; gpgme_error_t error = false; auto thread = QThread::create([&]() { @@ -145,6 +155,10 @@ void KeyGenDialog::slot_key_gen_accept() { dialog->close(); + if (!gen_key_info_->IsNoPassPhrase()) { + CoreCommonUtil::GetInstance()->ResetTempCacheValue("__key_passphrase"); + } + SPDLOG_INFO("generate done"); if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) { @@ -337,11 +351,8 @@ void KeyGenDialog::set_signal_slot() { connect(no_pass_phrase_check_box_, &QCheckBox::stateChanged, this, [this](int state) -> void { - if (state == 0) { - gen_key_info_->SetNonPassPhrase(false); - } else { - gen_key_info_->SetNonPassPhrase(true); - } + gen_key_info_->SetNonPassPhrase(state != 0); + passphrase_edit_->setDisabled(state != 0); }); } @@ -356,6 +367,7 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() { comment_edit_ = new QLineEdit(this); key_size_spin_box_ = new QSpinBox(this); key_type_combo_box_ = new QComboBox(this); + passphrase_edit_ = new QLineEdit(this); for (auto& algo : GenKeyInfo::GetSupportedKeyAlgo()) { key_type_combo_box_->addItem(QString::fromStdString(algo.first)); @@ -375,6 +387,8 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() { expire_check_box_ = new QCheckBox(this); expire_check_box_->setCheckState(Qt::Unchecked); + passphrase_edit_->setEchoMode(QLineEdit::Password); + no_pass_phrase_check_box_ = new QCheckBox(this); no_pass_phrase_check_box_->setCheckState(Qt::Unchecked); @@ -387,7 +401,8 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() { vbox1->addWidget(new QLabel(QString(_("Never Expire")) + ": "), 3, 3); vbox1->addWidget(new QLabel(QString(_("KeySize (in Bit)")) + ": "), 4, 0); vbox1->addWidget(new QLabel(QString(_("Key Type")) + ": "), 5, 0); - vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase")) + ": "), 6, 0); + vbox1->addWidget(new QLabel(QString(_("Password")) + ": "), 6, 0); + vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase")) + ": "), 7, 0); vbox1->addWidget(name_edit_, 0, 1, 1, 3); vbox1->addWidget(email_edit_, 1, 1, 1, 3); @@ -396,7 +411,8 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() { vbox1->addWidget(expire_check_box_, 3, 2); vbox1->addWidget(key_size_spin_box_, 4, 1); vbox1->addWidget(key_type_combo_box_, 5, 1); - vbox1->addWidget(no_pass_phrase_check_box_, 6, 1); + vbox1->addWidget(passphrase_edit_, 6, 1); + vbox1->addWidget(no_pass_phrase_check_box_, 7, 1); auto basicInfoGroupBox = new QGroupBox(); basicInfoGroupBox->setLayout(vbox1); diff --git a/src/ui/dialog/key_generate/KeygenDialog.h b/src/ui/dialog/key_generate/KeygenDialog.h index baf10dbf..a1d7f39a 100644 --- a/src/ui/dialog/key_generate/KeygenDialog.h +++ b/src/ui/dialog/key_generate/KeygenDialog.h @@ -93,6 +93,7 @@ class KeyGenDialog : public GeneralDialog { QLineEdit* name_edit_{}; ///< Line edit for the keys name QLineEdit* email_edit_{}; ///< Line edit for the keys email QLineEdit* comment_edit_{}; ///< Line edit for the keys comment + QLineEdit* passphrase_edit_{}; ///< QSpinBox* key_size_spin_box_{}; ///< Spinbox for the keys size (in bit) QComboBox* key_type_combo_box_{}; ///< Combobox for Key type QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date |