33 #include <config-kleopatra.h>
37 #include "ui_chooseprotocolpage.h"
38 #include "ui_enterdetailspage.h"
39 #include "ui_overviewpage.h"
40 #include "ui_keycreationpage.h"
41 #include "ui_resultpage.h"
43 #include "ui_advancedsettingsdialog.h"
55 #include <kleo/stl_util.h>
57 #include <kleo/oidmap.h>
58 #include <kleo/keygenerationjob.h>
59 #include <kleo/cryptobackendfactory.h>
60 #include <kleo/cryptobackend.h>
62 #include <gpgme++/global.h>
63 #include <gpgme++/keygenerationresult.h>
66 #include <KConfigGroup>
68 #include <KLocalizedString>
71 #include <KMessageBox>
73 #include <QRegExpValidator>
75 #include <QMetaProperty>
79 #include <QDesktopServices>
82 #include <boost/range.hpp>
88 using namespace Kleo::NewCertificateUi;
89 using namespace Kleo::Commands;
90 using namespace GpgME;
91 using namespace boost;
127 static bool is_rsa(
unsigned int algo ) {
128 return is_algo( static_cast<gpgme_pubkey_algo_t>( algo ),
RSA );
131 static bool is_dsa(
unsigned int algo ) {
132 return is_algo( static_cast<gpgme_pubkey_algo_t>( algo ),
DSA );
135 static bool is_elg(
unsigned int algo ) {
136 return is_algo( static_cast<gpgme_pubkey_algo_t>( algo ),
ELG );
150 const int idx = cb->
findData( static_cast<int>( strength ) );
152 kWarning() <<
"keysize " << strength <<
" not allowed";
166 namespace NewCertificateUi {
170 explicit WizardPage(
QWidget * parent=0 )
182 bool isButtonVisible( QWizard::WizardButton button )
const {
192 void setButtonVisible( QWizard::WizardButton button,
bool visible ) {
194 b->setVisible( visible );
198 #define FIELD(type, name) type name() const { return field( QLatin1String(#name) ).value<type>(); }
200 FIELD(
bool, signingAllowed )
201 FIELD(
bool, encryptionAllowed )
202 FIELD(
bool, certificationAllowed )
203 FIELD(
bool, authenticationAllowed )
207 FIELD( QString, comment )
210 FIELD(
int, keyType )
211 FIELD(
int, keyStrength )
213 FIELD(
int, subkeyType )
214 FIELD(
int, subkeyStrength )
219 FIELD( QStringList, additionalEMailAddresses )
220 FIELD( QStringList, dnsNames )
221 FIELD( QStringList, uris )
223 FIELD( QString, url )
224 FIELD( QString, error )
225 FIELD( QString, result )
226 FIELD( QString, fingerprint )
232 using namespace Kleo::NewCertificateUi;
236 class AdvancedSettingsDialog :
public QDialog {
238 Q_PROPERTY(
QStringList additionalUserIDs READ additionalUserIDs WRITE setAdditionalUserIDs )
239 Q_PROPERTY(
QStringList additionalEMailAddresses READ additionalEMailAddresses WRITE setAdditionalEMailAddresses )
240 Q_PROPERTY(
QStringList dnsNames READ dnsNames WRITE setDnsNames )
241 Q_PROPERTY(
QStringList uris READ uris WRITE setUris )
242 Q_PROPERTY( uint keyStrength READ keyStrength WRITE setKeyStrength )
243 Q_PROPERTY( uint keyType READ keyType WRITE setKeyType )
244 Q_PROPERTY( uint subkeyStrength READ subkeyStrength WRITE setSubkeyStrength )
245 Q_PROPERTY( uint subkeyType READ subkeyType WRITE setSubkeyType )
246 Q_PROPERTY(
bool signingAllowed READ signingAllowed WRITE setSigningAllowed )
247 Q_PROPERTY(
bool encryptionAllowed READ encryptionAllowed WRITE setEncryptionAllowed )
248 Q_PROPERTY(
bool certificationAllowed READ certificationAllowed WRITE setCertificationAllowed )
249 Q_PROPERTY(
bool authenticationAllowed READ authenticationAllowed WRITE setAuthenticationAllowed )
250 Q_PROPERTY(
QDate expiryDate READ expiryDate WRITE setExpiryDate )
252 explicit AdvancedSettingsDialog(
QWidget * parent=0 )
254 protocol( UnknownProtocol ),
255 pgpDefaultAlgorithm( GPGME_PK_ELG_E ),
256 cmsDefaultAlgorithm( GPGME_PK_RSA ),
257 keyTypeImmutable(
false ),
262 ui.expiryDE->setMinimumDate( today );
263 ui.expiryDE->setDate( today.
addYears( 2 ) );
264 ui.emailLW->setDefaultValue( i18n(
"new email") );
265 ui.dnsLW->setDefaultValue( i18n(
"new dns name") );
266 ui.uriLW->setDefaultValue( i18n(
"new uri") );
268 fillKeySizeComboBoxen();
271 void setProtocol( GpgME::Protocol proto ) {
272 if ( protocol == proto )
275 loadDefaultKeyType();
278 void setAdditionalUserIDs(
const QStringList & items ) { ui.uidLW->setItems( items ); }
279 QStringList additionalUserIDs()
const {
return ui.uidLW->items(); }
281 void setAdditionalEMailAddresses(
const QStringList & items ) { ui.emailLW->setItems( items ); }
282 QStringList additionalEMailAddresses()
const {
return ui.emailLW->items(); }
284 void setDnsNames(
const QStringList & items ) { ui.dnsLW->setItems( items ); }
285 QStringList dnsNames()
const {
return ui.dnsLW->items(); }
287 void setUris(
const QStringList & items ) { ui.uriLW->setItems( items ); }
288 QStringList uris()
const {
return ui.uriLW->items(); }
291 void setKeyStrength(
unsigned int strength ) {
295 unsigned int keyStrength()
const {
297 ui.dsaRB->isChecked() ?
get_keysize( ui.dsaKeyStrengthCB ) :
298 ui.rsaRB->isChecked() ?
get_keysize( ui.rsaKeyStrengthCB ) : 0 ;
301 void setKeyType(
unsigned int algo ) {
303 is_rsa( algo ) ? ui.rsaRB :
304 is_dsa( algo ) ? ui.dsaRB : 0 ;
308 unsigned int keyType()
const {
310 ui.dsaRB->isChecked() ? GPGME_PK_DSA :
311 ui.rsaRB->isChecked() ? GPGME_PK_RSA :
315 void setSubkeyType(
unsigned int algo ) {
316 ui.elgCB->setChecked(
is_elg( algo ) );
317 ui.rsaSubCB->setChecked(
is_rsa( algo ) );
319 unsigned int subkeyType()
const {
320 if ( ui.elgCB->isChecked() ) {
321 return GPGME_PK_ELG_E;
322 }
else if ( ui.rsaSubCB->isChecked() ) {
328 void setSubkeyStrength(
unsigned int strength ) {
329 if ( subkeyType() == GPGME_PK_RSA ) {
335 unsigned int subkeyStrength()
const {
336 if ( subkeyType() == GPGME_PK_RSA ) {
342 void setSigningAllowed(
bool on ) { ui.signingCB->setChecked( on ); }
343 bool signingAllowed()
const {
return ui.signingCB->isChecked(); }
345 void setEncryptionAllowed(
bool on ) { ui.encryptionCB->setChecked( on ); }
346 bool encryptionAllowed()
const {
return ui.encryptionCB->isChecked(); }
348 void setCertificationAllowed(
bool on ) { ui.certificationCB->setChecked( on ); }
349 bool certificationAllowed()
const {
return ui.certificationCB->isChecked(); }
351 void setAuthenticationAllowed(
bool on ) { ui.authenticationCB->setChecked( on ); }
352 bool authenticationAllowed()
const {
return ui.authenticationCB->isChecked(); }
354 void setExpiryDate(
const QDate & date ) {
if ( date.
isValid() ) ui.expiryDE->setDate( date );
else ui.expiryCB->setChecked(
false ); }
355 QDate expiryDate()
const {
return ui.expiryCB->isChecked() ? ui.expiryDE->date() :
QDate() ; }
361 void slotKeyMaterialSelectionChanged() {
362 const unsigned int algo = keyType();
363 const unsigned int sk_algo = subkeyType();
365 if ( !keyTypeImmutable ) {
366 ui.elgCB->setEnabled(
is_dsa( algo ) );
367 if ( sender() == ui.dsaRB || sender() == ui.rsaRB )
368 ui.elgCB->setChecked(
is_dsa( algo ) );
371 ui.encryptionCB->setEnabled(
true );
372 ui.encryptionCB->setChecked(
true );
373 ui.signingCB->setEnabled(
true );
374 ui.signingCB->setChecked(
true );
375 ui.authenticationCB->setEnabled(
true );
376 if (
is_rsa( sk_algo ) ) {
377 ui.encryptionCB->setEnabled(
false );
378 ui.encryptionCB->setChecked(
true );
380 ui.encryptionCB->setEnabled(
true );
382 }
else if (
is_dsa( algo ) ) {
383 ui.encryptionCB->setEnabled(
false );
385 ui.encryptionCB->setChecked(
true );
387 ui.encryptionCB->setChecked(
false );
394 void slotSigningAllowedToggled(
bool on ) {
395 if ( !on && protocol ==
CMS && !encryptionAllowed() )
396 setEncryptionAllowed(
true );
398 void slotEncryptionAllowedToggled(
bool on ) {
399 if ( !on && protocol ==
CMS && !signingAllowed() )
400 setSigningAllowed(
true );
404 void fillKeySizeComboBoxen();
405 void loadDefaultKeyType();
406 void updateWidgetVisibility();
409 GpgME::Protocol protocol;
410 unsigned int pgpDefaultAlgorithm;
411 unsigned int cmsDefaultAlgorithm;
412 bool keyTypeImmutable;
413 Ui_AdvancedSettingsDialog ui;
416 class ChooseProtocolPage :
public WizardPage {
419 explicit ChooseProtocolPage(
QWidget * p=0 )
421 initialized( false ),
428 void setProtocol( Protocol proto ) {
430 ui.pgpCLB->setChecked(
true );
431 else if ( proto ==
CMS )
432 ui.x509CLB->setChecked(
true );
439 Protocol protocol()
const {
441 ui.pgpCLB->isChecked() ?
OpenPGP :
442 ui.x509CLB->isChecked() ?
CMS : UnknownProtocol ;
445 void initializePage() {
446 if ( !initialized ) {
447 connect( ui.pgpCLB, SIGNAL(clicked()), wizard(), SLOT(next()), Qt::QueuedConnection );
448 connect( ui.x509CLB, SIGNAL(clicked()), wizard(), SLOT(next()), Qt::QueuedConnection );
453 bool isComplete()
const {
454 return protocol() != UnknownProtocol ;
458 bool initialized : 1;
459 Ui_ChooseProtocolPage ui;
469 class EnterDetailsPage :
public WizardPage {
472 explicit EnterDetailsPage(
QWidget * p=0 )
473 : WizardPage( p ), dialog( this ), ui()
479 ui.errorLB->setFixedHeight( ui.errorLB->minimumSizeHint().height() );
482 connect( ui.resultLE, SIGNAL(textChanged(
QString)),
483 SIGNAL(completeChanged()) );
485 connect( ui.emailLE, SIGNAL(textChanged(
QString)),
486 SIGNAL(completeChanged()) );
487 connect( ui.addEmailToDnCB, SIGNAL(toggled(
bool)),
488 SLOT(slotUpdateResultLabel()) );
489 registerDialogPropertiesAsFields();
497 bool isComplete()
const;
498 void initializePage() {
510 void registerDialogPropertiesAsFields();
517 void slotAdvancedSettingsClicked();
518 void slotUpdateResultLabel() {
519 ui.resultLE->setText( pgp() ? pgpUserID() : cmsDN() );
526 AdvancedSettingsDialog dialog;
527 Ui_EnterDetailsPage ui;
530 class OverviewPage :
public WizardPage {
533 explicit OverviewPage(
QWidget * p=0 )
534 : WizardPage( p ), ui()
537 setCommitPage(
true );
538 setButtonText( QWizard::CommitButton, i18nc(
"@action",
"Create Key") );
541 void initializePage() {
546 void slotShowDetails() {
547 ui.textBrowser->setHtml( i18nFormatGnupgKeyParms( ui.showAllDetailsCB->isChecked() ) );
554 QString i18nFormatGnupgKeyParms(
bool details )
const;
560 class KeyCreationPage :
public WizardPage {
563 explicit KeyCreationPage(
QWidget * p=0 )
570 bool isComplete()
const {
574 void initializePage() {
580 const CryptoBackend::Protocol *
const proto = CryptoBackendFactory::instance()->protocol( pgp() ?
OpenPGP :
CMS );
583 KeyGenerationJob *
const j = proto->keyGenerationJob();
588 if (
const Error err = j->start( createGnupgKeyParms() ) )
589 setField(
QLatin1String(
"error"), i18n(
"Could not start certificate creation: %1",
596 QString createGnupgKeyParms()
const;
599 void slotResult(
const GpgME::KeyGenerationResult & result,
const QByteArray & request,
const QString & auditLog )
601 Q_UNUSED( auditLog );
602 if ( result.error().code() ) {
603 setField(
QLatin1String(
"error"), result.error().isCanceled()
604 ? i18n(
"Operation canceled.")
605 : i18n(
"Could not create certificate: %1",
606 QString::fromLocal8Bit( result.error().asString() ) ) );
609 }
else if ( pgp() ) {
612 setField(
QLatin1String(
"result"), i18n(
"Certificate created successfully.\n"
617 if ( !file.open( QIODevice::WriteOnly ) ) {
618 setField(
QLatin1String(
"error"), i18n(
"Could not write output file %1: %2",
619 file.fileName(), file.errorString() ) );
623 file.write( request );
626 setField(
QLatin1String(
"result"), i18n(
"Certificate created successfully.") );
631 emit completeChanged();
637 Ui_KeyCreationPage ui;
640 class ResultPage :
public WizardPage {
643 explicit ResultPage(
QWidget * p=0 )
645 initialized( false ),
646 successfullyCreatedSigningCertificate( false ),
647 successfullyCreatedEncryptionCertificate( false ),
651 ui.dragQueen->setPixmap( KIcon(
QLatin1String(
"kleopatra") ).pixmap( 64, 64 ) );
652 registerField(
QLatin1String(
"error"), ui.errorTB,
"plainText" );
653 registerField(
QLatin1String(
"result"), ui.resultTB,
"plainText" );
661 void initializePage() {
662 const bool error = isError();
665 setTitle( i18nc(
"@title",
"Key Creation Failed") );
666 setSubTitle( i18n(
"Key pair creation failed. Please find details about the failure below.") );
668 setTitle( i18nc(
"@title",
"Key Pair Successfully Created") );
669 setSubTitle( i18n(
"Your new key pair was created successfully. Please find details on the result and some suggested next steps below.") );
672 ui.resultTB ->setVisible( !error );
673 ui.errorTB ->setVisible( error );
674 ui.dragQueen ->setVisible( !error && !pgp() );
675 ui.restartWizardPB ->setVisible( error );
676 ui.nextStepsGB ->setVisible( !error );
677 ui.saveRequestToFilePB ->setVisible( !pgp() );
678 ui.makeBackupPB ->setVisible( pgp() );
679 ui.createRevocationRequestPB->setVisible( pgp() &&
false );
681 #ifdef KDEPIM_MOBILE_UI
682 ui.sendCertificateByEMailPB ->setVisible(
false );
683 ui.sendRequestByEMailPB ->setVisible(
false );
684 ui.uploadToKeyserverPB ->setVisible(
false );
686 ui.sendCertificateByEMailPB ->setVisible( pgp() );
687 ui.sendRequestByEMailPB ->setVisible( !pgp() );
688 ui.uploadToKeyserverPB ->setVisible( pgp() );
691 if ( !error && !pgp() ) {
692 if ( signingAllowed() && !encryptionAllowed() )
693 successfullyCreatedSigningCertificate =
true;
694 else if ( !signingAllowed() && encryptionAllowed() )
695 successfullyCreatedEncryptionCertificate =
true;
697 successfullyCreatedEncryptionCertificate = successfullyCreatedSigningCertificate =
true;
700 ui.createSigningCertificatePB->setVisible( successfullyCreatedEncryptionCertificate && !successfullyCreatedSigningCertificate );
701 ui.createEncryptionCertificatePB->setVisible( successfullyCreatedSigningCertificate && !successfullyCreatedEncryptionCertificate );
703 setButtonVisible( QWizard::CancelButton, error );
706 connect( ui.restartWizardPB, SIGNAL(clicked()),
707 wizard(), SLOT(restart()) );
712 setButtonVisible( QWizard::CancelButton,
true );
715 bool isError()
const {
716 return !ui.errorTB->toPlainText().isEmpty();
719 bool isComplete()
const {
725 return KeyCache::instance()->findByFingerprint( fingerprint().toLatin1().constData() );
729 void slotSaveRequestToFile() {
736 QFile src(
QUrl( url() ).toLocalFile() );
737 if ( !src.copy( fileName ) )
738 KMessageBox::error(
this,
740 "Could not copy temporary file <filename>%1</filename> "
741 "to file <filename>%2</filename>: <message>%3</message>",
742 src.fileName(), fileName, src.errorString() ),
743 i18nc(
"@title",
"Error Saving Request") );
745 KMessageBox::information(
this,
747 "<para>Successfully wrote request to <filename>%1</filename>.</para>"
748 "<para>You should now send the request to the Certification Authority (CA).</para>",
750 i18nc(
"@title",
"Request Saved" ) );
753 void slotSendRequestByEMail() {
756 const KConfigGroup config( KGlobal::config(),
"CertificateCreationWizard" );
757 invokeMailer( config.readEntry(
"CAEmailAddress" ),
758 i18n(
"Please process this certificate."),
759 i18n(
"Please process this certificate and inform the sender about the location to fetch the resulting certificate.\n\nThanks,\n"),
763 void slotSendCertificateByEMail() {
764 if ( !pgp() || exportCertificateCommand )
767 connect( cmd, SIGNAL(finished()), SLOT(slotSendCertificateByEMailContinuation()) );
770 exportCertificateCommand = cmd;
773 void slotSendCertificateByEMailContinuation() {
774 if ( !exportCertificateCommand )
777 const QString fileName = exportCertificateCommand->openPGPFileName();
778 kDebug() <<
"fileName" << fileName;
779 exportCertificateCommand = 0;
783 i18n(
"My new OpenPGP certificate"),
784 i18n(
"Please find attached my new OpenPGP certificate."),
790 return "\"\"" + str.
replace(
'"',
"\\\"" ) +
"\"\"";
798 kDebug() <<
"to:" << to <<
"subject:" << subject
799 <<
"body:" << body <<
"attachment:" << attachment;
809 if ( !attachment.isEmpty() )
813 KMessageBox::information(
this,
815 "<para><application>Kleopatra</application> tried to send a mail via your default mail client.</para>"
816 "<para>Some mail clients are known not to support attachments when invoked this way.</para>"
817 "<para>If your mail client does not have an attachment, then drag the <application>Kleopatra</application> icon and drop it on the message compose window of your mail client.</para>"
818 "<para>If that does not work, either, save the request to a file, and then attach that.</para>"),
819 i18nc(
"@title",
"Sending Mail"),
823 void slotUploadCertificateToDirectoryServer() {
828 void slotBackupCertificate() {
833 void slotCreateRevocationRequest() {
837 void slotCreateSigningCertificate() {
838 if ( successfullyCreatedSigningCertificate )
840 toggleSignEncryptAndRestart();
843 void slotCreateEncryptionCertificate() {
844 if ( successfullyCreatedEncryptionCertificate )
846 toggleSignEncryptAndRestart();
850 void toggleSignEncryptAndRestart() {
853 if ( KMessageBox::warningContinueCancel(
856 "This operation will delete the certification request. "
857 "Please make sure that you have sent or saved it before proceeding." ),
858 i18nc(
"@title",
"Certification Request About To Be Deleted") ) != KMessageBox::Continue )
860 const bool sign = signingAllowed();
861 const bool encr = encryptionAllowed();
871 bool initialized : 1;
872 bool successfullyCreatedSigningCertificate : 1;
873 bool successfullyCreatedEncryptionCertificate : 1;
879 class NewCertificateWizard::Private {
880 friend class ::Kleo::NewCertificateWizard;
881 friend class ::Kleo::NewCertificateUi::WizardPage;
889 q->setWindowTitle( i18nc(
"@title",
"Certificate Creation Wizard") );
895 ChooseProtocolPage chooseProtocolPage;
896 EnterDetailsPage enterDetailsPage;
897 OverviewPage overviewPage;
898 KeyCreationPage keyCreationPage;
899 ResultPage resultPage;
902 : chooseProtocolPage( q ),
903 enterDetailsPage( q ),
905 keyCreationPage( q ),
914 q->
setOptions( DisabledBackButtonOnLastPage );
916 q->
setPage( ChooseProtocolPageId, &chooseProtocolPage );
917 q->
setPage( EnterDetailsPageId, &enterDetailsPage );
918 q->
setPage( OverviewPageId, &overviewPage );
919 q->
setPage( KeyCreationPageId, &keyCreationPage );
930 :
QWizard( p ),
d( new Private( this ) )
938 d->ui.chooseProtocolPage.setProtocol( proto );
943 return d->ui.chooseProtocolPage.protocol();
950 return i18n(
"Comment");
952 return i18n(
"EMail");
959 const QString label = pgp ?
pgpLabel( attr ) : Kleo::DNAttributeMapper::instance()->name2label( attr ) ;
964 return i18nc(
"Format string for the labels in the \"Your Personal Data\" page",
965 "%1 (%2)", label, attr );
972 static QString attributeLabelWithColor(
const QString & attr,
bool pgp ) {
987 for (
unsigned int i = 0 ; i < numOidMaps ; ++i )
988 if ( qstricmp( attrUtf8, oidmap[i].
name ) == 0 )
989 return oidmap[i].oid;
993 QDir WizardPage::tmpDir()
const {
997 void EnterDetailsPage::registerDialogPropertiesAsFields() {
999 const QMetaObject *
const mo = dialog.metaObject();
1008 void EnterDetailsPage::saveValues() {
1009 Q_FOREACH(
const Line & line, lineList )
1010 savedValues[
attributeFromKey( line.attr ) ] = line.edit->text().trimmed();
1013 void EnterDetailsPage::clearForm() {
1014 qDeleteAll( dynamicWidgets );
1015 dynamicWidgets.clear();
1021 ui.nameRequiredLB->hide();
1024 ui.emailLE->clear();
1026 ui.emailRequiredLB->hide();
1028 ui.commentLE->hide();
1029 ui.commentLE->clear();
1030 ui.commentLB->hide();
1031 ui.commentRequiredLB->hide();
1033 ui.addEmailToDnCB->hide();
1037 const int idx = l->
indexOf( w );
1046 assert( row < l->rowCount() );
1056 lb->
setText( i18nc(
"interpunctation for labels",
"%1:", label ) );
1058 reqLB->
setText( required ? i18n(
"(required)") : i18n(
"(optional)") );
1061 if ( !validator->
parent() )
1089 void EnterDetailsPage::updateForm() {
1093 const KConfigGroup config( KGlobal::config(),
"CertificateCreationWizard" );
1095 QStringList attrOrder = config.readEntry( pgp() ?
"OpenPGPAttributeOrder" :
"DNAttributeOrder",
QStringList() );
1096 if ( attrOrder.
empty() ) {
1110 Q_FOREACH(
const QString & rawKey, attrOrder ) {
1115 const QString preset = savedValues.value( attr, config.readEntry( attr,
QString() ) );
1117 const bool readonly = config.isEntryImmutable( attr );
1129 ui.addEmailToDnCB->show();
1143 row =
add_row( ui.gridLayout, &dynamicWidgets );
1145 if ( !validator && !regex.
isEmpty() )
1148 QLineEdit * le =
adjust_row( ui.gridLayout, row, label, preset, validator, readonly, required );
1150 const Line line = { key, label, regex, le };
1157 disconnect( le, SIGNAL(textChanged(
QString)),
1158 this, SLOT(slotUpdateResultLabel()) );
1159 connect( le, SIGNAL(textChanged(
QString)),
1160 this, SLOT(slotUpdateResultLabel()) );
1165 lineList = kdtools::copy< QVector<Line> >( lines );
1174 QString EnterDetailsPage::cmsDN()
const {
1181 if ( attr ==
QLatin1String(
"EMAIL") && !ui.addEmailToDnCB->isChecked() )
1185 dn.
append( DN::Attribute( attr, text ) );
1190 QString EnterDetailsPage::pgpUserID()
const {
1194 ui.commentLE->text().
trimmed() );
1201 return v && v->
validate( text, pos ) == QValidator::Intermediate ;
1205 Q_FOREACH(
const Line & line, list ) {
1209 const QString key = line.attr;
1210 kDebug() <<
"requirementsAreMet(): checking \"" << key <<
"\" against \"" << le->
text() <<
"\":";
1211 if ( le->
text().trimmed().isEmpty() ) {
1213 if ( line.regex.isEmpty() )
1214 error = i18nc(
"@info",
"<interface>%1</interface> is required, but empty.", line.label );
1216 error = i18nc(
"@info",
"<interface>%1</interface> is required, but empty.<nl/>"
1217 "Local Admin rule: <icode>%2</icode>", line.label, line.regex );
1221 if ( line.regex.isEmpty() )
1222 error = i18nc(
"@info",
"<interface>%1</interface> is incomplete.", line.label );
1224 error = i18nc(
"@info",
"<interface>%1</interface> is incomplete.<nl/>"
1225 "Local Admin rule: <icode>%2</icode>", line.label, line.regex );
1228 if ( line.regex.isEmpty() )
1229 error = i18nc(
"@info",
"<interface>%1</interface> is invalid.", line.label );
1231 error = i18nc(
"@info",
"<interface>%1</interface> is invalid.<nl/>"
1232 "Local Admin rule: <icode>%2</icode>", line.label, line.regex );
1235 kDebug() <<
"ok" << endl;
1240 bool EnterDetailsPage::isComplete()
const {
1243 ui.errorLB->setText( error );
1247 void EnterDetailsPage::slotAdvancedSettingsClicked() {
1253 if ( signingAllowed() )
1255 if ( encryptionAllowed() && !
is_dsa( keyType() ) && !
is_rsa( subkeyType() ) )
1258 if ( certificationAllowed() )
1260 if ( authenticationAllowed() )
1267 if ( signingAllowed() )
1268 usages << i18n(
"Sign");
1269 if ( encryptionAllowed() && !
is_dsa( keyType() ) && !
is_rsa( subkeyType() ) )
1270 usages << i18n(
"Encrypt");
1272 if ( certificationAllowed() )
1273 usages << i18n(
"Certify");
1274 if ( authenticationAllowed() )
1275 usages << i18n(
"Authenticate");
1279 QStringList KeyCreationPage::subkeyUsages()
const {
1281 if ( encryptionAllowed() && (
is_dsa( keyType() ) ||
is_rsa ( subkeyType() ) ) ) {
1282 assert( subkeyType() );
1288 QStringList OverviewPage::i18nSubkeyUsages()
const {
1290 if ( encryptionAllowed() && (
is_dsa( keyType() ) ||
is_rsa ( subkeyType() ) ) ) {
1291 assert( subkeyType() );
1292 usages << i18n(
"Encrypt");
1297 QStringList OverviewPage::i18nCombinedKeyUsages()
const {
1298 return i18nSubkeyUsages() + i18nKeyUsages();
1302 template <
typename T=QString>
1307 Row(
const QString & k,
const T & v ) : key( k ), value( v ) {}
1309 template <
typename T>
1310 QTextStream & operator<<( QTextStream & s, const Row<T> & row ) {
1311 if ( row.key.isEmpty() )
1314 return s <<
"<tr><td>" << row.key <<
"</td><td>" << row.value <<
"</td></tr>";
1318 QString OverviewPage::i18nFormatGnupgKeyParms(
bool details )
const {
1323 s << Row< >( i18n(
"Name:"),
name() );
1324 s << Row< >( i18n(
"Email Address:"),
email() );
1326 if ( !comment().isEmpty() )
1327 s << Row< >( i18n(
"Comment:"), comment() );
1329 s << Row< >( i18n(
"Subject-DN:"), DN( dn() ).dn(
QLatin1String(
",<br>") ) );
1332 s << Row< >( i18n(
"Key Type:"),
QLatin1String(gpgme_pubkey_algo_name( static_cast<gpgme_pubkey_algo_t>( keyType() ) )) );
1333 if (
const unsigned int strength = keyStrength() )
1334 s << Row< >( i18n(
"Key Strength:"), i18np(
"1 bit",
"%1 bits", strength ) );
1336 s << Row< >( i18n(
"Key Strength:"), i18n(
"default") );
1337 s << Row< >( i18n(
"Certificate Usage:"), i18nCombinedKeyUsages().join(i18nc(
"separator for key usages",
", ")) );
1338 if (
const unsigned int subkey = subkeyType() ) {
1339 s << Row< >( i18n(
"Subkey Type:"),
QLatin1String(gpgme_pubkey_algo_name( static_cast<gpgme_pubkey_algo_t>( subkey ) )) );
1340 if (
const unsigned int strength = subkeyStrength() )
1341 s << Row< >( i18n(
"Subkey Strength:"), i18np(
"1 bit",
"%1 bits", strength ) );
1343 s << Row< >( i18n(
"Subkey Strength:"), i18n(
"default") );
1344 s << Row< >( i18n(
"Subkey Usage:"), i18nSubkeyUsages().join(i18nc(
"separator for key usages",
", ")) );
1347 if ( pgp() && details && expiryDate().isValid() )
1348 s << Row< >( i18n(
"Valid Until:"), KGlobal::locale()->formatDate( expiryDate() ) );
1349 if ( !pgp() && details ) {
1350 Q_FOREACH(
const QString &
email, additionalEMailAddresses() )
1351 s << Row< >( i18n("Add. Email Address:"),email );
1352 Q_FOREACH( const
QString & dns, dnsNames() )
1353 s << Row< >( i18n("DNS Name:"), dns );
1354 Q_FOREACH( const
QString & uri, uris() )
1355 s << Row< >( i18n("URI:"), uri );
1371 QString KeyCreationPage::createGnupgKeyParms()
const {
1374 s <<
"<GnupgKeyParms format=\"internal\">" << endl;
1376 s <<
"%ask-passphrase" << endl;
1377 s <<
"key-type: " << gpgme_pubkey_algo_name( static_cast<gpgme_pubkey_algo_t>( keyType() ) ) << endl;
1378 if (
const unsigned int strength = keyStrength() )
1379 s <<
"key-length: " << strength << endl;
1380 s <<
"key-usage: " << keyUsages().join(
QLatin1String(
" ")) << endl;
1381 if (
const unsigned int subkey = subkeyType() ) {
1382 s <<
"subkey-type: " << gpgme_pubkey_algo_name( static_cast<gpgme_pubkey_algo_t>( subkey ) ) << endl;
1383 if (
const unsigned int strength = subkeyStrength() )
1384 s <<
"subkey-length: " << strength << endl;
1385 s <<
"subkey-usage: " << subkeyUsages().join(
QLatin1String(
" ")) << endl;
1387 if ( pgp() && expiryDate().isValid() )
1388 s <<
"expire-date: " << expiryDate().toString( Qt::ISODate ) << endl;
1391 s <<
"name-real: " <<
name() << endl;
1392 if ( !comment().isEmpty() )
1393 s <<
"name-comment: " << comment() << endl;
1395 s <<
"name-dn: " << dn() << endl;
1396 Q_FOREACH(
const QString & email, additionalEMailAddresses() )
1398 Q_FOREACH( const
QString & dns, dnsNames() )
1400 Q_FOREACH( const
QString & uri, uris() )
1401 s << "
name-uri: " << uri << endl;
1403 s << "</GnupgKeyParms>" << endl;
1404 kDebug() << '\n' << result;
1410 for (
int i = 0, end = sizes.size() ; i != end ; ++i ) {
1411 cb.addItem( i < labels.size() && !labels[i].trimmed().isEmpty()
1413 ? i18ncp(
"%2: some admin-supplied text, %1: key size in bits",
"%2 (1 bit; default)",
"%2 (%1 bits; default)", -sizes[i], labels[i].trimmed() )
1414 : i18ncp(
"%2: some admin-supplied text, %1: key size in bits",
"%2 (1 bit)",
"%2 (%1 bits)", sizes[i], labels[i].trimmed() )
1416 ? i18ncp(
"%1: key size in bits",
"1 bit (default)",
"%1 bits (default)", -sizes[i] )
1417 : i18ncp(
"%1: key size in bits",
"1 bit",
"%1 bits", sizes[i] ),
1418 std::abs( sizes[i] ) );
1420 cb.setCurrentIndex( cb.count() - 1 );
1424 void AdvancedSettingsDialog::fillKeySizeComboBoxen() {
1426 const KConfigGroup config( KGlobal::config(),
"CertificateCreationWizard" );
1436 fill_combobox( *ui.rsaKeyStrengthCB, rsaKeySizes, rsaKeySizeLabels );
1437 fill_combobox( *ui.rsaKeyStrengthSubCB, rsaKeySizes, rsaKeySizeLabels );
1438 fill_combobox( *ui.dsaKeyStrengthCB, dsaKeySizes, dsaKeySizeLabels );
1439 fill_combobox( *ui.elgKeyStrengthCB, elgKeySizes, elgKeySizeLabels );
1443 void AdvancedSettingsDialog::loadDefaultKeyType() {
1445 if ( protocol != CMS && protocol !=
OpenPGP )
1448 const KConfigGroup config( KGlobal::config(),
"CertificateCreationWizard" );
1453 if ( protocol ==
OpenPGP && keyType == QLatin1String(
"DSA") ) {
1454 setKeyType( GPGME_PK_DSA );
1456 }
else if ( protocol ==
OpenPGP && keyType == QLatin1String(
"DSA+ELG") ) {
1457 setKeyType( GPGME_PK_DSA );
1458 setSubkeyType( GPGME_PK_ELG_E );
1460 if ( !keyType.
isEmpty() && keyType != QLatin1String(
"RSA") )
1461 kWarning() <<
"invalid value \"" << qPrintable( keyType )
1462 <<
"\" for entry \"[CertificateCreationWizard]"
1463 << qPrintable( entry ) <<
"\"";
1464 setKeyType( GPGME_PK_RSA );
1465 setSubkeyType( GPGME_PK_RSA );
1468 keyTypeImmutable = config.isEntryImmutable( entry );
1469 updateWidgetVisibility();
1472 void AdvancedSettingsDialog::updateWidgetVisibility() {
1475 if ( ui.tabWidget->indexOf( ui.personalTab ) != -1 )
1476 ui.tabWidget->removeTab( ui.tabWidget->indexOf( ui.personalTab ) );
1478 if ( ui.tabWidget->indexOf( ui.personalTab ) == -1 )
1479 ui.tabWidget->addTab( ui.personalTab, tr2i18n(
"Personal Details", 0 ) );
1481 ui.uidGB->setVisible( protocol ==
OpenPGP );
1482 ui.uidGB->setEnabled(
false );
1483 ui.uidGB->setToolTip( i18nc(
"@info:tooltip",
"Adding more than one User ID is not yet implemented.") );
1484 ui.emailGB->setVisible( protocol == CMS );
1485 ui.dnsGB->setVisible( protocol == CMS );
1486 ui.uriGB->setVisible( protocol == CMS );
1488 if ( keyTypeImmutable ) {
1489 ui.rsaRB->setEnabled(
false );
1490 ui.rsaSubCB->setEnabled(
false );
1491 ui.dsaRB->setEnabled(
false );
1492 ui.elgCB->setEnabled(
false );
1494 ui.rsaRB->setEnabled(
true );
1495 ui.rsaSubCB->setEnabled( protocol ==
OpenPGP );
1496 ui.dsaRB->setEnabled( protocol ==
OpenPGP );
1497 ui.elgCB->setEnabled( protocol ==
OpenPGP );
1499 ui.certificationCB->setVisible( protocol ==
OpenPGP );
1500 ui.authenticationCB->setVisible( protocol ==
OpenPGP );
1502 ui.certificationCB->setChecked(
true );
1503 ui.certificationCB->setEnabled(
false );
1505 if ( protocol == CMS ) {
1506 ui.encryptionCB->setEnabled(
true );
1507 ui.rsaSubCB->setChecked(
false );
1509 ui.expiryDE->setVisible( protocol ==
OpenPGP );
1510 ui.expiryCB->setVisible( protocol ==
OpenPGP );
1511 slotKeyMaterialSelectionChanged();
1514 #include "newcertificatewizard.moc"
static const char CMS_KEY_TYPE_ENTRY[]
QString & append(QChar ch)
QDate addYears(int nyears) const
QValidator * email(QObject *parent=0)
static void set_tab_order(const QList< QWidget * > &wl)
void setPage(int id, QWizardPage *page)
static void set_keysize(QComboBox *cb, unsigned int strength)
void getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan)
void push_back(const T &value)
void setText(const QString &)
void setOptions(QFlags< QWizard::WizardOption > options)
static std::string email(const UserID &uid)
static const char PGP_KEY_TYPE_ENTRY[]
#define FIELD(type, name)
static const char DSA_KEYSIZE_LABELS_ENTRY[]
static int add_row(QGridLayout *l, QList< QWidget * > *wl)
QString & remove(int position, int n)
static const char * oidForAttributeName(const QString &attr)
static int row_index_of(QWidget *w, QGridLayout *l)
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
GpgME::Protocol protocol() const
NewCertificateWizard(QWidget *parent=0)
virtual int indexOf(QWidget *widget) const
void setBuddy(QWidget *buddy)
static bool is_elg(unsigned int algo)
QString fromLocal8Bit(const char *str, int size)
QString fromUtf8(const char *str, int size)
static bool is_dsa(unsigned int algo)
int toInt(bool *ok) const
QByteArray toAce(const QString &domain)
void setProtocol(GpgME::Protocol protocol)
static bool requirementsAreMet(const QVector< Line > &list, QString &error)
static QLineEdit * adjust_row(QGridLayout *l, int row, const QString &label, const QString &preset, QValidator *validator, bool readonly, bool required)
QByteArray & replace(int pos, int len, const char *after)
static void fill_combobox(QComboBox &cb, const QList< int > &sizes, const QStringList &labels)
QValidator * pgpComment(QObject *parent=0)
static const char ELG_KEYSIZE_LABELS_ENTRY[]
const QValidator * validator() const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
void setText(const QString &)
static unsigned int get_keysize(const QComboBox *cb)
static const char DSA_KEYSIZES_ENTRY[]
QString toLocalFile() const
QVariant itemData(int index, int role) const
static bool is_algo(gpgme_pubkey_algo_t algo, KeyAlgo what)
virtual State validate(QString &input, int &pos) const =0
void setParent(QObject *parent)
static const char RSA_KEYSIZES_ENTRY[]
QString getSaveFileName(QWidget *parent=0, const QString &caption=QString(), const QString &dirID=QString(), const QString &filter=QString())
void setOpenPGPFileName(const QString &fileName)
static QString encode_dns(const QString &dns)
QString & replace(int position, int n, QChar after)
QString mid(int position, int n) const
int findData(const QVariant &data, int role, QFlags< Qt::MatchFlag > flags) const
char * toString(const T &value)
static QString encode_email(const QString &email)
QByteArray toPercentEncoding(const QString &input, const QByteArray &exclude, const QByteArray &include)
void setCurrentIndex(int index)
static boost::shared_ptr< const KeyCache > instance()
static QString attributeFromKey(QString key)
QValidator * pgpName(QObject *parent=0)
QString left(int n) const
static QString pgpLabel(const QString &attr)
QString fromLatin1(const char *str, int size)
static bool has_intermediate_input(const QLineEdit *le)
static bool is_rsa(unsigned int algo)
bool openUrl(const QUrl &url)
static const char RSA_KEYSIZE_LABELS_ENTRY[]
QLayoutItem * itemAtPosition(int row, int column) const
void setValidator(const QValidator *v)
static void force_set_checked(QAbstractButton *b, bool on)
QUrl fromEncoded(const QByteArray &input)
QUrl fromLocalFile(const QString &localFile)
static QString attributeLabel(const QString &attr, bool pgp)
static const char ELG_KEYSIZES_ENTRY[]
QByteArray toUtf8() const