QGIS API Documentation 3.41.0-Master (57ec4277f5e)
Loading...
Searching...
No Matches
qgsauthauthoritieseditor.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsauthauthoritieseditor.cpp
3 ---------------------
4 begin : April 26, 2015
5 copyright : (C) 2015 by Boundless Spatial, Inc. USA
6 author : Larry Shaffer
7 email : lshaffer at boundlessgeo dot com
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
18#include "moc_qgsauthauthoritieseditor.cpp"
19#include "ui_qgsauthauthoritieseditor.h"
20
21#include <QAction>
22#include <QComboBox>
23#include <QDateTime>
24#include <QDir>
25#include <QFileDialog>
26#include <QFileInfo>
27#include <QMenu>
28#include <QMessageBox>
29#include <QPair>
30#include <QPushButton>
31#include <QSslConfiguration>
32
33#include "qgssettings.h"
34#include "qgsapplication.h"
36#include "qgsauthcertutils.h"
37#include "qgsauthguiutils.h"
39#include "qgsauthmanager.h"
41#include "qgslogger.h"
42#include "qgsvariantutils.h"
43
45 : QWidget( parent )
46{
47 if ( QgsApplication::authManager()->isDisabled() )
48 {
49 mDisabled = true;
50 mAuthNotifyLayout = new QVBoxLayout;
51 this->setLayout( mAuthNotifyLayout );
52 mAuthNotify = new QLabel( QgsApplication::authManager()->disabledMessage(), this );
53 mAuthNotifyLayout->addWidget( mAuthNotify );
54 }
55 else
56 {
57 setupUi( this );
58 connect( btnAddCa, &QToolButton::clicked, this, &QgsAuthAuthoritiesEditor::btnAddCa_clicked );
59 connect( btnRemoveCa, &QToolButton::clicked, this, &QgsAuthAuthoritiesEditor::btnRemoveCa_clicked );
60 connect( btnInfoCa, &QToolButton::clicked, this, &QgsAuthAuthoritiesEditor::btnInfoCa_clicked );
61 connect( btnGroupByOrg, &QToolButton::toggled, this, &QgsAuthAuthoritiesEditor::btnGroupByOrg_toggled );
62 connect( btnCaFile, &QToolButton::clicked, this, &QgsAuthAuthoritiesEditor::btnCaFile_clicked );
63 connect( btnCaFileClear, &QToolButton::clicked, this, &QgsAuthAuthoritiesEditor::btnCaFileClear_clicked );
64
65 connect( QgsApplication::authManager(), &QgsAuthManager::messageLog, this, &QgsAuthAuthoritiesEditor::logMessage );
66
67 connect( QgsApplication::authManager(), &QgsAuthManager::authDatabaseChanged, this, &QgsAuthAuthoritiesEditor::refreshCaCertsView );
68
69 setupCaCertsTree();
70
71 connect( treeWidgetCAs->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsAuthAuthoritiesEditor::selectionChanged );
72
73 connect( treeWidgetCAs, &QTreeWidget::itemDoubleClicked, this, &QgsAuthAuthoritiesEditor::handleDoubleClick );
74
75 connect( btnViewRefresh, &QAbstractButton::clicked, this, &QgsAuthAuthoritiesEditor::refreshCaCertsView );
76
77 const QVariant cafileval = QgsApplication::authManager()->authSetting( QStringLiteral( "cafile" ) );
78 if ( !QgsVariantUtils::isNull( cafileval ) )
79 {
80 leCaFile->setText( cafileval.toString() );
81 }
82
83 btnGroupByOrg->setChecked( false );
84 const QVariant sortbyval = QgsApplication::authManager()->authSetting( QStringLiteral( "casortby" ), QVariant( false ) );
85 if ( !QgsVariantUtils::isNull( sortbyval ) )
86 btnGroupByOrg->setChecked( sortbyval.toBool() );
87
88 mDefaultTrustPolicy = QgsApplication::authManager()->defaultCertTrustPolicy();
89 populateCaCertsView();
90 checkSelection();
91
92 populateUtilitiesMenu();
93 }
94}
95
96void QgsAuthAuthoritiesEditor::setupCaCertsTree()
97{
98 treeWidgetCAs->setColumnCount( 4 );
99 treeWidgetCAs->setHeaderLabels(
100 QStringList() << tr( "Common Name" )
101 << tr( "Serial #" )
102 << tr( "Expiry Date" )
103 << tr( "Trust Policy" )
104 );
105 treeWidgetCAs->setColumnWidth( 0, 300 );
106 treeWidgetCAs->setColumnWidth( 1, 75 );
107 treeWidgetCAs->setColumnWidth( 2, 200 );
108
109 // add root sections
110 mDbCaSecItem = new QTreeWidgetItem(
111 treeWidgetCAs,
113 static_cast<int>( QgsAuthAuthoritiesEditor::Section )
114 );
115 QgsAuthGuiUtils::setItemBold( mDbCaSecItem );
116 mDbCaSecItem->setFlags( Qt::ItemIsEnabled );
117 mDbCaSecItem->setExpanded( true );
118 treeWidgetCAs->insertTopLevelItem( 0, mDbCaSecItem );
119
120 mFileCaSecItem = new QTreeWidgetItem(
121 treeWidgetCAs,
123 static_cast<int>( QgsAuthAuthoritiesEditor::Section )
124 );
125 QgsAuthGuiUtils::setItemBold( mFileCaSecItem );
126 mFileCaSecItem->setFlags( Qt::ItemIsEnabled );
127 mFileCaSecItem->setExpanded( true );
128 treeWidgetCAs->insertTopLevelItem( 0, mFileCaSecItem );
129
130 mRootCaSecItem = new QTreeWidgetItem(
131 treeWidgetCAs,
133 static_cast<int>( QgsAuthAuthoritiesEditor::Section )
134 );
135 QgsAuthGuiUtils::setItemBold( mRootCaSecItem );
136 mRootCaSecItem->setFlags( Qt::ItemIsEnabled );
137 mRootCaSecItem->setExpanded( false );
138 treeWidgetCAs->insertTopLevelItem( 0, mRootCaSecItem );
139}
140
141void QgsAuthAuthoritiesEditor::populateCaCertsView()
142{
143 updateCertTrustPolicyCache();
144 populateDatabaseCaCerts();
145 populateFileCaCerts();
146 populateRootCaCerts();
147}
148
149void QgsAuthAuthoritiesEditor::refreshCaCertsView()
150{
151 // QgsApplication::authManager()->rebuildCaCertsCache();
152 populateCaCertsView();
153}
154
155void QgsAuthAuthoritiesEditor::populateDatabaseCaCerts()
156{
157 QgsAuthGuiUtils::removeChildren( mDbCaSecItem );
158
159 const bool expanded = mDbCaSecItem->isExpanded();
160 populateCaCertsSection( mDbCaSecItem, QgsApplication::authManager()->databaseCAs(), QgsAuthAuthoritiesEditor::DbCaCert );
161 mDbCaSecItem->setExpanded( expanded );
162}
163
164void QgsAuthAuthoritiesEditor::populateFileCaCerts()
165{
166 QgsAuthGuiUtils::removeChildren( mFileCaSecItem );
167
168 const bool expanded = mFileCaSecItem->isExpanded();
169 populateCaCertsSection( mFileCaSecItem, QgsApplication::authManager()->extraFileCAs(), QgsAuthAuthoritiesEditor::FileCaCert );
170 mFileCaSecItem->setExpanded( expanded );
171}
172
173void QgsAuthAuthoritiesEditor::populateRootCaCerts()
174{
175 QgsAuthGuiUtils::removeChildren( mRootCaSecItem );
176
177 const bool expanded = mRootCaSecItem->isExpanded();
178 populateCaCertsSection( mRootCaSecItem, QgsApplication::authManager()->systemRootCAs(), QgsAuthAuthoritiesEditor::RootCaCert );
179 mRootCaSecItem->setExpanded( expanded );
180}
181
182void QgsAuthAuthoritiesEditor::populateCaCertsSection( QTreeWidgetItem *item, const QList<QSslCertificate> &certs, QgsAuthAuthoritiesEditor::CaType catype )
183{
184 if ( btnGroupByOrg->isChecked() )
185 {
186 appendCertsToGroup( certs, catype, item );
187 }
188 else
189 {
190 appendCertsToItem( certs, catype, item );
191 }
192}
193
194void QgsAuthAuthoritiesEditor::appendCertsToGroup( const QList<QSslCertificate> &certs, QgsAuthAuthoritiesEditor::CaType catype, QTreeWidgetItem *parent )
195{
196 if ( certs.empty() )
197 return;
198
199 if ( !parent )
200 {
201 parent = treeWidgetCAs->currentItem();
202 }
203
204 // TODO: find all organizational name, sort and make subsections
205 const QMap<QString, QList<QSslCertificate>> orgcerts(
207 );
208
209 QMap<QString, QList<QSslCertificate>>::const_iterator it = orgcerts.constBegin();
210 for ( ; it != orgcerts.constEnd(); ++it )
211 {
212 QTreeWidgetItem *grpitem( new QTreeWidgetItem( parent, QStringList() << it.key(), static_cast<int>( QgsAuthAuthoritiesEditor::OrgName ) ) );
213 grpitem->setFirstColumnSpanned( true );
214 grpitem->setFlags( Qt::ItemIsEnabled );
215 grpitem->setExpanded( true );
216
217 QBrush orgb( grpitem->foreground( 0 ) );
218 orgb.setColor( QColor::fromRgb( 90, 90, 90 ) );
219 grpitem->setForeground( 0, orgb );
220 QFont grpf( grpitem->font( 0 ) );
221 grpf.setItalic( true );
222 grpitem->setFont( 0, grpf );
223
224 appendCertsToItem( it.value(), catype, grpitem );
225 }
226
227 parent->sortChildren( 0, Qt::AscendingOrder );
228}
229
230void QgsAuthAuthoritiesEditor::appendCertsToItem( const QList<QSslCertificate> &certs, QgsAuthAuthoritiesEditor::CaType catype, QTreeWidgetItem *parent )
231{
232 if ( certs.empty() )
233 return;
234
235 if ( !parent )
236 {
237 parent = treeWidgetCAs->currentItem();
238 }
239
240 const QBrush greenb( QgsAuthGuiUtils::greenColor() );
241 const QBrush redb( QgsAuthGuiUtils::redColor() );
242
243 const QStringList trustedids = mCertTrustCache.value( QgsAuthCertUtils::Trusted );
244 const QStringList untrustedids = mCertTrustCache.value( QgsAuthCertUtils::Untrusted );
245
246 // Columns: Common Name, Serial #, Expiry Date
247 const auto constCerts = certs;
248 for ( const QSslCertificate &cert : constCerts )
249 {
250 const QString id( QgsAuthCertUtils::shaHexForCert( cert ) );
251
252 QStringList coltxts;
253 coltxts << QgsAuthCertUtils::resolvedCertName( cert );
254 coltxts << QString( cert.serialNumber() );
255 coltxts << cert.expiryDate().toString();
256
257 // trust policy
258 QString policy( QgsAuthCertUtils::getCertTrustName( mDefaultTrustPolicy ) );
259 if ( trustedids.contains( id ) )
260 {
262 }
263 else if ( untrustedids.contains( id )
264 || cert.isBlacklisted()
265 || cert.isNull()
266 || cert.expiryDate() <= QDateTime::currentDateTime()
267 || cert.effectiveDate() > QDateTime::currentDateTime() )
268 {
270 }
271 coltxts << policy;
272
273 QTreeWidgetItem *item( new QTreeWidgetItem( parent, coltxts, static_cast<int>( catype ) ) );
274
275 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificate.svg" ) ) );
276 if ( cert.isBlacklisted()
277 || cert.isNull()
278 || cert.expiryDate() <= QDateTime::currentDateTime()
279 || cert.effectiveDate() > QDateTime::currentDateTime() )
280 {
281 item->setForeground( 2, redb );
282 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateUntrusted.svg" ) ) );
283 }
284
285 if ( trustedids.contains( id ) )
286 {
287 item->setForeground( 3, greenb );
288 if ( !cert.isBlacklisted()
289 && !cert.isNull()
290 && cert.expiryDate() > QDateTime::currentDateTime()
291 && cert.effectiveDate() <= QDateTime::currentDateTime() )
292 {
293 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateTrusted.svg" ) ) );
294 }
295 }
296 else if ( untrustedids.contains( id ) )
297 {
298 item->setForeground( 3, redb );
299 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateUntrusted.svg" ) ) );
300 }
301 else if ( mDefaultTrustPolicy == QgsAuthCertUtils::Untrusted )
302 {
303 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateUntrusted.svg" ) ) );
304 }
305
306 item->setData( 0, Qt::UserRole, id );
307 }
308
309 parent->sortChildren( 0, Qt::AscendingOrder );
310}
311
312void QgsAuthAuthoritiesEditor::updateCertTrustPolicyCache()
313{
314 mCertTrustCache = QgsApplication::authManager()->certTrustCache();
315}
316
317void QgsAuthAuthoritiesEditor::populateUtilitiesMenu()
318{
319 mActionDefaultTrustPolicy = new QAction( QStringLiteral( "Change default trust policy" ), this );
320 connect( mActionDefaultTrustPolicy, &QAction::triggered, this, &QgsAuthAuthoritiesEditor::editDefaultTrustPolicy );
321
322 mActionShowTrustedCAs = new QAction( QStringLiteral( "Show trusted authorities/issuers" ), this );
323 connect( mActionShowTrustedCAs, &QAction::triggered, this, &QgsAuthAuthoritiesEditor::showTrustedCertificateAuthorities );
324
325 mUtilitiesMenu = new QMenu( this );
326 mUtilitiesMenu->addAction( mActionDefaultTrustPolicy );
327 mUtilitiesMenu->addSeparator();
328 mUtilitiesMenu->addAction( mActionShowTrustedCAs );
329
330 btnUtilities->setMenu( mUtilitiesMenu );
331}
332
333void QgsAuthAuthoritiesEditor::showCertInfo( QTreeWidgetItem *item )
334{
335 if ( !item )
336 return;
337
338 const QString digest( item->data( 0, Qt::UserRole ).toString() );
339
340 const QMap<QString, QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate>> cacertscache(
341 QgsApplication::authManager()->caCertsCache()
342 );
343
344 if ( !cacertscache.contains( digest ) )
345 {
346 QgsDebugError( QStringLiteral( "Certificate Authority not in CA certs cache" ) );
347 return;
348 }
349
350 const QSslCertificate cert( cacertscache.value( digest ).second );
351
352 QgsAuthCertInfoDialog *dlg = new QgsAuthCertInfoDialog( cert, true, this );
353 dlg->setWindowModality( Qt::WindowModal );
354 dlg->resize( 675, 500 );
355 dlg->exec();
356 if ( dlg->trustCacheRebuilt() )
357 {
358 // QgsApplication::authManager()->rebuildTrustedCaCertsCache() already called in dlg
359 populateCaCertsView();
360 }
361 dlg->deleteLater();
362}
363
364void QgsAuthAuthoritiesEditor::selectionChanged( const QItemSelection &selected, const QItemSelection &deselected )
365{
366 Q_UNUSED( selected )
367 Q_UNUSED( deselected )
368 checkSelection();
369}
370
371void QgsAuthAuthoritiesEditor::checkSelection()
372{
373 bool iscert = false;
374 bool isdbcert = false;
375 if ( treeWidgetCAs->selectionModel()->selection().length() > 0 )
376 {
377 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
378
379 switch ( ( QgsAuthAuthoritiesEditor::CaType ) item->type() )
380 {
381 case QgsAuthAuthoritiesEditor::RootCaCert:
382 iscert = true;
383 break;
384 case QgsAuthAuthoritiesEditor::FileCaCert:
385 iscert = true;
386 break;
387 case QgsAuthAuthoritiesEditor::DbCaCert:
388 iscert = true;
389 isdbcert = true;
390 break;
391 default:
392 break;
393 }
394 }
395
396 btnRemoveCa->setEnabled( isdbcert );
397 btnInfoCa->setEnabled( iscert );
398}
399
400void QgsAuthAuthoritiesEditor::handleDoubleClick( QTreeWidgetItem *item, int col )
401{
402 Q_UNUSED( col )
403 bool iscert = true;
404
405 switch ( ( QgsAuthAuthoritiesEditor::CaType ) item->type() )
406 {
407 case QgsAuthAuthoritiesEditor::Section:
408 iscert = false;
409 break;
410 case QgsAuthAuthoritiesEditor::OrgName:
411 iscert = false;
412 break;
413 default:
414 break;
415 }
416
417 if ( iscert )
418 {
419 showCertInfo( item );
420 }
421}
422
423void QgsAuthAuthoritiesEditor::btnAddCa_clicked()
424{
426 dlg->setWindowModality( Qt::WindowModal );
427 dlg->resize( 400, 450 );
428 if ( dlg->exec() )
429 {
430 const QList<QSslCertificate> &certs( dlg->certificatesToImport() );
431 if ( !QgsApplication::authManager()->storeCertAuthorities( certs ) )
432 {
433 messageBar()->pushMessage( tr( "ERROR storing CA(s) in authentication database" ), Qgis::MessageLevel::Critical );
434 }
435
437
439 {
440 const auto constCerts = certs;
441 for ( const QSslCertificate &cert : constCerts )
442 {
443 if ( !QgsApplication::authManager()->storeCertTrustPolicy( cert, dlg->certTrustPolicy() ) )
444 {
445 logMessage( QObject::tr( "Could not set trust policy for imported certificates" ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
446 }
447 }
449 updateCertTrustPolicyCache();
450 }
451
453 populateDatabaseCaCerts();
454 mDbCaSecItem->setExpanded( true );
455 }
456 dlg->deleteLater();
457}
458
459void QgsAuthAuthoritiesEditor::btnRemoveCa_clicked()
460{
461 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
462
463 if ( !item )
464 {
465 QgsDebugMsgLevel( QStringLiteral( "Current tree widget item not set" ), 2 );
466 return;
467 }
468
469 const QString digest( item->data( 0, Qt::UserRole ).toString() );
470
471 if ( digest.isEmpty() )
472 {
473 messageBar()->pushMessage( tr( "Certificate id missing" ), Qgis::MessageLevel::Warning );
474 return;
475 }
476
477 const QMap<QString, QSslCertificate> mappedcerts(
478 QgsApplication::authManager()->mappedDatabaseCAs()
479 );
480
481 if ( !mappedcerts.contains( digest ) )
482 {
483 QgsDebugError( QStringLiteral( "Certificate Authority not in mapped database CAs" ) );
484 return;
485 }
486
487 if ( QMessageBox::warning(
488 this, tr( "Remove Certificate Authority" ),
489 tr( "Are you sure you want to remove the selected "
490 "Certificate Authority from the database?\n\n"
491 "Operation can NOT be undone!" ),
492 QMessageBox::Ok | QMessageBox::Cancel,
493 QMessageBox::Cancel
494 )
495 == QMessageBox::Cancel )
496 {
497 return;
498 }
499
500 const QSslCertificate cert( mappedcerts.value( digest ) );
501
502 if ( cert.isNull() )
503 {
504 messageBar()->pushMessage( tr( "Certificate could not be found in database for id %1:" ).arg( digest ), Qgis::MessageLevel::Warning );
505 return;
506 }
507
508 if ( !QgsApplication::authManager()->removeCertAuthority( cert ) )
509 {
510 messageBar()->pushMessage( tr( "ERROR removing CA from authentication database for id %1:" ).arg( digest ), Qgis::MessageLevel::Critical );
511 return;
512 }
513
514 if ( !QgsApplication::authManager()->removeCertTrustPolicy( cert ) )
515 {
516 messageBar()->pushMessage( tr( "ERROR removing cert trust policy from authentication database for id %1:" ).arg( digest ), Qgis::MessageLevel::Critical );
517 return;
518 }
519
522 updateCertTrustPolicyCache();
523
524 item->parent()->removeChild( item );
525 delete item;
526
527 // populateDatabaseCaCerts();
528 mDbCaSecItem->setExpanded( true );
529}
530
531void QgsAuthAuthoritiesEditor::btnInfoCa_clicked()
532{
533 if ( treeWidgetCAs->selectionModel()->selection().length() > 0 )
534 {
535 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
536 handleDoubleClick( item, 0 );
537 }
538}
539
540void QgsAuthAuthoritiesEditor::btnGroupByOrg_toggled( bool checked )
541{
542 if ( !QgsApplication::authManager()->storeAuthSetting( QStringLiteral( "casortby" ), QVariant( checked ) ) )
543 {
544 logMessage( QObject::tr( "Could not store sort by preference" ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
545 }
546 populateCaCertsView();
547}
548
549void QgsAuthAuthoritiesEditor::editDefaultTrustPolicy()
550{
551 QDialog *dlg = new QDialog( this );
552 dlg->setWindowTitle( tr( "Default Trust Policy" ) );
553 QVBoxLayout *layout = new QVBoxLayout( dlg );
554
555 QHBoxLayout *hlayout = new QHBoxLayout();
556
557 QLabel *lblwarn = new QLabel( dlg );
558 QStyle *style = QApplication::style();
559 lblwarn->setPixmap( style->standardIcon( QStyle::SP_MessageBoxWarning ).pixmap( 48, 48 ) );
560 lblwarn->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
561 hlayout->addWidget( lblwarn );
562
563 QLabel *lbltxt = new QLabel( dlg );
564 lbltxt->setText( tr( "Changing the default certificate authority trust policy to 'Untrusted' "
565 "can cause unexpected SSL network connection results." ) );
566 lbltxt->setWordWrap( true );
567 hlayout->addWidget( lbltxt );
568
569 layout->addLayout( hlayout );
570
571 QHBoxLayout *hlayout2 = new QHBoxLayout();
572
573 QLabel *lblpolicy = new QLabel( tr( "Default policy" ), dlg );
574 lblpolicy->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );
575 hlayout2->addWidget( lblpolicy );
576
577 QComboBox *cmbpolicy = new QComboBox( dlg );
578 QList<QPair<QgsAuthCertUtils::CertTrustPolicy, QString>> policies;
581
582 for ( int i = 0; i < policies.size(); i++ )
583 {
584 cmbpolicy->addItem( policies.at( i ).second, QVariant( static_cast<int>( policies.at( i ).first ) ) );
585 }
586
587 const int idx = cmbpolicy->findData( QVariant( static_cast<int>( mDefaultTrustPolicy ) ) );
588 cmbpolicy->setCurrentIndex( idx == -1 ? 0 : idx );
589 hlayout2->addWidget( cmbpolicy );
590
591 layout->addLayout( hlayout2 );
592
593 QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Close | QDialogButtonBox::Ok, Qt::Horizontal, dlg );
594 buttonBox->button( QDialogButtonBox::Close )->setDefault( true );
595
596 layout->addWidget( buttonBox );
597
598 connect( buttonBox, &QDialogButtonBox::accepted, dlg, &QDialog::accept );
599 connect( buttonBox, &QDialogButtonBox::rejected, dlg, &QWidget::close );
600
601 dlg->setLayout( layout );
602 dlg->setWindowModality( Qt::WindowModal );
603 dlg->resize( 400, 200 );
604 dlg->setMinimumSize( 400, 200 );
605 dlg->setMaximumSize( 500, 300 );
606 if ( dlg->exec() )
607 {
608 const QgsAuthCertUtils::CertTrustPolicy trustpolicy(
609 ( QgsAuthCertUtils::CertTrustPolicy ) cmbpolicy->currentData().toInt()
610 );
611 if ( mDefaultTrustPolicy != trustpolicy )
612 {
613 defaultTrustPolicyChanged( trustpolicy );
614 }
615 }
616 dlg->deleteLater();
617}
618
619void QgsAuthAuthoritiesEditor::defaultTrustPolicyChanged( QgsAuthCertUtils::CertTrustPolicy trustpolicy )
620{
621 if ( !QgsApplication::authManager()->setDefaultCertTrustPolicy( trustpolicy ) )
622 {
623 logMessage( QObject::tr( "Could not store default trust policy." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Critical );
624 }
625 mDefaultTrustPolicy = trustpolicy;
628 populateCaCertsView();
629}
630
631void QgsAuthAuthoritiesEditor::btnCaFile_clicked()
632{
634 dlg->setWindowModality( Qt::WindowModal );
635 dlg->resize( 400, 250 );
636 if ( dlg->exec() )
637 {
638 // clear out any currently defined file certs and their trust settings
639 if ( !leCaFile->text().isEmpty() )
640 {
641 btnCaFileClear_clicked();
642 }
643
644 const QString &fn = dlg->certFileToImport();
645 leCaFile->setText( fn );
646
647 if ( !QgsApplication::authManager()->storeAuthSetting( QStringLiteral( "cafile" ), QVariant( fn ) ) )
648 {
649 logMessage( QObject::tr( "Could not store 'CA file path' in authentication database." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
650 }
651 if ( !QgsApplication::authManager()->storeAuthSetting( QStringLiteral( "cafileallowinvalid" ), QVariant( dlg->allowInvalidCerts() ) ) )
652 {
653 logMessage( QObject::tr( "Could not store 'CA file allow invalids' setting in authentication database." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
654 }
655
657
659 {
660 const QList<QSslCertificate> certs( QgsApplication::authManager()->extraFileCAs() );
661 const auto constCerts = certs;
662 for ( const QSslCertificate &cert : constCerts )
663 {
664 if ( !QgsApplication::authManager()->storeCertTrustPolicy( cert, dlg->certTrustPolicy() ) )
665 {
666 logMessage( QObject::tr( "Could not set trust policy for imported certificates." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
667 }
668 }
670 updateCertTrustPolicyCache();
671 }
672
674
675 populateFileCaCerts();
676 mFileCaSecItem->setExpanded( true );
677 }
678 dlg->deleteLater();
679}
680
681void QgsAuthAuthoritiesEditor::btnCaFileClear_clicked()
682{
683 if ( !QgsApplication::authManager()->removeAuthSetting( QStringLiteral( "cafile" ) ) )
684 {
685 logMessage( QObject::tr( "Could not remove 'CA file path' from authentication database." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
686 return;
687 }
688 if ( !QgsApplication::authManager()->removeAuthSetting( QStringLiteral( "cafileallowinvalid" ) ) )
689 {
690 logMessage( QObject::tr( "Could not remove 'CA file allow invalids' setting from authentication database." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
691 return;
692 }
693
695
696 const QString fn( leCaFile->text() );
697 if ( QFile::exists( fn ) )
698 {
699 const QList<QSslCertificate> certs( QgsAuthCertUtils::certsFromFile( fn ) );
700
701 if ( !certs.isEmpty() )
702 {
703 if ( !QgsApplication::authManager()->removeCertTrustPolicies( certs ) )
704 {
705 messageBar()->pushMessage( tr( "ERROR removing cert(s) trust policy from authentication database." ), Qgis::MessageLevel::Critical );
706 return;
707 }
709 updateCertTrustPolicyCache();
710 }
711 }
712
714
715 leCaFile->clear();
716 populateFileCaCerts();
717}
718
719void QgsAuthAuthoritiesEditor::showTrustedCertificateAuthorities()
720{
722 dlg->setWindowModality( Qt::WindowModal );
723 dlg->resize( 675, 500 );
724 dlg->exec();
725 dlg->deleteLater();
726}
727
728void QgsAuthAuthoritiesEditor::logMessage( const QString &message, const QString &authtag, Qgis::MessageLevel level )
729{
730 messageBar()->pushMessage( authtag, message, level, 7 );
731}
732
734{
735 if ( !mDisabled )
736 {
737 treeWidgetCAs->setFocus();
738 }
739 QWidget::showEvent( e );
740}
741
742QgsMessageBar *QgsAuthAuthoritiesEditor::messageBar()
743{
744 return msgBar;
745}
746
747int QgsAuthAuthoritiesEditor::messageTimeout()
748{
749 const QgsSettings settings;
750 return settings.value( QStringLiteral( "qgis/messageTimeout" ), 5 ).toInt();
751}
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:154
@ Warning
Warning message.
Definition qgis.h:156
@ Critical
Critical/error message.
Definition qgis.h:157
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
void showEvent(QShowEvent *e) override
Overridden show event of base widget.
QgsAuthAuthoritiesEditor(QWidget *parent=nullptr)
Widget for viewing and editing certificate authorities directly in database.
Dialog wrapper for widget displaying detailed info on a certificate and its hierarchical trust chain.
bool trustCacheRebuilt()
Whether the trust cache has been rebuilt.
static QString resolvedCertName(const QSslCertificate &cert, bool issuer=false)
Gets the general name via RFC 5280 resolution.
static QMap< QString, QList< QSslCertificate > > certsGroupedByOrg(const QList< QSslCertificate > &certs)
Map certificates to their oraganization.
static QString getCertTrustName(QgsAuthCertUtils::CertTrustPolicy trust)
Gets the general name for certificate trust.
static QString shaHexForCert(const QSslCertificate &cert, bool formatted=false)
Gets the sha1 hash for certificate.
CertTrustPolicy
Type of certificate trust policy.
static QList< QSslCertificate > certsFromFile(const QString &certspath)
Returns a list of concatenated certs from a PEM or DER formatted file.
static QString getCaSourceName(QgsAuthCertUtils::CaCertSource source, bool single=false)
Gets the general name for CA source enum type.
static QColor greenColor()
Green color representing valid, trusted, etc. certificate.
static void setItemBold(QTreeWidgetItem *item)
Call setFirstColumnSpanned(true) on the item and make its font bold.
static void removeChildren(QTreeWidgetItem *item)
Remove the children of the passed item.
static QColor redColor()
Red color representing invalid, untrusted, etc. certificate.
Widget for importing a certificate into the authentication database.
QgsAuthCertUtils::CertTrustPolicy certTrustPolicy()
Defined trust policy for imported certificates.
const QString certFileToImport()
Gets the file path to a certificate to import.
const QList< QSslCertificate > certificatesToImport()
Gets list of certificate objects to import.
bool allowInvalidCerts()
Whether to allow importation of invalid certificates (so trust policy can be overridden)
const QMap< QgsAuthCertUtils::CertTrustPolicy, QStringList > certTrustCache()
certTrustCache get cache of certificate sha1s, per trust policy
bool rebuildCaCertsCache()
Rebuild certificate authority cache.
void authDatabaseChanged()
Emitted when the authentication db is significantly changed, e.g. large record removal,...
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 ))
QgsAuthCertUtils::CertTrustPolicy defaultCertTrustPolicy()
Gets the default certificate trust policy preferred by user.
bool rebuildCertTrustCache()
Rebuild certificate authority cache.
void messageLog(const QString &message, const QString &tag=QgsAuthManager::AUTH_MAN_TAG, Qgis::MessageLevel level=Qgis::MessageLevel::Info) const
Custom logging signal to relay to console output and QgsMessageLog.
bool rebuildTrustedCaCertsCache()
Rebuild trusted certificate authorities cache.
Widget for listing trusted Certificate (Intermediate) Authorities used in secure connections.
A bar for displaying non-blocking messages to the user.
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::MessageLevel::Info, int duration=-1)
A convenience method for pushing a message with the specified text to the bar.
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39
#define QgsDebugError(str)
Definition qgslogger.h:38