QGIS API Documentation 3.39.0-Master (bca3cdb6021)
Loading...
Searching...
No Matches
qgsauthsslconfigwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsauthsslconfigwidget.cpp
3 ---------------------
4 begin : May 17, 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
19
20#include <QDialogButtonBox>
21#include <QPushButton>
22#include <QSpinBox>
23#include <QUrl>
24
25#include "qgsauthguiutils.h"
26#include "qgsauthmanager.h"
27#include "qgslogger.h"
28#include "qgsapplication.h"
29
30
31static void setItemBold_( QTreeWidgetItem *item )
32{
33 item->setFirstColumnSpanned( true );
34 QFont secf( item->font( 0 ) );
35 secf.setBold( true );
36 item->setFont( 0, secf );
37}
38
39static const QString configFoundText_() { return QObject::tr( "Configuration loaded from database" ); }
40static const QString configNotFoundText_() { return QObject::tr( "Configuration not found in database" ); }
41
43 const QSslCertificate &cert,
44 const QString &hostport,
45 const QList<QSslCertificate> &connectionCAs )
46 : QWidget( parent )
47 , mCert( nullptr )
48 , mConnectionCAs( connectionCAs )
49{
50 if ( QgsApplication::authManager()->isDisabled() )
51 {
52 mDisabled = true;
53 mAuthNotifyLayout = new QVBoxLayout;
54 this->setLayout( mAuthNotifyLayout );
55 mAuthNotify = new QLabel( QgsApplication::authManager()->disabledMessage(), this );
56 mAuthNotifyLayout->addWidget( mAuthNotify );
57 }
58 else
59 {
60 setupUi( this );
61 connect( btnCertInfo, &QToolButton::clicked, this, &QgsAuthSslConfigWidget::btnCertInfo_clicked );
62
63 connect( grpbxSslConfig, &QGroupBox::toggled, this, &QgsAuthSslConfigWidget::configEnabledChanged );
66
67 setUpSslConfigTree();
68
69 lblLoadedConfig->setVisible( false );
70 lblLoadedConfig->clear();
71
72 connect( leHost, &QLineEdit::textChanged,
74
75 if ( !cert.isNull() )
76 {
77 setSslCertificate( cert, hostport );
78 }
79 }
80}
81
83{
84 if ( mDisabled )
85 {
86 return nullptr;
87 }
88 return grpbxCert;
89}
90
92{
93 if ( mDisabled )
94 {
95 return nullptr;
96 }
97 return grpbxSslConfig;
98}
99
100// private
101QTreeWidgetItem *QgsAuthSslConfigWidget::addRootItem( const QString &label )
102{
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 );
110
111 return item;
112}
113
114void QgsAuthSslConfigWidget::setUpSslConfigTree()
115{
116 treeSslConfig->setColumnCount( 1 );
117
118 // add config field names
119 mProtocolItem = addRootItem( tr( "Protocol" ) );
120 mProtocolCmbBx = new QComboBox( treeSslConfig );
121 mProtocolCmbBx->addItem( QgsAuthCertUtils::getSslProtocolName( QSsl::SecureProtocols ),
122 static_cast<int>( QSsl::SecureProtocols ) );
123 mProtocolCmbBx->addItem( QgsAuthCertUtils::getSslProtocolName( QSsl::TlsV1_0 ),
124 static_cast<int>( QSsl::TlsV1_0 ) );
125 mProtocolCmbBx->setMaximumWidth( 300 );
126 mProtocolCmbBx->setCurrentIndex( 0 );
127 QTreeWidgetItem *protocolitem = new QTreeWidgetItem(
128 mProtocolItem,
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 );
134
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(
144 mVerifyModeItem,
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 );
150
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(
158 mVerifyDepthItem,
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 );
164
165 mIgnoreErrorsItem = addRootItem( tr( "Ignore errors" ) );
166
167 const QList<QPair<QSslError::SslError, QString> > errenums = QgsAuthCertUtils::sslErrorEnumStrings();
168 for ( int i = 0; i < errenums.size(); i++ )
169 {
170 QTreeWidgetItem *item = new QTreeWidgetItem(
171 mIgnoreErrorsItem,
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 );
178 }
179 mIgnoreErrorsItem->setExpanded( true );
180}
181
183{
185 if ( mDisabled )
186 {
187 return config;
188 }
189 config.setSslCertificate( mCert );
190 config.setSslHostPort( leHost->text() );
191 config.setSslProtocol( sslProtocol() );
195 return config;
196}
197
199{
200 if ( mDisabled )
201 {
202 return QSslCertificate();
203 }
204 return mCert;
205}
206
208{
209 if ( mDisabled )
210 {
211 return QString();
212 }
213 return leHost->text();
214}
215
217{
218 if ( mDisabled )
219 {
220 return;
221 }
222 if ( grpbxSslConfig->isCheckable() )
223 {
224 grpbxSslConfig->setChecked( enable );
225 }
226}
227
228void QgsAuthSslConfigWidget::setSslCertificate( const QSslCertificate &cert, const QString &hostport )
229{
230 if ( mDisabled )
231 {
232 return;
233 }
234 if ( cert.isNull() )
235 {
236 return;
237 }
238 mCert = cert;
239
240 if ( !hostport.isEmpty() )
241 {
242 setSslHost( hostport );
243 }
244
245 const QString sha( QgsAuthCertUtils::shaHexForCert( cert ) );
246 const QgsAuthConfigSslServer config(
247 QgsApplication::authManager()->sslCertCustomConfig( sha, hostport.isEmpty() ? sslHost() : hostport ) );
248
249 emit certFoundInAuthDatabase( !config.isNull() );
250
251 lblLoadedConfig->setVisible( true );
252 if ( !config.isNull() )
253 {
254 loadSslCustomConfig( config );
255 leCommonName->setStyleSheet( QgsAuthGuiUtils::greenTextStyleSheet() );
256 }
257 else
258 {
259 lblLoadedConfig->setText( configNotFoundText_() );
260 leCommonName->setText( QgsAuthCertUtils::resolvedCertName( mCert ) );
261 leCommonName->setStyleSheet( QgsAuthGuiUtils::orangeTextStyleSheet() );
262 }
263 validateHostPortText( leHost->text() );
264}
265
267{
268 if ( mDisabled )
269 {
270 return;
271 }
273 if ( config.isNull() )
274 {
275 QgsDebugError( QStringLiteral( "Passed-in SSL custom config is null" ) );
276 return;
277 }
278
279 const QSslCertificate cert( config.sslCertificate() );
280 if ( cert.isNull() )
281 {
282 QgsDebugError( QStringLiteral( "SSL custom config's cert is null" ) );
283 return;
284 }
285
287 mCert = cert;
288 leCommonName->setText( QgsAuthCertUtils::resolvedCertName( cert ) );
289 leHost->setText( config.sslHostPort() );
291 setSslProtocol( config.sslProtocol() );
293
294 lblLoadedConfig->setVisible( true );
295 lblLoadedConfig->setText( configFoundText_() );
296}
297
299{
300 if ( mDisabled )
301 {
302 return;
303 }
304 if ( !QgsApplication::authManager()->storeSslCertCustomConfig( sslCustomConfig() ) )
305 {
306 QgsDebugError( QStringLiteral( "SSL custom config FAILED to store in authentication database" ) );
307 }
308}
309
311{
312 if ( mDisabled )
313 {
314 return;
315 }
316 mCert.clear();
317 mConnectionCAs.clear();
318 leCommonName->clear();
319 leCommonName->setStyleSheet( QString() );
320 leHost->clear();
321
322 lblLoadedConfig->setVisible( false );
323 lblLoadedConfig->clear();
327 enableSslCustomOptions( false );
328}
329
331{
332 if ( mDisabled )
333 {
334 return QSsl::UnknownProtocol;
335 }
336 return ( QSsl::SslProtocol )mProtocolCmbBx->currentData().toInt();
337}
338
339void QgsAuthSslConfigWidget::setSslProtocol( QSsl::SslProtocol protocol )
340{
341 if ( mDisabled )
342 {
343 return;
344 }
345 const int indx( mProtocolCmbBx->findData( static_cast<int>( protocol ) ) );
346 mProtocolCmbBx->setCurrentIndex( indx );
347}
348
350{
351 if ( mDisabled )
352 {
353 return;
354 }
355 mProtocolCmbBx->setCurrentIndex( 0 );
356}
357
358void QgsAuthSslConfigWidget::appendSslIgnoreErrors( const QList<QSslError> &errors )
359{
360 if ( mDisabled )
361 {
362 return;
363 }
365
366 QList<QSslError::SslError> errenums;
367 const auto constErrors = errors;
368 for ( const QSslError &err : constErrors )
369 {
370 errenums << err.error();
371 }
372
373 for ( int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
374 {
375 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
376 if ( errenums.contains( ( QSslError::SslError )item->data( 0, Qt::UserRole ).toInt() ) )
377 {
378 item->setCheckState( 0, Qt::Checked );
379 }
380 }
381}
382
383void QgsAuthSslConfigWidget::setSslIgnoreErrorEnums( const QList<QSslError::SslError> &errorenums )
384{
385 if ( mDisabled )
386 {
387 return;
388 }
389 QList<QSslError> errors;
390 const auto constErrorenums = errorenums;
391 for ( const QSslError::SslError errorenum : constErrorenums )
392 {
393 errors << QSslError( errorenum );
394 }
395 setSslIgnoreErrors( errors );
396}
397
398void QgsAuthSslConfigWidget::setSslIgnoreErrors( const QList<QSslError> &errors )
399{
400 if ( mDisabled )
401 {
402 return;
403 }
404 if ( errors.isEmpty() )
405 {
406 return;
407 }
408
410
411 QList<QSslError::SslError> errenums;
412 const auto constErrors = errors;
413 for ( const QSslError &err : constErrors )
414 {
415 errenums << err.error();
416 }
417
418 for ( int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
419 {
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 );
423 }
424}
425
427{
428 if ( mDisabled )
429 {
430 return;
431 }
432 for ( int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
433 {
434 mIgnoreErrorsItem->child( i )->setCheckState( 0, Qt::Unchecked );
435 }
436}
437
438const QList<QSslError::SslError> QgsAuthSslConfigWidget::sslIgnoreErrorEnums()
439{
440 QList<QSslError::SslError> errs;
441 if ( mDisabled )
442 {
443 return errs;
444 }
445 for ( int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
446 {
447 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
448 if ( item->checkState( 0 ) == Qt::Checked )
449 {
450 errs.append( ( QSslError::SslError )item->data( 0, Qt::UserRole ).toInt() );
451 }
452 }
453 return errs;
454}
455
457{
458 if ( mDisabled )
459 {
460 return QSslSocket::AutoVerifyPeer;
461 }
462 return ( QSslSocket::PeerVerifyMode )mVerifyPeerCmbBx->currentData().toInt();
463}
464
466{
467 if ( mDisabled )
468 {
469 return 0;
470 }
471 return mVerifyDepthSpnBx->value();
472}
473
474void QgsAuthSslConfigWidget::setSslPeerVerify( QSslSocket::PeerVerifyMode mode, int modedepth )
475{
476 if ( mDisabled )
477 {
478 return;
479 }
481
482 const int indx( mVerifyPeerCmbBx->findData( static_cast<int>( mode ) ) );
483 mVerifyPeerCmbBx->setCurrentIndex( indx );
484
485 mVerifyDepthSpnBx->setValue( modedepth );
486}
487
489{
490 if ( mDisabled )
491 {
492 return;
493 }
494 mVerifyPeerCmbBx->setCurrentIndex( 0 );
495 mVerifyDepthSpnBx->setValue( 0 );
496}
497
499{
500 if ( mDisabled )
501 {
502 return false;
503 }
504 const bool cansave = ( isEnabled()
505 && ( grpbxSslConfig->isCheckable() ? grpbxSslConfig->isChecked() : true )
506 && validateHostPort( leHost->text() ) );
507 if ( mCanSave != cansave )
508 {
509 mCanSave = cansave;
510 emit readyToSaveChanged( cansave );
511 }
512 return cansave;
513}
514
515void QgsAuthSslConfigWidget::setSslHost( const QString &host )
516{
517 if ( mDisabled )
518 {
519 return;
520 }
521 leHost->setText( host );
522}
523
524bool QgsAuthSslConfigWidget::validateHostPort( const QString &txt )
525{
526 const QString hostport( txt );
527 if ( hostport.isEmpty() )
528 {
529 return false;
530 }
531
532 // TODO: add QRegex checks against valid IP and domain.tld input
533 // i.e., currently accepts unlikely (though maybe valid) host:port combo, like 'a:1'
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 );
538}
539
541{
542 if ( mDisabled )
543 {
544 return;
545 }
546 const bool valid = validateHostPort( txt );
547 leHost->setStyleSheet( valid ? QgsAuthGuiUtils::greenTextStyleSheet()
549 emit hostPortValidityChanged( valid );
550}
551
553{
554 if ( mDisabled )
555 {
556 return;
557 }
558 grpbxSslConfig->setCheckable( checkable );
559 if ( !checkable )
560 {
561 grpbxSslConfig->setEnabled( true );
562 }
563}
564
565void QgsAuthSslConfigWidget::btnCertInfo_clicked()
566{
567 if ( mCert.isNull() )
568 {
569 return;
570 }
571
572 QgsAuthCertInfoDialog *dlg = new QgsAuthCertInfoDialog( mCert, false, this, mConnectionCAs );
573 dlg->setWindowModality( Qt::WindowModal );
574 dlg->resize( 675, 500 );
575 dlg->exec();
576 dlg->deleteLater();
577}
578
579
581
582QgsAuthSslConfigDialog::QgsAuthSslConfigDialog( QWidget *parent, const QSslCertificate &cert, const QString &hostport )
583 : QDialog( parent )
584
585{
586 setWindowTitle( tr( "Custom Certificate Configuration" ) );
587 QVBoxLayout *layout = new QVBoxLayout( this );
588 layout->setContentsMargins( 6, 6, 6, 6 );
589
590 mSslConfigWdgt = new QgsAuthSslConfigWidget( this, cert, hostport );
591 connect( mSslConfigWdgt, &QgsAuthSslConfigWidget::readyToSaveChanged,
592 this, &QgsAuthSslConfigDialog::checkCanSave );
593 layout->addWidget( mSslConfigWdgt );
594
595 QDialogButtonBox *buttonBox = new QDialogButtonBox(
596 QDialogButtonBox::Close | QDialogButtonBox::Save, Qt::Horizontal, this );
597
598 buttonBox->button( QDialogButtonBox::Close )->setDefault( true );
599 mSaveButton = buttonBox->button( QDialogButtonBox::Save );
600 connect( buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close );
601 connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsAuthSslConfigDialog::accept );
602 layout->addWidget( buttonBox );
603
604 setLayout( layout );
605 mSaveButton->setEnabled( mSslConfigWdgt->readyToSave() );
606}
607
609{
610 mSslConfigWdgt->saveSslCertConfig();
611 QDialog::accept();
612}
613
614void QgsAuthSslConfigDialog::checkCanSave( bool cansave )
615{
616 mSaveButton->setEnabled( cansave );
617}
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.
Widget for editing an SSL server configuration.
QgsAuthSslConfigWidget(QWidget *parent=nullptr, const QSslCertificate &cert=QSslCertificate(), const QString &hostport=QString(), const QList< QSslCertificate > &connectionCAs=QList< QSslCertificate >())
Construct a widget for editing an SSL server certificate configuration.
const QSslCertificate sslCertificate()
Gets the SSL server certificate.
void validateHostPortText(const QString &txt)
Parse string for host:port.
void setSslPeerVerify(QSslSocket::PeerVerifyMode mode, int modedepth)
Sets the client's peer verify mode for connections.
QSslSocket::PeerVerifyMode sslPeerVerifyMode()
Gets the client's peer verify mode for connections.
QSsl::SslProtocol sslProtocol()
Gets the SSL protocol used for connections.
QGroupBox * sslConfigGroupBox()
Access to the SSL configuration's group box widget.
const QString sslHost()
Gets the host:port to associate with the server certificate.
void resetSslCertConfig()
Clear the current SSL server configuration and disabled it.
void setSslCertificate(const QSslCertificate &cert, const QString &hostport=QString())
Sets SSl certificate and any associated host:port.
void saveSslCertConfig()
Save the current SSL server configuration to the authentication database.
void certFoundInAuthDatabase(bool found)
Emitted when an certificate of same SHA hash is found in authentication database.
void resetSslProtocol()
Reset the SSL protocol to use in connections to the default.
void setSslHost(const QString &host)
Sets the host of the server.
void appendSslIgnoreErrors(const QList< QSslError > &errors)
Add to SSL errors to ignore for the connection.
void hostPortValidityChanged(bool valid)
Emitted when the validity of the host:port changes.
void setSslIgnoreErrorEnums(const QList< QSslError::SslError > &errorenums)
Sets the SSL errors (as enums) to ignore for the connection.
void readyToSaveChanged(bool cansave)
Emitted when the configuration can be saved changes.
void resetSslIgnoreErrors()
Clear the SSL errors to ignore for the connection.
void configEnabledChanged(bool enabled)
Emitted when the enabled state of the configuration changes.
void setSslIgnoreErrors(const QList< QSslError > &errors)
Sets the SSL errors to ignore for the connection.
int sslPeerVerifyDepth()
Gets the client's peer verify depth for connections.
void loadSslCustomConfig(const QgsAuthConfigSslServer &config=QgsAuthConfigSslServer())
Load an existing SSL server configuration.
const QList< QSslError::SslError > sslIgnoreErrorEnums()
Gets list of the SSL errors (as enums) to be ignored for connections.
bool readyToSave()
Verify if the configuration if ready to save.
void setSslProtocol(QSsl::SslProtocol protocol)
Sets the SSL protocol to use in connections.
QGroupBox * certificateGroupBox()
Access to the certificate's group box widget.
void enableSslCustomOptions(bool enable)
Enable or disable the custom options widget.
void resetSslPeerVerify()
Reset the client's peer verify mode for connections to default.
void setConfigCheckable(bool checkable)
Sets whether the config group box is checkable.
const QgsAuthConfigSslServer sslCustomConfig()
Gets the SSL configuration.
#define QgsDebugError(str)
Definition qgslogger.h:38