diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 69aed69da..7ef83da09 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,411 +1,412 @@ # SPDX-FileCopyrightText: none # SPDX-License-Identifier: BSD-3-Clause add_subdirectory(icons) add_subdirectory(mimetypes) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) if (NOT DISABLE_KWATCHGNUPG) add_subdirectory(kwatchgnupg) endif() add_subdirectory(libkleopatraclient) add_subdirectory(conf) add_subdirectory(kconf_update) if(WIN32) set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_win.cpp) set(_kleopatra_extra_SRCS utils/gnupg-registry.c selftest/registrycheck.cpp utils/windowsprocessdevice.cpp utils/userinfo_win.cpp ) else() set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_unix.cpp) set(_kleopatra_extra_SRCS) endif() set(_kleopatra_uiserver_SRCS uiserver/sessiondata.cpp uiserver/uiserver.cpp ${_kleopatra_extra_uiserver_SRCS} uiserver/assuanserverconnection.cpp uiserver/echocommand.cpp uiserver/decryptverifycommandemailbase.cpp uiserver/decryptverifycommandfilesbase.cpp uiserver/signcommand.cpp uiserver/signencryptfilescommand.cpp uiserver/prepencryptcommand.cpp uiserver/prepsigncommand.cpp uiserver/encryptcommand.cpp uiserver/selectcertificatecommand.cpp uiserver/importfilescommand.cpp uiserver/createchecksumscommand.cpp uiserver/verifychecksumscommand.cpp selftest/uiservercheck.cpp ) if(ASSUAN2_FOUND) include_directories(${ASSUAN2_INCLUDES}) set(_kleopatra_uiserver_extra_libs ${ASSUAN2_LIBRARIES}) else() include_directories(${ASSUAN_INCLUDES}) if(WIN32) set(_kleopatra_uiserver_extra_libs ${ASSUAN_VANILLA_LIBRARIES}) else() set(_kleopatra_uiserver_extra_libs ${ASSUAN_PTHREAD_LIBRARIES}) endif() endif() if(HAVE_GPG_ERR_SOURCE_KLEO) add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO) add_definitions(-DGPGMEPP_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO) else() add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1) add_definitions(-DGPGMEPP_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1) endif() if(KF5IdentityManagement_FOUND AND KF5MailTransport_FOUND AND KF5MailTransportAkonadi_FOUND) set(_kleopatra_mail_libs KF5::IdentityManagement # Export OpenPGP keys using WKS KF5::MailTransport KF5::MailTransportAkonadi ) add_definitions(-DMAILAKONADI_ENABLED) endif() ki18n_wrap_ui(_kleopatra_uiserver_SRCS crypto/gui/signingcertificateselectionwidget.ui) set(_kleopatra_SRCS utils/accessibility.cpp utils/gui-helper.cpp utils/filedialog.cpp utils/kdpipeiodevice.cpp utils/headerview.cpp utils/scrollarea.cpp utils/dragqueen.cpp utils/multivalidator.cpp utils/systemtrayicon.cpp utils/path-helper.cpp utils/input.cpp utils/output.cpp utils/validation.cpp utils/wsastarter.cpp utils/iodevicelogger.cpp utils/log.cpp utils/action_data.cpp utils/types.cpp utils/archivedefinition.cpp utils/auditlog.cpp utils/clipboardmenu.cpp utils/kuniqueservice.cpp utils/tags.cpp utils/writecertassuantransaction.cpp utils/keyparameters.cpp utils/userinfo.cpp utils/keys.cpp selftest/selftest.cpp selftest/enginecheck.cpp selftest/gpgconfcheck.cpp selftest/gpgagentcheck.cpp selftest/libkleopatrarccheck.cpp selftest/compliancecheck.cpp ${_kleopatra_extra_SRCS} view/errorlabel.cpp view/formtextinput.cpp view/htmllabel.cpp view/keylistcontroller.cpp view/keytreeview.cpp view/searchbar.cpp view/smartcardwidget.cpp view/openpgpkeycardwidget.cpp view/padwidget.cpp view/pgpcardwidget.cpp view/pivcardwidget.cpp view/p15cardwidget.cpp view/netkeywidget.cpp view/nullpinwidget.cpp view/tabwidget.cpp view/keycacheoverlay.cpp view/urllabel.cpp view/waitwidget.cpp view/welcomewidget.cpp dialogs/certificateselectiondialog.cpp dialogs/certifywidget.cpp dialogs/expirydialog.cpp dialogs/lookupcertificatesdialog.cpp dialogs/ownertrustdialog.cpp dialogs/selftestdialog.cpp dialogs/certifycertificatedialog.cpp dialogs/revokecertificationwidget.cpp dialogs/revokecertificationdialog.cpp dialogs/adduseriddialog.cpp dialogs/deletecertificatesdialog.cpp dialogs/setinitialpindialog.cpp dialogs/certificatedetailsdialog.cpp dialogs/certificatedetailswidget.cpp dialogs/trustchainwidget.cpp dialogs/weboftrustwidget.cpp dialogs/weboftrustdialog.cpp dialogs/exportdialog.cpp dialogs/subkeyswidget.cpp dialogs/gencardkeydialog.cpp dialogs/updatenotification.cpp dialogs/pivcardapplicationadministrationkeyinputdialog.cpp dialogs/certificatedetailsinputwidget.cpp dialogs/createcsrforcardkeydialog.cpp dialogs/groupdetailsdialog.cpp dialogs/editgroupdialog.cpp dialogs/revokekeydialog.cpp crypto/controller.cpp crypto/certificateresolver.cpp crypto/sender.cpp crypto/recipient.cpp crypto/task.cpp crypto/taskcollection.cpp crypto/decryptverifytask.cpp crypto/decryptverifyemailcontroller.cpp crypto/decryptverifyfilescontroller.cpp crypto/autodecryptverifyfilescontroller.cpp crypto/encryptemailtask.cpp crypto/encryptemailcontroller.cpp crypto/newsignencryptemailcontroller.cpp crypto/signencrypttask.cpp crypto/signencryptfilescontroller.cpp crypto/signemailtask.cpp crypto/signemailcontroller.cpp crypto/createchecksumscontroller.cpp crypto/verifychecksumscontroller.cpp crypto/gui/wizard.cpp crypto/gui/wizardpage.cpp crypto/gui/certificateselectionline.cpp crypto/gui/certificatelineedit.cpp crypto/gui/signingcertificateselectionwidget.cpp crypto/gui/signingcertificateselectiondialog.cpp crypto/gui/resultitemwidget.cpp crypto/gui/resultlistwidget.cpp crypto/gui/resultpage.cpp crypto/gui/newresultpage.cpp crypto/gui/signencryptfileswizard.cpp crypto/gui/signencryptemailconflictdialog.cpp crypto/gui/decryptverifyoperationwidget.cpp crypto/gui/decryptverifyfileswizard.cpp crypto/gui/decryptverifyfilesdialog.cpp crypto/gui/objectspage.cpp crypto/gui/resolverecipientspage.cpp crypto/gui/signerresolvepage.cpp crypto/gui/encryptemailwizard.cpp crypto/gui/signemailwizard.cpp crypto/gui/signencryptwidget.cpp crypto/gui/signencryptwizard.cpp crypto/gui/unknownrecipientwidget.cpp crypto/gui/verifychecksumsdialog.cpp commands/command.cpp commands/gnupgprocesscommand.cpp commands/detailscommand.cpp commands/exportcertificatecommand.cpp commands/exportgroupscommand.cpp commands/importcertificatescommand.cpp commands/importcertificatefromfilecommand.cpp commands/importcertificatefromclipboardcommand.cpp commands/importcertificatefromdatacommand.cpp commands/importcertificatefromkeyservercommand.cpp commands/lookupcertificatescommand.cpp commands/reloadkeyscommand.cpp commands/refreshcertificatecommand.cpp commands/refreshx509certscommand.cpp commands/refreshopenpgpcertscommand.cpp commands/deletecertificatescommand.cpp commands/decryptverifyfilescommand.cpp commands/signencryptfilescommand.cpp commands/signencryptfoldercommand.cpp commands/encryptclipboardcommand.cpp commands/signclipboardcommand.cpp commands/decryptverifyclipboardcommand.cpp commands/clearcrlcachecommand.cpp commands/dumpcrlcachecommand.cpp commands/dumpcertificatecommand.cpp commands/importcrlcommand.cpp commands/changeexpirycommand.cpp commands/changeownertrustcommand.cpp commands/changeroottrustcommand.cpp commands/changepassphrasecommand.cpp commands/certifycertificatecommand.cpp commands/revokecertificationcommand.cpp commands/selftestcommand.cpp commands/exportsecretkeycommand.cpp commands/exportsecretkeycommand_old.cpp commands/exportsecretsubkeycommand.cpp commands/exportopenpgpcertstoservercommand.cpp commands/exportopenpgpcerttoprovidercommand.cpp commands/adduseridcommand.cpp commands/newcertificatecommand.cpp commands/setinitialpincommand.cpp commands/learncardkeyscommand.cpp commands/checksumcreatefilescommand.cpp commands/checksumverifyfilescommand.cpp commands/exportpaperkeycommand.cpp commands/importpaperkeycommand.cpp commands/genrevokecommand.cpp commands/keytocardcommand.cpp commands/cardcommand.cpp commands/pivgeneratecardkeycommand.cpp commands/changepincommand.cpp commands/authenticatepivcardapplicationcommand.cpp commands/setpivcardapplicationadministrationkeycommand.cpp commands/certificatetopivcardcommand.cpp commands/importcertificatefrompivcardcommand.cpp commands/createopenpgpkeyfromcardkeyscommand.cpp commands/createcsrforcardkeycommand.cpp commands/revokekeycommand.cpp commands/revokeuseridcommand.cpp ${_kleopatra_uiserver_files} conf/configuredialog.cpp conf/groupsconfigdialog.cpp conf/groupsconfigpage.cpp conf/groupsconfigwidget.cpp newcertificatewizard/advancedsettingsdialog.cpp newcertificatewizard/chooseprotocolpage.cpp newcertificatewizard/enterdetailspage.cpp newcertificatewizard/keyalgo.cpp newcertificatewizard/keycreationpage.cpp newcertificatewizard/listwidget.cpp newcertificatewizard/newcertificatewizard.cpp + newcertificatewizard/resultpage.cpp newcertificatewizard/wizardpage.cpp smartcard/readerstatus.cpp smartcard/card.cpp smartcard/openpgpcard.cpp smartcard/netkeycard.cpp smartcard/pivcard.cpp smartcard/p15card.cpp smartcard/keypairinfo.cpp smartcard/utils.cpp smartcard/deviceinfowatcher.cpp accessibility/accessiblerichtextlabel.cpp accessibility/accessiblewidgetfactory.cpp aboutdata.cpp systrayicon.cpp kleopatraapplication.cpp mainwindow.cpp main.cpp kleopatra.qrc ) if(WIN32) configure_file (versioninfo.rc.in versioninfo.rc) set(_kleopatra_SRCS ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc ${_kleopatra_SRCS}) endif() set (_kleopatra_SRCS conf/kleopageconfigdialog.cpp ${_kleopatra_SRCS}) ecm_qt_declare_logging_category(_kleopatra_SRCS HEADER kleopatra_debug.h IDENTIFIER KLEOPATRA_LOG CATEGORY_NAME org.kde.pim.kleopatra DESCRIPTION "kleopatra (kleopatra)" OLD_CATEGORY_NAMES log_kleopatra EXPORT KLEOPATRA ) if(KLEO_MODEL_TEST) add_definitions(-DKLEO_MODEL_TEST) set(_kleopatra_SRCS ${_kleopatra_SRCS} models/modeltest.cpp) endif() ki18n_wrap_ui(_kleopatra_SRCS dialogs/ownertrustdialog.ui dialogs/selectchecklevelwidget.ui dialogs/selftestdialog.ui dialogs/setinitialpindialog.ui dialogs/trustchainwidget.ui dialogs/subkeyswidget.ui newcertificatewizard/listwidget.ui newcertificatewizard/enterdetailspage.ui newcertificatewizard/keycreationpage.ui newcertificatewizard/resultpage.ui newcertificatewizard/advancedsettingsdialog.ui ) kconfig_add_kcfg_files(_kleopatra_SRCS kcfg/tooltippreferences.kcfgc kcfg/emailoperationspreferences.kcfgc kcfg/fileoperationspreferences.kcfgc kcfg/smimevalidationpreferences.kcfgc kcfg/tagspreferences.kcfgc kcfg/settings.kcfgc ) file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/icons/*-apps-kleopatra.png") ecm_add_app_icon(_kleopatra_SRCS ICONS ${ICONS_SRCS}) add_executable(kleopatra_bin ${_kleopatra_SRCS} ${_kleopatra_uiserver_SRCS}) # For the ConfigureDialog & KCMs target_link_libraries(kleopatra_bin kcm_kleopatra_static) #if (COMPILE_WITH_UNITY_CMAKE_SUPPORT) # set_target_properties(kleopatra_bin PROPERTIES UNITY_BUILD ON) #endif() set_target_properties(kleopatra_bin PROPERTIES OUTPUT_NAME kleopatra) if (WIN32) set(_kleopatra_platform_libs "secur32") endif () target_link_libraries(kleopatra_bin Gpgmepp QGpgme ${_kleopatra_extra_libs} KF5::Libkleo KF5::Mime KF5::I18n KF5::XmlGui KF5::IconThemes KF5::WindowSystem KF5::CoreAddons KF5::ItemModels KF5::Crash ${_kleopatra_mail_libs} Qt${QT_MAJOR_VERSION}::Network Qt${QT_MAJOR_VERSION}::PrintSupport # Printing secret keys ${_kleopatra_uiserver_extra_libs} ${_kleopatra_dbusaddons_libs} kleopatraclientcore ${_kleopatra_platform_libs} ) install(TARGETS kleopatra_bin ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install( PROGRAMS data/org.kde.kleopatra.desktop data/kleopatra_import.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) install(FILES data/org.kde.kleopatra.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) install( PROGRAMS data/kleopatra_signencryptfiles.desktop data/kleopatra_signencryptfolders.desktop data/kleopatra_decryptverifyfiles.desktop data/kleopatra_decryptverifyfolders.desktop DESTINATION ${KDE_INSTALL_DATADIR}/kio/servicemenus ) diff --git a/src/newcertificatewizard/newcertificatewizard.cpp b/src/newcertificatewizard/newcertificatewizard.cpp index d32193874..9ad6e8211 100644 --- a/src/newcertificatewizard/newcertificatewizard.cpp +++ b/src/newcertificatewizard/newcertificatewizard.cpp @@ -1,453 +1,181 @@ /* -*- mode: c++; c-basic-offset:4 -*- newcertificatewizard/newcertificatewizard.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB SPDX-FileCopyrightText: 2016, 2017 Bundesamt für Sicherheit in der Informationstechnik SPDX-FileContributor: Intevation GmbH SPDX-License-Identifier: GPL-2.0-or-later */ #include #include "newcertificatewizard.h" #include #include "chooseprotocolpage_p.h" #include "enterdetailspage_p.h" #include "keyalgo_p.h" #include "keycreationpage_p.h" -#include "ui_resultpage.h" +#include "resultpage_p.h" #include "wizardpage_p.h" #ifdef QGPGME_SUPPORTS_SECRET_KEY_EXPORT # include "commands/exportsecretkeycommand.h" #else # include "commands/exportsecretkeycommand_old.h" #endif #include "commands/exportopenpgpcertstoservercommand.h" #include "commands/exportcertificatecommand.h" #include "kleopatraapplication.h" #include "utils/validation.h" #include "utils/filedialog.h" #include "utils/keyparameters.h" #include "utils/userinfo.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kleopatra_debug.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Kleo; using namespace Kleo::NewCertificateUi; using namespace Kleo::Commands; using namespace GpgME; #ifndef QGPGME_SUPPORTS_SECRET_KEY_EXPORT using Kleo::Commands::Compat::ExportSecretKeyCommand; #endif -namespace -{ - -class ResultPage : public WizardPage -{ - Q_OBJECT -public: - explicit ResultPage(QWidget *p = nullptr) - : WizardPage(p), - initialized(false), - successfullyCreatedSigningCertificate(false), - successfullyCreatedEncryptionCertificate(false), - ui() - { - ui.setupUi(this); - ui.dragQueen->setPixmap(QIcon::fromTheme(QStringLiteral("kleopatra")).pixmap(64, 64)); - registerField(QStringLiteral("error"), ui.errorTB, "plainText"); - registerField(QStringLiteral("result"), ui.resultTB, "plainText"); - registerField(QStringLiteral("url"), ui.dragQueen, "url"); - // hidden field, since QWizard can't deal with non-widget-backed fields... - auto le = new QLineEdit(this); - le->hide(); - registerField(QStringLiteral("fingerprint"), le); - } - - void initializePage() override { - const bool error = isError(); - - if (error) - { - setTitle(i18nc("@title", "Key Creation Failed")); - setSubTitle(i18n("Key pair creation failed. Please find details about the failure below.")); - } else { - setTitle(i18nc("@title", "Key Pair Successfully Created")); - setSubTitle(i18n("Your new key pair was created successfully. Please find details on the result and some suggested next steps below.")); - } - - ui.resultTB ->setVisible(!error); - ui.errorTB ->setVisible(error); - ui.dragQueen ->setVisible(!error &&!pgp()); - ui.restartWizardPB ->setVisible(error); - ui.nextStepsGB ->setVisible(!error); - ui.saveRequestToFilePB ->setVisible(!pgp()); - ui.makeBackupPB ->setVisible(pgp()); - ui.createRevocationRequestPB->setVisible(pgp() &&false); // not implemented - - ui.sendCertificateByEMailPB ->setVisible(pgp()); - ui.sendRequestByEMailPB ->setVisible(!pgp()); - ui.uploadToKeyserverPB ->setVisible(pgp()); - - if (!error && !pgp()) - { - if (signingAllowed() && !encryptionAllowed()) { - successfullyCreatedSigningCertificate = true; - } else if (!signingAllowed() && encryptionAllowed()) { - successfullyCreatedEncryptionCertificate = true; - } else { - successfullyCreatedEncryptionCertificate = successfullyCreatedSigningCertificate = true; - } - } - - ui.createSigningCertificatePB->setVisible(successfullyCreatedEncryptionCertificate &&!successfullyCreatedSigningCertificate); - ui.createEncryptionCertificatePB->setVisible(successfullyCreatedSigningCertificate &&!successfullyCreatedEncryptionCertificate); - - if (error) { - wizard()->setOptions(wizard()->options() & ~QWizard::NoCancelButtonOnLastPage); - } else { - wizard()->setOptions(wizard()->options() | QWizard::NoCancelButtonOnLastPage); - } - - if (!initialized) { - connect(ui.restartWizardPB, &QAbstractButton::clicked, - this, [this]() { - restartAtEnterDetailsPage(); - }); - } - initialized = true; - } - - bool isError() const - { - return !ui.errorTB->document()->isEmpty(); - } - - bool isComplete() const override - { - return !isError(); - } - -private: - Key key() const - { - return KeyCache::instance()->findByFingerprint(fingerprint().toLatin1().constData()); - } - -private Q_SLOTS: - void slotSaveRequestToFile() - { - QString fileName = FileDialog::getSaveFileName(this, i18nc("@title", "Save Request"), - QStringLiteral("imp"), i18n("PKCS#10 Requests (*.p10)")); - if (fileName.isEmpty()) { - return; - } - if (!fileName.endsWith(QLatin1String(".p10"), Qt::CaseInsensitive)) { - fileName += QLatin1String(".p10"); - } - QFile src(QUrl(url()).toLocalFile()); - if (!src.copy(fileName)) - KMessageBox::error(this, - xi18nc("@info", - "Could not copy temporary file %1 " - "to file %2: %3", - src.fileName(), fileName, src.errorString()), - i18nc("@title", "Error Saving Request")); - else - KMessageBox::information(this, - xi18nc("@info", - "Successfully wrote request to %1." - "You should now send the request to the Certification Authority (CA).", - fileName), - i18nc("@title", "Request Saved")); - } - - void slotSendRequestByEMail() - { - if (pgp()) { - return; - } - const KConfigGroup config(KSharedConfig::openConfig(), "CertificateCreationWizard"); - invokeMailer(config.readEntry("CAEmailAddress"), // to - i18n("Please process this certificate."), // subject - i18n("Please process this certificate and inform the sender about the location to fetch the resulting certificate.\n\nThanks,\n"), // body - QUrl(url()).toLocalFile()); // attachment - } - - void slotSendCertificateByEMail() - { - if (!pgp() || exportCertificateCommand) { - return; - } - auto cmd = new ExportCertificateCommand(key()); - connect(cmd, &ExportCertificateCommand::finished, this, &ResultPage::slotSendCertificateByEMailContinuation); - cmd->setOpenPGPFileName(tmpDir().absoluteFilePath(fingerprint() + QLatin1String(".asc"))); - cmd->start(); - exportCertificateCommand = cmd; - } - - void slotSendCertificateByEMailContinuation() - { - if (!exportCertificateCommand) { - return; - } - // ### better error handling? - const QString fileName = exportCertificateCommand->openPGPFileName(); - qCDebug(KLEOPATRA_LOG) << "fileName" << fileName; - exportCertificateCommand = nullptr; - if (fileName.isEmpty()) { - return; - } - invokeMailer(QString(), // to - i18n("My new public OpenPGP key"), // subject - i18n("Please find attached my new public OpenPGP key."), // body - fileName); - } - - QByteArray ol_quote(QByteArray str) - { -#ifdef Q_OS_WIN - return "\"\"" + str.replace('"', "\\\"") + "\"\""; - //return '"' + str.replace( '"', "\\\"" ) + '"'; -#else - return str; -#endif - } - - void invokeMailer(const QString &to, const QString &subject, const QString &body, const QString &attachment) - { - qCDebug(KLEOPATRA_LOG) << "to:" << to << "subject:" << subject - << "body:" << body << "attachment:" << attachment; - - // RFC 2368 says body's linebreaks need to be encoded as - // "%0D%0A", so normalize body to CRLF: - //body.replace(QLatin1Char('\n'), QStringLiteral("\r\n")).remove(QStringLiteral("\r\r")); - - QUrlQuery query; - query.addQueryItem(QStringLiteral("subject"), subject); - query.addQueryItem(QStringLiteral("body"), body); - if (!attachment.isEmpty()) { - query.addQueryItem(QStringLiteral("attach"), attachment); - } - QUrl url; - url.setScheme(QStringLiteral("mailto")); - url.setQuery(query); - qCDebug(KLEOPATRA_LOG) << "openUrl" << url; - QDesktopServices::openUrl(url); - KMessageBox::information(this, - xi18nc("@info", - "Kleopatra tried to send a mail via your default mail client." - "Some mail clients are known not to support attachments when invoked this way." - "If your mail client does not have an attachment, then drag the Kleopatra icon and drop it on the message compose window of your mail client." - "If that does not work, either, save the request to a file, and then attach that."), - i18nc("@title", "Sending Mail"), - QStringLiteral("newcertificatewizard-mailto-troubles")); - } - - void slotUploadCertificateToDirectoryServer() - { - if (pgp()) { - (new ExportOpenPGPCertsToServerCommand(key()))->start(); - } - } - - void slotBackupCertificate() - { - if (pgp()) { - (new ExportSecretKeyCommand(key()))->start(); - } - } - - void slotCreateRevocationRequest() - { - - } - - void slotCreateSigningCertificate() - { - if (successfullyCreatedSigningCertificate) { - return; - } - toggleSignEncryptAndRestart(); - } - - void slotCreateEncryptionCertificate() - { - if (successfullyCreatedEncryptionCertificate) { - return; - } - toggleSignEncryptAndRestart(); - } - -private: - void toggleSignEncryptAndRestart() - { - if (!wizard()) { - return; - } - if (KMessageBox::warningContinueCancel( - this, - i18nc("@info", - "This operation will delete the certification request. " - "Please make sure that you have sent or saved it before proceeding."), - i18nc("@title", "Certification Request About To Be Deleted")) != KMessageBox::Continue) { - return; - } - const bool sign = signingAllowed(); - const bool encr = encryptionAllowed(); - setField(QStringLiteral("signingAllowed"), !sign); - setField(QStringLiteral("encryptionAllowed"), !encr); - restartAtEnterDetailsPage(); - } - -private: - bool initialized : 1; - bool successfullyCreatedSigningCertificate : 1; - bool successfullyCreatedEncryptionCertificate : 1; - QPointer exportCertificateCommand; - Ui_ResultPage ui; -}; -} - class NewCertificateWizard::Private { friend class ::Kleo::NewCertificateWizard; NewCertificateWizard *const q; public: explicit Private(NewCertificateWizard *qq) : q(qq), tmp(QDir::temp().absoluteFilePath(QStringLiteral("kleo-"))), ui(q) { q->setWindowTitle(i18nc("@title:window", "Key Pair Creation Wizard")); } private: GpgME::Protocol initialProtocol = GpgME::UnknownProtocol; QTemporaryDir tmp; struct Ui { ChooseProtocolPage chooseProtocolPage; EnterDetailsPage enterDetailsPage; KeyCreationPage keyCreationPage; ResultPage resultPage; explicit Ui(NewCertificateWizard *q) : chooseProtocolPage(q), enterDetailsPage(q), keyCreationPage(q), resultPage(q) { KDAB_SET_OBJECT_NAME(chooseProtocolPage); KDAB_SET_OBJECT_NAME(enterDetailsPage); KDAB_SET_OBJECT_NAME(keyCreationPage); KDAB_SET_OBJECT_NAME(resultPage); q->setOptions(NoBackButtonOnStartPage|DisabledBackButtonOnLastPage); q->setPage(ChooseProtocolPageId, &chooseProtocolPage); q->setPage(EnterDetailsPageId, &enterDetailsPage); q->setPage(KeyCreationPageId, &keyCreationPage); q->setPage(ResultPageId, &resultPage); q->setStartId(ChooseProtocolPageId); } } ui; }; NewCertificateWizard::NewCertificateWizard(QWidget *p) : QWizard(p), d(new Private(this)) { } NewCertificateWizard::~NewCertificateWizard() {} void NewCertificateWizard::showEvent(QShowEvent *event) { // set WA_KeyboardFocusChange attribute to force visual focus of the // focussed button when the wizard is shown (required for Breeze style // and some other styles) window()->setAttribute(Qt::WA_KeyboardFocusChange); QWizard::showEvent(event); } void NewCertificateWizard::setProtocol(Protocol proto) { d->initialProtocol = proto; d->ui.chooseProtocolPage.setProtocol(proto); setStartId(proto == UnknownProtocol ? ChooseProtocolPageId : EnterDetailsPageId); } Protocol NewCertificateWizard::protocol() const { return d->ui.chooseProtocolPage.protocol(); } void NewCertificateWizard::resetProtocol() { d->ui.chooseProtocolPage.setProtocol(d->initialProtocol); } void NewCertificateWizard::restartAtEnterDetailsPage() { const auto protocol = d->ui.chooseProtocolPage.protocol(); restart(); // resets the protocol to the initial protocol d->ui.chooseProtocolPage.setProtocol(protocol); while (currentId() != NewCertificateWizard::EnterDetailsPageId) { next(); } } QDir NewCertificateWizard::tmpDir() const { return QDir(d->tmp.path()); } - -#include "newcertificatewizard.moc" diff --git a/src/newcertificatewizard/resultpage.cpp b/src/newcertificatewizard/resultpage.cpp new file mode 100644 index 000000000..ff06bf204 --- /dev/null +++ b/src/newcertificatewizard/resultpage.cpp @@ -0,0 +1,291 @@ +/* -*- mode: c++; c-basic-offset:4 -*- + newcertificatewizard/resultpage.cpp + + This file is part of Kleopatra, the KDE keymanager + SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB + SPDX-FileCopyrightText: 2016, 2017 Bundesamt für Sicherheit in der Informationstechnik + SPDX-FileContributor: Intevation GmbH + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include + +#include "resultpage_p.h" + +#include + +#include "commands/exportcertificatecommand.h" +#include "commands/exportopenpgpcertstoservercommand.h" +#ifdef QGPGME_SUPPORTS_SECRET_KEY_EXPORT +# include "commands/exportsecretkeycommand.h" +#else +# include "commands/exportsecretkeycommand_old.h" +#endif +#include "utils/filedialog.h" + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include "kleopatra_debug.h" + +using namespace Kleo; +using namespace Kleo::Commands; +using namespace Kleo::NewCertificateUi; +using namespace GpgME; +#ifndef QGPGME_SUPPORTS_SECRET_KEY_EXPORT +using Kleo::Commands::Compat::ExportSecretKeyCommand; +#endif + +ResultPage::ResultPage(QWidget *p) + : WizardPage{p} + , ui{new Ui_ResultPage} + , initialized{false} + , successfullyCreatedSigningCertificate{false} + , successfullyCreatedEncryptionCertificate{false} +{ + ui->setupUi(this); + ui->dragQueen->setPixmap(QIcon::fromTheme(QStringLiteral("kleopatra")).pixmap(64, 64)); + registerField(QStringLiteral("error"), ui->errorTB, "plainText"); + registerField(QStringLiteral("result"), ui->resultTB, "plainText"); + registerField(QStringLiteral("url"), ui->dragQueen, "url"); + // hidden field, since QWizard can't deal with non-widget-backed fields... + auto le = new QLineEdit(this); + le->hide(); + registerField(QStringLiteral("fingerprint"), le); +} + +ResultPage::~ResultPage() = default; + +void ResultPage::initializePage() +{ + const bool error = isError(); + + if (error) + { + setTitle(i18nc("@title", "Key Creation Failed")); + setSubTitle(i18n("Key pair creation failed. Please find details about the failure below.")); + } else { + setTitle(i18nc("@title", "Key Pair Successfully Created")); + setSubTitle(i18n("Your new key pair was created successfully. Please find details on the result and some suggested next steps below.")); + } + + ui->resultTB ->setVisible(!error); + ui->errorTB ->setVisible(error); + ui->dragQueen ->setVisible(!error &&!pgp()); + ui->restartWizardPB ->setVisible(error); + ui->nextStepsGB ->setVisible(!error); + ui->saveRequestToFilePB ->setVisible(!pgp()); + ui->makeBackupPB ->setVisible(pgp()); + ui->createRevocationRequestPB->setVisible(pgp() &&false); // not implemented + + ui->sendCertificateByEMailPB ->setVisible(pgp()); + ui->sendRequestByEMailPB ->setVisible(!pgp()); + ui->uploadToKeyserverPB ->setVisible(pgp()); + + if (!error && !pgp()) + { + if (signingAllowed() && !encryptionAllowed()) { + successfullyCreatedSigningCertificate = true; + } else if (!signingAllowed() && encryptionAllowed()) { + successfullyCreatedEncryptionCertificate = true; + } else { + successfullyCreatedEncryptionCertificate = successfullyCreatedSigningCertificate = true; + } + } + + ui->createSigningCertificatePB->setVisible(successfullyCreatedEncryptionCertificate &&!successfullyCreatedSigningCertificate); + ui->createEncryptionCertificatePB->setVisible(successfullyCreatedSigningCertificate &&!successfullyCreatedEncryptionCertificate); + + if (error) { + wizard()->setOptions(wizard()->options() & ~QWizard::NoCancelButtonOnLastPage); + } else { + wizard()->setOptions(wizard()->options() | QWizard::NoCancelButtonOnLastPage); + } + + if (!initialized) { + connect(ui->restartWizardPB, &QAbstractButton::clicked, + this, [this]() { + restartAtEnterDetailsPage(); + }); + } + initialized = true; +} + +bool ResultPage::isError() const +{ + return !ui->errorTB->document()->isEmpty(); +} + +bool ResultPage::isComplete() const +{ + return !isError(); +} + +Key ResultPage::key() const +{ + return KeyCache::instance()->findByFingerprint(fingerprint().toLatin1().constData()); +} + +void ResultPage::slotSaveRequestToFile() +{ + QString fileName = FileDialog::getSaveFileName(this, i18nc("@title", "Save Request"), + QStringLiteral("imp"), i18n("PKCS#10 Requests (*.p10)")); + if (fileName.isEmpty()) { + return; + } + if (!fileName.endsWith(QLatin1String(".p10"), Qt::CaseInsensitive)) { + fileName += QLatin1String(".p10"); + } + QFile src(QUrl(url()).toLocalFile()); + if (!src.copy(fileName)) + KMessageBox::error(this, + xi18nc("@info", + "Could not copy temporary file %1 " + "to file %2: %3", + src.fileName(), fileName, src.errorString()), + i18nc("@title", "Error Saving Request")); + else + KMessageBox::information(this, + xi18nc("@info", + "Successfully wrote request to %1." + "You should now send the request to the Certification Authority (CA).", + fileName), + i18nc("@title", "Request Saved")); +} + +void ResultPage::slotSendRequestByEMail() +{ + if (pgp()) { + return; + } + const KConfigGroup config(KSharedConfig::openConfig(), "CertificateCreationWizard"); + invokeMailer(config.readEntry("CAEmailAddress"), // to + i18n("Please process this certificate."), // subject + i18n("Please process this certificate and inform the sender about the location to fetch the resulting certificate.\n\nThanks,\n"), // body + QUrl(url()).toLocalFile()); // attachment +} + +void ResultPage::slotSendCertificateByEMail() +{ + if (!pgp() || exportCertificateCommand) { + return; + } + auto cmd = new ExportCertificateCommand(key()); + connect(cmd, &ExportCertificateCommand::finished, this, &ResultPage::slotSendCertificateByEMailContinuation); + cmd->setOpenPGPFileName(tmpDir().absoluteFilePath(fingerprint() + QLatin1String(".asc"))); + cmd->start(); + exportCertificateCommand = cmd; +} + +void ResultPage::slotSendCertificateByEMailContinuation() +{ + if (!exportCertificateCommand) { + return; + } + // ### better error handling? + const QString fileName = exportCertificateCommand->openPGPFileName(); + qCDebug(KLEOPATRA_LOG) << "fileName" << fileName; + exportCertificateCommand = nullptr; + if (fileName.isEmpty()) { + return; + } + invokeMailer(QString(), // to + i18n("My new public OpenPGP key"), // subject + i18n("Please find attached my new public OpenPGP key."), // body + fileName); +} + +void ResultPage::invokeMailer(const QString &to, const QString &subject, const QString &body, const QString &attachment) +{ + qCDebug(KLEOPATRA_LOG) << "to:" << to << "subject:" << subject + << "body:" << body << "attachment:" << attachment; + + // RFC 2368 says body's linebreaks need to be encoded as + // "%0D%0A", so normalize body to CRLF: + //body.replace(QLatin1Char('\n'), QStringLiteral("\r\n")).remove(QStringLiteral("\r\r")); + + QUrlQuery query; + query.addQueryItem(QStringLiteral("subject"), subject); + query.addQueryItem(QStringLiteral("body"), body); + if (!attachment.isEmpty()) { + query.addQueryItem(QStringLiteral("attach"), attachment); + } + QUrl url; + url.setScheme(QStringLiteral("mailto")); + url.setQuery(query); + qCDebug(KLEOPATRA_LOG) << "openUrl" << url; + QDesktopServices::openUrl(url); + KMessageBox::information(this, + xi18nc("@info", + "Kleopatra tried to send a mail via your default mail client." + "Some mail clients are known not to support attachments when invoked this way." + "If your mail client does not have an attachment, then drag the Kleopatra icon and drop it on the message compose window of your mail client." + "If that does not work, either, save the request to a file, and then attach that."), + i18nc("@title", "Sending Mail"), + QStringLiteral("newcertificatewizard-mailto-troubles")); +} + +void ResultPage::slotUploadCertificateToDirectoryServer() +{ + if (pgp()) { + (new ExportOpenPGPCertsToServerCommand(key()))->start(); + } +} + +void ResultPage::slotBackupCertificate() +{ + if (pgp()) { + (new ExportSecretKeyCommand(key()))->start(); + } +} + +void ResultPage::slotCreateRevocationRequest() +{ + +} + +void ResultPage::slotCreateSigningCertificate() +{ + if (successfullyCreatedSigningCertificate) { + return; + } + toggleSignEncryptAndRestart(); +} + +void ResultPage::slotCreateEncryptionCertificate() +{ + if (successfullyCreatedEncryptionCertificate) { + return; + } + toggleSignEncryptAndRestart(); +} + +void ResultPage::toggleSignEncryptAndRestart() +{ + if (!wizard()) { + return; + } + if (KMessageBox::warningContinueCancel( + this, + i18nc("@info", + "This operation will delete the certification request. " + "Please make sure that you have sent or saved it before proceeding."), + i18nc("@title", "Certification Request About To Be Deleted")) != KMessageBox::Continue) { + return; + } + const bool sign = signingAllowed(); + const bool encr = encryptionAllowed(); + setField(QStringLiteral("signingAllowed"), !sign); + setField(QStringLiteral("encryptionAllowed"), !encr); + restartAtEnterDetailsPage(); +} diff --git a/src/newcertificatewizard/resultpage_p.h b/src/newcertificatewizard/resultpage_p.h new file mode 100644 index 000000000..558e312b3 --- /dev/null +++ b/src/newcertificatewizard/resultpage_p.h @@ -0,0 +1,65 @@ +/* -*- mode: c++; c-basic-offset:4 -*- + newcertificatewizard/resultpage_p.h + + This file is part of Kleopatra, the KDE keymanager + SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB + SPDX-FileCopyrightText: 2016, 2017 Bundesamt für Sicherheit in der Informationstechnik + SPDX-FileContributor: Intevation GmbH + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include "wizardpage_p.h" + +namespace GpgME +{ +class Key; +} +namespace Kleo +{ +class ExportCertificateCommand; +} +namespace Kleo::NewCertificateUi +{ +class Ui_ResultPage; + +class ResultPage : public WizardPage +{ + Q_OBJECT +public: + explicit ResultPage(QWidget *p = nullptr); + ~ResultPage() override; + + void initializePage() override; + bool isError() const; + bool isComplete() const override; + +private: + GpgME::Key key() const; + +private Q_SLOTS: + void slotSaveRequestToFile(); + void slotSendRequestByEMail(); + void slotSendCertificateByEMail(); + void slotSendCertificateByEMailContinuation(); + void invokeMailer(const QString &to, const QString &subject, const QString &body, const QString &attachment); + void slotUploadCertificateToDirectoryServer(); + void slotBackupCertificate(); + void slotCreateRevocationRequest(); + void slotCreateSigningCertificate(); + void slotCreateEncryptionCertificate(); + +private: + void toggleSignEncryptAndRestart(); + +private: + std::unique_ptr ui; + bool initialized : 1; + bool successfullyCreatedSigningCertificate : 1; + bool successfullyCreatedEncryptionCertificate : 1; + QPointer exportCertificateCommand; +}; + +}