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