#include "networkmodel.h"
#include "quassel.h"
#include "signalproxy.h"
+#include "util.h"
ClientSyncer::ClientSyncer(QObject *parent)
: QObject(parent)
#ifdef HAVE_SSL
QSslSocket *sock = new QSslSocket(Client::instance());
+ connect(sock, SIGNAL(encrypted()), this, SIGNAL(encrypted()));
#else
if(conn["useSsl"].toBool()) {
emit connectionError(tr("<b>This client is built without SSL Support!</b><br />Disable the usage of SSL in the account settings."));
- emit encrypted(false);
return;
}
QTcpSocket *sock = new QTcpSocket(Client::instance());
}
emit connectionMsg(msg["CoreInfo"].toString());
+#ifndef QT_NO_COMPRESS
+ if(msg["SupportsCompression"].toBool()) {
+ socket->setProperty("UseCompression", true);
+ }
+#endif
+
+ _coreMsgBuffer = msg;
#ifdef HAVE_SSL
if(coreConnectionInfo["useSsl"].toBool()) {
if(msg["SupportSsl"].toBool()) {
QSslSocket *sslSocket = qobject_cast<QSslSocket *>(socket);
Q_ASSERT(sslSocket);
+ connect(sslSocket, SIGNAL(encrypted()), this, SLOT(sslSocketEncrypted()));
connect(sslSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &)));
+
sslSocket->startClientEncryption();
- emit encrypted(true);
- Client::instance()->setSecuredConnection();
} else {
emit connectionError(tr("<b>The Quassel Core you are trying to connect to does not support SSL!</b><br />If you want to connect anyways, disable the usage of SSL in the account settings."));
- emit encrypted(false);
disconnectFromCore();
- return;
}
+ return;
}
#endif
+ // if we use SSL we wait for the next step until every SSL warning has been cleared
+ connectionReady();
+}
-#ifndef QT_NO_COMPRESS
- if(msg["SupportsCompression"].toBool()) {
- socket->setProperty("UseCompression", true);
- }
-#endif
-
- if(!msg["Configured"].toBool()) {
+void ClientSyncer::connectionReady() {
+ if(!_coreMsgBuffer["Configured"].toBool()) {
// start wizard
- emit startCoreSetup(msg["StorageBackends"].toList());
- } else if(msg["LoginEnabled"].toBool()) {
+ emit startCoreSetup(_coreMsgBuffer["StorageBackends"].toList());
+ } else if(_coreMsgBuffer["LoginEnabled"].toBool()) {
emit startLogin();
}
+ _coreMsgBuffer.clear();
+ resetWarningsHandler();
}
void ClientSyncer::doCoreSetup(const QVariant &setupData) {
}
}
+void ClientSyncer::setWarningsHandler(const char *slot) {
+ resetWarningsHandler();
+ connect(this, SIGNAL(handleIgnoreWarnings(bool)), this, slot);
+}
+
+void ClientSyncer::resetWarningsHandler() {
+ disconnect(this, SIGNAL(handleIgnoreWarnings(bool)), this, 0);
+}
+
#ifdef HAVE_SSL
-void ClientSyncer::sslErrors(const QList<QSslError> &errors) {
- qDebug() << "SSL Errors:";
- foreach(QSslError err, errors)
- qDebug() << " " << err;
+void ClientSyncer::ignoreSslWarnings(bool permanently) {
+ QSslSocket *sock = qobject_cast<QSslSocket *>(socket);
+ if(sock) {
+ // ensure that a proper state is displayed and no longer a warning
+ emit socketStateChanged(sock->state());
+ }
+ if(permanently) {
+ if(!sock)
+ qWarning() << Q_FUNC_INFO << "unable to save cert digest! Socket is either a nullptr or not a QSslSocket";
+ else
+ KnownHostsSettings().saveKnownHost(sock);
+ }
+ emit connectionMsg(_coreMsgBuffer["CoreInfo"].toString());
+ connectionReady();
+}
+void ClientSyncer::sslSocketEncrypted() {
+ QSslSocket *socket = qobject_cast<QSslSocket *>(sender());
+ if(socket) {
+ QByteArray digest = socket->peerCertificate().digest();
+ }
+}
+
+void ClientSyncer::sslErrors(const QList<QSslError> &errors) {
+ QByteArray knownDigest;
QSslSocket *socket = qobject_cast<QSslSocket *>(sender());
- if(socket)
+ if(socket) {
socket->ignoreSslErrors();
+ knownDigest = KnownHostsSettings().knownDigest(socket);
+ if(knownDigest == socket->peerCertificate().digest()) {
+ connectionReady();
+ return;
+ }
+ }
+
+ QStringList warnings;
+
+ foreach(QSslError err, errors)
+ warnings << err.errorString();
+
+ if(!knownDigest.isEmpty()) {
+ warnings << tr("Cert Digest changed! was: %1").arg(QString(prettyDigest(knownDigest)));
+ }
+
+ setWarningsHandler(SLOT(ignoreSslWarnings(bool)));
+ emit connectionWarnings(warnings);
}
#endif