66#include "ui_qgsauthsslimporterrors.h" 
   89    mAuthNotifyLayout = 
new QVBoxLayout;
 
   90    this->setLayout( mAuthNotifyLayout );
 
   92    mAuthNotifyLayout->addWidget( mAuthNotify );
 
   97    connect( btnCertPath, &QToolButton::clicked, 
this, &QgsAuthSslImportDialog::btnCertPath_clicked );
 
   98    QStyle *style = QApplication::style();
 
   99    lblWarningIcon->setPixmap( style->standardIcon( QStyle::SP_MessageBoxWarning ).pixmap( 48, 48 ) );
 
  100    lblWarningIcon->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
 
  102    closeButton()->setDefault( 
false );
 
  103    saveButton()->setEnabled( 
false );
 
  105    leServer->setSelection( 0, leServer->text().size() );
 
  106    pteSessionStatus->setReadOnly( 
true );
 
  107    spinbxTimeout->setClearValue( 15 );
 
  108    spinbxTimeout->setValue( 15 );
 
  109    spinbxPort->setClearValue( 443 );
 
  111    grpbxServer->setCollapsed( 
false );
 
  112    radioServerImport->setChecked( 
true );
 
  113    frameServerImport->setEnabled( 
true );
 
  114    radioFileImport->setChecked( 
false );
 
  115    frameFileImport->setEnabled( 
false );
 
  117    connect( radioServerImport, &QAbstractButton::toggled,
 
  118             this, &QgsAuthSslImportDialog::radioServerImportToggled );
 
  119    connect( radioFileImport, &QAbstractButton::toggled,
 
  120             this, &QgsAuthSslImportDialog::radioFileImportToggled );
 
  122    connect( leServer, &QLineEdit::textChanged,
 
  123             this, &QgsAuthSslImportDialog::updateEnabledState );
 
  124    connect( btnConnect, &QAbstractButton::clicked,
 
  125             this, &QgsAuthSslImportDialog::secureConnect );
 
  126    connect( leServer, &QLineEdit::returnPressed,
 
  127             btnConnect, &QAbstractButton::click );
 
  129    connect( buttonBox, &QDialogButtonBox::accepted,
 
  131    connect( buttonBox, &QDialogButtonBox::rejected,
 
  132             this, &QDialog::reject );
 
  135             this, &QgsAuthSslImportDialog::widgetReadyToSaveChanged );
 
  136    wdgtSslConfig->setEnabled( 
false );
 
  144  wdgtSslConfig->saveSslCertConfig();
 
  148void QgsAuthSslImportDialog::updateEnabledState()
 
  150  leServer->setStyleSheet( QString() );
 
  152  const bool unconnected = !mSocket || mSocket->state() == QAbstractSocket::UnconnectedState;
 
  154  leServer->setReadOnly( !unconnected );
 
  155  spinbxPort->setReadOnly( !unconnected );
 
  156  spinbxTimeout->setReadOnly( !unconnected );
 
  158  leServer->setFocusPolicy( unconnected ? Qt::StrongFocus : Qt::NoFocus );
 
  159  btnConnect->setEnabled( unconnected && !leServer->text().isEmpty() );
 
  161  const bool connected = mSocket && mSocket->state() == QAbstractSocket::ConnectedState;
 
  162  if ( connected && !mSocket->peerName().isEmpty() )
 
  164    appendString( tr( 
"Connected to %1: %2" ).arg( mSocket->peerName() ).arg( mSocket->peerPort() ) );
 
  168void QgsAuthSslImportDialog::secureConnect()
 
  170  if ( leServer->text().isEmpty() )
 
  175  leServer->setStyleSheet( QString() );
 
  176  clearStatusCertificateConfig();
 
  180    mSocket = 
new QSslSocket( 
this );
 
  181    connect( mSocket, &QAbstractSocket::stateChanged,
 
  182             this, &QgsAuthSslImportDialog::socketStateChanged );
 
  183    connect( mSocket, &QAbstractSocket::connected,
 
  184             this, &QgsAuthSslImportDialog::socketConnected );
 
  185    connect( mSocket, &QAbstractSocket::disconnected,
 
  186             this, &QgsAuthSslImportDialog::socketDisconnected );
 
  187    connect( mSocket, &QSslSocket::encrypted,
 
  188             this, &QgsAuthSslImportDialog::socketEncrypted );
 
  189#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 
  190    connect( mSocket, 
static_cast<void ( QAbstractSocket::* )( QAbstractSocket::SocketError )
>( &QAbstractSocket::error ),
 
  191             this, &QgsAuthSslImportDialog::socketError );
 
  193    connect( mSocket, &QAbstractSocket::errorOccurred, 
this, &QgsAuthSslImportDialog::socketError );
 
  195    connect( mSocket, 
static_cast<void ( QSslSocket::* )( 
const QList<QSslError> & )
>( &QSslSocket::sslErrors ),
 
  196             this, &QgsAuthSslImportDialog::sslErrors );
 
  197    connect( mSocket, &QIODevice::readyRead,
 
  198             this, &QgsAuthSslImportDialog::socketReadyRead );
 
  201  QSslConfiguration sslConfig = mSocket->sslConfiguration();
 
  202  sslConfig.setCaCertificates( mTrustedCAs );
 
  203  mSocket->setSslConfiguration( sslConfig );
 
  207    mTimer = 
new QTimer( 
this );
 
  208    connect( mTimer, &QTimer::timeout, 
this, &QgsAuthSslImportDialog::destroySocket );
 
  210  mTimer->start( spinbxTimeout->value() * 1000 );
 
  212  mSocket->connectToHost( leServer->text(), spinbxPort->value() );
 
  213  updateEnabledState();
 
  216void QgsAuthSslImportDialog::socketStateChanged( QAbstractSocket::SocketState state )
 
  218  if ( mExecErrorsDialog )
 
  223  updateEnabledState();
 
  224  if ( state == QAbstractSocket::UnconnectedState )
 
  226    leServer->setFocus();
 
  231void QgsAuthSslImportDialog::socketConnected()
 
  233  appendString( tr( 
"Socket CONNECTED" ) );
 
  234  mSocket->startClientEncryption();
 
  237void QgsAuthSslImportDialog::socketDisconnected()
 
  239  appendString( tr( 
"Socket DISCONNECTED" ) );
 
  242void QgsAuthSslImportDialog::socketEncrypted()
 
  248  appendString( tr( 
"Socket ENCRYPTED" ) );
 
  250  appendString( QStringLiteral( 
"%1: %2" ).arg( tr( 
"Protocol" ),
 
  253  const QSslCipher ciph = mSocket->sessionCipher();
 
  254  const QString cipher = QStringLiteral( 
"%1: %2, %3 (%4/%5)" )
 
  255                         .arg( tr( 
"Session cipher" ), ciph.authenticationMethod(), ciph.name() )
 
  256                         .arg( ciph.usedBits() ).arg( ciph.supportedBits() );
 
  257  appendString( cipher );
 
  261  wdgtSslConfig->setEnabled( 
true );
 
  262  const QString hostport( QStringLiteral( 
"%1:%2" ).arg( mSocket->peerName() ).arg( mSocket->peerPort() ) );
 
  263  wdgtSslConfig->setSslCertificate( mSocket->peerCertificate(), hostport.trimmed() );
 
  264  if ( !mSslErrors.isEmpty() )
 
  266    wdgtSslConfig->appendSslIgnoreErrors( mSslErrors );
 
  278void QgsAuthSslImportDialog::socketError( QAbstractSocket::SocketError err )
 
  283    appendString( QStringLiteral( 
"%1: %2" ).arg( tr( 
"Socket ERROR" ), mSocket->errorString() ) );
 
  287void QgsAuthSslImportDialog::socketReadyRead()
 
  289  appendString( QString::fromUtf8( mSocket->readAll() ) );
 
  292void QgsAuthSslImportDialog::destroySocket()
 
  298  if ( !mSocket->isEncrypted() )
 
  300    appendString( tr( 
"Socket unavailable or not encrypted" ) );
 
  302  mSocket->disconnectFromHost();
 
  303  mSocket->deleteLater();
 
  307void QgsAuthSslImportDialog::sslErrors( 
const QList<QSslError> &errors )
 
  309  if ( !mTimer->isActive() )
 
  315  QDialog errorDialog( 
this );
 
  317  ui.setupUi( &errorDialog );
 
  318  const auto constErrors = errors;
 
  319  for ( 
const QSslError &error : constErrors )
 
  321    ui.sslErrorList->addItem( error.errorString() );
 
  324  mExecErrorsDialog = 
true;
 
  325  if ( errorDialog.exec() == QDialog::Accepted )
 
  327    mSocket->ignoreSslErrors();
 
  330  mExecErrorsDialog = 
false;
 
  335  if ( mSocket->state() != QAbstractSocket::ConnectedState )
 
  336    socketStateChanged( mSocket->state() );
 
  339void QgsAuthSslImportDialog::showCertificateInfo()
 
  341  QList<QSslCertificate> peerchain( mSocket->peerCertificateChain() );
 
  343  if ( !peerchain.isEmpty() )
 
  345    const QSslCertificate cert = peerchain.takeFirst();
 
  346    if ( !cert.isNull() )
 
  355void QgsAuthSslImportDialog::widgetReadyToSaveChanged( 
bool cansave )
 
  357  saveButton()->setEnabled( cansave );
 
  360void QgsAuthSslImportDialog::checkCanSave()
 
  362  saveButton()->setEnabled( wdgtSslConfig->readyToSave() );
 
  363  saveButton()->setDefault( 
false );
 
  364  closeButton()->setDefault( 
false );
 
  367void QgsAuthSslImportDialog::radioServerImportToggled( 
bool checked )
 
  369  frameServerImport->setEnabled( checked );
 
  370  clearStatusCertificateConfig();
 
  373void QgsAuthSslImportDialog::radioFileImportToggled( 
bool checked )
 
  375  frameFileImport->setEnabled( checked );
 
  376  clearStatusCertificateConfig();
 
  379void QgsAuthSslImportDialog::btnCertPath_clicked()
 
  381  const QString &fn = getOpenFileName( tr( 
"Open Server Certificate File" ),  tr( 
"All files (*.*);;PEM (*.pem);;DER (*.der)" ) );
 
  384    leCertPath->setText( fn );
 
  389void QgsAuthSslImportDialog::clearCertificateConfig()
 
  391  wdgtSslConfig->resetSslCertConfig();
 
  392  wdgtSslConfig->setEnabled( 
false );
 
  395void QgsAuthSslImportDialog::clearStatusCertificateConfig()
 
  398  pteSessionStatus->clear();
 
  399  saveButton()->setEnabled( 
false );
 
  400  clearCertificateConfig();
 
  403void QgsAuthSslImportDialog::loadCertFromFile()
 
  405  clearStatusCertificateConfig();
 
  408  if ( certs.isEmpty() )
 
  410    appendString( tr( 
"Could not load any certs from file" ) );
 
  414  const QSslCertificate cert( certs.first() );
 
  417    appendString( tr( 
"Could not load server cert from file" ) );
 
  423    appendString( tr( 
"Certificate does not appear for be for an SSL server. " 
  424                      "You can still add a configuration, if you know it is the correct certificate." ) );
 
  427  wdgtSslConfig->setEnabled( 
true );
 
  428  wdgtSslConfig->setSslHost( QString() );
 
  429  wdgtSslConfig->setSslCertificate( cert );
 
  430  if ( !mSslErrors.isEmpty() )
 
  432    wdgtSslConfig->appendSslIgnoreErrors( mSslErrors );
 
  438void QgsAuthSslImportDialog::appendString( 
const QString &line )
 
  440  QTextCursor cursor( pteSessionStatus->textCursor() );
 
  441  cursor.movePosition( QTextCursor::End );
 
  442  cursor.insertText( line + 
'\n' );
 
  446QPushButton *QgsAuthSslImportDialog::saveButton()
 
  448  return buttonBox->button( QDialogButtonBox::Save );
 
  451QPushButton *QgsAuthSslImportDialog::closeButton()
 
  453  return buttonBox->button( QDialogButtonBox::Close );
 
  456QString QgsAuthSslImportDialog::getOpenFileName( 
const QString &title, 
const QString &extfilter )
 
  459  const QString recentdir = settings.
value( QStringLiteral( 
"UI/lastAuthImportSslOpenFileDir" ), QDir::homePath() ).toString();
 
  460  QString f = QFileDialog::getOpenFileName( 
this, title, recentdir, extfilter );
 
  464  this->activateWindow();
 
  468    settings.
setValue( QStringLiteral( 
"UI/lastAuthImportSslOpenFileDir" ), QFileInfo( f ).absoluteDir().path() );
 
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 getSslProtocolName(QSsl::SslProtocol protocol)
SSL Protocol name strings per enum.
 
static QList< QSslCertificate > certsFromFile(const QString &certspath)
Returns a list of concatenated certs from a PEM or DER formatted file.
 
static bool certificateIsSslServer(const QSslCertificate &cert)
Gets whether a certificate is probably used for a SSL server.
 
static QString greenTextStyleSheet(const QString &selector="*")
Green text stylesheet representing valid, trusted, etc. certificate.
 
const QList< QSslCertificate > trustedCaCertsCache()
trustedCaCertsCache cache of trusted certificate authorities, ready for network connections
 
QgsAuthSslImportDialog(QWidget *parent=nullptr)
Construct dialog for importing certificates.
 
This class is a composition of two QSettings instances:
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
 
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
 
#define QgsDebugMsgLevel(str, level)