File indexing completed on 2022-08-04 16:24:16

0001 /*
0002     SPDX-FileCopyrightText: 2002 Jean-Baptiste Mardelle <bj@altern.org>
0003     SPDX-FileCopyrightText: 2007, 2009, 2010, 2012, 2013, 2014 Rolf Eike Beer <kde@opensource.sf-tec.de>
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "kgpgkeygenerate.h"
0008 
0009 #include "core/convert.h"
0010 #include "core/emailvalidator.h"
0011 #include "gpgproc.h"
0012 #include "kgpgsettings.h"
0013 
0014 #include <KConfigGroup>
0015 #include <KLocalizedString>
0016 #include <KMessageBox>
0017 
0018 #include <QComboBox>
0019 #include <QDialogButtonBox>
0020 #include <QIntValidator>
0021 #include <QHBoxLayout>
0022 #include <QStringList>
0023 #include <QVBoxLayout>
0024 #include <QWhatsThis>
0025 #include <QWidget>
0026 
0027 using namespace KgpgCore;
0028 
0029 KgpgKeyGenerate::KgpgKeyGenerate(QWidget *parent)
0030     : QDialog(parent),
0031     m_expert(false)
0032 {
0033     setupUi(this);
0034 
0035     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
0036     QWidget *mainWidget = new QWidget(this);
0037     QVBoxLayout *mainLayout = new QVBoxLayout(this);
0038     setLayout(mainLayout);
0039     mainLayout->addWidget(mainWidget);
0040     okButton = buttonBox->button(QDialogButtonBox::Ok);
0041     okButton->setDefault(true);
0042     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0043     QPushButton *user1Button = new QPushButton;
0044     buttonBox->addButton(user1Button, QDialogButtonBox::ActionRole);
0045     connect(buttonBox, &QDialogButtonBox::accepted, this, &KgpgKeyGenerate::accept);
0046     connect(buttonBox, &QDialogButtonBox::rejected, this, &KgpgKeyGenerate::reject);
0047 
0048     user1Button->setText(i18n("&Expert Mode"));
0049     user1Button->setToolTip(i18n("Go to Expert Mode"));
0050     user1Button->setWhatsThis(i18n( "If you go to expert mode, you will use the command line to create your key." ));
0051 
0052     connect(m_kname, &QLineEdit::textChanged, this, &KgpgKeyGenerate::slotEnableOk);
0053 
0054     m_keyexp->setMinimumSize(m_keyexp->sizeHint());
0055     connect(m_keyexp, QOverload<int>::of(&QComboBox::activated), this, &KgpgKeyGenerate::slotEnableDays);
0056 
0057     m_keysize->addItem(i18n("1024"));
0058     m_keysize->addItem(i18n("2048"));
0059     m_keysize->addItem(i18n("4096"));
0060     m_keysize->setCurrentIndex(1); // 2048
0061     m_keysize->setMinimumSize(m_keysize->sizeHint());
0062 
0063     const QStringList pkAlgos = GPGProc::getGpgPubkeyAlgorithms(KGpgSettings::gpgBinaryPath());
0064     if (pkAlgos.contains(QLatin1String("RSA"))) {
0065     m_keykind->addItem(KgpgCore::Convert::toString(KgpgCore::ALGO_RSA_RSA));
0066     m_keykind->addItem(KgpgCore::Convert::toString(KgpgCore::ALGO_RSA));
0067     }
0068     if (pkAlgos.contains(QLatin1String("DSA")) && pkAlgos.contains(QLatin1String("ELG")))
0069     m_keykind->addItem(KgpgCore::Convert::toString(KgpgCore::ALGO_DSA_ELGAMAL));
0070     m_keykind->setCurrentIndex(0); // normally RSA+RSA
0071     slotEnableCaps(m_keykind->currentIndex());
0072     m_keykind->setMinimumSize(m_keykind->sizeHint());
0073 
0074     mainLayout->addWidget(vgroup);
0075     mainLayout->addWidget(buttonBox);
0076 
0077     slotEnableOk();
0078     updateGeometry();
0079     show();
0080 
0081     connect(okButton, &QPushButton::clicked, this, &KgpgKeyGenerate::slotOk);
0082     connect(user1Button, &QPushButton::clicked, this, &KgpgKeyGenerate::slotUser1);
0083     connect(m_keykind, QOverload<int>::of(&QComboBox::activated), this, &KgpgKeyGenerate::slotEnableCaps);
0084 }
0085 
0086 void KgpgKeyGenerate::slotOk()
0087 {
0088     if (m_kname->text().simplified().isEmpty())
0089     {
0090         KMessageBox::error(this, i18n("You must give a name."));
0091         return;
0092     }
0093 
0094     if (m_kname->text().simplified().length() < 5)
0095     {
0096         KMessageBox::error(this, i18n("The name must have at least 5 characters"));
0097         return;
0098     }
0099 
0100     if (m_kname->text().simplified().at(0).isDigit())
0101     {
0102         KMessageBox::error(this, i18n("The name must not start with a digit"));
0103         return;
0104     }
0105 
0106     QString vmail = m_mail->text();
0107     if (vmail.isEmpty())
0108     {
0109         int result = KMessageBox::warningContinueCancel(this, i18n("You are about to create a key with no email address"));
0110         if (result != KMessageBox::Continue)
0111             return;
0112     } else {
0113         int pos = 0;
0114         if (EmailValidator().validate(vmail, pos) == QValidator::Invalid)
0115         {
0116             KMessageBox::error(this, i18n("Email address not valid"));
0117             return;
0118         }
0119     }
0120 
0121     accept();
0122 }
0123 
0124 void KgpgKeyGenerate::slotUser1()
0125 {
0126     m_expert = true;
0127     accept();
0128 }
0129 
0130 void KgpgKeyGenerate::slotEnableDays(const int state)
0131 {
0132     m_days->setDisabled(state == 0);
0133 }
0134 
0135 void KgpgKeyGenerate::slotEnableCaps(const int state)
0136 {
0137     // currently only supported for standalone RSA keys
0138     capabilities->setDisabled(state != 2);
0139 }
0140 
0141 void KgpgKeyGenerate::slotEnableOk()
0142 {
0143     okButton->setEnabled((m_kname->text().simplified().length() >= 5) &&
0144             !m_kname->text().simplified().at(0).isDigit());
0145 }
0146 
0147 bool KgpgKeyGenerate::isExpertMode() const
0148 {
0149     return m_expert;
0150 }
0151 
0152 KgpgCore::KgpgKeyAlgo KgpgKeyGenerate::algo() const
0153 {
0154     if (m_keykind->currentText() == KgpgCore::Convert::toString(KgpgCore::ALGO_RSA))
0155         return KgpgCore::ALGO_RSA;
0156     else if (m_keykind->currentText() == KgpgCore::Convert::toString(KgpgCore::ALGO_RSA_RSA))
0157         return KgpgCore::ALGO_RSA_RSA;
0158     else
0159         return KgpgCore::ALGO_DSA_ELGAMAL;
0160 }
0161 
0162 KgpgCore::KgpgSubKeyType KgpgKeyGenerate::caps() const
0163 {
0164     KgpgCore::KgpgSubKeyType ret;
0165 
0166     if (!capabilities->isEnabled())
0167         return ret;
0168 
0169     if (capAuth->isChecked())
0170         ret |= KgpgCore::SKT_AUTHENTICATION;
0171     if (capCert->isChecked())
0172         ret |= KgpgCore::SKT_CERTIFICATION;
0173     if (capEncrypt->isChecked())
0174         ret |= KgpgCore::SKT_ENCRYPTION;
0175     if (capSign->isChecked())
0176         ret |= KgpgCore::SKT_SIGNATURE;
0177 
0178     return ret;
0179 }
0180 
0181 uint KgpgKeyGenerate::size() const
0182 {
0183     return m_keysize->currentText().toUInt();
0184 }
0185 
0186 char KgpgKeyGenerate::expiration() const
0187 {
0188     switch (m_keyexp->currentIndex()) {
0189     case 1:
0190         return 'd';
0191     case 2:
0192         return 'w';
0193     case 3:
0194         return 'm';
0195     case 4:
0196     default:
0197         return 'y';
0198     }
0199 }
0200 
0201 uint KgpgKeyGenerate::days() const
0202 {
0203     if (m_days->text().isEmpty())
0204         return 0;
0205     return m_days->text().toUInt();
0206 }
0207 
0208 QString KgpgKeyGenerate::name() const
0209 {
0210     if (m_kname->text().isEmpty())
0211         return QString();
0212     return m_kname->text();
0213 }
0214 
0215 QString KgpgKeyGenerate::email() const
0216 {
0217     if (m_mail->text().isEmpty())
0218         return QString();
0219     return m_mail->text();
0220 }
0221 
0222 QString KgpgKeyGenerate::comment() const
0223 {
0224     if (m_comment->text().isEmpty())
0225         return QString();
0226     return m_comment->text();
0227 }