X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Fclientauthhandler.cpp;h=a3fc870d84343b761329fb683acd0bc5093f0070;hp=7ed231c2f144378d38c3bd15ea8da15a782f44ad;hb=39328183a6a87c6eb10a9dbbffcd5d65bf154a1f;hpb=d32f2fcafe3d3925cd64e332e0d02261a134af21 diff --git a/src/client/clientauthhandler.cpp b/src/client/clientauthhandler.cpp index 7ed231c2..a3fc870d 100644 --- a/src/client/clientauthhandler.cpp +++ b/src/client/clientauthhandler.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2015 by the Quassel Project * + * Copyright (C) 2005-2018 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -20,8 +20,6 @@ #include "clientauthhandler.h" -// TODO: support system application proxy (new in Qt 4.6) - #include #ifdef HAVE_SSL @@ -32,13 +30,14 @@ #include "client.h" #include "clientsettings.h" +#include "logmessage.h" #include "peerfactory.h" using namespace Protocol; ClientAuthHandler::ClientAuthHandler(CoreAccount account, QObject *parent) : AuthHandler(parent), - _peer(0), + _peer(nullptr), _account(account), _probing(false), _legacy(false), @@ -48,6 +47,12 @@ ClientAuthHandler::ClientAuthHandler(CoreAccount account, QObject *parent) } +Peer *ClientAuthHandler::peer() const +{ + return _peer; +} + + void ClientAuthHandler::connectToCore() { CoreAccountSettings s; @@ -71,10 +76,21 @@ void ClientAuthHandler::connectToCore() QTcpSocket *socket = new QTcpSocket(this); #endif -// TODO: Handle system proxy #ifndef QT_NO_NETWORKPROXY - if (_account.useProxy()) { - QNetworkProxy proxy(_account.proxyType(), _account.proxyHostName(), _account.proxyPort(), _account.proxyUser(), _account.proxyPassword()); + QNetworkProxy proxy; + proxy.setType(_account.proxyType()); + if (_account.proxyType() == QNetworkProxy::Socks5Proxy || + _account.proxyType() == QNetworkProxy::HttpProxy) { + proxy.setHostName(_account.proxyHostName()); + proxy.setPort(_account.proxyPort()); + proxy.setUser(_account.proxyUser()); + proxy.setPassword(_account.proxyPassword()); + } + + if (_account.proxyType() == QNetworkProxy::DefaultProxy) { + QNetworkProxyFactory::setUseSystemConfiguration(true); + } else { + QNetworkProxyFactory::setUseSystemConfiguration(false); socket->setProxy(proxy); } #endif @@ -284,7 +300,7 @@ void ClientAuthHandler::startRegistration() useSsl = _account.useSsl(); #endif - _peer->dispatch(RegisterClient(Quassel::buildInfo().fancyVersionString, Quassel::buildInfo().buildDate, useSsl)); + _peer->dispatch(RegisterClient(Quassel::Features{}, Quassel::buildInfo().fancyVersionString, Quassel::buildInfo().commitDate, useSsl)); } @@ -299,8 +315,9 @@ void ClientAuthHandler::handle(const ClientRegistered &msg) { _coreConfigured = msg.coreConfigured; _backendInfo = msg.backendInfo; + _authenticatorInfo = msg.authenticatorInfo; - Client::setCoreFeatures(static_cast(msg.coreFeatures)); + _peer->setFeatures(std::move(msg.features)); // The legacy protocol enables SSL at this point if(_legacy && _account.useSsl()) @@ -312,12 +329,21 @@ void ClientAuthHandler::handle(const ClientRegistered &msg) void ClientAuthHandler::onConnectionReady() { + const auto &coreFeatures = _peer->features(); + auto unsupported = coreFeatures.toStringList(false); + if (!unsupported.isEmpty()) { + quInfo() << qPrintable(tr("Core does not support the following features: %1").arg(unsupported.join(", "))); + } + if (!coreFeatures.unknownFeatures().isEmpty()) { + quInfo() << qPrintable(tr("Core supports unknown features: %1").arg(coreFeatures.unknownFeatures().join(", "))); + } + emit connectionReady(); emit statusMessage(tr("Connected to %1").arg(_account.accountName())); if (!_coreConfigured) { // start wizard - emit startCoreSetup(_backendInfo); + emit startCoreSetup(_backendInfo, _authenticatorInfo); } else // TODO: check if we need LoginEnabled login(); @@ -385,10 +411,10 @@ void ClientAuthHandler::handle(const LoginSuccess &msg) void ClientAuthHandler::handle(const SessionState &msg) { - disconnect(socket(), 0, this, 0); // this is the last message we shall ever get + disconnect(socket(), nullptr, this, nullptr); // this is the last message we shall ever get // give up ownership of the peer; CoreSession takes responsibility now - _peer->setParent(0); + _peer->setParent(nullptr); emit handshakeComplete(_peer, msg); } @@ -423,6 +449,7 @@ void ClientAuthHandler::checkAndEnableSsl(bool coreSupportsSsl) } s.setAccountValue("ShowNoCoreSslWarning", false); s.setAccountValue("SslCert", QString()); + s.setAccountValue("SslCertDigestVersion", QVariant(QVariant::Int)); } if (_legacy) onConnectionReady(); @@ -444,6 +471,7 @@ void ClientAuthHandler::onSslSocketEncrypted() // That way, a warning will appear in case it becomes invalid at some point CoreAccountSettings s; s.setAccountValue("SSLCert", QString()); + s.setAccountValue("SslCertDigestVersion", QVariant(QVariant::Int)); } emit encrypted(true); @@ -462,8 +490,23 @@ void ClientAuthHandler::onSslErrors() CoreAccountSettings s; QByteArray knownDigest = s.accountValue("SslCert").toByteArray(); + ClientAuthHandler::DigestVersion knownDigestVersion = static_cast(s.accountValue("SslCertDigestVersion").toInt()); + + QByteArray calculatedDigest; + switch (knownDigestVersion) { + case ClientAuthHandler::DigestVersion::Md5: + calculatedDigest = socket->peerCertificate().digest(QCryptographicHash::Md5); + break; + + case ClientAuthHandler::DigestVersion::Sha2_512: + calculatedDigest = socket->peerCertificate().digest(QCryptographicHash::Sha512); + break; + + default: + qWarning() << "Certificate digest version" << QString(knownDigestVersion) << "is not supported"; + } - if (knownDigest != socket->peerCertificate().digest()) { + if (knownDigest != calculatedDigest) { bool accepted = false; bool permanently = false; emit handleSslErrors(socket, &accepted, &permanently); @@ -473,10 +516,18 @@ void ClientAuthHandler::onSslErrors() return; } - if (permanently) - s.setAccountValue("SslCert", socket->peerCertificate().digest()); - else + if (permanently) { + s.setAccountValue("SslCert", socket->peerCertificate().digest(QCryptographicHash::Sha512)); + s.setAccountValue("SslCertDigestVersion", ClientAuthHandler::DigestVersion::Latest); + } + else { s.setAccountValue("SslCert", QString()); + s.setAccountValue("SslCertDigestVersion", QVariant(QVariant::Int)); + } + } + else if (knownDigestVersion != ClientAuthHandler::DigestVersion::Latest) { + s.setAccountValue("SslCert", socket->peerCertificate().digest(QCryptographicHash::Sha512)); + s.setAccountValue("SslCertDigestVersion", ClientAuthHandler::DigestVersion::Latest); } socket->ignoreSslErrors();