X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Fclientsyncer.cpp;h=e0b502b69dd59ed23ae262993f6c7529fba80451;hp=afc1e162ce17d03b07419faa5ac1cab6cc07d361;hb=d4b7af7050bac6f894a05bff4eab1becaffa27ce;hpb=d1b6499b0b848d4287efae89107576548533502c diff --git a/src/client/clientsyncer.cpp b/src/client/clientsyncer.cpp index afc1e162..e0b502b6 100644 --- a/src/client/clientsyncer.cpp +++ b/src/client/clientsyncer.cpp @@ -20,6 +20,10 @@ #include "clientsyncer.h" +#ifndef QT_NO_NETWORKPROXY +# include +#endif + #include "client.h" #include "global.h" #include "identity.h" @@ -29,20 +33,18 @@ #include "signalproxy.h" -ClientSyncer::ClientSyncer(QObject *parent) : QObject(parent) { +ClientSyncer::ClientSyncer(QObject *parent) + : QObject(parent) +{ socket = 0; blockSize = 0; connect(Client::signalProxy(), SIGNAL(disconnected()), this, SLOT(coreSocketDisconnected())); - } ClientSyncer::~ClientSyncer() { - - } - void ClientSyncer::coreHasData() { QVariant item; while(SignalProxy::readDataFromDevice(socket, blockSize, item)) { @@ -60,6 +62,10 @@ void ClientSyncer::coreHasData() { emit connectionError(msg["Error"].toString()); disconnectFromCore(); return; + } else if(msg["MsgType"] == "CoreSetupAck") { + emit coreSetupSuccess(); + } else if(msg["MsgType"] == "CoreSetupReject") { + emit coreSetupFailed(msg["Error"].toString()); } else if(msg["MsgType"] == "ClientLoginReject") { emit loginFailed(msg["Error"].toString()); } else if(msg["MsgType"] == "ClientLoginAck") { @@ -69,23 +75,12 @@ void ClientSyncer::coreHasData() { emit loginSuccess(); } else if(msg["MsgType"] == "SessionInit") { sessionStateReceived(msg["SessionState"].toMap()); + break; // this is definitively the last message we process here! } else { emit connectionError(tr("Invalid data received from core!
Disconnecting.")); disconnectFromCore(); return; } - /* - if (!msg["StartWizard"].toBool()) { - recvCoreState(msg["Reply"]); - } else { - qWarning("Core not configured!"); - qDebug() << "Available storage providers: " << msg["StorageProviders"].toStringList(); - emit showConfigWizard(msg); - } - blockSize = 0; - return; - } - */ } if(blockSize > 0) { emit recvPartialItem(socket->bytesAvailable(), blockSize); @@ -93,6 +88,7 @@ void ClientSyncer::coreHasData() { } void ClientSyncer::coreSocketError(QAbstractSocket::SocketError) { + qDebug() << "coreSocketError" << socket << socket->errorString(); emit connectionError(socket->errorString()); socket->deleteLater(); } @@ -108,7 +104,6 @@ void ClientSyncer::connectToCore(const QVariantMap &conn) { // emit coreConnectionError(tr("Already connected to Core!")); // return; // } - if(socket != 0) { socket->deleteLater(); socket = 0; @@ -127,7 +122,23 @@ void ClientSyncer::connectToCore(const QVariantMap &conn) { //clientMode = RemoteCore; //emit coreConnectionMsg(tr("Connecting...")); Q_ASSERT(!socket); + +#ifndef QT_NO_OPENSSL + QSslSocket *sock = new QSslSocket(Client::instance()); +#else + if(conn["useSsl"].toBool()) { + emit connectionError(tr("This client is built without SSL Support!
Disable the usage of SSL in the account settings.")); + emit encrypted(false); + return; + } QTcpSocket *sock = new QTcpSocket(Client::instance()); +#endif +#ifndef QT_NO_NETWORKPROXY + if(conn.contains("useProxy") && conn["useProxy"].toBool()) { + QNetworkProxy proxy((QNetworkProxy::ProxyType)conn["proxyType"].toInt(), conn["proxyHost"].toString(), conn["proxyPort"].toUInt(), conn["proxyUser"].toString(), conn["proxyPassword"].toString()); + sock->setProxy(proxy); + } +#endif socket = sock; connect(sock, SIGNAL(readyRead()), this, SLOT(coreHasData())); connect(sock, SIGNAL(connected()), this, SLOT(coreSocketConnected())); @@ -146,9 +157,16 @@ void ClientSyncer::coreSocketConnected() { QVariantMap clientInit; clientInit["MsgType"] = "ClientInit"; clientInit["ClientVersion"] = Global::quasselVersion; - clientInit["ClientDate"] = Global::quasselDate; - clientInit["ClientBuild"] = Global::quasselBuild; // this is a minimum, since we probably won't update for every commit - clientInit["UseSsl"] = false; // FIXME implement SSL + clientInit["ClientBuild"] = 860; // FIXME legacy! + clientInit["ClientDate"] = Global::quasselBuildDate; + clientInit["ProtocolVersion"] = Global::protocolVersion; + clientInit["UseSsl"] = coreConnectionInfo["useSsl"]; +#ifndef QT_NO_COMPRESS + clientInit["UseCompression"] = true; +#else + clientInit["UseCompression"] = false; +#endif + SignalProxy::writeDataToDevice(socket, clientInit); } @@ -168,18 +186,54 @@ void ClientSyncer::coreSocketDisconnected() { void ClientSyncer::clientInitAck(const QVariantMap &msg) { // Core has accepted our version info and sent its own. Let's see if we accept it as well... - if(msg["CoreBuild"].toUInt() < Global::coreBuildNeeded) { + if((msg.contains("CoreBuild") && msg["CoreBuild"].toUInt() < 732) // legacy! + || (!msg.contains("CoreBuild") && msg["ProtocolVersion"].toUInt() < Global::clientNeedsProtocol)) { emit connectionError(tr("The Quassel Core you are trying to connect to is too old!
" - "Need at least a Core Version %1 (Build >= %2) to connect.").arg(Global::quasselVersion).arg(Global::quasselBuild)); + "Need at least core/client protocol v%1 to connect.").arg(Global::clientNeedsProtocol)); disconnectFromCore(); return; } emit connectionMsg(msg["CoreInfo"].toString()); - if(msg["LoginEnabled"].toBool()) { + +#ifndef QT_NO_OPENSSL + if(coreConnectionInfo["useSsl"].toBool()) { + if(msg["SupportSsl"].toBool()) { + QSslSocket *sslSocket = qobject_cast(socket); + Q_ASSERT(sslSocket); + connect(sslSocket, SIGNAL(sslErrors(const QList &)), this, SLOT(sslErrors(const QList &))); + sslSocket->startClientEncryption(); + emit encrypted(true); + Client::instance()->setSecuredConnection(); + } 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.")); + emit encrypted(false); + disconnectFromCore(); + return; + } + } +#endif + +#ifndef QT_NO_COMPRESS + if(msg["SupportsCompression"].toBool()) { + socket->setProperty("UseCompression", true); + } +#endif + + if(!msg["Configured"].toBool()) { + // start wizard + emit startCoreSetup(msg["StorageBackends"].toList()); + } else if(msg["LoginEnabled"].toBool()) { emit startLogin(); } } +void ClientSyncer::doCoreSetup(const QVariant &setupData) { + QVariantMap setup; + setup["MsgType"] = "CoreSetupData"; + setup["SetupData"] = setupData; + SignalProxy::writeDataToDevice(socket, setup); +} + void ClientSyncer::loginToCore(const QString &user, const QString &passwd) { emit connectionMsg(tr("Logging in...")); QVariantMap clientLogin; @@ -194,16 +248,12 @@ void ClientSyncer::sessionStateReceived(const QVariantMap &state) { disconnect(this, SIGNAL(recvPartialItem(quint32, quint32)), this, SIGNAL(sessionProgress(quint32, quint32))); disconnect(socket, 0, this, 0); // rest of communication happens through SignalProxy //Client::signalProxy()->addPeer(socket); - Client::instance()->setConnectedToCore(socket); + Client::instance()->setConnectedToCore(socket, coreConnectionInfo["AccountId"].value()); syncToCore(state); } void ClientSyncer::syncToCore(const QVariantMap &sessionState) { - // store sessionData - QVariantMap sessData = sessionState["SessionData"].toMap(); - foreach(QString key, sessData.keys()) Client::instance()->recvSessionData(key, sessData[key]); - // create identities foreach(QVariant vid, sessionState["Identities"].toList()) { Client::instance()->coreIdentityCreated(vid.value()); @@ -238,6 +288,7 @@ void ClientSyncer::syncToCore(const QVariantMap &sessionState) { connect(net, SIGNAL(ircChannelRemoved(QObject *)), this, SLOT(ircChannelRemoved(QObject *))); Client::addNetwork(net); } + checkSyncState(); } void ClientSyncer::networkInitDone() { @@ -295,7 +346,8 @@ void ClientSyncer::ircUserRemoved(QObject *user) { } void ClientSyncer::checkSyncState() { - if(usersToSync.count() + channelsToSync.count() + netsToSync.count() == 0) { + // if(usersToSync.count() + channelsToSync.count() + netsToSync.count() == 0) { + if(netsToSync.isEmpty()) { // done syncing! /* qDebug() << "done"; @@ -326,3 +378,14 @@ void ClientSyncer::checkSyncState() { } } +#ifndef QT_NO_OPENSSL +void ClientSyncer::sslErrors(const QList &errors) { + qDebug() << "SSL Errors:"; + foreach(QSslError err, errors) + qDebug() << " " << err; + + QSslSocket *socket = qobject_cast(sender()); + if(socket) + socket->ignoreSslErrors(); +} +#endif