File indexing completed on 2022-06-23 11:26:59

0001 /*
0002     SPDX-FileCopyrightText: 2008, 2010, 2012 Rolf Eike Beer <kde@opensource.sf-tec.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "kgpgfirstassistant.h"
0008 
0009 #include "gpgproc.h"
0010 #include "kgpginterface.h"
0011 #include "core/kgpgkey.h"
0012 
0013 #include <KLocalizedString>
0014 #include <KMessageBox>
0015 #include <KUrlRequester>
0016 
0017 #include <QCheckBox>
0018 #include <QComboBox>
0019 #include <QGridLayout>
0020 #include <QHBoxLayout>
0021 #include <QLabel>
0022 #include <QSpacerItem>
0023 #include <QStandardPaths>
0024 #include <QTextStream>
0025 #include <QWidget>
0026 #include <QUrl>
0027 
0028 using namespace KgpgCore;
0029 
0030 KGpgFirstAssistant::KGpgFirstAssistant(QWidget *parent)
0031         : KAssistantDialog(parent)
0032 {
0033     setWindowTitle(i18n("KGpg Assistant"));
0034 
0035     QWidget *page = new QWidget(this);
0036     QGridLayout *gridLayout = new QGridLayout(page);
0037     gridLayout->setSpacing(6);
0038     gridLayout->setContentsMargins(0, 0, 0, 0);
0039 
0040     QLabel *label = new QLabel(page);
0041     QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
0042     sizePolicy.setHorizontalStretch(0);
0043     sizePolicy.setVerticalStretch(0);
0044     sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
0045     label->setSizePolicy(sizePolicy);
0046     label->setFrameShape(QFrame::NoFrame);
0047     label->setFrameShadow(QFrame::Plain);
0048     label->setScaledContents(false);
0049     label->setAlignment(Qt::AlignTop);
0050     label->setWordWrap(false);
0051 
0052     gridLayout->addWidget(label, 0, 0, 3, 1);
0053 
0054     label = new QLabel(page);
0055     label->setAlignment(Qt::AlignTop);
0056     label->setWordWrap(true);
0057     label->setText(i18n("This assistant will first setup some basic configuration options required for KGpg to work properly. Next, it will allow you to create your own key pair, enabling you to encrypt your files and emails."));
0058 
0059     gridLayout->addWidget(label, 0, 1, 1, 1);
0060 
0061     QSpacerItem *spacerItem = new QSpacerItem(20, 41, QSizePolicy::Minimum, QSizePolicy::Expanding);
0062 
0063     gridLayout->addItem(spacerItem, 1, 1, 1, 1);
0064 
0065     page_welcome = addPage(page, i18n("Welcome to the KGpg Assistant"));
0066 
0067     page = new QWidget(this);
0068 
0069     gridLayout = new QGridLayout(page);
0070     gridLayout->setSpacing(6);
0071     gridLayout->setContentsMargins(0, 0, 0, 0);
0072 
0073     label = new QLabel(page);
0074     label->setAlignment(Qt::AlignTop);
0075     label->setWordWrap(true);
0076     label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
0077     label->setText(i18n("KGpg needs to know which GnuPG binary to use."));
0078 
0079     gridLayout->addWidget(label, 0, 1, 1, 1);
0080 
0081     label = new QLabel(page);
0082     label->setAlignment(Qt::AlignTop);
0083     label->setWordWrap(true);
0084     label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
0085     label->setText(i18n("Unless you want to try some unusual settings, just click on the \"next\" button."));
0086 
0087     gridLayout->addWidget(label, 1, 1, 1, 1);
0088 
0089     spacerItem = new QSpacerItem(20, 60, QSizePolicy::Minimum, QSizePolicy::Expanding);
0090 
0091     gridLayout->addItem(spacerItem, 4, 1, 1, 1);
0092 
0093     txtGpgVersion = new QLabel(page);
0094     txtGpgVersion->setWordWrap(true);
0095 
0096     gridLayout->addWidget(txtGpgVersion, 3, 1, 1, 1);
0097 
0098     binURL = new KUrlRequester(page);
0099     binURL->setFilter(i18nc("search filter for gpg binary", "gpg|GnuPG binary\n*|All files"));
0100     QString gpgBin = QStandardPaths::findExecutable(QLatin1String("gpg2"));
0101     if (gpgBin.isEmpty())
0102         gpgBin = QStandardPaths::findExecutable(QLatin1String("gpg"));
0103     if (gpgBin.isEmpty())
0104         gpgBin = QLatin1String("gpg");
0105     binURL->setUrl(QUrl::fromLocalFile(gpgBin));
0106 
0107     connect(binURL, &KUrlRequester::textChanged, this, &KGpgFirstAssistant::slotBinaryChanged);
0108     slotBinaryChanged(gpgBin);
0109 
0110     gridLayout->addWidget(binURL, 2, 1, 1, 1);
0111 
0112     page_binary = addPage(page, i18n("GnuPG Binary"));
0113 
0114     page = new QWidget(this);
0115 
0116     gridLayout = new QGridLayout(page);
0117     gridLayout->setSpacing(6);
0118     gridLayout->setContentsMargins(0, 0, 0, 0);
0119     text_optionsfound = new QLabel(page);
0120     text_optionsfound->setAlignment(Qt::AlignTop);
0121     text_optionsfound->setWordWrap(true);
0122     text_optionsfound->setText(i18n("Unless you want to try some unusual settings, just click on the \"next\" button."));
0123 
0124     gridLayout->addWidget(text_optionsfound, 1, 1, 1, 1);
0125 
0126     label = new QLabel(page);
0127     label->setAlignment(Qt::AlignTop);
0128     label->setWordWrap(true);
0129     label->setText(i18n("KGpg needs to know where your GnuPG configuration file is stored."));
0130 
0131     gridLayout->addWidget(label, 0, 1, 1, 1);
0132 
0133     spacerItem = new QSpacerItem(20, 60, QSizePolicy::Minimum, QSizePolicy::Expanding);
0134 
0135     gridLayout->addItem(spacerItem, 4, 1, 1, 1);
0136 
0137     pathURL = new KUrlRequester(page);
0138 
0139     gridLayout->addWidget(pathURL, 3, 1, 1, 1);
0140 
0141     label = new QLabel(page);
0142     label->setAlignment(Qt::AlignVCenter);
0143     label->setWordWrap(true);
0144     label->setText(i18n("Path to your GnuPG configuration file:"));
0145 
0146     gridLayout->addWidget(label, 2, 1, 1, 1);
0147 
0148     label = new QLabel(page);
0149     sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
0150     label->setSizePolicy(sizePolicy);
0151     label->setFrameShape(QFrame::NoFrame);
0152     label->setFrameShadow(QFrame::Plain);
0153     label->setScaledContents(false);
0154     label->setAlignment(Qt::AlignTop);
0155     label->setWordWrap(false);
0156 
0157     gridLayout->addWidget(label, 0, 0, 5, 1);
0158     page_config = addPage(page, i18n("Configuration File"));
0159 
0160     page = new QWidget(this);
0161     gridLayout = new QGridLayout(page);
0162     gridLayout->setSpacing(6);
0163     gridLayout->setContentsMargins(0, 0, 0, 0);
0164 
0165     QHBoxLayout *hboxLayout = new QHBoxLayout();
0166     hboxLayout->setSpacing(6);
0167     label = new QLabel(page);
0168     label->setText(i18n("Your default key:"));
0169 
0170     hboxLayout->addWidget(label);
0171 
0172     CBdefault = new QComboBox(page);
0173     QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Fixed);
0174     sizePolicy1.setHorizontalStretch(0);
0175     sizePolicy1.setVerticalStretch(0);
0176     sizePolicy1.setHeightForWidth(CBdefault->sizePolicy().hasHeightForWidth());
0177     CBdefault->setSizePolicy(sizePolicy1);
0178 
0179     hboxLayout->addWidget(CBdefault);
0180 
0181     gridLayout->addLayout(hboxLayout, 0, 1, 1, 1);
0182 
0183     spacerItem = new QSpacerItem(20, 30, QSizePolicy::Minimum, QSizePolicy::Expanding);
0184 
0185     gridLayout->addItem(spacerItem, 1, 1, 1, 1);
0186 
0187     page_defaultkey = addPage(page, i18n("Default Key"));
0188 
0189     page = new QWidget(this);
0190 
0191     gridLayout = new QGridLayout(page);
0192     gridLayout->setSpacing(6);
0193     gridLayout->setContentsMargins(0, 0, 0, 0);
0194 
0195     binlabel = new QLabel(page);
0196 
0197     gridLayout->addWidget(binlabel, 0, 1, 1, 1);
0198 
0199     versionLabel = new QLabel(page);
0200 
0201     gridLayout->addWidget(versionLabel, 1, 1, 1, 1);
0202 
0203     defaultkeylabel = new QLabel(page);
0204 
0205     gridLayout->addWidget(defaultkeylabel, 2, 1, 1, 1);
0206 
0207     generateCB = new QCheckBox(page);
0208     generateCB->setText(i18n("Generate new key"));
0209 
0210     gridLayout->addWidget(generateCB, 3, 1, 1, 1);
0211 
0212     spacerItem = new QSpacerItem(20, 30, QSizePolicy::Minimum, QSizePolicy::Expanding);
0213 
0214     gridLayout->addItem(spacerItem, 4, 1, 1, 1);
0215 
0216     autostartCB = new QCheckBox(page);
0217     autostartCB->setChecked(true);
0218     autostartCB->setText(i18n("Start KGpg automatically at KDE startup."));
0219 
0220     gridLayout->addWidget(autostartCB, 5, 1, 1, 1);
0221 
0222     page_done = addPage(page, i18n("Done"));
0223 }
0224 
0225 void
0226 KGpgFirstAssistant::findConfigPath(const QString &gpgBinary)
0227 {
0228     const QString gpgHome = GPGProc::getGpgHome(gpgBinary);
0229     QString confPath = gpgHome + QLatin1String( "gpg.conf" );
0230 
0231     if (!QFile(confPath).exists()) {
0232         const QString confPathOpt = gpgHome + QLatin1String("options");
0233         if (QFile(confPathOpt).exists()) {
0234             confPath = confPathOpt;
0235         } else {
0236                         if (KMessageBox::questionYesNo(nullptr, i18n("<qt><b>The GnuPG configuration file was not found</b>. Should KGpg try to create a config file ?</qt>"), QString(), KGuiItem(i18n("Create Config")), KGuiItem(i18n("Do Not Create"))) == KMessageBox::Yes) {
0237                 QFile file(confPath);
0238                 if (file.open(QIODevice::WriteOnly)) {
0239                     QTextStream stream(&file);
0240                     stream << "# GnuPG config file created by KGpg\n";
0241                     file.close();
0242                 }
0243             } else {
0244                 text_optionsfound->setText(i18n("<qt><b>The GnuPG configuration file was not found</b>.</qt>"));
0245                 confPath.clear();
0246             }
0247         }
0248     }
0249 
0250     pathURL->setUrl(QUrl::fromLocalFile(confPath));
0251 
0252     const QStringList secids = KgpgInterface::readSecretKeys();
0253 
0254     bool noSecKeys = secids.isEmpty();
0255     generateCB->setChecked(noSecKeys);
0256     setAppropriate(page_defaultkey, !noSecKeys);
0257 
0258     if (noSecKeys) {
0259         defaultkeylabel->setVisible(false);
0260         return;
0261     }
0262 
0263     const KgpgKeyList publiclist = KgpgInterface::readPublicKeys(secids);
0264 
0265     CBdefault->clear();
0266 
0267     for (const KgpgKey &k : publiclist) {
0268         QString s;
0269 
0270         if (k.email().isEmpty())
0271             s = i18nc("Name: ID", "%1: %2", k.name(), k.id());
0272         else
0273             s = i18nc("Name (Email): ID", "%1 (%2): %3", k.name(), k.email(), k.id());
0274 
0275         CBdefault->addItem(s, k.fingerprint());
0276     }
0277 
0278     CBdefault->setCurrentIndex(0);
0279 }
0280 
0281 void
0282 KGpgFirstAssistant::next()
0283 {
0284     if (currentPage() == page_binary) {
0285         const QString &gpgbin = binURL->url().path();
0286         binlabel->setText(i18n("Your GnuPG binary is: %1", gpgbin));
0287         findConfigPath(gpgbin);
0288     } else if (currentPage() == page_config) {
0289         m_confPath = pathURL->url().path();
0290 
0291         const QString defaultID = KgpgInterface::getGpgSetting(QLatin1String( "default-key" ), m_confPath);
0292 
0293         if (!defaultID.isEmpty()) {
0294             for (int i = 0; i < CBdefault->count(); i++) {
0295 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0296                 if (CBdefault->itemData(i).toString().rightRef(defaultID.length()).compare(defaultID) == 0) {
0297 #else
0298                 if (QStringView(CBdefault->itemData(i).toString()).right(defaultID.length()).compare(defaultID) == 0) {
0299 #endif
0300                     CBdefault->setCurrentIndex(i);
0301                     break;
0302                 }
0303             }
0304         }
0305         versionLabel->setText(i18n("You have GnuPG version: %1", m_gpgVersion));
0306     } else if (currentPage() == page_defaultkey) {
0307         defaultkeylabel->setVisible(true);
0308         defaultkeylabel->setText(i18n("Your default key is: %1", CBdefault->currentText()));
0309         int i = CBdefault->currentIndex();
0310         if (i >= 0) {
0311             defaultkeylabel->setToolTip(CBdefault->itemData(i).toString());
0312         }
0313     }
0314     KAssistantDialog::next();
0315 }
0316 
0317 bool
0318 KGpgFirstAssistant::runKeyGenerate() const
0319 {
0320     return generateCB->isChecked();
0321 }
0322 
0323 QString
0324 KGpgFirstAssistant::getConfigPath() const
0325 {
0326     return m_confPath;
0327 }
0328 
0329 QString
0330 KGpgFirstAssistant::getDefaultKey() const
0331 {
0332     int i = CBdefault->currentIndex();
0333     if (i < 0)
0334         return QString();
0335     else
0336         return CBdefault->itemData(i).toString();
0337 }
0338 
0339 bool
0340 KGpgFirstAssistant::getAutoStart() const
0341 {
0342     return autostartCB->isChecked();
0343 }
0344 
0345 void
0346 KGpgFirstAssistant::slotBinaryChanged(const QString &binary)
0347 {
0348     if (binary.isEmpty()) {
0349         setValid(page_binary, false);
0350         return;
0351     }
0352 
0353     m_gpgVersion = GPGProc::gpgVersionString(binary);
0354     setValid(page_binary, !m_gpgVersion.isEmpty());
0355     if (!m_gpgVersion.isEmpty()) {
0356         const int gpgver = GPGProc::gpgVersion(m_gpgVersion);
0357 
0358         if (gpgver < 0x10400) {
0359             txtGpgVersion->setText(i18n("Your GnuPG version (%1) seems to be too old.<br />Compatibility with versions before 1.4.0 is no longer guaranteed.", m_gpgVersion));
0360         } else {
0361             txtGpgVersion->setText(i18n("You have GnuPG version: %1", m_gpgVersion));
0362         }
0363     }
0364 }