20#include <QDialogButtonBox>
31static void setItemBold_( QTreeWidgetItem *item )
33 item->setFirstColumnSpanned(
true );
34 QFont secf( item->font( 0 ) );
36 item->setFont( 0, secf );
39static const QString configFoundText_() {
return QObject::tr(
"Configuration loaded from database" ); }
40static 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;
101QTreeWidgetItem *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 );
114void QgsAuthSslConfigWidget::setUpSslConfigTree()
116 treeSslConfig->setColumnCount( 1 );
119 mProtocolItem = addRootItem( tr(
"Protocol" ) );
120 mProtocolCmbBx =
new QComboBox( treeSslConfig );
122 static_cast<int>( QSsl::SecureProtocols ) );
124 static_cast<int>( QSsl::TlsV1_0 ) );
125 mProtocolCmbBx->setMaximumWidth( 300 );
126 mProtocolCmbBx->setCurrentIndex( 0 );
127 QTreeWidgetItem *protocolitem =
new QTreeWidgetItem(
129 QStringList() << QString(),
130 static_cast<int>( ConfigItem ) );
131 protocolitem->setFlags( protocolitem->flags() & ~Qt::ItemIsSelectable );
132 treeSslConfig->setItemWidget( protocolitem, 0, mProtocolCmbBx );
133 mProtocolItem->setExpanded(
true );
135 mVerifyModeItem = addRootItem( tr(
"Peer verification" ) );
136 mVerifyPeerCmbBx =
new QComboBox( treeSslConfig );
137 mVerifyPeerCmbBx->addItem( tr(
"Verify Peer Certs" ),
138 static_cast<int>( QSslSocket::VerifyPeer ) );
139 mVerifyPeerCmbBx->addItem( tr(
"Do Not Verify Peer Certs" ),
140 static_cast<int>( QSslSocket::VerifyNone ) );
141 mVerifyPeerCmbBx->setMaximumWidth( 300 );
142 mVerifyPeerCmbBx->setCurrentIndex( 0 );
143 QTreeWidgetItem *peerverifycmbxitem =
new QTreeWidgetItem(
145 QStringList() << QString(),
146 static_cast<int>( ConfigItem ) );
147 peerverifycmbxitem->setFlags( peerverifycmbxitem->flags() & ~Qt::ItemIsSelectable );
148 treeSslConfig->setItemWidget( peerverifycmbxitem, 0, mVerifyPeerCmbBx );
149 mVerifyModeItem->setExpanded(
true );
151 mVerifyDepthItem = addRootItem( tr(
"Peer verification depth (0 = complete cert chain)" ) );
152 mVerifyDepthSpnBx =
new QSpinBox( treeSslConfig );
153 mVerifyDepthSpnBx->setMinimum( 0 );
154 mVerifyDepthSpnBx->setMaximum( 10 );
155 mVerifyDepthSpnBx->setMaximumWidth( 200 );
156 mVerifyDepthSpnBx->setAlignment( Qt::AlignHCenter );
157 QTreeWidgetItem *peerverifyspnbxitem =
new QTreeWidgetItem(
159 QStringList() << QString(),
160 static_cast<int>( ConfigItem ) );
161 peerverifyspnbxitem->setFlags( peerverifyspnbxitem->flags() & ~Qt::ItemIsSelectable );
162 treeSslConfig->setItemWidget( peerverifyspnbxitem, 0, mVerifyDepthSpnBx );
163 mVerifyDepthItem->setExpanded(
true );
165 mIgnoreErrorsItem = addRootItem( tr(
"Ignore errors" ) );
168 for (
int i = 0; i < errenums.size(); i++ )
170 QTreeWidgetItem *item =
new QTreeWidgetItem(
172 QStringList() << errenums.at( i ).second,
173 static_cast<int>( ConfigItem ) );
174 item->setCheckState( 0, Qt::Unchecked );
175 item->setTextAlignment( 0, Qt::AlignVCenter );
176 item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
177 item->setData( 0, Qt::UserRole, errenums.at( i ).first );
179 mIgnoreErrorsItem->setExpanded(
true );
202 return QSslCertificate();
213 return leHost->text();
222 if ( grpbxSslConfig->isCheckable() )
224 grpbxSslConfig->setChecked( enable );
240 if ( !hostport.isEmpty() )
251 lblLoadedConfig->setVisible(
true );
259 lblLoadedConfig->setText( configNotFoundText_() );
275 QgsDebugError( QStringLiteral(
"Passed-in SSL custom config is null" ) );
282 QgsDebugError( QStringLiteral(
"SSL custom config's cert is null" ) );
294 lblLoadedConfig->setVisible(
true );
295 lblLoadedConfig->setText( configFoundText_() );
306 QgsDebugError( QStringLiteral(
"SSL custom config FAILED to store in authentication database" ) );
317 mConnectionCAs.clear();
318 leCommonName->clear();
319 leCommonName->setStyleSheet( QString() );
322 lblLoadedConfig->setVisible(
false );
323 lblLoadedConfig->clear();
334 return QSsl::UnknownProtocol;
336 return ( QSsl::SslProtocol )mProtocolCmbBx->currentData().toInt();
345 const int indx( mProtocolCmbBx->findData(
static_cast<int>( protocol ) ) );
346 mProtocolCmbBx->setCurrentIndex( indx );
355 mProtocolCmbBx->setCurrentIndex( 0 );
366 QList<QSslError::SslError> errenums;
367 const auto constErrors = errors;
368 for (
const QSslError &err : constErrors )
370 errenums << err.error();
373 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
375 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
376 if ( errenums.contains( ( QSslError::SslError )item->data( 0, Qt::UserRole ).toInt() ) )
378 item->setCheckState( 0, Qt::Checked );
389 QList<QSslError> errors;
390 const auto constErrorenums = errorenums;
391 for (
const QSslError::SslError errorenum : constErrorenums )
393 errors << QSslError( errorenum );
404 if ( errors.isEmpty() )
411 QList<QSslError::SslError> errenums;
412 const auto constErrors = errors;
413 for (
const QSslError &err : constErrors )
415 errenums << err.error();
418 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
420 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
421 const bool enable( errenums.contains( ( QSslError::SslError )item->data( 0, Qt::UserRole ).toInt() ) );
422 item->setCheckState( 0, enable ? Qt::Checked : Qt::Unchecked );
432 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
434 mIgnoreErrorsItem->child( i )->setCheckState( 0, Qt::Unchecked );
440 QList<QSslError::SslError> errs;
445 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
447 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
448 if ( item->checkState( 0 ) == Qt::Checked )
450 errs.append( ( QSslError::SslError )item->data( 0, Qt::UserRole ).toInt() );
460 return QSslSocket::AutoVerifyPeer;
462 return ( QSslSocket::PeerVerifyMode )mVerifyPeerCmbBx->currentData().toInt();
471 return mVerifyDepthSpnBx->value();
482 const int indx( mVerifyPeerCmbBx->findData(
static_cast<int>( mode ) ) );
483 mVerifyPeerCmbBx->setCurrentIndex( indx );
485 mVerifyDepthSpnBx->setValue( modedepth );
494 mVerifyPeerCmbBx->setCurrentIndex( 0 );
495 mVerifyDepthSpnBx->setValue( 0 );
504 const bool cansave = ( isEnabled()
505 && ( grpbxSslConfig->isCheckable() ? grpbxSslConfig->isChecked() : true )
506 && validateHostPort( leHost->text() ) );
507 if ( mCanSave != cansave )
521 leHost->setText( host );
524bool QgsAuthSslConfigWidget::validateHostPort(
const QString &txt )
526 const QString hostport( txt );
527 if ( hostport.isEmpty() )
534 const QString urlbase( QStringLiteral(
"https://%1" ).arg( hostport ) );
535 const QUrl url( urlbase );
536 return ( !url.host().isEmpty() && QString::number( url.port() ).size() > 0
537 && QStringLiteral(
"https://%1:%2" ).arg( url.host() ).arg( url.port() ) == urlbase );
546 const bool valid = validateHostPort( txt );
558 grpbxSslConfig->setCheckable( checkable );
561 grpbxSslConfig->setEnabled(
true );
565void QgsAuthSslConfigWidget::btnCertInfo_clicked()
567 if ( mCert.isNull() )
573 dlg->setWindowModality( Qt::WindowModal );
574 dlg->resize( 675, 500 );
586 setWindowTitle( tr(
"Custom Certificate Configuration" ) );
587 QVBoxLayout *layout =
new QVBoxLayout(
this );
588 layout->setContentsMargins( 6, 6, 6, 6 );
592 this, &QgsAuthSslConfigDialog::checkCanSave );
593 layout->addWidget( mSslConfigWdgt );
595 QDialogButtonBox *buttonBox =
new QDialogButtonBox(
596 QDialogButtonBox::Close | QDialogButtonBox::Save, Qt::Horizontal,
this );
598 buttonBox->button( QDialogButtonBox::Close )->setDefault(
true );
599 mSaveButton = buttonBox->button( QDialogButtonBox::Save );
600 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QWidget::close );
602 layout->addWidget( buttonBox );
605 mSaveButton->setEnabled( mSslConfigWdgt->
readyToSave() );
614void QgsAuthSslConfigDialog::checkCanSave(
bool cansave )
616 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.
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.
const QList< QSslError::SslError > sslIgnoredErrorEnums() const
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.
#define QgsDebugError(str)