20 #include <QDialogButtonBox> 
   21 #include <QPushButton> 
   31 static void setItemBold_( QTreeWidgetItem *item )
 
   33   item->setFirstColumnSpanned( 
true );
 
   34   QFont secf( item->font( 0 ) );
 
   36   item->setFont( 0, secf );
 
   39 static const QString configFoundText_() { 
return QObject::tr( 
"Configuration loaded from database" ); }
 
   40 static const QString configNotFoundText_() { 
return QObject::tr( 
"Configuration not found in database" ); }
 
   43     const QSslCertificate &cert,
 
   44     const QString &hostport,
 
   45     const QList<QSslCertificate> &connectionCAs )
 
   48   , mConnectionCAs( connectionCAs )
 
   53     mAuthNotifyLayout = 
new QVBoxLayout;
 
   54     this->setLayout( mAuthNotifyLayout );
 
   56     mAuthNotifyLayout->addWidget( mAuthNotify );
 
   61     connect( btnCertInfo, &QToolButton::clicked, 
this, &QgsAuthSslConfigWidget::btnCertInfo_clicked );
 
   69     lblLoadedConfig->setVisible( 
false );
 
   70     lblLoadedConfig->clear();
 
   72     connect( leHost, &QLineEdit::textChanged,
 
   97   return grpbxSslConfig;
 
  101 QTreeWidgetItem *QgsAuthSslConfigWidget::addRootItem( 
const QString &label )
 
  103   QTreeWidgetItem *item = 
new QTreeWidgetItem(
 
  104     QStringList() << label,
 
  105     static_cast<int>( ConfigParent ) );
 
  106   setItemBold_( item );
 
  107   item->setTextAlignment( 0, Qt::AlignVCenter );
 
  108   item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
 
  109   treeSslConfig->insertTopLevelItem( treeSslConfig->topLevelItemCount(), item );
 
  114 void QgsAuthSslConfigWidget::setUpSslConfigTree()
 
  116   treeSslConfig->setColumnCount( 1 );
 
  119   mProtocolItem = addRootItem( tr( 
"Protocol" ) );
 
  120   mProtocolCmbBx = 
new QComboBox( treeSslConfig );
 
  122                            static_cast<int>( QSsl::SecureProtocols ) );
 
  123 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 
  125                            static_cast<int>( QSsl::TlsV1SslV3 ) );
 
  128                            static_cast<int>( QSsl::TlsV1_0 ) );
 
  129 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 
  131                            static_cast<int>( QSsl::SslV3 ) );
 
  133                            static_cast<int>( QSsl::SslV2 ) );
 
  135   mProtocolCmbBx->setMaximumWidth( 300 );
 
  136   mProtocolCmbBx->setCurrentIndex( 0 );
 
  137   QTreeWidgetItem *protocolitem = 
new QTreeWidgetItem(
 
  139     QStringList() << QString(),
 
  140     static_cast<int>( ConfigItem ) );
 
  141   protocolitem->setFlags( protocolitem->flags() & ~Qt::ItemIsSelectable );
 
  142   treeSslConfig->setItemWidget( protocolitem, 0, mProtocolCmbBx );
 
  143   mProtocolItem->setExpanded( 
true );
 
  145   mVerifyModeItem = addRootItem( tr( 
"Peer verification" ) );
 
  146   mVerifyPeerCmbBx = 
new QComboBox( treeSslConfig );
 
  147   mVerifyPeerCmbBx->addItem( tr( 
"Verify Peer Certs" ),
 
  148                              static_cast<int>( QSslSocket::VerifyPeer ) );
 
  149   mVerifyPeerCmbBx->addItem( tr( 
"Do Not Verify Peer Certs" ),
 
  150                              static_cast<int>( QSslSocket::VerifyNone ) );
 
  151   mVerifyPeerCmbBx->setMaximumWidth( 300 );
 
  152   mVerifyPeerCmbBx->setCurrentIndex( 0 );
 
  153   QTreeWidgetItem *peerverifycmbxitem = 
new QTreeWidgetItem(
 
  155     QStringList() << QString(),
 
  156     static_cast<int>( ConfigItem ) );
 
  157   peerverifycmbxitem->setFlags( peerverifycmbxitem->flags() & ~Qt::ItemIsSelectable );
 
  158   treeSslConfig->setItemWidget( peerverifycmbxitem, 0, mVerifyPeerCmbBx );
 
  159   mVerifyModeItem->setExpanded( 
true );
 
  161   mVerifyDepthItem = addRootItem( tr( 
"Peer verification depth (0 = complete cert chain)" ) );
 
  162   mVerifyDepthSpnBx = 
new QSpinBox( treeSslConfig );
 
  163   mVerifyDepthSpnBx->setMinimum( 0 );
 
  164   mVerifyDepthSpnBx->setMaximum( 10 );
 
  165   mVerifyDepthSpnBx->setMaximumWidth( 200 );
 
  166   mVerifyDepthSpnBx->setAlignment( Qt::AlignHCenter );
 
  167   QTreeWidgetItem *peerverifyspnbxitem = 
new QTreeWidgetItem(
 
  169     QStringList() << QString(),
 
  170     static_cast<int>( ConfigItem ) );
 
  171   peerverifyspnbxitem->setFlags( peerverifyspnbxitem->flags() & ~Qt::ItemIsSelectable );
 
  172   treeSslConfig->setItemWidget( peerverifyspnbxitem, 0, mVerifyDepthSpnBx );
 
  173   mVerifyDepthItem->setExpanded( 
true );
 
  175   mIgnoreErrorsItem = addRootItem( tr( 
"Ignore errors" ) );
 
  178   for ( 
int i = 0; i < errenums.size(); i++ )
 
  180     QTreeWidgetItem *item = 
new QTreeWidgetItem(
 
  182       QStringList() << errenums.at( i ).second,
 
  183       static_cast<int>( ConfigItem ) );
 
  184     item->setCheckState( 0, Qt::Unchecked );
 
  185     item->setTextAlignment( 0, Qt::AlignVCenter );
 
  186     item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
 
  187     item->setData( 0, Qt::UserRole, errenums.at( i ).first );
 
  189   mIgnoreErrorsItem->setExpanded( 
true );
 
  212     return QSslCertificate();
 
  223   return leHost->text();
 
  232   if ( grpbxSslConfig->isCheckable() )
 
  234     grpbxSslConfig->setChecked( enable );
 
  250   if ( !hostport.isEmpty() )
 
  261   lblLoadedConfig->setVisible( 
true );
 
  269     lblLoadedConfig->setText( configNotFoundText_() );
 
  285     QgsDebugMsg( QStringLiteral( 
"Passed-in SSL custom config is null" ) );
 
  292     QgsDebugMsg( QStringLiteral( 
"SSL custom config's cert is null" ) );
 
  304   lblLoadedConfig->setVisible( 
true );
 
  305   lblLoadedConfig->setText( configFoundText_() );
 
  316     QgsDebugMsg( QStringLiteral( 
"SSL custom config FAILED to store in authentication database" ) );
 
  327   mConnectionCAs.clear();
 
  328   leCommonName->clear();
 
  329   leCommonName->setStyleSheet( QString() );
 
  332   lblLoadedConfig->setVisible( 
false );
 
  333   lblLoadedConfig->clear();
 
  344     return QSsl::UnknownProtocol;
 
  346   return ( QSsl::SslProtocol )mProtocolCmbBx->currentData().toInt();
 
  355   int indx( mProtocolCmbBx->findData( 
static_cast<int>( protocol ) ) );
 
  356   mProtocolCmbBx->setCurrentIndex( indx );
 
  365   mProtocolCmbBx->setCurrentIndex( 0 );
 
  376   QList<QSslError::SslError> errenums;
 
  377   const auto constErrors = errors;
 
  378   for ( 
const QSslError &err : constErrors )
 
  380     errenums << err.error();
 
  383   for ( 
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
 
  385     QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
 
  386     if ( errenums.contains( ( QSslError::SslError )item->data( 0, Qt::UserRole ).toInt() ) )
 
  388       item->setCheckState( 0, Qt::Checked );
 
  399   QList<QSslError> errors;
 
  400   const auto constErrorenums = errorenums;
 
  401   for ( QSslError::SslError errorenum : constErrorenums )
 
  403     errors << QSslError( errorenum );
 
  414   if ( errors.isEmpty() )
 
  421   QList<QSslError::SslError> errenums;
 
  422   const auto constErrors = errors;
 
  423   for ( 
const QSslError &err : constErrors )
 
  425     errenums << err.error();
 
  428   for ( 
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
 
  430     QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
 
  431     bool enable( errenums.contains( ( QSslError::SslError )item->data( 0, Qt::UserRole ).toInt() ) );
 
  432     item->setCheckState( 0, enable ? Qt::Checked : Qt::Unchecked );
 
  442   for ( 
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
 
  444     mIgnoreErrorsItem->child( i )->setCheckState( 0, Qt::Unchecked );
 
  450   QList<QSslError::SslError> errs;
 
  455   for ( 
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
 
  457     QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
 
  458     if ( item->checkState( 0 ) == Qt::Checked )
 
  460       errs.append( ( QSslError::SslError )item->data( 0, Qt::UserRole ).toInt() );
 
  470     return QSslSocket::AutoVerifyPeer;
 
  472   return ( QSslSocket::PeerVerifyMode )mVerifyPeerCmbBx->currentData().toInt();
 
  481   return mVerifyDepthSpnBx->value();
 
  492   int indx( mVerifyPeerCmbBx->findData( 
static_cast<int>( mode ) ) );
 
  493   mVerifyPeerCmbBx->setCurrentIndex( indx );
 
  495   mVerifyDepthSpnBx->setValue( modedepth );
 
  504   mVerifyPeerCmbBx->setCurrentIndex( 0 );
 
  505   mVerifyDepthSpnBx->setValue( 0 );
 
  514   bool cansave = ( isEnabled()
 
  515                    && ( grpbxSslConfig->isCheckable() ? grpbxSslConfig->isChecked() : true )
 
  516                    && validateHostPort( leHost->text() ) );
 
  517   if ( mCanSave != cansave )
 
  531   leHost->setText( host );
 
  534 bool QgsAuthSslConfigWidget::validateHostPort( 
const QString &txt )
 
  536   QString hostport( txt );
 
  537   if ( hostport.isEmpty() )
 
  544   QString urlbase( QStringLiteral( 
"https://%1" ).arg( hostport ) );
 
  546   return ( !url.host().isEmpty() && QString::number( url.port() ).size() > 0
 
  547            && QStringLiteral( 
"https://%1:%2" ).arg( url.host() ).arg( url.port() ) == urlbase );
 
  556   bool valid = validateHostPort( txt );
 
  568   grpbxSslConfig->setCheckable( checkable );
 
  571     grpbxSslConfig->setEnabled( 
true );
 
  575 void QgsAuthSslConfigWidget::btnCertInfo_clicked()
 
  577   if ( mCert.isNull() )
 
  583   dlg->setWindowModality( Qt::WindowModal );
 
  584   dlg->resize( 675, 500 );
 
  596   setWindowTitle( tr( 
"Custom Certificate Configuration" ) );
 
  597   QVBoxLayout *layout = 
new QVBoxLayout( 
this );
 
  598   layout->setContentsMargins( 6, 6, 6, 6 );
 
  602            this, &QgsAuthSslConfigDialog::checkCanSave );
 
  603   layout->addWidget( mSslConfigWdgt );
 
  605   QDialogButtonBox *buttonBox = 
new QDialogButtonBox(
 
  606     QDialogButtonBox::Close | QDialogButtonBox::Save, Qt::Horizontal, 
this );
 
  608   buttonBox->button( QDialogButtonBox::Close )->setDefault( 
true );
 
  609   mSaveButton = buttonBox->button( QDialogButtonBox::Save );
 
  610   connect( buttonBox, &QDialogButtonBox::rejected, 
this, &QWidget::close );
 
  612   layout->addWidget( buttonBox );
 
  615   mSaveButton->setEnabled( mSslConfigWdgt->
readyToSave() );
 
  624 void QgsAuthSslConfigDialog::checkCanSave( 
bool cansave )
 
  626   mSaveButton->setEnabled( cansave );
 
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
Dialog wrapper for widget displaying detailed info on a certificate and its hierarchical trust chain.
static QString resolvedCertName(const QSslCertificate &cert, bool issuer=false)
Gets the general name via RFC 5280 resolution.
static QString shaHexForCert(const QSslCertificate &cert, bool formatted=false)
Gets the sha1 hash for certificate.
static QString getSslProtocolName(QSsl::SslProtocol protocol)
SSL Protocol name strings per enum.
static QList< QPair< QSslError::SslError, QString > > sslErrorEnumStrings()
Gets short strings describing SSL errors.
Configuration container for SSL server connection exceptions or overrides.
void setSslProtocol(QSsl::SslProtocol protocol)
Sets SSL server protocol to use in connections.
void setSslCertificate(const QSslCertificate &cert)
Sets server certificate object.
void setSslHostPort(const QString &hostport)
Sets server host:port string.
QSsl::SslProtocol sslProtocol() const
SSL server protocol to use in connections.
void setSslPeerVerifyMode(QSslSocket::PeerVerifyMode mode)
Sets SSL client's peer verify mode to use in connections.
void setSslPeerVerifyDepth(int depth)
Set number or SSL client's peer to verify in connections.
const QList< QSslError::SslError > sslIgnoredErrorEnums() const
SSL server errors (as enum list) to ignore in connections.
int sslPeerVerifyDepth() const
Number or SSL client's peer to verify in connections.
bool isNull() const
Whether configuration is null (missing components)
void setSslIgnoredErrorEnums(const QList< QSslError::SslError > &errors)
Sets SSL server errors (as enum list) to ignore in connections.
QSslSocket::PeerVerifyMode sslPeerVerifyMode() const
SSL client's peer verify mode to use in connections.
const QSslCertificate sslCertificate() const
Server certificate object.
const QString sslHostPort() const
Server host:port string.
static QString greenTextStyleSheet(const QString &selector="*")
Green text stylesheet representing valid, trusted, etc. certificate.
static QString redTextStyleSheet(const QString &selector="*")
Red text stylesheet representing invalid, untrusted, etc. certificate.
static QString orangeTextStyleSheet(const QString &selector="*")
Orange text stylesheet representing loaded component, but not stored in database.
QgsAuthSslConfigDialog(QWidget *parent=nullptr, const QSslCertificate &cert=QSslCertificate(), const QString &hostport=QString())
Construct wrapper dialog for the SSL config widget.