diff --git a/src/commands/changepincommand.cpp b/src/commands/changepincommand.cpp index 94ceb9ef2..5a05156fb 100644 --- a/src/commands/changepincommand.cpp +++ b/src/commands/changepincommand.cpp @@ -1,191 +1,220 @@ /* commands/changepincommand.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2020 g10 Code GmbH SPDX-FileContributor: Ingo Klöcker SPDX-License-Identifier: GPL-2.0-or-later */ #include "changepincommand.h" #include "cardcommand_p.h" +#include "smartcard/netkeycard.h" #include "smartcard/openpgpcard.h" #include "smartcard/pivcard.h" #include "smartcard/readerstatus.h" #include #include #include "kleopatra_debug.h" using namespace Kleo; using namespace Kleo::Commands; using namespace Kleo::SmartCard; using namespace GpgME; class ChangePinCommand::Private : public CardCommand::Private { friend class ::Kleo::Commands::ChangePinCommand; ChangePinCommand *q_func() const { return static_cast(q); } public: explicit Private(ChangePinCommand *qq, const std::string &serialNumber, const std::string &appName, QWidget *p); ~Private(); void init(); private: void slotResult(const Error &err); private: void changePin(); private: std::string appName; std::string keyRef; ChangePinMode mode = NormalMode; }; ChangePinCommand::Private *ChangePinCommand::d_func() { return static_cast(d.get()); } const ChangePinCommand::Private *ChangePinCommand::d_func() const { return static_cast(d.get()); } #define d d_func() #define q q_func() ChangePinCommand::Private::Private(ChangePinCommand *qq, const std::string &serialNumber, const std::string &appName_, QWidget *p) : CardCommand::Private(qq, serialNumber, p) , appName(appName_) { } ChangePinCommand::Private::~Private() { qCDebug(KLEOPATRA_LOG) << "ChangePinCommand::Private::~Private()"; } ChangePinCommand::ChangePinCommand(const std::string &serialNumber, const std::string &appName, QWidget *p) : CardCommand(new Private(this, serialNumber, appName, p)) { d->init(); } void ChangePinCommand::Private::init() { } ChangePinCommand::~ChangePinCommand() { qCDebug(KLEOPATRA_LOG) << "ChangePinCommand::~ChangePinCommand()"; } void ChangePinCommand::setKeyRef(const std::string &keyRef) { d->keyRef = keyRef; } void ChangePinCommand::setMode(ChangePinMode mode) { d->mode = mode; } void ChangePinCommand::doStart() { qCDebug(KLEOPATRA_LOG) << "ChangePinCommand::doStart()"; d->changePin(); } void ChangePinCommand::doCancel() { } void ChangePinCommand::Private::changePin() { qCDebug(KLEOPATRA_LOG) << "ChangePinCommand::changePin()"; const auto card = SmartCard::ReaderStatus::instance()->getCard(serialNumber(), appName); if (!card) { error(i18n("Failed to find the smartcard with the serial number: %1", QString::fromStdString(serialNumber()))); finished(); return; } QByteArrayList command; command << "SCD PASSWD"; if (mode == ResetMode) { command << "--reset"; } else if (mode == NullPinMode) { command << "--nullpin"; } command << QByteArray::fromStdString(keyRef); ReaderStatus::mutableInstance()->startSimpleTransaction(card, command.join(' '), q, "slotResult"); } namespace { static QString errorMessage(const std::string &keyRef, ChangePinCommand::ChangePinMode mode, const QString &errorText) { // see cmd_passwd() in gpg-card.c if (keyRef == PIVCard::pukKeyRef()) { return i18nc("@info", "Changing the PUK failed: %1", errorText); } if (keyRef == OpenPGPCard::resetCodeKeyRef()) { return i18nc("@info", "Unblocking the PIN failed: %1", errorText); } if (keyRef == OpenPGPCard::adminPinKeyRef()) { return i18nc("@info", "Changing the Admin PIN failed: %1", errorText); } if (keyRef == OpenPGPCard::resetCodeKeyRef() && mode == ChangePinCommand::ResetMode) { return i18nc("@info", "Changing the Reset Code failed: %1", errorText); } + if (keyRef == NetKeyCard::nksPinKeyRef()) { + if (mode == ChangePinCommand::NullPinMode) { + return i18nc("@info", "Setting the NKS PIN failed: %1", errorText); + } else { + return i18nc("@info", "Changing the NKS PIN failed: %1", errorText); + } + } + if (keyRef == NetKeyCard::sigGPinKeyRef()) { + if (mode == ChangePinCommand::NullPinMode) { + return i18nc("@info", "Setting the SigG PIN failed: %1", errorText); + } else { + return i18nc("@info", "Changing the SigG PIN failed: %1", errorText); + } + } return i18nc("@info", "Changing the PIN failed: %1", errorText); } static QString successMessage(const std::string &keyRef, ChangePinCommand::ChangePinMode mode) { // see cmd_passwd() in gpg-card.c if (keyRef == PIVCard::pukKeyRef()) { return i18nc("@info", "PUK successfully changed."); } if (keyRef == OpenPGPCard::resetCodeKeyRef()) { return i18nc("@info", "Unblocked and set a new PIN successfully."); } if (keyRef == OpenPGPCard::adminPinKeyRef()) { return i18nc("@info", "Admin PIN changed successfully."); } if (keyRef == OpenPGPCard::resetCodeKeyRef() && mode == ChangePinCommand::ResetMode) { return i18nc("@info", "Reset Code changed successfully."); } + if (keyRef == NetKeyCard::nksPinKeyRef()) { + if (mode == ChangePinCommand::NullPinMode) { + return i18nc("@info", "NKS PIN set successfully."); + } else { + return i18nc("@info", "NKS PIN changed successfully."); + } + } + if (keyRef == NetKeyCard::sigGPinKeyRef()) { + if (mode == ChangePinCommand::NullPinMode) { + return i18nc("@info", "SigG PIN set successfully."); + } else { + return i18nc("@info", "SigG PIN changed successfully."); + } + } return i18nc("@info", "PIN changed successfully."); } } void ChangePinCommand::Private::slotResult(const GpgME::Error& err) { qCDebug(KLEOPATRA_LOG) << "ChangePinCommand::slotResult():" << err.asString() << "(" << err.code() << ")"; if (err) { error(errorMessage(keyRef, mode, QString::fromLatin1(err.asString())), i18nc("@title", "Error")); } else if (!err.isCanceled()) { information(successMessage(keyRef, mode), i18nc("@title", "Success")); ReaderStatus::mutableInstance()->updateStatus(); } finished(); } #undef d #undef q #include "moc_changepincommand.cpp" diff --git a/src/view/nullpinwidget.cpp b/src/view/nullpinwidget.cpp index aa1dc1c1e..9a8f10036 100644 --- a/src/view/nullpinwidget.cpp +++ b/src/view/nullpinwidget.cpp @@ -1,130 +1,102 @@ /* view/nullpinwidget.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2017 Intevation GmbH SPDX-License-Identifier: GPL-2.0-or-later */ #include "nullpinwidget.h" #include "kleopatra_debug.h" #include "smartcard/netkeycard.h" -#include "smartcard/readerstatus.h" -#include +#include "commands/changepincommand.h" #include #include #include #include #include #include using namespace Kleo; +using namespace Kleo::Commands; using namespace Kleo::SmartCard; NullPinWidget::NullPinWidget(QWidget *parent) : QWidget(parent) { const auto nullTitle = i18nc("NullPIN is a word that is used all over in the netkey " "documentation and should be understandable by Netkey cardholders", "The NullPIN is still active on this card."); const auto nullDescription = i18n("You need to set a PIN before you can use the certificates."); const auto descriptionLbl = new QLabel(QStringLiteral("%1
%2").arg(nullTitle, nullDescription)); auto vLay = new QVBoxLayout(this); vLay->addWidget(descriptionLbl, 0, Qt::AlignCenter); mNKSBtn = new QPushButton(i18nc("NKS is an identifier for a type of keys on a NetKey card", "Set NKS PIN")); mSigGBtn = new QPushButton(i18nc("SigG is an identifier for a type of keys on a NetKey card", "Set SigG PIN")); connect(mNKSBtn, &QPushButton::clicked, this, [this] () { - doChangePin(false); + doChangePin(NetKeyCard::nksPinKeyRef()); }); connect(mSigGBtn, &QPushButton::clicked, this, [this] () { - doChangePin(true); + doChangePin(NetKeyCard::sigGPinKeyRef()); }); auto hLayBtn = new QHBoxLayout; hLayBtn->addStretch(1); hLayBtn->addWidget(mNKSBtn); hLayBtn->addWidget(mSigGBtn); hLayBtn->addStretch(1); vLay->addLayout(hLayBtn); } void NullPinWidget::setSerialNumber(const std::string &serialNumber) { mSerialNumber = serialNumber; } -void NullPinWidget::doChangePin(bool sigG) +void NullPinWidget::doChangePin(const std::string &keyRef) { parentWidget()->setEnabled(false); auto ret = KMessageBox::warningContinueCancel(this, i18n("Setting a PIN is required but can't be reverted.") + QStringLiteral("

%1

%2

").arg( i18n("If you proceed you will be asked to enter a new PIN " "and later to repeat that PIN.")).arg( i18n("It will not be possible to recover the " "card if the PIN has been entered wrongly more than 2 times.")), i18n("Set initial PIN"), KStandardGuiItem::cont(), KStandardGuiItem::cancel()); if (ret != KMessageBox::Continue) { parentWidget()->setEnabled(true); return; } - const auto nksCard = ReaderStatus::instance()->getCard(mSerialNumber); - if (!nksCard) { - KMessageBox::error(this, i18n("Failed to find the NetKey card with the serial number: %1", QString::fromStdString(mSerialNumber))); - parentWidget()->setEnabled(true); - return; - } - - if (sigG) { - ReaderStatus::mutableInstance()->startSimpleTransaction( - nksCard, "SCD PASSWD --nullpin PW1.CH.SIG", this, "setSigGPinSettingResult"); - } else { - ReaderStatus::mutableInstance()->startSimpleTransaction( - nksCard, "SCD PASSWD --nullpin PW1.CH", this, "setNksPinSettingResult"); - } -} - -void NullPinWidget::handleResult(const GpgME::Error &err) -{ - if (err) { - KMessageBox::error(this, i18nc("@info", - "Failed to set PIN: %1", QString::fromLatin1(err.asString())), - i18nc("@title", "Error")); - } else if (!err.isCanceled()) { - ReaderStatus::mutableInstance()->updateStatus(); - } - parentWidget()->setEnabled(true); + auto cmd = new ChangePinCommand(mSerialNumber, NetKeyCard::AppName, this); + connect(cmd, &ChangePinCommand::finished, + this, [this]() { + this->parentWidget()->setEnabled(true); + }); + cmd->setKeyRef(keyRef); + cmd->setMode(ChangePinCommand::NullPinMode); + cmd->start(); } void NullPinWidget::setSigGVisible(bool val) { mSigGBtn->setVisible(val); } void NullPinWidget::setNKSVisible(bool val) { mNKSBtn->setVisible(val); } - -void NullPinWidget::setSigGPinSettingResult(const GpgME::Error &err) -{ - handleResult(err); -} - -void NullPinWidget::setNksPinSettingResult(const GpgME::Error &err) -{ - handleResult(err); -} diff --git a/src/view/nullpinwidget.h b/src/view/nullpinwidget.h index c117963cd..1eaf07bfa 100644 --- a/src/view/nullpinwidget.h +++ b/src/view/nullpinwidget.h @@ -1,49 +1,44 @@ #ifndef VIEW_NULLPINWIDGET_H #define VIEW_NULLPINWIDGET_H /* view/nullpinwidget.h This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2017 Intevation GmbH SPDX-License-Identifier: GPL-2.0-or-later */ #include class QPushButton; namespace GpgME { class Error; } // namespace GpgME namespace Kleo { class NullPinWidget: public QWidget { Q_OBJECT public: explicit NullPinWidget(QWidget *parent = nullptr); void setSerialNumber(const std::string &serialNumber); void setSigGVisible(bool val); void setNKSVisible(bool val); private: - void doChangePin(bool sigG); - void handleResult(const GpgME::Error &err); - -private Q_SLOTS: - void setSigGPinSettingResult(const GpgME::Error &err); - void setNksPinSettingResult(const GpgME::Error &err); + void doChangePin(const std::string &keyRef); private: std::string mSerialNumber; QPushButton *mNKSBtn, *mSigGBtn; }; } // namespace Kleo #endif // VIEW_NULLPINWIDGET_H