From 1a8626dfb31df145f32ad5ceaa480fbd2a0a42bf Mon Sep 17 00:00:00 2001 From: Saturneric Date: Fri, 3 Dec 2021 06:30:34 +0800 Subject: [PATCH] Fixed 1. Fixed Known Issues. --- src/gpg/function/GpgKeyOpera.cpp | 36 ++++++++++++--- src/gpg/function/GpgKeyOpera.h | 4 +- src/ui/UserInterfaceUtils.cpp | 43 ++++++++++++++++++ src/ui/UserInterfaceUtils.h | 5 ++- src/ui/keypair_details/KeyPairDetailTab.cpp | 50 +++++++++++++++++---- 5 files changed, 120 insertions(+), 18 deletions(-) diff --git a/src/gpg/function/GpgKeyOpera.cpp b/src/gpg/function/GpgKeyOpera.cpp index 2406cbb9..a7371904 100644 --- a/src/gpg/function/GpgKeyOpera.cpp +++ b/src/gpg/function/GpgKeyOpera.cpp @@ -93,21 +93,43 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire( */ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert( const GpgKey& key, const std::string& output_file_name) { - auto args = std::vector{"--command-fd", "0", - "--status-fd", "1", - "-o", output_file_name.c_str(), - "--gen-revoke", key.fpr().c_str()}; + auto args = std::vector{ + "--no-tty", "--command-fd", "0", "--status-fd", "1", "-o", + output_file_name, "--gen-revoke", key.fpr()}; + using boost::asio::async_write; using boost::process::async_pipe; GpgCommandExecutor::GetInstance().Execute( args, [](async_pipe& in, async_pipe& out) -> void { boost::asio::streambuf buff; boost::asio::read_until(in, buff, '\n'); - std::string line; std::istream is(&buff); - is >> line; - // Code From Gpg4Win + + while (!is.eof()) { + std::string line; + is >> line; + LOG(INFO) << "line" << line; + boost::algorithm::trim(line); + if (line == std::string("[GNUPG:] GET_BOOL gen_revoke.okay")) { + + } else if (line == + std::string( + "[GNUPG:] GET_LINE ask_revocation_reason.code")) { + + } else if (line == + std::string( + "[GNUPG:] GET_LINE ask_revocation_reason.text")) { + + } else if (line == + std::string("[GNUPG:] GET_BOOL openfile.overwrite.okay")) { + + } else if (line == + std::string( + "[GNUPG:] GET_BOOL ask_revocation_reason.okay")) { + + } + } }); } diff --git a/src/gpg/function/GpgKeyOpera.h b/src/gpg/function/GpgKeyOpera.h index d9573bd7..71e2de8b 100644 --- a/src/gpg/function/GpgKeyOpera.h +++ b/src/gpg/function/GpgKeyOpera.h @@ -38,8 +38,8 @@ class GpgKeyOpera : public SingletonFunctionObject { GpgError SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr, std::unique_ptr& expires); - void GenerateRevokeCert(const GpgKey& key, - const std::string& output_file_name); + static void GenerateRevokeCert(const GpgKey& key, + const std::string& output_file_name); GpgFrontend::GpgError GenerateKey(const std::unique_ptr& params); diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp index 395d292e..e8f27d2c 100644 --- a/src/ui/UserInterfaceUtils.cpp +++ b/src/ui/UserInterfaceUtils.cpp @@ -125,4 +125,47 @@ void CommonUtils::slotImportKeyFromClipboard(QWidget* parent) { cb->text(QClipboard::Clipboard).toUtf8().toStdString()); } +void CommonUtils::slotExecuteGpgCommand( + const QStringList& arguments, + const std::function& interact_func) { + QEventLoop looper; + auto dialog = new WaitingDialog(_("Processing"), nullptr); + dialog->show(); + auto* gpgProcess = new QProcess(&looper); + gpgProcess->setProcessChannelMode(QProcess::MergedChannels); + + connect(gpgProcess, qOverload(&QProcess::finished), + &looper, &QEventLoop::quit); + connect(gpgProcess, qOverload(&QProcess::finished), + dialog, &WaitingDialog::deleteLater); + connect(gpgProcess, &QProcess::errorOccurred, &looper, &QEventLoop::quit); + connect(gpgProcess, &QProcess::started, + []() -> void { LOG(ERROR) << "Gpg Process Started Success"; }); + connect(gpgProcess, &QProcess::readyReadStandardOutput, + [interact_func, gpgProcess]() { interact_func(gpgProcess); }); + connect(gpgProcess, &QProcess::errorOccurred, this, [=]() -> void { + LOG(ERROR) << "Error in Process"; + dialog->close(); + QMessageBox::critical(nullptr, _("Failure"), + _("Failed to execute command.")); + }); + connect(gpgProcess, qOverload(&QProcess::finished), + this, [=](int, QProcess::ExitStatus status) { + dialog->close(); + if (status == QProcess::NormalExit) + QMessageBox::information(nullptr, _("Success"), + _("Succeed in executing command.")); + else + QMessageBox::information(nullptr, _("Warning"), + _("Finished executing command.")); + }); + + gpgProcess->setProgram(GpgContext::GetInstance().GetInfo().AppPath.c_str()); + gpgProcess->setArguments(arguments); + gpgProcess->start(); + looper.exec(); + dialog->close(); + dialog->deleteLater(); +} + } // namespace GpgFrontend::UI \ No newline at end of file diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h index b5014f29..df974257 100644 --- a/src/ui/UserInterfaceUtils.h +++ b/src/ui/UserInterfaceUtils.h @@ -69,9 +69,12 @@ class CommonUtils : public QWidget { void slotImportKeyFromClipboard(QWidget* parent); + void slotExecuteGpgCommand( + const QStringList& arguments, + const std::function& interact_func); + private: static std::unique_ptr _instance; - }; } // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyPairDetailTab.cpp b/src/ui/keypair_details/KeyPairDetailTab.cpp index 53c2ee01..f88e9edc 100644 --- a/src/ui/keypair_details/KeyPairDetailTab.cpp +++ b/src/ui/keypair_details/KeyPairDetailTab.cpp @@ -27,6 +27,7 @@ #include "gpg/function/GpgKeyGetter.h" #include "gpg/function/GpgKeyImportExportor.h" #include "ui/SignalStation.h" +#include "ui/UserInterfaceUtils.h" #include "ui/WaitingDialog.h" namespace GpgFrontend::UI { @@ -228,8 +229,9 @@ void KeyPairDetailTab::slotExportPrivateKey() { ByteArrayPtr keyArray = nullptr; if (!GpgKeyImportExportor::GetInstance().ExportSecretKey(mKey, keyArray)) { - QMessageBox::critical(this, "Error", - "An error occurred during the export operation."); + QMessageBox::critical( + this, _("Error"), + _("An error occurred during the export operation.")); return; } @@ -356,15 +358,47 @@ void KeyPairDetailTab::slotUpdateKeyToServer() { } void KeyPairDetailTab::slotGenRevokeCert() { - auto mOutputFileName = QFileDialog::getSaveFileName( - this, _("Generate revocation certificate"), QString(), - QStringLiteral("%1 (*.rev)").arg(_("Revocation Certificates"))); + auto literal = QStringLiteral("%1 (*.rev)").arg(_("Revocation Certificates")); + QString m_output_file_name; - // if (!mOutputFileName.isEmpty()) - // mCtx->generateRevokeCert(mKey, mOutputFileName); + QFileDialog dialog(this, "Generate revocation certificate", QString(), + literal); + dialog.setDefaultSuffix(".rev"); + dialog.setAcceptMode(QFileDialog::AcceptSave); + + if (dialog.exec()) m_output_file_name = dialog.selectedFiles().front(); + + if (!m_output_file_name.isEmpty()) + CommonUtils::GetInstance()->slotExecuteGpgCommand( + {"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o", + m_output_file_name, "--gen-revoke", mKey.fpr().c_str()}, + [](QProcess* proc) -> void { + // Code From Gpg4Win + while (proc->canReadLine()) { + const QString line = QString::fromUtf8(proc->readLine()).trimmed(); + LOG(INFO) << "line" << line.toStdString(); + if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) { + proc->write("y\n"); + } else if (line == QLatin1String("[GNUPG:] GET_LINE " + "ask_revocation_reason.code")) { + proc->write("0\n"); + } else if (line == QLatin1String("[GNUPG:] GET_LINE " + "ask_revocation_reason.text")) { + proc->write("\n"); + } else if (line == + QLatin1String( + "[GNUPG:] GET_BOOL openfile.overwrite.okay")) { + // We asked before + proc->write("y\n"); + } else if (line == QLatin1String("[GNUPG:] GET_BOOL " + "ask_revocation_reason.okay")) { + proc->write("y\n"); + } + } + }); } void KeyPairDetailTab::slotRefreshKey() { - LOG(INFO) << "KeyPairDetailTab::slotRefreshKey Called"; + LOG(INFO) << _("Called"); this->mKey = GpgKeyGetter::GetInstance().GetKey(mKey.id()); this->slotRefreshKeyInfo(); }