18 #include "ui_qgsauthauthoritieseditor.h" 24 #include <QFileDialog> 27 #include <QMessageBox> 29 #include <QPushButton> 30 #include <QSslConfiguration> 48 mAuthNotifyLayout =
new QVBoxLayout;
49 this->setLayout( mAuthNotifyLayout );
51 mAuthNotifyLayout->addWidget( mAuthNotify );
56 connect( btnAddCa, &QToolButton::clicked,
this, &QgsAuthAuthoritiesEditor::btnAddCa_clicked );
57 connect( btnRemoveCa, &QToolButton::clicked,
this, &QgsAuthAuthoritiesEditor::btnRemoveCa_clicked );
58 connect( btnInfoCa, &QToolButton::clicked,
this, &QgsAuthAuthoritiesEditor::btnInfoCa_clicked );
59 connect( btnGroupByOrg, &QToolButton::toggled,
this, &QgsAuthAuthoritiesEditor::btnGroupByOrg_toggled );
60 connect( btnCaFile, &QToolButton::clicked,
this, &QgsAuthAuthoritiesEditor::btnCaFile_clicked );
61 connect( btnCaFileClear, &QToolButton::clicked,
this, &QgsAuthAuthoritiesEditor::btnCaFileClear_clicked );
64 this, &QgsAuthAuthoritiesEditor::authMessageOut );
67 this, &QgsAuthAuthoritiesEditor::refreshCaCertsView );
71 connect( treeWidgetCAs->selectionModel(), &QItemSelectionModel::selectionChanged,
72 this, &QgsAuthAuthoritiesEditor::selectionChanged );
74 connect( treeWidgetCAs, &QTreeWidget::itemDoubleClicked,
75 this, &QgsAuthAuthoritiesEditor::handleDoubleClick );
77 connect( btnViewRefresh, &QAbstractButton::clicked,
this, &QgsAuthAuthoritiesEditor::refreshCaCertsView );
80 if ( !cafileval.isNull() )
82 leCaFile->setText( cafileval.toString() );
85 btnGroupByOrg->setChecked(
false );
87 if ( !sortbyval.isNull() )
88 btnGroupByOrg->setChecked( sortbyval.toBool() );
91 populateCaCertsView();
94 populateUtilitiesMenu();
98 static void setItemBold_( QTreeWidgetItem *item )
100 item->setFirstColumnSpanned(
true );
101 QFont secf( item->font( 0 ) );
102 secf.setBold(
true );
103 item->setFont( 0, secf );
106 void QgsAuthAuthoritiesEditor::setupCaCertsTree()
108 treeWidgetCAs->setColumnCount( 4 );
109 treeWidgetCAs->setHeaderLabels(
110 QStringList() << tr(
"Common Name" )
112 << tr(
"Expiry Date" )
113 << tr(
"Trust Policy" ) );
114 treeWidgetCAs->setColumnWidth( 0, 300 );
115 treeWidgetCAs->setColumnWidth( 1, 75 );
116 treeWidgetCAs->setColumnWidth( 2, 200 );
119 mDbCaSecItem =
new QTreeWidgetItem(
122 static_cast<int>( QgsAuthAuthoritiesEditor::Section ) );
123 setItemBold_( mDbCaSecItem );
124 mDbCaSecItem->setFlags( Qt::ItemIsEnabled );
125 mDbCaSecItem->setExpanded(
true );
126 treeWidgetCAs->insertTopLevelItem( 0, mDbCaSecItem );
128 mFileCaSecItem =
new QTreeWidgetItem(
131 static_cast<int>( QgsAuthAuthoritiesEditor::Section ) );
132 setItemBold_( mFileCaSecItem );
133 mFileCaSecItem->setFlags( Qt::ItemIsEnabled );
134 mFileCaSecItem->setExpanded(
true );
135 treeWidgetCAs->insertTopLevelItem( 0, mFileCaSecItem );
137 mRootCaSecItem =
new QTreeWidgetItem(
140 static_cast<int>( QgsAuthAuthoritiesEditor::Section ) );
141 setItemBold_( mRootCaSecItem );
142 mRootCaSecItem->setFlags( Qt::ItemIsEnabled );
143 mRootCaSecItem->setExpanded(
false );
144 treeWidgetCAs->insertTopLevelItem( 0, mRootCaSecItem );
147 void QgsAuthAuthoritiesEditor::populateCaCertsView()
149 updateCertTrustPolicyCache();
150 populateDatabaseCaCerts();
151 populateFileCaCerts();
152 populateRootCaCerts();
155 void QgsAuthAuthoritiesEditor::refreshCaCertsView()
158 populateCaCertsView();
161 static void removeChildren_( QTreeWidgetItem *item )
163 Q_FOREACH ( QTreeWidgetItem *child, item->takeChildren() )
169 void QgsAuthAuthoritiesEditor::populateDatabaseCaCerts()
171 removeChildren_( mDbCaSecItem );
173 bool expanded = mDbCaSecItem->isExpanded();
174 populateCaCertsSection( mDbCaSecItem,
176 QgsAuthAuthoritiesEditor::DbCaCert );
177 mDbCaSecItem->setExpanded( expanded );
180 void QgsAuthAuthoritiesEditor::populateFileCaCerts()
182 removeChildren_( mFileCaSecItem );
184 bool expanded = mFileCaSecItem->isExpanded();
185 populateCaCertsSection( mFileCaSecItem,
187 QgsAuthAuthoritiesEditor::FileCaCert );
188 mFileCaSecItem->setExpanded( expanded );
191 void QgsAuthAuthoritiesEditor::populateRootCaCerts()
193 removeChildren_( mRootCaSecItem );
195 bool expanded = mRootCaSecItem->isExpanded();
196 populateCaCertsSection( mRootCaSecItem,
198 QgsAuthAuthoritiesEditor::RootCaCert );
199 mRootCaSecItem->setExpanded( expanded );
202 void QgsAuthAuthoritiesEditor::populateCaCertsSection( QTreeWidgetItem *item,
const QList<QSslCertificate> &certs,
203 QgsAuthAuthoritiesEditor::CaType catype )
205 if ( btnGroupByOrg->isChecked() )
207 appendCertsToGroup( certs, catype, item );
211 appendCertsToItem( certs, catype, item );
215 void QgsAuthAuthoritiesEditor::appendCertsToGroup(
const QList<QSslCertificate> &certs,
216 QgsAuthAuthoritiesEditor::CaType catype,
217 QTreeWidgetItem *parent )
224 parent = treeWidgetCAs->currentItem();
228 QMap< QString, QList<QSslCertificate> > orgcerts(
231 QMap< QString, QList<QSslCertificate> >::const_iterator it = orgcerts.constBegin();
232 for ( ; it != orgcerts.constEnd(); ++it )
234 QTreeWidgetItem *grpitem(
new QTreeWidgetItem( parent,
235 QStringList() << it.key(),
236 static_cast<int>( QgsAuthAuthoritiesEditor::OrgName ) ) );
237 grpitem->setFirstColumnSpanned(
true );
238 grpitem->setFlags( Qt::ItemIsEnabled );
239 grpitem->setExpanded(
true );
241 QBrush orgb( grpitem->foreground( 0 ) );
242 orgb.setColor( QColor::fromRgb( 90, 90, 90 ) );
243 grpitem->setForeground( 0, orgb );
244 QFont grpf( grpitem->font( 0 ) );
245 grpf.setItalic(
true );
246 grpitem->setFont( 0, grpf );
248 appendCertsToItem( it.value(), catype, grpitem );
251 parent->sortChildren( 0, Qt::AscendingOrder );
254 void QgsAuthAuthoritiesEditor::appendCertsToItem(
const QList<QSslCertificate> &certs,
255 QgsAuthAuthoritiesEditor::CaType catype,
256 QTreeWidgetItem *parent )
263 parent = treeWidgetCAs->currentItem();
273 Q_FOREACH (
const QSslCertificate &cert, certs )
279 coltxts << QString( cert.serialNumber() );
280 coltxts << cert.expiryDate().toString();
284 if ( trustedids.contains(
id ) )
288 else if ( untrustedids.contains(
id ) || !cert.isValid() )
294 QTreeWidgetItem *item(
new QTreeWidgetItem( parent, coltxts, static_cast<int>( catype ) ) );
297 if ( !cert.isValid() )
299 item->setForeground( 2, redb );
303 if ( trustedids.contains(
id ) )
305 item->setForeground( 3, greenb );
306 if ( cert.isValid() )
311 else if ( untrustedids.contains(
id ) )
313 item->setForeground( 3, redb );
321 item->setData( 0, Qt::UserRole,
id );
324 parent->sortChildren( 0, Qt::AscendingOrder );
327 void QgsAuthAuthoritiesEditor::updateCertTrustPolicyCache()
332 void QgsAuthAuthoritiesEditor::populateUtilitiesMenu()
334 mActionDefaultTrustPolicy =
new QAction( QStringLiteral(
"Change default trust policy" ),
this );
335 connect( mActionDefaultTrustPolicy, &QAction::triggered,
this, &QgsAuthAuthoritiesEditor::editDefaultTrustPolicy );
337 mActionShowTrustedCAs =
new QAction( QStringLiteral(
"Show trusted authorities/issuers" ),
this );
338 connect( mActionShowTrustedCAs, &QAction::triggered,
this, &QgsAuthAuthoritiesEditor::showTrustedCertificateAuthorities );
340 mUtilitiesMenu =
new QMenu(
this );
341 mUtilitiesMenu->addAction( mActionDefaultTrustPolicy );
342 mUtilitiesMenu->addSeparator();
343 mUtilitiesMenu->addAction( mActionShowTrustedCAs );
345 btnUtilities->setMenu( mUtilitiesMenu );
348 void QgsAuthAuthoritiesEditor::showCertInfo( QTreeWidgetItem *item )
353 QString digest( item->data( 0, Qt::UserRole ).toString() );
355 QMap<QString, QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > cacertscache(
358 if ( !cacertscache.contains( digest ) )
360 QgsDebugMsg( QStringLiteral(
"Certificate Authority not in CA certs cache" ) );
364 QSslCertificate cert( cacertscache.value( digest ).second );
367 dlg->setWindowModality( Qt::WindowModal );
368 dlg->resize( 675, 500 );
370 if ( dlg->trustCacheRebuilt() )
373 populateCaCertsView();
378 void QgsAuthAuthoritiesEditor::selectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected )
380 Q_UNUSED( selected );
381 Q_UNUSED( deselected );
385 void QgsAuthAuthoritiesEditor::checkSelection()
388 bool isdbcert =
false;
389 if ( treeWidgetCAs->selectionModel()->selection().length() > 0 )
391 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
393 switch ( ( QgsAuthAuthoritiesEditor::CaType )item->type() )
395 case QgsAuthAuthoritiesEditor::RootCaCert:
398 case QgsAuthAuthoritiesEditor::FileCaCert:
401 case QgsAuthAuthoritiesEditor::DbCaCert:
410 btnRemoveCa->setEnabled( isdbcert );
411 btnInfoCa->setEnabled( iscert );
414 void QgsAuthAuthoritiesEditor::handleDoubleClick( QTreeWidgetItem *item,
int col )
419 switch ( ( QgsAuthAuthoritiesEditor::CaType )item->type() )
421 case QgsAuthAuthoritiesEditor::Section:
424 case QgsAuthAuthoritiesEditor::OrgName:
433 showCertInfo( item );
437 void QgsAuthAuthoritiesEditor::btnAddCa_clicked()
440 dlg->setWindowModality( Qt::WindowModal );
441 dlg->resize( 400, 450 );
447 messageBar()->
pushMessage( tr(
"ERROR storing CA(s) in authentication database" ),
455 Q_FOREACH (
const QSslCertificate &cert, certs )
459 authMessageOut( QObject::tr(
"Could not set trust policy for imported certificates" ),
460 QObject::tr(
"Authorities Manager" ),
465 updateCertTrustPolicyCache();
469 populateDatabaseCaCerts();
470 mDbCaSecItem->setExpanded(
true );
475 void QgsAuthAuthoritiesEditor::btnRemoveCa_clicked()
477 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
481 QgsDebugMsg( QStringLiteral(
"Current tree widget item not set" ) );
485 QString digest( item->data( 0, Qt::UserRole ).toString() );
487 if ( digest.isEmpty() )
489 messageBar()->
pushMessage( tr(
"Certificate id missing" ),
494 QMap<QString, QSslCertificate> mappedcerts(
497 if ( !mappedcerts.contains( digest ) )
499 QgsDebugMsg( QStringLiteral(
"Certificate Authority not in mapped database CAs" ) );
503 if ( QMessageBox::warning(
504 this, tr(
"Remove Certificate Authority" ),
505 tr(
"Are you sure you want to remove the selected " 506 "Certificate Authority from the database?\n\n" 507 "Operation can NOT be undone!" ),
508 QMessageBox::Ok | QMessageBox::Cancel,
509 QMessageBox::Cancel ) == QMessageBox::Cancel )
514 QSslCertificate cert( mappedcerts.value( digest ) );
518 messageBar()->
pushMessage( tr(
"Certificate could not be found in database for id %1:" ).arg( digest ),
525 messageBar()->
pushMessage( tr(
"ERROR removing CA from authentication database for id %1:" ).arg( digest ),
532 messageBar()->
pushMessage( tr(
"ERROR removing cert trust policy from authentication database for id %1:" ).arg( digest ),
539 updateCertTrustPolicyCache();
541 item->parent()->removeChild( item );
545 mDbCaSecItem->setExpanded(
true );
548 void QgsAuthAuthoritiesEditor::btnInfoCa_clicked()
550 if ( treeWidgetCAs->selectionModel()->selection().length() > 0 )
552 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
553 handleDoubleClick( item, 0 );
557 void QgsAuthAuthoritiesEditor::btnGroupByOrg_toggled(
bool checked )
561 authMessageOut( QObject::tr(
"Could not store sort by preference" ),
562 QObject::tr(
"Authorities Manager" ),
565 populateCaCertsView();
568 void QgsAuthAuthoritiesEditor::editDefaultTrustPolicy()
570 QDialog *dlg =
new QDialog(
this );
571 dlg->setWindowTitle( tr(
"Default Trust Policy" ) );
572 QVBoxLayout *layout =
new QVBoxLayout( dlg );
574 QHBoxLayout *hlayout =
new QHBoxLayout();
576 QLabel *lblwarn =
new QLabel( dlg );
577 QStyle *style = QApplication::style();
578 lblwarn->setPixmap( style->standardIcon( QStyle::SP_MessageBoxWarning ).pixmap( 48, 48 ) );
579 lblwarn->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
580 hlayout->addWidget( lblwarn );
582 QLabel *lbltxt =
new QLabel( dlg );
583 lbltxt->setText( tr(
"Changing the default certificate authority trust policy to 'Untrusted' " 584 "can cause unexpected SSL network connection results." ) );
585 lbltxt->setWordWrap(
true );
586 hlayout->addWidget( lbltxt );
588 layout->addLayout( hlayout );
590 QHBoxLayout *hlayout2 =
new QHBoxLayout();
592 QLabel *lblpolicy =
new QLabel( tr(
"Default policy" ), dlg );
593 lblpolicy->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );
594 hlayout2->addWidget( lblpolicy );
596 QComboBox *cmbpolicy =
new QComboBox( dlg );
597 QList < QPair<QgsAuthCertUtils::CertTrustPolicy, QString> > policies;
603 for (
int i = 0; i < policies.size(); i++ )
605 cmbpolicy->addItem( policies.at( i ).second, QVariant( static_cast<int>( policies.at( i ).first ) ) );
608 int idx = cmbpolicy->findData( QVariant( static_cast<int>( mDefaultTrustPolicy ) ) );
609 cmbpolicy->setCurrentIndex( idx == -1 ? 0 : idx );
610 hlayout2->addWidget( cmbpolicy );
612 layout->addLayout( hlayout2 );
614 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Close | QDialogButtonBox::Ok,
615 Qt::Horizontal, dlg );
616 buttonBox->button( QDialogButtonBox::Close )->setDefault(
true );
618 layout->addWidget( buttonBox );
620 connect( buttonBox, &QDialogButtonBox::accepted, dlg, &QDialog::accept );
621 connect( buttonBox, &QDialogButtonBox::rejected, dlg, &QWidget::close );
623 dlg->setLayout( layout );
624 dlg->setWindowModality( Qt::WindowModal );
625 dlg->resize( 400, 200 );
626 dlg->setMinimumSize( 400, 200 );
627 dlg->setMaximumSize( 500, 300 );
632 if ( mDefaultTrustPolicy != trustpolicy )
634 defaultTrustPolicyChanged( trustpolicy );
644 authMessageOut( QObject::tr(
"Could not store default trust policy." ),
645 QObject::tr(
"Authorities Manager" ),
648 mDefaultTrustPolicy = trustpolicy;
651 populateCaCertsView();
654 void QgsAuthAuthoritiesEditor::btnCaFile_clicked()
659 dlg->setWindowModality( Qt::WindowModal );
660 dlg->resize( 400, 250 );
664 if ( !leCaFile->text().isEmpty() )
666 btnCaFileClear_clicked();
670 leCaFile->setText( fn );
674 authMessageOut( QObject::tr(
"Could not store 'CA file path' in authentication database." ),
675 QObject::tr(
"Authorities Manager" ),
681 authMessageOut( QObject::tr(
"Could not store 'CA file allow invalids' setting in authentication database." ),
682 QObject::tr(
"Authorities Manager" ),
691 Q_FOREACH (
const QSslCertificate &cert, certs )
695 authMessageOut( QObject::tr(
"Could not set trust policy for imported certificates." ),
696 QObject::tr(
"Authorities Manager" ),
701 updateCertTrustPolicyCache();
706 populateFileCaCerts();
707 mFileCaSecItem->setExpanded(
true );
712 void QgsAuthAuthoritiesEditor::btnCaFileClear_clicked()
716 authMessageOut( QObject::tr(
"Could not remove 'CA file path' from authentication database." ),
717 QObject::tr(
"Authorities Manager" ),
723 authMessageOut( QObject::tr(
"Could not remove 'CA file allow invalids' setting from authentication database." ),
724 QObject::tr(
"Authorities Manager" ),
731 QString fn( leCaFile->text() );
732 if ( QFile::exists( fn ) )
736 if ( !certs.isEmpty() )
740 messageBar()->
pushMessage( tr(
"ERROR removing cert(s) trust policy from authentication database." ),
745 updateCertTrustPolicyCache();
752 populateFileCaCerts();
755 void QgsAuthAuthoritiesEditor::showTrustedCertificateAuthorities()
758 dlg->setWindowModality( Qt::WindowModal );
759 dlg->resize( 675, 500 );
766 int levelint =
static_cast<int>( level );
774 treeWidgetCAs->setFocus();
776 QWidget::showEvent( e );
784 int QgsAuthAuthoritiesEditor::messageTimeout()
787 return settings.
value( QStringLiteral(
"qgis/messageTimeout" ), 5 ).toInt();
bool rebuildTrustedCaCertsCache()
Rebuild trusted certificate authorities cache.
void messageOut(const QString &message, const QString &tag=QgsAuthManager::AUTH_MAN_TAG, QgsAuthManager::MessageLevel level=QgsAuthManager::INFO) const
Custom logging signal to relay to console output and QgsMessageLog.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
static QList< QSslCertificate > certsFromFile(const QString &certspath)
Returns a list of concatenated certs from a PEM or DER formatted file.
A bar for displaying non-blocking messages to the user.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
bool allowInvalidCerts()
Whether to allow importation of invalid certificates (so trust policy can be overridden) ...
MessageLevel
Level for messages This will be used both for message log and message bar in application.
const QString certFileToImport()
Gets the file path to a certificate to import.
MessageLevel
Message log level (mirrors that of QgsMessageLog, so it can also output there)
bool rebuildCaCertsCache()
Rebuild certificate authority cache.
void showEvent(QShowEvent *e) override
Overridden show event of base widget.
QgsAuthCertUtils::CertTrustPolicy certTrustPolicy()
Defined trust policy for imported certificates.
static QColor redColor()
Red color representing invalid, untrusted, etc. certificate.
Dialog wrapper for widget displaying detailed info on a certificate and its hierarchical trust chain...
static QColor greenColor()
Green color representing valid, trusted, etc. certificate.
bool removeCertTrustPolicies(const QList< QSslCertificate > &certs)
Remove a group certificate authorities.
void authDatabaseChanged()
Emitted when the authentication db is significantly changed, e.g. large record removal, erased, etc.
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::Info, int duration=5)
convenience method for pushing a message to the bar
QgsAuthAuthoritiesEditor(QWidget *parent=nullptr)
Widget for viewing and editing certificate authorities directly in database.
Widget for importing a certificate into the authentication database.
bool storeCertAuthorities(const QList< QSslCertificate > &certs)
Store multiple certificate authorities.
const QList< QSslCertificate > certificatesToImport()
Gets list of certificate objects to import.
static QString shaHexForCert(const QSslCertificate &cert, bool formatted=false)
Gets the sha1 hash for certificate.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
QVariant authSetting(const QString &key, const QVariant &defaultValue=QVariant(), bool decrypt=false)
authSetting get an authentication setting (retrieved as string and returned as QVariant( QString )) ...
const QMap< QgsAuthCertUtils::CertTrustPolicy, QStringList > certTrustCache()
certTrustCache get cache of certificate sha1s, per trust policy
static QMap< QString, QList< QSslCertificate > > certsGroupedByOrg(const QList< QSslCertificate > &certs)
Map certificates to their oraganization.
Widget for listing trusted Certificate (Intermediate) Authorities used in secure connections.
CertTrustPolicy
Type of certificate trust policy.
QgsAuthCertUtils::CertTrustPolicy defaultCertTrustPolicy()
Gets the default certificate trust policy preferred by user.
static QString getCertTrustName(QgsAuthCertUtils::CertTrustPolicy trust)
Gets the general name for certificate trust.
static QString getCaSourceName(QgsAuthCertUtils::CaCertSource source, bool single=false)
Gets the general name for CA source enum type.
static QString resolvedCertName(const QSslCertificate &cert, bool issuer=false)
Gets the general name via RFC 5280 resolution.
bool rebuildCertTrustCache()
Rebuild certificate authority cache.