QGIS API Documentation 3.41.0-Master (fda2aa46e9a)
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
66 this, &QgsAuthAuthoritiesEditor::logMessage );
67
69 this, &QgsAuthAuthoritiesEditor::refreshCaCertsView );
70
71 setupCaCertsTree();
72
73 connect( treeWidgetCAs->selectionModel(), &QItemSelectionModel::selectionChanged,
74 this, &QgsAuthAuthoritiesEditor::selectionChanged );
75
76 connect( treeWidgetCAs, &QTreeWidget::itemDoubleClicked,
77 this, &QgsAuthAuthoritiesEditor::handleDoubleClick );
78
79 connect( btnViewRefresh, &QAbstractButton::clicked, this, &QgsAuthAuthoritiesEditor::refreshCaCertsView );
80
81 const QVariant cafileval = QgsApplication::authManager()->authSetting( QStringLiteral( "cafile" ) );
82 if ( !QgsVariantUtils::isNull( cafileval ) )
83 {
84 leCaFile->setText( cafileval.toString() );
85 }
86
87 btnGroupByOrg->setChecked( false );
88 const QVariant sortbyval = QgsApplication::authManager()->authSetting( QStringLiteral( "casortby" ), QVariant( false ) );
89 if ( !QgsVariantUtils::isNull( sortbyval ) )
90 btnGroupByOrg->setChecked( sortbyval.toBool() );
91
92 mDefaultTrustPolicy = QgsApplication::authManager()->defaultCertTrustPolicy();
93 populateCaCertsView();
94 checkSelection();
95
96 populateUtilitiesMenu();
97 }
98}
99
100static void setItemBold_( QTreeWidgetItem *item )
101{
102 item->setFirstColumnSpanned( true );
103 QFont secf( item->font( 0 ) );
104 secf.setBold( true );
105 item->setFont( 0, secf );
106}
107
108void QgsAuthAuthoritiesEditor::setupCaCertsTree()
109{
110 treeWidgetCAs->setColumnCount( 4 );
111 treeWidgetCAs->setHeaderLabels(
112 QStringList() << tr( "Common Name" )
113 << tr( "Serial #" )
114 << tr( "Expiry Date" )
115 << tr( "Trust Policy" ) );
116 treeWidgetCAs->setColumnWidth( 0, 300 );
117 treeWidgetCAs->setColumnWidth( 1, 75 );
118 treeWidgetCAs->setColumnWidth( 2, 200 );
119
120 // add root sections
121 mDbCaSecItem = new QTreeWidgetItem(
122 treeWidgetCAs,
124 static_cast<int>( QgsAuthAuthoritiesEditor::Section ) );
125 setItemBold_( mDbCaSecItem );
126 mDbCaSecItem->setFlags( Qt::ItemIsEnabled );
127 mDbCaSecItem->setExpanded( true );
128 treeWidgetCAs->insertTopLevelItem( 0, mDbCaSecItem );
129
130 mFileCaSecItem = new QTreeWidgetItem(
131 treeWidgetCAs,
133 static_cast<int>( QgsAuthAuthoritiesEditor::Section ) );
134 setItemBold_( mFileCaSecItem );
135 mFileCaSecItem->setFlags( Qt::ItemIsEnabled );
136 mFileCaSecItem->setExpanded( true );
137 treeWidgetCAs->insertTopLevelItem( 0, mFileCaSecItem );
138
139 mRootCaSecItem = new QTreeWidgetItem(
140 treeWidgetCAs,
142 static_cast<int>( QgsAuthAuthoritiesEditor::Section ) );
143 setItemBold_( mRootCaSecItem );
144 mRootCaSecItem->setFlags( Qt::ItemIsEnabled );
145 mRootCaSecItem->setExpanded( false );
146 treeWidgetCAs->insertTopLevelItem( 0, mRootCaSecItem );
147}
148
149void QgsAuthAuthoritiesEditor::populateCaCertsView()
150{
151 updateCertTrustPolicyCache();
152 populateDatabaseCaCerts();
153 populateFileCaCerts();
154 populateRootCaCerts();
155}
156
157void QgsAuthAuthoritiesEditor::refreshCaCertsView()
158{
159// QgsApplication::authManager()->rebuildCaCertsCache();
160 populateCaCertsView();
161}
162
163static void removeChildren_( QTreeWidgetItem *item )
164{
165 const auto constTakeChildren = item->takeChildren();
166 for ( QTreeWidgetItem *child : constTakeChildren )
167 {
168 delete child;
169 }
170}
171
172void QgsAuthAuthoritiesEditor::populateDatabaseCaCerts()
173{
174 removeChildren_( mDbCaSecItem );
175
176 const bool expanded = mDbCaSecItem->isExpanded();
177 populateCaCertsSection( mDbCaSecItem,
178 QgsApplication::authManager()->databaseCAs(),
179 QgsAuthAuthoritiesEditor::DbCaCert );
180 mDbCaSecItem->setExpanded( expanded );
181}
182
183void QgsAuthAuthoritiesEditor::populateFileCaCerts()
184{
185 removeChildren_( mFileCaSecItem );
186
187 const bool expanded = mFileCaSecItem->isExpanded();
188 populateCaCertsSection( mFileCaSecItem,
189 QgsApplication::authManager()->extraFileCAs(),
190 QgsAuthAuthoritiesEditor::FileCaCert );
191 mFileCaSecItem->setExpanded( expanded );
192}
193
194void QgsAuthAuthoritiesEditor::populateRootCaCerts()
195{
196 removeChildren_( mRootCaSecItem );
197
198 const bool expanded = mRootCaSecItem->isExpanded();
199 populateCaCertsSection( mRootCaSecItem,
200 QgsApplication::authManager()->systemRootCAs(),
201 QgsAuthAuthoritiesEditor::RootCaCert );
202 mRootCaSecItem->setExpanded( expanded );
203}
204
205void QgsAuthAuthoritiesEditor::populateCaCertsSection( QTreeWidgetItem *item, const QList<QSslCertificate> &certs,
206 QgsAuthAuthoritiesEditor::CaType catype )
207{
208 if ( btnGroupByOrg->isChecked() )
209 {
210 appendCertsToGroup( certs, catype, item );
211 }
212 else
213 {
214 appendCertsToItem( certs, catype, item );
215 }
216}
217
218void QgsAuthAuthoritiesEditor::appendCertsToGroup( const QList<QSslCertificate> &certs,
219 QgsAuthAuthoritiesEditor::CaType catype,
220 QTreeWidgetItem *parent )
221{
222 if ( certs.empty() )
223 return;
224
225 if ( !parent )
226 {
227 parent = treeWidgetCAs->currentItem();
228 }
229
230 // TODO: find all organizational name, sort and make subsections
231 const QMap< QString, QList<QSslCertificate> > orgcerts(
233
234 QMap< QString, QList<QSslCertificate> >::const_iterator it = orgcerts.constBegin();
235 for ( ; it != orgcerts.constEnd(); ++it )
236 {
237 QTreeWidgetItem *grpitem( new QTreeWidgetItem( parent,
238 QStringList() << it.key(),
239 static_cast<int>( QgsAuthAuthoritiesEditor::OrgName ) ) );
240 grpitem->setFirstColumnSpanned( true );
241 grpitem->setFlags( Qt::ItemIsEnabled );
242 grpitem->setExpanded( true );
243
244 QBrush orgb( grpitem->foreground( 0 ) );
245 orgb.setColor( QColor::fromRgb( 90, 90, 90 ) );
246 grpitem->setForeground( 0, orgb );
247 QFont grpf( grpitem->font( 0 ) );
248 grpf.setItalic( true );
249 grpitem->setFont( 0, grpf );
250
251 appendCertsToItem( it.value(), catype, grpitem );
252 }
253
254 parent->sortChildren( 0, Qt::AscendingOrder );
255}
256
257void QgsAuthAuthoritiesEditor::appendCertsToItem( const QList<QSslCertificate> &certs,
258 QgsAuthAuthoritiesEditor::CaType catype,
259 QTreeWidgetItem *parent )
260{
261 if ( certs.empty() )
262 return;
263
264 if ( !parent )
265 {
266 parent = treeWidgetCAs->currentItem();
267 }
268
269 const QBrush greenb( QgsAuthGuiUtils::greenColor() );
270 const QBrush redb( QgsAuthGuiUtils::redColor() );
271
272 const QStringList trustedids = mCertTrustCache.value( QgsAuthCertUtils::Trusted );
273 const QStringList untrustedids = mCertTrustCache.value( QgsAuthCertUtils::Untrusted );
274
275 // Columns: Common Name, Serial #, Expiry Date
276 const auto constCerts = certs;
277 for ( const QSslCertificate &cert : constCerts )
278 {
279 const QString id( QgsAuthCertUtils::shaHexForCert( cert ) );
280
281 QStringList coltxts;
282 coltxts << QgsAuthCertUtils::resolvedCertName( cert );
283 coltxts << QString( cert.serialNumber() );
284 coltxts << cert.expiryDate().toString();
285
286 // trust policy
287 QString policy( QgsAuthCertUtils::getCertTrustName( mDefaultTrustPolicy ) );
288 if ( trustedids.contains( id ) )
289 {
291 }
292 else if ( untrustedids.contains( id )
293 || cert.isBlacklisted()
294 || cert.isNull()
295 || cert.expiryDate() <= QDateTime::currentDateTime()
296 || cert.effectiveDate() > QDateTime::currentDateTime() )
297 {
299 }
300 coltxts << policy;
301
302 QTreeWidgetItem *item( new QTreeWidgetItem( parent, coltxts, static_cast<int>( catype ) ) );
303
304 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificate.svg" ) ) );
305 if ( cert.isBlacklisted()
306 || cert.isNull()
307 || cert.expiryDate() <= QDateTime::currentDateTime()
308 || cert.effectiveDate() > QDateTime::currentDateTime() )
309 {
310 item->setForeground( 2, redb );
311 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateUntrusted.svg" ) ) );
312 }
313
314 if ( trustedids.contains( id ) )
315 {
316 item->setForeground( 3, greenb );
317 if ( !cert.isBlacklisted()
318 && !cert.isNull()
319 && cert.expiryDate() > QDateTime::currentDateTime()
320 && cert.effectiveDate() <= QDateTime::currentDateTime() )
321 {
322 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateTrusted.svg" ) ) );
323 }
324 }
325 else if ( untrustedids.contains( id ) )
326 {
327 item->setForeground( 3, redb );
328 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateUntrusted.svg" ) ) );
329 }
330 else if ( mDefaultTrustPolicy == QgsAuthCertUtils::Untrusted )
331 {
332 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateUntrusted.svg" ) ) );
333 }
334
335 item->setData( 0, Qt::UserRole, id );
336 }
337
338 parent->sortChildren( 0, Qt::AscendingOrder );
339}
340
341void QgsAuthAuthoritiesEditor::updateCertTrustPolicyCache()
342{
343 mCertTrustCache = QgsApplication::authManager()->certTrustCache();
344}
345
346void QgsAuthAuthoritiesEditor::populateUtilitiesMenu()
347{
348 mActionDefaultTrustPolicy = new QAction( QStringLiteral( "Change default trust policy" ), this );
349 connect( mActionDefaultTrustPolicy, &QAction::triggered, this, &QgsAuthAuthoritiesEditor::editDefaultTrustPolicy );
350
351 mActionShowTrustedCAs = new QAction( QStringLiteral( "Show trusted authorities/issuers" ), this );
352 connect( mActionShowTrustedCAs, &QAction::triggered, this, &QgsAuthAuthoritiesEditor::showTrustedCertificateAuthorities );
353
354 mUtilitiesMenu = new QMenu( this );
355 mUtilitiesMenu->addAction( mActionDefaultTrustPolicy );
356 mUtilitiesMenu->addSeparator();
357 mUtilitiesMenu->addAction( mActionShowTrustedCAs );
358
359 btnUtilities->setMenu( mUtilitiesMenu );
360}
361
362void QgsAuthAuthoritiesEditor::showCertInfo( QTreeWidgetItem *item )
363{
364 if ( !item )
365 return;
366
367 const QString digest( item->data( 0, Qt::UserRole ).toString() );
368
369 const QMap<QString, QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > cacertscache(
370 QgsApplication::authManager()->caCertsCache() );
371
372 if ( !cacertscache.contains( digest ) )
373 {
374 QgsDebugError( QStringLiteral( "Certificate Authority not in CA certs cache" ) );
375 return;
376 }
377
378 const QSslCertificate cert( cacertscache.value( digest ).second );
379
380 QgsAuthCertInfoDialog *dlg = new QgsAuthCertInfoDialog( cert, true, this );
381 dlg->setWindowModality( Qt::WindowModal );
382 dlg->resize( 675, 500 );
383 dlg->exec();
384 if ( dlg->trustCacheRebuilt() )
385 {
386 // QgsApplication::authManager()->rebuildTrustedCaCertsCache() already called in dlg
387 populateCaCertsView();
388 }
389 dlg->deleteLater();
390}
391
392void QgsAuthAuthoritiesEditor::selectionChanged( const QItemSelection &selected, const QItemSelection &deselected )
393{
394 Q_UNUSED( selected )
395 Q_UNUSED( deselected )
396 checkSelection();
397}
398
399void QgsAuthAuthoritiesEditor::checkSelection()
400{
401 bool iscert = false;
402 bool isdbcert = false;
403 if ( treeWidgetCAs->selectionModel()->selection().length() > 0 )
404 {
405 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
406
407 switch ( ( QgsAuthAuthoritiesEditor::CaType )item->type() )
408 {
409 case QgsAuthAuthoritiesEditor::RootCaCert:
410 iscert = true;
411 break;
412 case QgsAuthAuthoritiesEditor::FileCaCert:
413 iscert = true;
414 break;
415 case QgsAuthAuthoritiesEditor::DbCaCert:
416 iscert = true;
417 isdbcert = true;
418 break;
419 default:
420 break;
421 }
422 }
423
424 btnRemoveCa->setEnabled( isdbcert );
425 btnInfoCa->setEnabled( iscert );
426}
427
428void QgsAuthAuthoritiesEditor::handleDoubleClick( QTreeWidgetItem *item, int col )
429{
430 Q_UNUSED( col )
431 bool iscert = true;
432
433 switch ( ( QgsAuthAuthoritiesEditor::CaType )item->type() )
434 {
435 case QgsAuthAuthoritiesEditor::Section:
436 iscert = false;
437 break;
438 case QgsAuthAuthoritiesEditor::OrgName:
439 iscert = false;
440 break;
441 default:
442 break;
443 }
444
445 if ( iscert )
446 {
447 showCertInfo( item );
448 }
449}
450
451void QgsAuthAuthoritiesEditor::btnAddCa_clicked()
452{
454 dlg->setWindowModality( Qt::WindowModal );
455 dlg->resize( 400, 450 );
456 if ( dlg->exec() )
457 {
458 const QList<QSslCertificate> &certs( dlg->certificatesToImport() );
459 if ( !QgsApplication::authManager()->storeCertAuthorities( certs ) )
460 {
461 messageBar()->pushMessage( tr( "ERROR storing CA(s) in authentication database" ),
463 }
464
466
468 {
469 const auto constCerts = certs;
470 for ( const QSslCertificate &cert : constCerts )
471 {
472 if ( !QgsApplication::authManager()->storeCertTrustPolicy( cert, dlg->certTrustPolicy() ) )
473 {
474 logMessage( QObject::tr( "Could not set trust policy for imported certificates" ),
475 QObject::tr( "Authorities Manager" ),
477 }
478 }
480 updateCertTrustPolicyCache();
481 }
482
484 populateDatabaseCaCerts();
485 mDbCaSecItem->setExpanded( true );
486 }
487 dlg->deleteLater();
488}
489
490void QgsAuthAuthoritiesEditor::btnRemoveCa_clicked()
491{
492 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
493
494 if ( !item )
495 {
496 QgsDebugMsgLevel( QStringLiteral( "Current tree widget item not set" ), 2 );
497 return;
498 }
499
500 const QString digest( item->data( 0, Qt::UserRole ).toString() );
501
502 if ( digest.isEmpty() )
503 {
504 messageBar()->pushMessage( tr( "Certificate id missing" ),
506 return;
507 }
508
509 const QMap<QString, QSslCertificate> mappedcerts(
510 QgsApplication::authManager()->mappedDatabaseCAs() );
511
512 if ( !mappedcerts.contains( digest ) )
513 {
514 QgsDebugError( QStringLiteral( "Certificate Authority not in mapped database CAs" ) );
515 return;
516 }
517
518 if ( QMessageBox::warning(
519 this, tr( "Remove Certificate Authority" ),
520 tr( "Are you sure you want to remove the selected "
521 "Certificate Authority from the database?\n\n"
522 "Operation can NOT be undone!" ),
523 QMessageBox::Ok | QMessageBox::Cancel,
524 QMessageBox::Cancel ) == QMessageBox::Cancel )
525 {
526 return;
527 }
528
529 const QSslCertificate cert( mappedcerts.value( digest ) );
530
531 if ( cert.isNull() )
532 {
533 messageBar()->pushMessage( tr( "Certificate could not be found in database for id %1:" ).arg( digest ),
535 return;
536 }
537
538 if ( !QgsApplication::authManager()->removeCertAuthority( cert ) )
539 {
540 messageBar()->pushMessage( tr( "ERROR removing CA from authentication database for id %1:" ).arg( digest ),
542 return;
543 }
544
545 if ( !QgsApplication::authManager()->removeCertTrustPolicy( cert ) )
546 {
547 messageBar()->pushMessage( tr( "ERROR removing cert trust policy from authentication database for id %1:" ).arg( digest ),
549 return;
550 }
551
554 updateCertTrustPolicyCache();
555
556 item->parent()->removeChild( item );
557 delete item;
558
559// populateDatabaseCaCerts();
560 mDbCaSecItem->setExpanded( true );
561}
562
563void QgsAuthAuthoritiesEditor::btnInfoCa_clicked()
564{
565 if ( treeWidgetCAs->selectionModel()->selection().length() > 0 )
566 {
567 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
568 handleDoubleClick( item, 0 );
569 }
570}
571
572void QgsAuthAuthoritiesEditor::btnGroupByOrg_toggled( bool checked )
573{
574 if ( !QgsApplication::authManager()->storeAuthSetting( QStringLiteral( "casortby" ), QVariant( checked ) ) )
575 {
576 logMessage( QObject::tr( "Could not store sort by preference" ),
577 QObject::tr( "Authorities Manager" ),
579 }
580 populateCaCertsView();
581}
582
583void QgsAuthAuthoritiesEditor::editDefaultTrustPolicy()
584{
585 QDialog *dlg = new QDialog( this );
586 dlg->setWindowTitle( tr( "Default Trust Policy" ) );
587 QVBoxLayout *layout = new QVBoxLayout( dlg );
588
589 QHBoxLayout *hlayout = new QHBoxLayout();
590
591 QLabel *lblwarn = new QLabel( dlg );
592 QStyle *style = QApplication::style();
593 lblwarn->setPixmap( style->standardIcon( QStyle::SP_MessageBoxWarning ).pixmap( 48, 48 ) );
594 lblwarn->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
595 hlayout->addWidget( lblwarn );
596
597 QLabel *lbltxt = new QLabel( dlg );
598 lbltxt->setText( tr( "Changing the default certificate authority trust policy to 'Untrusted' "
599 "can cause unexpected SSL network connection results." ) );
600 lbltxt->setWordWrap( true );
601 hlayout->addWidget( lbltxt );
602
603 layout->addLayout( hlayout );
604
605 QHBoxLayout *hlayout2 = new QHBoxLayout();
606
607 QLabel *lblpolicy = new QLabel( tr( "Default policy" ), dlg );
608 lblpolicy->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );
609 hlayout2->addWidget( lblpolicy );
610
611 QComboBox *cmbpolicy = new QComboBox( dlg );
612 QList < QPair<QgsAuthCertUtils::CertTrustPolicy, QString> > policies;
613 policies << qMakePair( QgsAuthCertUtils::Trusted,
615 << qMakePair( QgsAuthCertUtils::Untrusted,
617
618 for ( int i = 0; i < policies.size(); i++ )
619 {
620 cmbpolicy->addItem( policies.at( i ).second, QVariant( static_cast<int>( policies.at( i ).first ) ) );
621 }
622
623 const int idx = cmbpolicy->findData( QVariant( static_cast<int>( mDefaultTrustPolicy ) ) );
624 cmbpolicy->setCurrentIndex( idx == -1 ? 0 : idx );
625 hlayout2->addWidget( cmbpolicy );
626
627 layout->addLayout( hlayout2 );
628
629 QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Close | QDialogButtonBox::Ok,
630 Qt::Horizontal, dlg );
631 buttonBox->button( QDialogButtonBox::Close )->setDefault( true );
632
633 layout->addWidget( buttonBox );
634
635 connect( buttonBox, &QDialogButtonBox::accepted, dlg, &QDialog::accept );
636 connect( buttonBox, &QDialogButtonBox::rejected, dlg, &QWidget::close );
637
638 dlg->setLayout( layout );
639 dlg->setWindowModality( Qt::WindowModal );
640 dlg->resize( 400, 200 );
641 dlg->setMinimumSize( 400, 200 );
642 dlg->setMaximumSize( 500, 300 );
643 if ( dlg->exec() )
644 {
645 const QgsAuthCertUtils::CertTrustPolicy trustpolicy(
646 ( QgsAuthCertUtils::CertTrustPolicy )cmbpolicy->currentData().toInt() );
647 if ( mDefaultTrustPolicy != trustpolicy )
648 {
649 defaultTrustPolicyChanged( trustpolicy );
650 }
651 }
652 dlg->deleteLater();
653}
654
655void QgsAuthAuthoritiesEditor::defaultTrustPolicyChanged( QgsAuthCertUtils::CertTrustPolicy trustpolicy )
656{
657 if ( !QgsApplication::authManager()->setDefaultCertTrustPolicy( trustpolicy ) )
658 {
659 logMessage( QObject::tr( "Could not store default trust policy." ),
660 QObject::tr( "Authorities Manager" ),
662 }
663 mDefaultTrustPolicy = trustpolicy;
666 populateCaCertsView();
667}
668
669void QgsAuthAuthoritiesEditor::btnCaFile_clicked()
670{
674 dlg->setWindowModality( Qt::WindowModal );
675 dlg->resize( 400, 250 );
676 if ( dlg->exec() )
677 {
678 // clear out any currently defined file certs and their trust settings
679 if ( !leCaFile->text().isEmpty() )
680 {
681 btnCaFileClear_clicked();
682 }
683
684 const QString &fn = dlg->certFileToImport();
685 leCaFile->setText( fn );
686
687 if ( !QgsApplication::authManager()->storeAuthSetting( QStringLiteral( "cafile" ), QVariant( fn ) ) )
688 {
689 logMessage( QObject::tr( "Could not store 'CA file path' in authentication database." ),
690 QObject::tr( "Authorities Manager" ),
692 }
693 if ( !QgsApplication::authManager()->storeAuthSetting( QStringLiteral( "cafileallowinvalid" ),
694 QVariant( dlg->allowInvalidCerts() ) ) )
695 {
696 logMessage( QObject::tr( "Could not store 'CA file allow invalids' setting in authentication database." ),
697 QObject::tr( "Authorities Manager" ),
699 }
700
702
704 {
705 const QList<QSslCertificate> certs( QgsApplication::authManager()->extraFileCAs() );
706 const auto constCerts = certs;
707 for ( const QSslCertificate &cert : constCerts )
708 {
709 if ( !QgsApplication::authManager()->storeCertTrustPolicy( cert, dlg->certTrustPolicy() ) )
710 {
711 logMessage( QObject::tr( "Could not set trust policy for imported certificates." ),
712 QObject::tr( "Authorities Manager" ),
714 }
715 }
717 updateCertTrustPolicyCache();
718 }
719
721
722 populateFileCaCerts();
723 mFileCaSecItem->setExpanded( true );
724 }
725 dlg->deleteLater();
726}
727
728void QgsAuthAuthoritiesEditor::btnCaFileClear_clicked()
729{
730 if ( !QgsApplication::authManager()->removeAuthSetting( QStringLiteral( "cafile" ) ) )
731 {
732 logMessage( QObject::tr( "Could not remove 'CA file path' from authentication database." ),
733 QObject::tr( "Authorities Manager" ),
735 return;
736 }
737 if ( !QgsApplication::authManager()->removeAuthSetting( QStringLiteral( "cafileallowinvalid" ) ) )
738 {
739 logMessage( QObject::tr( "Could not remove 'CA file allow invalids' setting from authentication database." ),
740 QObject::tr( "Authorities Manager" ),
742 return;
743 }
744
746
747 const QString fn( leCaFile->text() );
748 if ( QFile::exists( fn ) )
749 {
750 const QList<QSslCertificate> certs( QgsAuthCertUtils::certsFromFile( fn ) );
751
752 if ( !certs.isEmpty() )
753 {
754 if ( !QgsApplication::authManager()->removeCertTrustPolicies( certs ) )
755 {
756 messageBar()->pushMessage( tr( "ERROR removing cert(s) trust policy from authentication database." ),
758 return;
759 }
761 updateCertTrustPolicyCache();
762 }
763 }
764
766
767 leCaFile->clear();
768 populateFileCaCerts();
769}
770
771void QgsAuthAuthoritiesEditor::showTrustedCertificateAuthorities()
772{
774 dlg->setWindowModality( Qt::WindowModal );
775 dlg->resize( 675, 500 );
776 dlg->exec();
777 dlg->deleteLater();
778}
779
780void QgsAuthAuthoritiesEditor::logMessage( const QString &message, const QString &authtag, Qgis::MessageLevel level )
781{
782 messageBar()->pushMessage( authtag, message, level, 7 );
783}
784
786{
787 if ( !mDisabled )
788 {
789 treeWidgetCAs->setFocus();
790 }
791 QWidget::showEvent( e );
792}
793
794QgsMessageBar *QgsAuthAuthoritiesEditor::messageBar()
795{
796 return msgBar;
797}
798
799int QgsAuthAuthoritiesEditor::messageTimeout()
800{
801 const QgsSettings settings;
802 return settings.value( QStringLiteral( "qgis/messageTimeout" ), 5 ).toInt();
803}
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 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