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