18#include "moc_qgsauthauthoritieseditor.cpp" 
   19#include "ui_qgsauthauthoritieseditor.h" 
   31#include <QSslConfiguration> 
   50    mAuthNotifyLayout = 
new QVBoxLayout;
 
   51    this->setLayout( mAuthNotifyLayout );
 
   53    mAuthNotifyLayout->addWidget( mAuthNotify );
 
   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 );
 
   71    connect( treeWidgetCAs->selectionModel(), &QItemSelectionModel::selectionChanged, 
this, &QgsAuthAuthoritiesEditor::selectionChanged );
 
   73    connect( treeWidgetCAs, &QTreeWidget::itemDoubleClicked, 
this, &QgsAuthAuthoritiesEditor::handleDoubleClick );
 
   75    connect( btnViewRefresh, &QAbstractButton::clicked, 
this, &QgsAuthAuthoritiesEditor::refreshCaCertsView );
 
   80      leCaFile->setText( cafileval.toString() );
 
   83    btnGroupByOrg->setChecked( 
false );
 
   86      btnGroupByOrg->setChecked( sortbyval.toBool() );
 
   89    populateCaCertsView();
 
   92    populateUtilitiesMenu();
 
 
   96void QgsAuthAuthoritiesEditor::setupCaCertsTree()
 
   98  treeWidgetCAs->setColumnCount( 4 );
 
   99  treeWidgetCAs->setHeaderLabels(
 
  100    QStringList() << tr( 
"Common Name" )
 
  102                  << tr( 
"Expiry Date" )
 
  103                  << tr( 
"Trust Policy" )
 
  105  treeWidgetCAs->setColumnWidth( 0, 300 );
 
  106  treeWidgetCAs->setColumnWidth( 1, 75 );
 
  107  treeWidgetCAs->setColumnWidth( 2, 200 );
 
  110  mDbCaSecItem = 
new QTreeWidgetItem(
 
  113    static_cast<int>( QgsAuthAuthoritiesEditor::Section )
 
  116  mDbCaSecItem->setFlags( Qt::ItemIsEnabled );
 
  117  mDbCaSecItem->setExpanded( 
true );
 
  118  treeWidgetCAs->insertTopLevelItem( 0, mDbCaSecItem );
 
  120  mFileCaSecItem = 
new QTreeWidgetItem(
 
  123    static_cast<int>( QgsAuthAuthoritiesEditor::Section )
 
  126  mFileCaSecItem->setFlags( Qt::ItemIsEnabled );
 
  127  mFileCaSecItem->setExpanded( 
true );
 
  128  treeWidgetCAs->insertTopLevelItem( 0, mFileCaSecItem );
 
  130  mRootCaSecItem = 
new QTreeWidgetItem(
 
  133    static_cast<int>( QgsAuthAuthoritiesEditor::Section )
 
  136  mRootCaSecItem->setFlags( Qt::ItemIsEnabled );
 
  137  mRootCaSecItem->setExpanded( 
false );
 
  138  treeWidgetCAs->insertTopLevelItem( 0, mRootCaSecItem );
 
  141void QgsAuthAuthoritiesEditor::populateCaCertsView()
 
  143  updateCertTrustPolicyCache();
 
  144  populateDatabaseCaCerts();
 
  145  populateFileCaCerts();
 
  146  populateRootCaCerts();
 
  149void QgsAuthAuthoritiesEditor::refreshCaCertsView()
 
  152  populateCaCertsView();
 
  155void QgsAuthAuthoritiesEditor::populateDatabaseCaCerts()
 
  159  const bool expanded = mDbCaSecItem->isExpanded();
 
  161  mDbCaSecItem->setExpanded( expanded );
 
  164void QgsAuthAuthoritiesEditor::populateFileCaCerts()
 
  168  const bool expanded = mFileCaSecItem->isExpanded();
 
  170  mFileCaSecItem->setExpanded( expanded );
 
  173void QgsAuthAuthoritiesEditor::populateRootCaCerts()
 
  177  const bool expanded = mRootCaSecItem->isExpanded();
 
  179  mRootCaSecItem->setExpanded( expanded );
 
  182void QgsAuthAuthoritiesEditor::populateCaCertsSection( QTreeWidgetItem *item, 
const QList<QSslCertificate> &certs, QgsAuthAuthoritiesEditor::CaType catype )
 
  184  if ( btnGroupByOrg->isChecked() )
 
  186    appendCertsToGroup( certs, catype, item );
 
  190    appendCertsToItem( certs, catype, item );
 
  194void QgsAuthAuthoritiesEditor::appendCertsToGroup( 
const QList<QSslCertificate> &certs, QgsAuthAuthoritiesEditor::CaType catype, QTreeWidgetItem *parent )
 
  201    parent = treeWidgetCAs->currentItem();
 
  205  const QMap<QString, QList<QSslCertificate>> orgcerts(
 
  209  QMap<QString, QList<QSslCertificate>>::const_iterator it = orgcerts.constBegin();
 
  210  for ( ; it != orgcerts.constEnd(); ++it )
 
  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 );
 
  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 );
 
  224    appendCertsToItem( it.value(), catype, grpitem );
 
  227  parent->sortChildren( 0, Qt::AscendingOrder );
 
  230void QgsAuthAuthoritiesEditor::appendCertsToItem( 
const QList<QSslCertificate> &certs, QgsAuthAuthoritiesEditor::CaType catype, QTreeWidgetItem *parent )
 
  237    parent = treeWidgetCAs->currentItem();
 
  247  const auto constCerts = certs;
 
  248  for ( 
const QSslCertificate &cert : constCerts )
 
  254    coltxts << QString( cert.serialNumber() );
 
  255    coltxts << cert.expiryDate().toString();
 
  259    if ( trustedids.contains( 
id ) )
 
  263    else if ( untrustedids.contains( 
id )
 
  264              || cert.isBlacklisted()
 
  266              || cert.expiryDate() <= QDateTime::currentDateTime()
 
  267              || cert.effectiveDate() > QDateTime::currentDateTime() )
 
  273    QTreeWidgetItem *item( 
new QTreeWidgetItem( parent, coltxts, 
static_cast<int>( catype ) ) );
 
  276    if ( cert.isBlacklisted()
 
  278         || cert.expiryDate() <= QDateTime::currentDateTime()
 
  279         || cert.effectiveDate() > QDateTime::currentDateTime() )
 
  281      item->setForeground( 2, redb );
 
  285    if ( trustedids.contains( 
id ) )
 
  287      item->setForeground( 3, greenb );
 
  288      if ( !cert.isBlacklisted()
 
  290           && cert.expiryDate() > QDateTime::currentDateTime()
 
  291           && cert.effectiveDate() <= QDateTime::currentDateTime() )
 
  296    else if ( untrustedids.contains( 
id ) )
 
  298      item->setForeground( 3, redb );
 
  306    item->setData( 0, Qt::UserRole, 
id );
 
  309  parent->sortChildren( 0, Qt::AscendingOrder );
 
  312void QgsAuthAuthoritiesEditor::updateCertTrustPolicyCache()
 
  317void QgsAuthAuthoritiesEditor::populateUtilitiesMenu()
 
  319  mActionDefaultTrustPolicy = 
new QAction( QStringLiteral( 
"Change default trust policy" ), 
this );
 
  320  connect( mActionDefaultTrustPolicy, &QAction::triggered, 
this, &QgsAuthAuthoritiesEditor::editDefaultTrustPolicy );
 
  322  mActionShowTrustedCAs = 
new QAction( QStringLiteral( 
"Show trusted authorities/issuers" ), 
this );
 
  323  connect( mActionShowTrustedCAs, &QAction::triggered, 
this, &QgsAuthAuthoritiesEditor::showTrustedCertificateAuthorities );
 
  325  mUtilitiesMenu = 
new QMenu( 
this );
 
  326  mUtilitiesMenu->addAction( mActionDefaultTrustPolicy );
 
  327  mUtilitiesMenu->addSeparator();
 
  328  mUtilitiesMenu->addAction( mActionShowTrustedCAs );
 
  330  btnUtilities->setMenu( mUtilitiesMenu );
 
  333void QgsAuthAuthoritiesEditor::showCertInfo( QTreeWidgetItem *item )
 
  338  const QString digest( item->data( 0, Qt::UserRole ).toString() );
 
  340  const QMap<QString, QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate>> cacertscache(
 
  344  if ( !cacertscache.contains( digest ) )
 
  346    QgsDebugError( QStringLiteral( 
"Certificate Authority not in CA certs cache" ) );
 
  350  const QSslCertificate cert( cacertscache.value( digest ).second );
 
  353  dlg->setWindowModality( Qt::WindowModal );
 
  354  dlg->resize( 675, 500 );
 
  359    populateCaCertsView();
 
  364void QgsAuthAuthoritiesEditor::selectionChanged( 
const QItemSelection &selected, 
const QItemSelection &deselected )
 
  367  Q_UNUSED( deselected )
 
  371void QgsAuthAuthoritiesEditor::checkSelection()
 
  374  bool isdbcert = 
false;
 
  375  if ( treeWidgetCAs->selectionModel()->selection().length() > 0 )
 
  377    QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
 
  379    switch ( ( QgsAuthAuthoritiesEditor::CaType ) item->type() )
 
  381      case QgsAuthAuthoritiesEditor::RootCaCert:
 
  384      case QgsAuthAuthoritiesEditor::FileCaCert:
 
  387      case QgsAuthAuthoritiesEditor::DbCaCert:
 
  396  btnRemoveCa->setEnabled( isdbcert );
 
  397  btnInfoCa->setEnabled( iscert );
 
  400void QgsAuthAuthoritiesEditor::handleDoubleClick( QTreeWidgetItem *item, 
int col )
 
  405  switch ( ( QgsAuthAuthoritiesEditor::CaType ) item->type() )
 
  407    case QgsAuthAuthoritiesEditor::Section:
 
  410    case QgsAuthAuthoritiesEditor::OrgName:
 
  419    showCertInfo( item );
 
  423void QgsAuthAuthoritiesEditor::btnAddCa_clicked()
 
  426  dlg->setWindowModality( Qt::WindowModal );
 
  427  dlg->resize( 400, 450 );
 
  440      const auto constCerts = certs;
 
  441      for ( 
const QSslCertificate &cert : constCerts )
 
  445          logMessage( QObject::tr( 
"Could not set trust policy for imported certificates" ), QObject::tr( 
"Authorities Manager" ), 
Qgis::MessageLevel::Warning );
 
  449      updateCertTrustPolicyCache();
 
  453    populateDatabaseCaCerts();
 
  454    mDbCaSecItem->setExpanded( 
true );
 
  459void QgsAuthAuthoritiesEditor::btnRemoveCa_clicked()
 
  461  QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
 
  465    QgsDebugMsgLevel( QStringLiteral( 
"Current tree widget item not set" ), 2 );
 
  469  const QString digest( item->data( 0, Qt::UserRole ).toString() );
 
  471  if ( digest.isEmpty() )
 
  477  const QMap<QString, QSslCertificate> mappedcerts(
 
  481  if ( !mappedcerts.contains( digest ) )
 
  483    QgsDebugError( QStringLiteral( 
"Certificate Authority not in mapped database CAs" ) );
 
  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,
 
  495       == QMessageBox::Cancel )
 
  500  const QSslCertificate cert( mappedcerts.value( digest ) );
 
  522  updateCertTrustPolicyCache();
 
  524  item->parent()->removeChild( item );
 
  528  mDbCaSecItem->setExpanded( 
true );
 
  531void QgsAuthAuthoritiesEditor::btnInfoCa_clicked()
 
  533  if ( treeWidgetCAs->selectionModel()->selection().length() > 0 )
 
  535    QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
 
  536    handleDoubleClick( item, 0 );
 
  540void QgsAuthAuthoritiesEditor::btnGroupByOrg_toggled( 
bool checked )
 
  544    logMessage( QObject::tr( 
"Could not store sort by preference" ), QObject::tr( 
"Authorities Manager" ), 
Qgis::MessageLevel::Warning );
 
  546  populateCaCertsView();
 
  549void QgsAuthAuthoritiesEditor::editDefaultTrustPolicy()
 
  551  QDialog *dlg = 
new QDialog( 
this );
 
  552  dlg->setWindowTitle( tr( 
"Default Trust Policy" ) );
 
  553  QVBoxLayout *layout = 
new QVBoxLayout( dlg );
 
  555  QHBoxLayout *hlayout = 
new QHBoxLayout();
 
  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 );
 
  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 );
 
  569  layout->addLayout( hlayout );
 
  571  QHBoxLayout *hlayout2 = 
new QHBoxLayout();
 
  573  QLabel *lblpolicy = 
new QLabel( tr( 
"Default policy" ), dlg );
 
  574  lblpolicy->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );
 
  575  hlayout2->addWidget( lblpolicy );
 
  577  QComboBox *cmbpolicy = 
new QComboBox( dlg );
 
  578  QList<QPair<QgsAuthCertUtils::CertTrustPolicy, QString>> policies;
 
  582  for ( 
int i = 0; i < policies.size(); i++ )
 
  584    cmbpolicy->addItem( policies.at( i ).second, QVariant( 
static_cast<int>( policies.at( i ).first ) ) );
 
  587  const int idx = cmbpolicy->findData( QVariant( 
static_cast<int>( mDefaultTrustPolicy ) ) );
 
  588  cmbpolicy->setCurrentIndex( idx == -1 ? 0 : idx );
 
  589  hlayout2->addWidget( cmbpolicy );
 
  591  layout->addLayout( hlayout2 );
 
  593  QDialogButtonBox *buttonBox = 
new QDialogButtonBox( QDialogButtonBox::Close | QDialogButtonBox::Ok, Qt::Horizontal, dlg );
 
  594  buttonBox->button( QDialogButtonBox::Close )->setDefault( 
true );
 
  596  layout->addWidget( buttonBox );
 
  598  connect( buttonBox, &QDialogButtonBox::accepted, dlg, &QDialog::accept );
 
  599  connect( buttonBox, &QDialogButtonBox::rejected, dlg, &QWidget::close );
 
  601  dlg->setLayout( layout );
 
  602  dlg->setWindowModality( Qt::WindowModal );
 
  603  dlg->resize( 400, 200 );
 
  604  dlg->setMinimumSize( 400, 200 );
 
  605  dlg->setMaximumSize( 500, 300 );
 
  611    if ( mDefaultTrustPolicy != trustpolicy )
 
  613      defaultTrustPolicyChanged( trustpolicy );
 
  623    logMessage( QObject::tr( 
"Could not store default trust policy." ), QObject::tr( 
"Authorities Manager" ), 
Qgis::MessageLevel::Critical );
 
  625  mDefaultTrustPolicy = trustpolicy;
 
  628  populateCaCertsView();
 
  631void QgsAuthAuthoritiesEditor::btnCaFile_clicked()
 
  634  dlg->setWindowModality( Qt::WindowModal );
 
  635  dlg->resize( 400, 250 );
 
  639    if ( !leCaFile->text().isEmpty() )
 
  641      btnCaFileClear_clicked();
 
  645    leCaFile->setText( fn );
 
  649      logMessage( QObject::tr( 
"Could not store 'CA file path' in authentication storage." ), QObject::tr( 
"Authorities Manager" ), 
Qgis::MessageLevel::Warning );
 
  653      logMessage( QObject::tr( 
"Could not store 'CA file allow invalids' setting in authentication storage." ), QObject::tr( 
"Authorities Manager" ), 
Qgis::MessageLevel::Warning );
 
  661      const auto constCerts = certs;
 
  662      for ( 
const QSslCertificate &cert : constCerts )
 
  666          logMessage( QObject::tr( 
"Could not set trust policy for imported certificates." ), QObject::tr( 
"Authorities Manager" ), 
Qgis::MessageLevel::Warning );
 
  670      updateCertTrustPolicyCache();
 
  675    populateFileCaCerts();
 
  676    mFileCaSecItem->setExpanded( 
true );
 
  681void QgsAuthAuthoritiesEditor::btnCaFileClear_clicked()
 
  685    logMessage( QObject::tr( 
"Could not remove 'CA file path' from authentication storage." ), QObject::tr( 
"Authorities Manager" ), 
Qgis::MessageLevel::Warning );
 
  690    logMessage( QObject::tr( 
"Could not remove 'CA file allow invalids' setting from authentication storage." ), QObject::tr( 
"Authorities Manager" ), 
Qgis::MessageLevel::Warning );
 
  696  const QString fn( leCaFile->text() );
 
  697  if ( QFile::exists( fn ) )
 
  701    if ( !certs.isEmpty() )
 
  709      updateCertTrustPolicyCache();
 
  716  populateFileCaCerts();
 
  719void QgsAuthAuthoritiesEditor::showTrustedCertificateAuthorities()
 
  722  dlg->setWindowModality( Qt::WindowModal );
 
  723  dlg->resize( 675, 500 );
 
  728void QgsAuthAuthoritiesEditor::logMessage( 
const QString &message, 
const QString &authtag, 
Qgis::MessageLevel level )
 
  730  messageBar()->
pushMessage( authtag, message, level, 7 );
 
  737    treeWidgetCAs->setFocus();
 
  739  QWidget::showEvent( e );
 
 
  747int QgsAuthAuthoritiesEditor::messageTimeout()
 
  750  return settings.
value( QStringLiteral( 
"qgis/messageTimeout" ), 5 ).toInt();
 
MessageLevel
Level for messages This will be used both for message log and message bar in application.
 
@ Warning
Warning message.
 
@ Critical
Critical/error message.
 
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)
Returns a previously set authentication setting.
 
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.
 
Stores settings for use within QGIS.
 
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)
 
#define QgsDebugError(str)