File indexing completed on 2024-06-23 05:13:45
0001 /* -*- mode: c++; c-basic-offset:4 -*- 0002 commands/setinitialpincommand.cpp 0003 0004 This file is part of Kleopatra, the KDE keymanager 0005 SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include <config-kleopatra.h> 0011 0012 #include "cardcommand_p.h" 0013 #include "setinitialpincommand.h" 0014 0015 #include "dialogs/setinitialpindialog.h" 0016 0017 #include "smartcard/netkeycard.h" 0018 #include "smartcard/readerstatus.h" 0019 0020 #include <KLocalizedString> 0021 0022 using namespace Kleo; 0023 using namespace Kleo::Commands; 0024 using namespace Kleo::Dialogs; 0025 using namespace Kleo::SmartCard; 0026 using namespace GpgME; 0027 0028 class SetInitialPinCommand::Private : public CardCommand::Private 0029 { 0030 friend class ::Kleo::Commands::SetInitialPinCommand; 0031 SetInitialPinCommand *q_func() const 0032 { 0033 return static_cast<SetInitialPinCommand *>(q); 0034 } 0035 0036 public: 0037 explicit Private(SetInitialPinCommand *qq, const std::string &serialNumber); 0038 ~Private() override; 0039 0040 private: 0041 void init() 0042 { 0043 } 0044 0045 void ensureDialogCreated() 0046 { 0047 if (dialog) { 0048 return; 0049 } 0050 0051 auto dlg = new SetInitialPinDialog; 0052 applyWindowID(dlg); 0053 dlg->setAttribute(Qt::WA_DeleteOnClose); 0054 dlg->setWindowTitle(i18nc("@title:window", "Set Initial Pin")); 0055 0056 connect(dlg, &SetInitialPinDialog::nksPinRequested, q_func(), [this]() { 0057 slotNksPinRequested(); 0058 }); 0059 connect(dlg, &SetInitialPinDialog::sigGPinRequested, q_func(), [this]() { 0060 slotSigGPinRequested(); 0061 }); 0062 connect(dlg, &QDialog::rejected, q_func(), [this]() { 0063 slotDialogRejected(); 0064 }); 0065 connect(dlg, &QDialog::accepted, q_func(), [this]() { 0066 slotDialogAccepted(); 0067 }); 0068 0069 dialog = dlg; 0070 } 0071 0072 void ensureDialogVisible() 0073 { 0074 ensureDialogCreated(); 0075 if (dialog->isVisible()) { 0076 dialog->raise(); 0077 } else { 0078 dialog->show(); 0079 } 0080 } 0081 0082 private: 0083 void setInitialPin(const char *pinRef, const ReaderStatus::TransactionFunc &resultSlot) 0084 { 0085 const auto nksCard = ReaderStatus::instance()->getCard<NetKeyCard>(serialNumber()); 0086 if (!nksCard) { 0087 error(i18n("Failed to find the NetKey card with the serial number: %1", QString::fromStdString(serialNumber()))); 0088 return; 0089 } 0090 0091 const QByteArray command = QByteArray("SCD PASSWD --nullpin ") + pinRef; 0092 ReaderStatus::mutableInstance()->startSimpleTransaction(nksCard, command, dialog, resultSlot); 0093 } 0094 0095 void slotNksPinRequested() 0096 { 0097 setInitialPin("PW1.CH", [this](const GpgME::Error &error) { 0098 dialog->setNksPinSettingResult(error); 0099 }); 0100 } 0101 0102 void slotSigGPinRequested() 0103 { 0104 setInitialPin("PW1.CH.SIG", [this](const GpgME::Error &error) { 0105 dialog->setSigGPinSettingResult(error); 0106 }); 0107 } 0108 0109 void slotDialogRejected() 0110 { 0111 if (dialog->isComplete()) { 0112 slotDialogAccepted(); 0113 } else { 0114 canceled(); 0115 } 0116 } 0117 void slotDialogAccepted() 0118 { 0119 ReaderStatus::mutableInstance()->updateStatus(); 0120 finished(); 0121 } 0122 0123 private: 0124 mutable QPointer<SetInitialPinDialog> dialog; 0125 }; 0126 0127 SetInitialPinCommand::Private *SetInitialPinCommand::d_func() 0128 { 0129 return static_cast<Private *>(d.get()); 0130 } 0131 const SetInitialPinCommand::Private *SetInitialPinCommand::d_func() const 0132 { 0133 return static_cast<const Private *>(d.get()); 0134 } 0135 0136 #define q q_func() 0137 #define d d_func() 0138 0139 SetInitialPinCommand::Private::Private(SetInitialPinCommand *qq, const std::string &serialNumber) 0140 : CardCommand::Private(qq, serialNumber, nullptr) 0141 , dialog() 0142 { 0143 } 0144 0145 SetInitialPinCommand::Private::~Private() 0146 { 0147 } 0148 0149 SetInitialPinCommand::SetInitialPinCommand(const std::string &serialNumber) 0150 : CardCommand(new Private(this, serialNumber)) 0151 { 0152 d->init(); 0153 } 0154 0155 SetInitialPinCommand::~SetInitialPinCommand() 0156 { 0157 } 0158 0159 QDialog *SetInitialPinCommand::dialog() 0160 { 0161 d->ensureDialogCreated(); 0162 return d->dialog; 0163 } 0164 0165 void SetInitialPinCommand::doStart() 0166 { 0167 d->ensureDialogCreated(); 0168 0169 const auto nksCard = ReaderStatus::instance()->getCard<NetKeyCard>(d->serialNumber()); 0170 if (!nksCard) { 0171 d->error(i18n("Failed to find the NetKey card with the serial number: %1", QString::fromStdString(d->serialNumber()))); 0172 d->dialog->close(); 0173 finished(); 0174 return; 0175 } 0176 0177 const std::vector<Card::PinState> pinStates = nksCard->pinStates(); 0178 d->dialog->setNksPinPresent(pinStates.size() >= 1 && pinStates[0] != Card::NullPin); 0179 d->dialog->setSigGPinPresent(pinStates.size() >= 3 && pinStates[2] != Card::NullPin); 0180 0181 d->ensureDialogVisible(); 0182 } 0183 0184 void SetInitialPinCommand::doCancel() 0185 { 0186 if (d->dialog) { 0187 d->dialog->close(); 0188 } 0189 } 0190 0191 #undef q_func 0192 #undef d_func 0193 0194 #include "moc_setinitialpincommand.cpp"