Page MenuHome GnuPG

No OneTemporary

diff --git a/src/view/netkeywidget.cpp b/src/view/netkeywidget.cpp
index bb6c1c431..d5bad15b7 100644
--- a/src/view/netkeywidget.cpp
+++ b/src/view/netkeywidget.cpp
@@ -1,248 +1,253 @@
/* view/netkeywidget.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2017 Intevation GmbH
Kleopatra 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 2 of the License, or
(at your option) any later version.
Kleopatra 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#include "netkeywidget.h"
#include "nullpinwidget.h"
#include "keytreeview.h"
#include "kleopatraapplication.h"
#include "systrayicon.h"
#include "kleopatra_debug.h"
#include "smartcard/netkeycard.h"
#include "smartcard/readerstatus.h"
#include "commands/learncardkeyscommand.h"
#include "commands/detailscommand.h"
#include <Libkleo/KeyListModel>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QScrollArea>
#include <QPushButton>
#include <QTreeView>
#include <KLocalizedString>
#include <KMessageBox>
using namespace Kleo;
using namespace Kleo::SmartCard;
using namespace Kleo::Commands;
-NetKeyWidget::NetKeyWidget() :
- mSerialNumber(new QLabel),
- mVersionLabel(new QLabel),
- mLearnKeysLabel(new QLabel),
- mErrorLabel(new QLabel),
+NetKeyWidget::NetKeyWidget(QWidget *parent) :
+ QWidget(parent),
+ mSerialNumber(new QLabel(this)),
+ mVersionLabel(new QLabel(this)),
+ mLearnKeysLabel(new QLabel(this)),
+ mErrorLabel(new QLabel(this)),
mNullPinWidget(new NullPinWidget()),
- mLearnKeysBtn(new QPushButton),
- mChangeNKSPINBtn(new QPushButton),
- mChangeSigGPINBtn(new QPushButton),
+ mLearnKeysBtn(new QPushButton(this)),
+ mChangeNKSPINBtn(new QPushButton(this)),
+ mChangeSigGPINBtn(new QPushButton(this)),
mTreeView(new KeyTreeView(this)),
mArea(new QScrollArea)
{
auto vLay = new QVBoxLayout;
// Set up the scroll are
mArea->setFrameShape(QFrame::NoFrame);
mArea->setWidgetResizable(true);
auto mAreaWidget = new QWidget;
mAreaWidget->setLayout(vLay);
mArea->setWidget(mAreaWidget);
auto scrollLay = new QVBoxLayout(this);
scrollLay->addWidget(mArea);
// Add general widgets
mVersionLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
vLay->addWidget(mVersionLabel, 0, Qt::AlignLeft);
mSerialNumber->setTextInteractionFlags(Qt::TextBrowserInteraction);
auto hLay1 = new QHBoxLayout;
hLay1->addWidget(new QLabel(i18n("Serial number:")));
hLay1->addWidget(mSerialNumber);
hLay1->addStretch(1);
vLay->addLayout(hLay1);
vLay->addWidget(mNullPinWidget);
auto line1 = new QFrame();
line1->setFrameShape(QFrame::HLine);
vLay->addWidget(line1);
vLay->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Certificates:"))), 0, Qt::AlignLeft);
mLearnKeysLabel = new QLabel(i18n("There are unknown certificates on this card."));
mLearnKeysBtn->setText(i18nc("@action", "Load Certificates"));
connect(mLearnKeysBtn, &QPushButton::clicked, this, [this] () {
mLearnKeysBtn->setEnabled(false);
auto cmd = new LearnCardKeysCommand(GpgME::CMS);
cmd->setParentWidget(this);
cmd->start();
auto icon = KleopatraApplication::instance()->sysTrayIcon();
if (icon) {
icon->setLearningInProgress(true);
}
connect(cmd, &Command::finished, this, [icon] () {
ReaderStatus::mutableInstance()->updateStatus();
icon->setLearningInProgress(false);
});
});
auto hLay2 = new QHBoxLayout;
hLay2->addWidget(mLearnKeysLabel);
hLay2->addWidget(mLearnKeysBtn);
hLay2->addStretch(1);
vLay->addLayout(hLay2);
mErrorLabel->setVisible(false);
vLay->addWidget(mErrorLabel);
// The certificate view
mTreeView->setHierarchicalModel(AbstractKeyListModel::createHierarchicalKeyListModel(mTreeView));
mTreeView->setHierarchicalView(true);
connect(mTreeView->view(), &QAbstractItemView::doubleClicked, this, [this] (const QModelIndex &idx) {
const auto klm = dynamic_cast<KeyListModelInterface *> (mTreeView->view()->model());
if (!klm) {
qCDebug(KLEOPATRA_LOG) << "Unhandled Model: " << mTreeView->view()->model()->metaObject()->className();
return;
}
auto cmd = new DetailsCommand(klm->key(idx), nullptr);
cmd->setParentWidget(this);
cmd->start();
});
vLay->addWidget(mTreeView);
// The action area
auto line2 = new QFrame();
line2->setFrameShape(QFrame::HLine);
vLay->addWidget(line2);
vLay->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Actions:"))), 0, Qt::AlignLeft);
mChangeNKSPINBtn->setText(i18nc("NKS is an identifier for a type of keys on a NetKey card", "Change NKS PIN"));
mChangeSigGPINBtn->setText(i18nc("SigG is an identifier for a type of keys on a NetKey card", "Change SigG PIN"));
connect(mChangeNKSPINBtn, &QPushButton::clicked, this, [this] () {
mChangeNKSPINBtn->setEnabled(false);
doChangePin(false);
});
connect(mChangeSigGPINBtn, &QPushButton::clicked, this, [this] () {
mChangeSigGPINBtn->setEnabled(false);
doChangePin(true);
});
auto hLay3 = new QHBoxLayout();
hLay3->addWidget(mChangeNKSPINBtn);
hLay3->addWidget(mChangeSigGPINBtn);
hLay3->addStretch(1);
vLay->addLayout(hLay3);
vLay->addStretch(1);
}
+NetKeyWidget::~NetKeyWidget()
+{
+}
+
void NetKeyWidget::setCard(const NetKeyCard* card)
{
mVersionLabel->setText(i18nc("1 is a Version number", "NetKey v%1 Card", card->appVersion()));
mSerialNumber->setText(QString::fromStdString(card->serialNumber()));
/* According to users of NetKey Cards it is fairly uncommon
* to use SigG Certificates at all. So it should be optional to set the pins. */
mNullPinWidget->setVisible(card->hasNKSNullPin() /*|| card->hasSigGNullPin()*/);
mNullPinWidget->setSigGVisible(false/*card->hasSigGNullPin()*/);
mNullPinWidget->setNKSVisible(card->hasNKSNullPin());
mChangeNKSPINBtn->setEnabled(!card->hasNKSNullPin());
if (card->hasSigGNullPin()) {
mChangeSigGPINBtn->setText(i18nc("SigG is an identifier for a type of keys on a NetKey card",
"Set SigG PIN"));
} else {
mChangeSigGPINBtn->setText(i18nc("SigG is an identifier for a type of keys on a NetKey card",
"Change SigG PIN"));
}
mLearnKeysBtn->setEnabled(true);
mLearnKeysBtn->setVisible(card->canLearnKeys());
mTreeView->setVisible(!card->canLearnKeys());
mLearnKeysLabel->setVisible(card->canLearnKeys());
const auto errMsg = card->errorMsg();
if (!errMsg.isEmpty()) {
mErrorLabel->setText(QStringLiteral("<b>%1:</b> %2").arg(i18n("Error"), errMsg));
mErrorLabel->setVisible(true);
} else {
mErrorLabel->setVisible(false);
}
const auto keys = card->keys();
mTreeView->setKeys(keys);
}
void NetKeyWidget::handleResult(const GpgME::Error &err, QPushButton *btn)
{
btn->setEnabled(true);
if (err.isCanceled()) {
return;
}
if (err) {
KMessageBox::error(this, i18nc("@info",
"Failed to set PIN: %1", QString::fromLatin1(err.asString())),
i18nc("@title", "Error"));
return;
}
}
void NetKeyWidget::setSigGPinSettingResult(const GpgME::Error &err)
{
handleResult(err, mChangeSigGPINBtn);
}
void NetKeyWidget::setNksPinSettingResult(const GpgME::Error &err)
{
handleResult(err, mChangeNKSPINBtn);
}
void NetKeyWidget::doChangePin(bool sigG)
{
if (sigG) {
ReaderStatus::mutableInstance()
->startSimpleTransaction("SCD PASSWD PW1.CH.SIG",
this, "setSigGPinSettingResult");
} else {
ReaderStatus::mutableInstance()
->startSimpleTransaction("SCD PASSWD PW1.CH",
this, "setNksPinSettingResult");
}
}
diff --git a/src/view/netkeywidget.h b/src/view/netkeywidget.h
index f83e2387f..16fe9e520 100644
--- a/src/view/netkeywidget.h
+++ b/src/view/netkeywidget.h
@@ -1,83 +1,84 @@
/* view/netkeywidget.h
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2017 Intevation GmbH
Kleopatra 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 2 of the License, or
(at your option) any later version.
Kleopatra 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#ifndef VIEW_NETKEYWIDGET_H
#define VIEW_NETKEYWIDGET_H
#include <QWidget>
#include <gpgme++/error.h>
#include <string>
class QLabel;
class QPushButton;
class QScrollArea;
namespace Kleo
{
class NullPinWidget;
class KeyTreeView;
namespace SmartCard
{
class NetKeyCard;
} // namespace SmartCard
class NetKeyWidget: public QWidget
{
Q_OBJECT
public:
- NetKeyWidget();
+ explicit NetKeyWidget(QWidget *parent = nullptr);
+ ~NetKeyWidget();
void setCard(const SmartCard::NetKeyCard* card);
private:
void handleResult(const GpgME::Error &err, QPushButton *btn);
void doChangePin(bool sigG);
private Q_SLOTS:
void setSigGPinSettingResult(const GpgME::Error &err);
void setNksPinSettingResult(const GpgME::Error &err);
private:
QLabel *mSerialNumber,
*mVersionLabel,
*mLearnKeysLabel,
*mErrorLabel;
NullPinWidget *mNullPinWidget;
QPushButton *mLearnKeysBtn,
*mChangeNKSPINBtn,
*mChangeSigGPINBtn;
KeyTreeView *mTreeView;
QScrollArea *mArea;
};
} // namespace Kleo
#endif // VIEW_NETKEYWIDGET_H
diff --git a/src/view/nullpinwidget.cpp b/src/view/nullpinwidget.cpp
index 7d2c1094c..36820e86d 100644
--- a/src/view/nullpinwidget.cpp
+++ b/src/view/nullpinwidget.cpp
@@ -1,149 +1,150 @@
/* view/nullpinwidget.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2017 Intevation GmbH
Kleopatra 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 2 of the License, or
(at your option) any later version.
Kleopatra 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#include "nullpinwidget.h"
#include "kleopatra_debug.h"
#include "smartcard/readerstatus.h"
#include <gpgme++/error.h>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <KLocalizedString>
#include <KMessageBox>
using namespace Kleo;
using namespace Kleo::SmartCard;
-NullPinWidget::NullPinWidget()
+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("<b>%1</b><br/>%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] () {
mNKSBtn->setEnabled(false);
doChangePin(false);
});
connect(mSigGBtn, &QPushButton::clicked, this, [this] () {
mSigGBtn->setEnabled(false);
doChangePin(true);
});
auto hLayBtn = new QHBoxLayout;
hLayBtn->addStretch(1);
hLayBtn->addWidget(mNKSBtn);
hLayBtn->addWidget(mSigGBtn);
hLayBtn->addStretch(1);
vLay->addLayout(hLayBtn);
}
void NullPinWidget::doChangePin(bool sigG)
{
auto ret = KMessageBox::warningContinueCancel(this,
i18n("Setting a PIN is required but <b>can't be reverted</b>.") +
QStringLiteral("<p>%1</p><p>%2</p>").arg(
i18n("If you proceed you will be asked to enter a new PIN "
"and later to repeat that PIN.")).arg(
i18n("It will <b>not be possible</b> 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) {
return;
}
if (sigG) {
ReaderStatus::mutableInstance()
->startSimpleTransaction("SCD PASSWD --nullpin PW1.CH.SIG",
this, "setSigGPinSettingResult");
} else {
ReaderStatus::mutableInstance()
->startSimpleTransaction("SCD PASSWD --nullpin PW1.CH",
this, "setNksPinSettingResult");
}
}
void NullPinWidget::handleResult(const GpgME::Error &err, QPushButton *btn)
{
btn->setEnabled(true);
if (err.isCanceled()) {
return;
}
if (err) {
KMessageBox::error(this, i18nc("@info",
"Failed to set PIN: %1", QString::fromLatin1(err.asString())),
i18nc("@title", "Error"));
return;
}
btn->setVisible(false);
if (!mNKSBtn->isVisible() && !mSigGBtn->isVisible()) {
// Both pins are set, we can hide.
setVisible(false);
}
}
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, mSigGBtn);
}
void NullPinWidget::setNksPinSettingResult(const GpgME::Error &err)
{
handleResult(err, mNKSBtn);
}
diff --git a/src/view/nullpinwidget.h b/src/view/nullpinwidget.h
index 5cd9b36b5..25168334e 100644
--- a/src/view/nullpinwidget.h
+++ b/src/view/nullpinwidget.h
@@ -1,70 +1,70 @@
#ifndef VIEW_NULLPINWIDGET_H
#define VIEW_NULLPINWIDGET_H
/* view/nullpinwidget.h
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2017 Intevation GmbH
Kleopatra 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 2 of the License, or
(at your option) any later version.
Kleopatra 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#include <QWidget>
class QPushButton;
namespace GpgME
{
class Error;
} // namespace GpgME
namespace Kleo
{
class NullPinWidget: public QWidget
{
Q_OBJECT
public:
- NullPinWidget();
+ explicit NullPinWidget(QWidget *parent = nullptr);
void setSigGVisible(bool val);
void setNKSVisible(bool val);
private:
void doChangePin(bool sigG);
void handleResult(const GpgME::Error &err, QPushButton *btn);
private Q_SLOTS:
void setSigGPinSettingResult(const GpgME::Error &err);
void setNksPinSettingResult(const GpgME::Error &err);
private:
QPushButton *mNKSBtn,
*mSigGBtn;
};
} // namespace Kleo
#endif // VIEW_NULLPINWIDGET_H
diff --git a/src/view/pgpcardwidget.cpp b/src/view/pgpcardwidget.cpp
index dc4b81a37..bbb9bc8cb 100644
--- a/src/view/pgpcardwidget.cpp
+++ b/src/view/pgpcardwidget.cpp
@@ -1,510 +1,511 @@
/* view/pgpcardwiget.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2017 by Bundesamt für Sicherheit in der Informationstechnik
Software engineering by Intevation GmbH
Kleopatra 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 2 of the License, or
(at your option) any later version.
Kleopatra 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#include "pgpcardwidget.h"
#include "kleopatra_debug.h"
#include "smartcard/openpgpcard.h"
#include "smartcard/readerstatus.h"
#include "dialogs/gencardkeydialog.h"
#include "utils/gnupg-helper.h"
#include <QProgressDialog>
#include <QThread>
#include <QScrollArea>
#include <QInputDialog>
#include <QFileDialog>
#include <QFileInfo>
#include <QGridLayout>
#include <QPushButton>
#include <QLabel>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <KLocalizedString>
#include <KMessageBox>
#include <Libkleo/KeyCache>
#include <Libkleo/Formatting>
#include <gpgme++/gpgmepp_version.h>
#include <gpgme++/data.h>
#include <gpgme++/context.h>
#include <QGpgME/DataProvider>
#if GPGMEPP_VERSION > 0x10801 // 1.8.1
// TODO remove ifdef once > 1.8.1 is required
#include <gpgme++/gpggencardkeyinteractor.h>
# define GPGME_CAN_GENCARDKEY
#endif
using namespace Kleo;
using namespace Kleo::SmartCard;
namespace {
#ifdef GPGME_CAN_GENCARDKEY
class GenKeyThread: public QThread
{
Q_OBJECT
public:
explicit GenKeyThread(const GenCardKeyDialog::KeyParams &params, const std::string &serial):
mSerial(serial),
mParams(params)
{
}
GpgME::Error error()
{
return mErr;
}
std::string bkpFile()
{
return mBkpFile;
}
protected:
void run() override {
GpgME::GpgGenCardKeyInteractor *ei = new GpgME::GpgGenCardKeyInteractor(mSerial);
ei->setKeySize(mParams.keysize);
ei->setNameUtf8(mParams.name.toStdString());
ei->setEmailUtf8(mParams.email.toStdString());
ei->setDoBackup(mParams.backup);
const auto ctx = std::shared_ptr<GpgME::Context> (GpgME::Context::createForProtocol(GpgME::OpenPGP));
QGpgME::QByteArrayDataProvider dp;
GpgME::Data data(&dp);
mErr = ctx->cardEdit(GpgME::Key(), std::unique_ptr<GpgME::EditInteractor> (ei), data);
mBkpFile = ei->backupFileName();
}
private:
GpgME::Error mErr;
std::string mSerial;
GenCardKeyDialog::KeyParams mParams;
std::string mBkpFile;
};
#endif
} // Namespace
-PGPCardWidget::PGPCardWidget():
- mSerialNumber(new QLabel),
- mCardHolderLabel(new QLabel),
- mVersionLabel(new QLabel),
- mSigningKey(new QLabel),
- mEncryptionKey(new QLabel),
- mAuthKey(new QLabel),
- mUrlLabel(new QLabel),
+PGPCardWidget::PGPCardWidget(QWidget *parent):
+ QWidget(parent),
+ mSerialNumber(new QLabel(this)),
+ mCardHolderLabel(new QLabel(this)),
+ mVersionLabel(new QLabel(this)),
+ mSigningKey(new QLabel(this)),
+ mEncryptionKey(new QLabel(this)),
+ mAuthKey(new QLabel(this)),
+ mUrlLabel(new QLabel(this)),
mCardIsEmpty(false)
{
auto grid = new QGridLayout;
int row = 0;
// Set up the scroll are
auto area = new QScrollArea;
area->setFrameShape(QFrame::NoFrame);
area->setWidgetResizable(true);
auto areaWidget = new QWidget;
auto areaVLay = new QVBoxLayout(areaWidget);
areaVLay->addLayout(grid);
areaVLay->addStretch(1);
area->setWidget(areaWidget);
auto myLayout = new QVBoxLayout(this);
myLayout->addWidget(area);
// Version and Serialnumber
grid->addWidget(mVersionLabel, row++, 0, 1, 2);
mVersionLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
grid->addWidget(new QLabel(i18n("Serial number:")), row, 0);
grid->addWidget(mSerialNumber, row++, 1);
mSerialNumber->setTextInteractionFlags(Qt::TextBrowserInteraction);
// Cardholder Row
grid->addWidget(new QLabel(i18nc("The owner of a smartcard. GnuPG refers to this as cardholder.",
"Cardholder:")), row, 0);
grid->addWidget(mCardHolderLabel, row, 1);
mCardHolderLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
auto nameButtton = new QPushButton;
nameButtton->setIcon(QIcon::fromTheme(QStringLiteral("cell_edit")));
nameButtton->setToolTip(i18n("Change"));
grid->addWidget(nameButtton, row++, 2);
connect(nameButtton, &QPushButton::clicked, this, &PGPCardWidget::changeNameRequested);
// URL Row
grid->addWidget(new QLabel(i18nc("The URL under which a public key that "
"corresponds to a smartcard can be downloaded",
"Pubkey URL:")), row, 0);
grid->addWidget(mUrlLabel, row, 1);
mUrlLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
auto urlButtton = new QPushButton;
urlButtton->setIcon(QIcon::fromTheme(QStringLiteral("cell_edit")));
urlButtton->setToolTip(i18n("Change"));
grid->addWidget(urlButtton, row++, 2);
connect(urlButtton, &QPushButton::clicked, this, &PGPCardWidget::changeUrlRequested);
// The keys
auto line1 = new QFrame();
line1->setFrameShape(QFrame::HLine);
grid->addWidget(line1, row++, 0, 1, 4);
grid->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Keys:"))), row++, 0);
grid->addWidget(new QLabel(i18n("Signature:")), row, 0);
grid->addWidget(mSigningKey, row++, 1);
mSigningKey->setTextInteractionFlags(Qt::TextBrowserInteraction);
grid->addWidget(new QLabel(i18n("Encryption:")), row, 0);
grid->addWidget(mEncryptionKey, row++, 1);
mEncryptionKey->setTextInteractionFlags(Qt::TextBrowserInteraction);
grid->addWidget(new QLabel(i18n("Authentication:")), row, 0);
grid->addWidget(mAuthKey, row++, 1);
mAuthKey->setTextInteractionFlags(Qt::TextBrowserInteraction);
auto line2 = new QFrame();
line2->setFrameShape(QFrame::HLine);
grid->addWidget(line2, row++, 0, 1, 4);
grid->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Actions:"))), row++, 0);
auto actionLayout = new QHBoxLayout;
#ifdef GPGME_CAN_GENCARDKEY
auto generateButton = new QPushButton(i18n("Generate new Keys"));
generateButton->setToolTip(i18n("Create a new primary key and generate subkeys on the card."));
actionLayout->addWidget(generateButton);
connect(generateButton, &QPushButton::clicked, this, &PGPCardWidget::genkeyRequested);
#endif
auto pinButtton = new QPushButton(i18n("Change PIN"));
pinButtton->setToolTip(i18n("Change the PIN required to unblock the smartcard."));
actionLayout->addWidget(pinButtton);
connect(pinButtton, &QPushButton::clicked, this, [this] () {doChangePin(1);});
auto pukButton = new QPushButton(i18n("Change Admin PIN"));
pukButton->setToolTip(i18n("Change the PIN required to unlock the smartcard."));
actionLayout->addWidget(pukButton);
connect(pukButton, &QPushButton::clicked, this, [this] () {doChangePin(3);});
auto resetCodeButton = new QPushButton(i18n("Change Reset Code"));
pukButton->setToolTip(i18n("Change the PIN required to reset the smartcard to an empty state."));
actionLayout->addWidget(resetCodeButton);
connect(resetCodeButton, &QPushButton::clicked, this, [this] () {doChangePin(2);});
actionLayout->addStretch(-1);
grid->addLayout(actionLayout, row++, 0, 1, 4);
grid->setColumnStretch(4, -1);
}
void PGPCardWidget::setCard(const OpenPGPCard *card)
{
const QString version = QString::fromStdString(card->cardVersion());
mIs21 = versionIsAtLeast("2.1", card->cardVersion().c_str());
mVersionLabel->setText(i18nc("First placeholder is manufacturer, second placeholder is a version number",
"%1 OpenPGP v%2 card", QString::fromStdString(card->manufacturer()),
version));
const QString sn = QString::fromStdString(card->serialNumber()).mid(16, 12);
mSerialNumber->setText(sn);
mRealSerial = card->serialNumber();
const auto holder = QString::fromStdString(card->cardHolder());
const auto url = QString::fromStdString(card->pubkeyUrl());
mCardHolderLabel->setText(holder.isEmpty() ? i18n("not set") : holder);
mUrl = url;
mUrlLabel->setText(url.isEmpty() ? i18n("not set") :
QStringLiteral("<a href=\"%1\">%1</a>").arg(url.toHtmlEscaped()));
mUrlLabel->setOpenExternalLinks(true);
updateKey(mSigningKey, card->sigFpr());
updateKey(mEncryptionKey, card->encFpr());
updateKey(mAuthKey, card->authFpr());
mCardIsEmpty = card->authFpr().empty() && card->sigFpr().empty() && card->encFpr().empty();
}
void PGPCardWidget::doChangePin(int slot)
{
ReaderStatus::mutableInstance()
->startSimpleTransaction(QStringLiteral("SCD PASSWD %1").arg(slot).toUtf8().constData(),
this, "changePinResult");
}
#ifdef GPGME_CAN_GENCARDKEY
void PGPCardWidget::doGenKey(GenCardKeyDialog *dlg)
{
const auto params = dlg->getKeyParams();
auto progress = new QProgressDialog(this, Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::Dialog);
progress->setAutoClose(true);
progress->setMinimumDuration(0);
progress->setMaximum(0);
progress->setMinimum(0);
progress->setModal(true);
progress->setCancelButton(nullptr);
progress->setWindowTitle(i18nc("@title:window", "Generating Keys"));
progress->setLabel(new QLabel(i18n("This may take several minutes...")));
GenKeyThread *workerThread = new GenKeyThread(params, mRealSerial);
connect(workerThread, &QThread::finished, this, [this, workerThread, progress] {
progress->accept();
progress->deleteLater();
genKeyDone(workerThread->error(), workerThread->bkpFile());
delete workerThread;
});
workerThread->start();
progress->exec();
}
void PGPCardWidget::genKeyDone(const GpgME::Error &err, const std::string &backup)
{
if (err) {
KMessageBox::error(this, i18nc("@info",
"Failed to generate new key: %1", QString::fromLatin1(err.asString())),
i18nc("@title", "Error"));
return;
}
if (err.isCanceled()) {
return;
}
if (!backup.empty()) {
const auto bkpFile = QString::fromStdString(backup);
QFileInfo fi(bkpFile);
const auto target = QFileDialog::getSaveFileName(this, i18n("Save backup of encryption key"),
fi.fileName(),
QStringLiteral("%1 (*.gpg)").arg(i18n("Backup Key")));
if (!target.isEmpty() && !QFile::copy(bkpFile, target)) {
KMessageBox::error(this, i18nc("@info",
"Failed to move backup. The backup key is still stored under: %1", bkpFile),
i18nc("@title", "Error"));
} else if (!target.isEmpty()) {
QFile::remove(bkpFile);
}
}
KMessageBox::information(this, i18nc("@info",
"Successfully generated a new key for this card."),
i18nc("@title", "Success"));
}
#else
void PGPCardWidget::doGenKey(GenCardKeyDialog *) {}
void PGPCardWidget::genKeyDone(const GpgME::Error &, const std::string &) {}
#endif
void PGPCardWidget::genkeyRequested()
{
if (!mCardIsEmpty) {
auto ret = KMessageBox::warningContinueCancel(this,
i18n("The existing keys on this card will be <b>deleted</b> "
"and replaced by new keys.") + QStringLiteral("<br/><br/>") +
i18n("It will no longer be possible to decrypt past communication "
"encrypted for the existing key."),
i18n("Secret Key Deletion"),
KStandardGuiItem::guiItem(KStandardGuiItem::Delete),
KStandardGuiItem::cancel(), QString(), KMessageBox::Notify | KMessageBox::Dangerous);
if (ret != KMessageBox::Continue) {
return;
}
}
GenCardKeyDialog *dlg = new GenCardKeyDialog(this);
std::vector <int> sizes;
sizes.push_back(1024);
sizes.push_back(2048);
sizes.push_back(3072);
// There is probably a better way to check for capabilities
if (mIs21) {
sizes.push_back(4096);
}
dlg->setSupportedSizes(sizes);
connect(dlg, &QDialog::accepted, this, [this, dlg] () {
doGenKey(dlg);
dlg->deleteLater();
});
dlg->setModal(true);
dlg->show();
}
void PGPCardWidget::changePinResult(const GpgME::Error &err)
{
if (err) {
KMessageBox::error(this, i18nc("@info",
"PIN change failed: %1", QString::fromLatin1(err.asString())),
i18nc("@title", "Error"));
return;
}
if (!err.isCanceled()) {
KMessageBox::information(this, i18nc("@info",
"Code successfully changed."),
i18nc("@title", "Success"));
}
}
void PGPCardWidget::changeNameRequested()
{
QString text = mCardHolderLabel->text();
while (true) {
bool ok = false;
text = QInputDialog::getText(this, i18n("Change cardholder"),
i18n("New name:"), QLineEdit::Normal,
text, &ok, Qt::WindowFlags(),
Qt::ImhLatinOnly);
if (!ok) {
return;
}
// Some additional restrictions imposed by gnupg
if (text.contains(QLatin1Char('<'))) {
KMessageBox::error(this, i18nc("@info",
"The \"<\" character may not be used."),
i18nc("@title", "Error"));
continue;
}
if (text.contains(QLatin1String(" "))) {
KMessageBox::error(this, i18nc("@info",
"Double spaces are not allowed"),
i18nc("@title", "Error"));
continue;
}
if (text.size() > 38) {
KMessageBox::error(this, i18nc("@info",
"The size of the name may not exceed 38 characters."),
i18nc("@title", "Error"));
}
break;
}
auto parts = text.split(QLatin1Char(' '));
const auto lastName = parts.takeLast();
const QString formatted = lastName + QStringLiteral("<<") + parts.join(QLatin1Char('<'));
ReaderStatus::mutableInstance()
->startSimpleTransaction(QStringLiteral("SCD SETATTR DISP-NAME %1").arg(formatted).toUtf8().constData(),
this, "changeNameResult");
}
void PGPCardWidget::changeNameResult(const GpgME::Error &err)
{
if (err) {
KMessageBox::error(this, i18nc("@info",
"Name change failed: %1", QString::fromLatin1(err.asString())),
i18nc("@title", "Error"));
return;
}
if (!err.isCanceled()) {
KMessageBox::information(this, i18nc("@info",
"Name successfully changed."),
i18nc("@title", "Success"));
ReaderStatus::mutableInstance()->updateStatus();
}
}
void PGPCardWidget::changeUrlRequested()
{
QString text = mUrl;
while (true) {
bool ok = false;
text = QInputDialog::getText(this, i18n("Change the URL where the pubkey can be found"),
i18n("New pubkey URL:"), QLineEdit::Normal,
text, &ok, Qt::WindowFlags(),
Qt::ImhLatinOnly);
if (!ok) {
return;
}
// Some additional restrictions imposed by gnupg
if (text.size() > 254) {
KMessageBox::error(this, i18nc("@info",
"The size of the URL may not exceed 254 characters."),
i18nc("@title", "Error"));
}
break;
}
ReaderStatus::mutableInstance()
->startSimpleTransaction(QStringLiteral("SCD SETATTR PUBKEY-URL %1").arg(text).toUtf8().constData(),
this, "changeUrlResult");
}
void PGPCardWidget::changeUrlResult(const GpgME::Error &err)
{
if (err) {
KMessageBox::error(this, i18nc("@info",
"URL change failed: %1", QString::fromLatin1(err.asString())),
i18nc("@title", "Error"));
return;
}
if (!err.isCanceled()) {
KMessageBox::information(this, i18nc("@info",
"URL successfully changed."),
i18nc("@title", "Success"));
ReaderStatus::mutableInstance()->updateStatus();
}
}
void PGPCardWidget::updateKey(QLabel *label, const std::string &fpr)
{
label->setText(QString::fromStdString(fpr));
if (fpr.empty()) {
label->setText(i18n("Slot empty"));
return;
}
std::vector<std::string> vec;
std::string keyid = fpr;
keyid.erase(0, keyid.size() - 16);
vec.push_back(keyid);
const auto subkeys = KeyCache::instance()->findSubkeysByKeyID(vec);
if (subkeys.empty() || subkeys[0].isNull()) {
label->setToolTip(i18n("Public key not found."));
return;
}
QStringList toolTips;
toolTips.reserve(subkeys.size());
for (const auto &sub: subkeys) {
// Yep you can have one subkey associated with multiple
// primary keys.
toolTips << Formatting::toolTip(sub.parent(), Formatting::Validity |
Formatting::StorageLocation |
Formatting::ExpiryDates |
Formatting::UserIDs |
Formatting::Fingerprint);
}
label->setToolTip(toolTips.join(QLatin1String("<br/>")));
return;
}
#include "pgpcardwidget.moc"
diff --git a/src/view/pgpcardwidget.h b/src/view/pgpcardwidget.h
index 1e4e33ba2..38f4fd2b0 100644
--- a/src/view/pgpcardwidget.h
+++ b/src/view/pgpcardwidget.h
@@ -1,86 +1,86 @@
/* view/pgpcardwiget.h
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2017 by Bundesamt für Sicherheit in der Informationstechnik
Software engineering by Intevation GmbH
Kleopatra 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 2 of the License, or
(at your option) any later version.
Kleopatra 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#ifndef VIEW_PGPCARDWIDGET_H
#define VIEW_PGPCARDWIDGET_H
#include <QWidget>
#include <gpgme++/error.h>
#include <string>
class QLabel;
namespace Kleo
{
class GenCardKeyDialog;
namespace SmartCard
{
class OpenPGPCard;
} // namespace SmartCard
class PGPCardWidget: public QWidget
{
Q_OBJECT
public:
- PGPCardWidget();
+ explicit PGPCardWidget(QWidget *parent = nullptr);
void setCard(const SmartCard::OpenPGPCard* card);
void doChangePin(int slot);
void doGenKey(GenCardKeyDialog *dlg);
void genKeyDone(const GpgME::Error &err, const std::string &backup);
public Q_SLOTS:
void genkeyRequested();
void changePinResult(const GpgME::Error &err);
void changeNameRequested();
void changeNameResult(const GpgME::Error &err);
void changeUrlRequested();
void changeUrlResult(const GpgME::Error &err);
private:
void updateKey(QLabel *label, const std::string &fpr);
QLabel *mSerialNumber = nullptr,
*mCardHolderLabel = nullptr,
*mVersionLabel = nullptr,
*mSigningKey = nullptr,
*mEncryptionKey = nullptr,
*mAuthKey = nullptr,
*mUrlLabel = nullptr;
QString mUrl;
bool mCardIsEmpty = false;
bool mIs21 = false;
std::string mRealSerial;
};
} // namespace Kleo
#endif // VIEW_PGPCARDWIDGET_H
diff --git a/src/view/smartcardwidget.cpp b/src/view/smartcardwidget.cpp
index 039476318..9f7d5d708 100644
--- a/src/view/smartcardwidget.cpp
+++ b/src/view/smartcardwidget.cpp
@@ -1,162 +1,163 @@
/* view/smartcardwidget.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2017 by Bundesamt für Sicherheit in der Informationstechnik
Software engineering by Intevation GmbH
Kleopatra 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 2 of the License, or
(at your option) any later version.
Kleopatra 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#include "smartcardwidget.h"
#include "smartcard/readerstatus.h"
#include "smartcard/openpgpcard.h"
#include "smartcard/netkeycard.h"
#include "view/pgpcardwidget.h"
#include "view/netkeywidget.h"
#include "kleopatra_debug.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <QStackedWidget>
#include <KLocalizedString>
using namespace Kleo;
using namespace Kleo::SmartCard;
namespace {
class PlaceHolderWidget: public QWidget
{
Q_OBJECT
public:
- PlaceHolderWidget()
+ explicit PlaceHolderWidget(QWidget *parent = nullptr)
+ : QWidget(parent)
{
auto lay = new QVBoxLayout;
lay->addStretch(-1);
const QStringList supported = QStringList() << QStringLiteral("OpenPGP v2.0 - v3.3")
<< QStringLiteral("Gnuk")
<< QStringLiteral("NetKey v3");
lay->addWidget(new QLabel(QStringLiteral("\t\t<h3>") +
- i18n("Please insert a compatible smartcard.") + QStringLiteral("</h3>")));
+ i18n("Please insert a compatible smartcard.") + QStringLiteral("</h3>"), this));
lay->addSpacing(10);
lay->addWidget(new QLabel(QStringLiteral("\t\t") +
i18n("Kleopatra currently supports the following card types:") +
QStringLiteral("<ul><li>") + supported.join(QLatin1String("</li><li>")) +
- QStringLiteral("</li></ul>")));
+ QStringLiteral("</li></ul>"), this));
lay->addSpacing(10);
- lay->addWidget(new QLabel(i18n("Refresh the view (F5) to update the smartcard status.")));
+ lay->addWidget(new QLabel(i18n("Refresh the view (F5) to update the smartcard status."), this));
lay->addStretch(-1);
auto hLay = new QHBoxLayout(this);
hLay->addStretch(-1);
hLay->addLayout(lay);
hLay->addStretch(-1);
lay->addStretch(-1);
}
};
} // namespace
class SmartCardWidget::Private
{
public:
Private(SmartCardWidget *qq) : q(qq)
{
QPushButton *backBtn = new QPushButton(QIcon::fromTheme(QStringLiteral("arrow-left")), i18n("Back"));
QHBoxLayout *backH = new QHBoxLayout;
backH->addWidget(backBtn);
backH->addWidget(new QLabel(QStringLiteral("<h2>") + i18n("Smartcard Management") +
QStringLiteral("</h2>")));
backH->addStretch(-1);
QVBoxLayout *vLay = new QVBoxLayout(q);
connect(backBtn, &QPushButton::clicked, q, [this] () {Q_EMIT q->backRequested();});
vLay->addLayout(backH);
mStack = new QStackedWidget;
vLay->addWidget(mStack);
- mPGPCardWidget = new PGPCardWidget;
+ mPGPCardWidget = new PGPCardWidget(q);
mStack->addWidget(mPGPCardWidget);
- mNetKeyWidget = new NetKeyWidget;
+ mNetKeyWidget = new NetKeyWidget(q);
mStack->addWidget(mNetKeyWidget);
- mPlaceHolderWidget = new PlaceHolderWidget;
+ mPlaceHolderWidget = new PlaceHolderWidget(q);
mStack->addWidget(mPlaceHolderWidget);
mStack->setCurrentWidget(mPlaceHolderWidget);
connect (ReaderStatus::instance(), &ReaderStatus::cardChanged, q, [this] (unsigned int /*slot*/) {
const auto cards = ReaderStatus::instance()->getCards();
if (!cards.size()) {
setCard(std::shared_ptr<Card>(new Card()));
} else {
// No support for multiple reader / cards currently
setCard(cards[0]);
}
});
}
void setCard(std::shared_ptr<Card> card)
{
if (card->appType() == Card::OpenPGPApplication) {
mPGPCardWidget->setCard(static_cast<OpenPGPCard *> (card.get()));
mStack->setCurrentWidget(mPGPCardWidget);
} else if (card->appType() == Card::NksApplication) {
mNetKeyWidget->setCard(static_cast<NetKeyCard *> (card.get()));
mStack->setCurrentWidget(mNetKeyWidget);
} else {
mStack->setCurrentWidget(mPlaceHolderWidget);
}
}
private:
SmartCardWidget *q;
NetKeyWidget *mNetKeyWidget;
PGPCardWidget *mPGPCardWidget;
PlaceHolderWidget *mPlaceHolderWidget;
QStackedWidget *mStack;
};
SmartCardWidget::SmartCardWidget(QWidget *parent):
QWidget(parent),
d(new Private(this))
{
}
void SmartCardWidget::reload()
{
ReaderStatus::mutableInstance()->updateStatus();
}
#include "smartcardwidget.moc"

File Metadata

Mime Type
text/x-diff
Expires
Fri, Jan 30, 8:14 PM (1 d, 16 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
9d/da/92a6a10baf46c415a95102311ad9

Event Timeline