66 #include "ui_qgsauthsslimporterrors.h"
69 #include <QFileDialog>
71 #include <QPushButton>
75 #include <QToolButton>
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->setValue( 15 );
109 grpbxServer->setCollapsed(
false );
110 radioServerImport->setChecked(
true );
111 frameServerImport->setEnabled(
true );
112 radioFileImport->setChecked(
false );
113 frameFileImport->setEnabled(
false );
115 connect( radioServerImport, &QAbstractButton::toggled,
116 this, &QgsAuthSslImportDialog::radioServerImportToggled );
117 connect( radioFileImport, &QAbstractButton::toggled,
118 this, &QgsAuthSslImportDialog::radioFileImportToggled );
120 connect( leServer, &QLineEdit::textChanged,
121 this, &QgsAuthSslImportDialog::updateEnabledState );
122 connect( btnConnect, &QAbstractButton::clicked,
123 this, &QgsAuthSslImportDialog::secureConnect );
124 connect( leServer, &QLineEdit::returnPressed,
125 btnConnect, &QAbstractButton::click );
127 connect( buttonBox, &QDialogButtonBox::accepted,
129 connect( buttonBox, &QDialogButtonBox::rejected,
130 this, &QDialog::reject );
133 this, &QgsAuthSslImportDialog::widgetReadyToSaveChanged );
134 wdgtSslConfig->setEnabled(
false );
142 wdgtSslConfig->saveSslCertConfig();
146 void QgsAuthSslImportDialog::updateEnabledState()
148 leServer->setStyleSheet( QString() );
150 bool unconnected = !mSocket || mSocket->state() == QAbstractSocket::UnconnectedState;
152 leServer->setReadOnly( !unconnected );
153 spinbxPort->setReadOnly( !unconnected );
154 spinbxTimeout->setReadOnly( !unconnected );
156 leServer->setFocusPolicy( unconnected ? Qt::StrongFocus : Qt::NoFocus );
157 btnConnect->setEnabled( unconnected && !leServer->text().isEmpty() );
159 bool connected = mSocket && mSocket->state() == QAbstractSocket::ConnectedState;
160 if ( connected && !mSocket->peerName().isEmpty() )
162 appendString( tr(
"Connected to %1: %2" ).arg( mSocket->peerName() ).arg( mSocket->peerPort() ) );
166 void QgsAuthSslImportDialog::secureConnect()
168 if ( leServer->text().isEmpty() )
173 leServer->setStyleSheet( QString() );
174 clearStatusCertificateConfig();
178 mSocket =
new QSslSocket(
this );
179 connect( mSocket, &QAbstractSocket::stateChanged,
180 this, &QgsAuthSslImportDialog::socketStateChanged );
181 connect( mSocket, &QAbstractSocket::connected,
182 this, &QgsAuthSslImportDialog::socketConnected );
183 connect( mSocket, &QAbstractSocket::disconnected,
184 this, &QgsAuthSslImportDialog::socketDisconnected );
185 connect( mSocket, &QSslSocket::encrypted,
186 this, &QgsAuthSslImportDialog::socketEncrypted );
187 connect( mSocket,
static_cast<void ( QAbstractSocket::* )( QAbstractSocket::SocketError )
>( &QAbstractSocket::error ),
188 this, &QgsAuthSslImportDialog::socketError );
189 connect( mSocket,
static_cast<void ( QSslSocket::* )(
const QList<QSslError> & )
>( &QSslSocket::sslErrors ),
190 this, &QgsAuthSslImportDialog::sslErrors );
191 connect( mSocket, &QIODevice::readyRead,
192 this, &QgsAuthSslImportDialog::socketReadyRead );
195 QSslConfiguration sslConfig = mSocket->sslConfiguration();
196 sslConfig.setCaCertificates( mTrustedCAs );
197 mSocket->setSslConfiguration( sslConfig );
201 mTimer =
new QTimer(
this );
202 connect( mTimer, &QTimer::timeout,
this, &QgsAuthSslImportDialog::destroySocket );
204 mTimer->start( spinbxTimeout->value() * 1000 );
206 mSocket->connectToHost( leServer->text(), spinbxPort->value() );
207 updateEnabledState();
210 void QgsAuthSslImportDialog::socketStateChanged( QAbstractSocket::SocketState state )
212 if ( mExecErrorsDialog )
217 updateEnabledState();
218 if ( state == QAbstractSocket::UnconnectedState )
220 leServer->setFocus();
225 void QgsAuthSslImportDialog::socketConnected()
227 appendString( tr(
"Socket CONNECTED" ) );
228 mSocket->startClientEncryption();
231 void QgsAuthSslImportDialog::socketDisconnected()
233 appendString( tr(
"Socket DISCONNECTED" ) );
236 void QgsAuthSslImportDialog::socketEncrypted()
238 QgsDebugMsg( QStringLiteral(
"socketEncrypted entered" ) );
242 appendString( tr(
"Socket ENCRYPTED" ) );
244 appendString( QStringLiteral(
"%1: %2" ).arg( tr(
"Protocol" ),
247 QSslCipher ciph = mSocket->sessionCipher();
248 QString cipher = QStringLiteral(
"%1: %2, %3 (%4/%5)" )
249 .arg( tr(
"Session cipher" ), ciph.authenticationMethod(), ciph.name() )
250 .arg( ciph.usedBits() ).arg( ciph.supportedBits() );
251 appendString( cipher );
255 wdgtSslConfig->setEnabled(
true );
256 QString hostport( QStringLiteral(
"%1:%2" ).arg( mSocket->peerName() ).arg( mSocket->peerPort() ) );
257 wdgtSslConfig->setSslCertificate( mSocket->peerCertificate(), hostport.trimmed() );
258 if ( !mSslErrors.isEmpty() )
260 wdgtSslConfig->appendSslIgnoreErrors( mSslErrors );
272 void QgsAuthSslImportDialog::socketError( QAbstractSocket::SocketError err )
277 appendString( QStringLiteral(
"%1: %2" ).arg( tr(
"Socket ERROR" ), mSocket->errorString() ) );
281 void QgsAuthSslImportDialog::socketReadyRead()
283 appendString( QString::fromUtf8( mSocket->readAll() ) );
286 void QgsAuthSslImportDialog::destroySocket()
292 if ( !mSocket->isEncrypted() )
294 appendString( tr(
"Socket unavailable or not encrypted" ) );
296 mSocket->disconnectFromHost();
297 mSocket->deleteLater();
301 void QgsAuthSslImportDialog::sslErrors(
const QList<QSslError> &errors )
303 if ( !mTimer->isActive() )
309 QDialog errorDialog(
this );
311 ui.setupUi( &errorDialog );
312 const auto constErrors = errors;
313 for (
const QSslError &error : constErrors )
315 ui.sslErrorList->addItem( error.errorString() );
318 mExecErrorsDialog =
true;
319 if ( errorDialog.exec() == QDialog::Accepted )
321 mSocket->ignoreSslErrors();
324 mExecErrorsDialog =
false;
329 if ( mSocket->state() != QAbstractSocket::ConnectedState )
330 socketStateChanged( mSocket->state() );
333 void QgsAuthSslImportDialog::showCertificateInfo()
335 QList<QSslCertificate> peerchain( mSocket->peerCertificateChain() );
337 if ( !peerchain.isEmpty() )
339 QSslCertificate cert = peerchain.takeFirst();
340 if ( !cert.isNull() )
349 void QgsAuthSslImportDialog::widgetReadyToSaveChanged(
bool cansave )
351 saveButton()->setEnabled( cansave );
354 void QgsAuthSslImportDialog::checkCanSave()
356 saveButton()->setEnabled( wdgtSslConfig->readyToSave() );
357 saveButton()->setDefault(
false );
358 closeButton()->setDefault(
false );
361 void QgsAuthSslImportDialog::radioServerImportToggled(
bool checked )
363 frameServerImport->setEnabled( checked );
364 clearStatusCertificateConfig();
367 void QgsAuthSslImportDialog::radioFileImportToggled(
bool checked )
369 frameFileImport->setEnabled( checked );
370 clearStatusCertificateConfig();
373 void QgsAuthSslImportDialog::btnCertPath_clicked()
375 const QString &fn = getOpenFileName( tr(
"Open Server Certificate File" ), tr(
"All files (*.*);;PEM (*.pem);;DER (*.der)" ) );
378 leCertPath->setText( fn );
383 void QgsAuthSslImportDialog::clearCertificateConfig()
385 wdgtSslConfig->resetSslCertConfig();
386 wdgtSslConfig->setEnabled(
false );
389 void QgsAuthSslImportDialog::clearStatusCertificateConfig()
392 pteSessionStatus->clear();
393 saveButton()->setEnabled(
false );
394 clearCertificateConfig();
397 void QgsAuthSslImportDialog::loadCertFromFile()
399 clearStatusCertificateConfig();
402 if ( certs.isEmpty() )
404 appendString( tr(
"Could not load any certs from file" ) );
408 QSslCertificate cert( certs.first() );
411 appendString( tr(
"Could not load server cert from file" ) );
417 appendString( tr(
"Certificate does not appear for be for an SSL server. "
418 "You can still add a configuration, if you know it is the correct certificate." ) );
421 wdgtSslConfig->setEnabled(
true );
422 wdgtSslConfig->setSslHost( QString() );
423 wdgtSslConfig->setSslCertificate( cert );
424 if ( !mSslErrors.isEmpty() )
426 wdgtSslConfig->appendSslIgnoreErrors( mSslErrors );
432 void QgsAuthSslImportDialog::appendString(
const QString &line )
434 QTextCursor cursor( pteSessionStatus->textCursor() );
435 cursor.movePosition( QTextCursor::End );
436 cursor.insertText( line +
'\n' );
440 QPushButton *QgsAuthSslImportDialog::saveButton()
442 return buttonBox->button( QDialogButtonBox::Save );
445 QPushButton *QgsAuthSslImportDialog::closeButton()
447 return buttonBox->button( QDialogButtonBox::Close );
450 QString QgsAuthSslImportDialog::getOpenFileName(
const QString &title,
const QString &extfilter )
453 QString recentdir = settings.
value( QStringLiteral(
"UI/lastAuthImportSslOpenFileDir" ), QDir::homePath() ).toString();
454 QString f = QFileDialog::getOpenFileName(
this, title, recentdir, extfilter );
458 this->activateWindow();
462 settings.
setValue( QStringLiteral(
"UI/lastAuthImportSslOpenFileDir" ), QFileInfo( f ).absoluteDir().path() );