X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Fcoreconnection.cpp;h=a60fae389e02ecf9001adfe343b69ec9b2cc3595;hp=0b342ed55f5ff7029d6fc0623ea9c0687483456e;hb=e4491717487ddbff71b9b5a59d7b4cba3eb67629;hpb=e052c6532456d818b804ce726c8a6e66c81ad8a0 diff --git a/src/client/coreconnection.cpp b/src/client/coreconnection.cpp index 0b342ed5..a60fae38 100644 --- a/src/client/coreconnection.cpp +++ b/src/client/coreconnection.cpp @@ -103,6 +103,16 @@ void CoreConnection::resetConnection() { setProgressMaximum(-1); // disable setState(Disconnected); emit connectionMsg(tr("Disconnected from core.")); + emit encrypted(false); +} + +bool CoreConnection::isEncrypted() const { +#ifndef HAVE_SSL + return false; +#else + QSslSocket *sock = qobject_cast(_socket); + return isConnected() && sock && sock->isEncrypted(); +#endif } void CoreConnection::socketStateChanged(QAbstractSocket::SocketState socketState) { @@ -164,15 +174,6 @@ void CoreConnection::setState(ConnectionState state) { } } -void CoreConnection::setWarningsHandler(const char *slot) { - resetWarningsHandler(); - connect(this, SIGNAL(handleIgnoreWarnings(bool)), this, slot); -} - -void CoreConnection::resetWarningsHandler() { - disconnect(this, SIGNAL(handleIgnoreWarnings(bool)), this, 0); -} - void CoreConnection::coreSocketError(QAbstractSocket::SocketError) { qDebug() << "coreSocketError" << _socket << _socket->errorString(); emit connectionError(_socket->errorString()); @@ -289,13 +290,24 @@ void CoreConnection::connectToCurrentAccount() { return; } + CoreAccountSettings s; + Q_ASSERT(!_socket); #ifdef HAVE_SSL QSslSocket *sock = new QSslSocket(Client::instance()); + // make sure the warning is shown if we happen to connect without SSL support later + s.setAccountValue("ShowNoClientSslWarning", true); #else if(_account.useSsl()) { - emit connectionError(tr("This client is built without SSL Support!
Disable the usage of SSL in the account settings.")); - return; + if(s.accountValue("ShowNoClientSslWarning", true).toBool()) { + bool accepted = false; + emit handleNoSslInClient(&accepted); + if(!accepted) { + emit connectionError(tr("Unencrypted connection canceled")); + return; + } + s.setAccountValue("ShowNoClientSslWarning", false); + } } QTcpSocket *sock = new QTcpSocket(Client::instance()); #endif @@ -355,27 +367,86 @@ void CoreConnection::clientInitAck(const QVariantMap &msg) { #endif _coreMsgBuffer = msg; + #ifdef HAVE_SSL + CoreAccountSettings s; if(currentAccount().useSsl()) { if(msg["SupportSsl"].toBool()) { + // Make sure the warning is shown next time we don't have SSL in the core + s.setAccountValue("ShowNoCoreSslWarning", true); + QSslSocket *sslSocket = qobject_cast(_socket); Q_ASSERT(sslSocket); - connect(sslSocket, SIGNAL(encrypted()), this, SLOT(sslSocketEncrypted())); - connect(sslSocket, SIGNAL(sslErrors(const QList &)), this, SLOT(sslErrors(const QList &))); - + connect(sslSocket, SIGNAL(encrypted()), SLOT(sslSocketEncrypted())); + connect(sslSocket, SIGNAL(sslErrors(const QList &)), SLOT(sslErrors())); sslSocket->startClientEncryption(); } else { - emit connectionError(tr("The Quassel Core you are trying to connect to does not support SSL!
If you want to connect anyways, disable the usage of SSL in the account settings.")); - disconnectFromCore(); + if(s.accountValue("ShowNoCoreSslWarning", true).toBool()) { + bool accepted = false; + emit handleNoSslInCore(&accepted); + if(!accepted) { + emit connectionError(tr("Unencrypted connection canceled")); + disconnectFromCore(); + return; + } + s.setAccountValue("ShowNoCoreSslWarning", false); + s.setAccountValue("SslCert", QString()); + } + connectionReady(); } return; } #endif // if we use SSL we wait for the next step until every SSL warning has been cleared connectionReady(); +} +#ifdef HAVE_SSL + +void CoreConnection::sslSocketEncrypted() { + QSslSocket *socket = qobject_cast(sender()); + Q_ASSERT(socket); + + if(!socket->sslErrors().count()) { + // Cert is valid, so we don't want to store it as known + // That way, a warning will appear in case it becomes invalid at some point + CoreAccountSettings s; + s.setAccountValue("SSLCert", QString()); + } + + emit encrypted(true); + connectionReady(); +} + +void CoreConnection::sslErrors() { + QSslSocket *socket = qobject_cast(sender()); + Q_ASSERT(socket); + + CoreAccountSettings s; + QByteArray knownDigest = s.accountValue("SslCert").toByteArray(); + + if(knownDigest != socket->peerCertificate().digest()) { + bool accepted = false; + bool permanently = false; + emit handleSslErrors(socket, &accepted, &permanently); + + if(!accepted) { + emit connectionError(tr("Unencrypted connection canceled")); + disconnectFromCore(); + return; + } + + if(permanently) + s.setAccountValue("SslCert", socket->peerCertificate().digest()); + else + s.setAccountValue("SslCert", QString()); + } + + socket->ignoreSslErrors(); } +#endif /* HAVE_SSL */ + void CoreConnection::connectionReady() { if(!_coreMsgBuffer["Configured"].toBool()) { // start wizard @@ -384,7 +455,6 @@ void CoreConnection::connectionReady() { loginToCore(); } _coreMsgBuffer.clear(); - resetWarningsHandler(); } void CoreConnection::loginToCore(const QString &prevError) {