1 /***************************************************************************
2 * Copyright (C) 2005-2013 by the Quassel Project *
3 * devel@quassel-irc.org *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) version 3. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include "coreauthhandler.h"
24 # include <QSslSocket>
30 #include "protocols/legacy/legacypeer.h"
32 using namespace Protocol;
34 CoreAuthHandler::CoreAuthHandler(QTcpSocket *socket, QObject *parent)
37 , _clientRegistered(false)
41 // TODO: protocol detection
43 // FIXME: make sure _peer gets deleted
44 // TODO: socket ownership goes to the peer! (-> use shared ptr later...)
45 _peer = new LegacyPeer(this, socket, this);
46 // only in compat mode
47 connect(_peer, SIGNAL(protocolVersionMismatch(int,int)), SLOT(onProtocolVersionMismatch(int,int)));
51 // only in compat mode
52 void CoreAuthHandler::onProtocolVersionMismatch(int actual, int expected)
54 qWarning() << qPrintable(tr("Client")) << _peer->description() << qPrintable(tr("too old, rejecting."));
55 QString errorString = tr("<b>Your Quassel Client is too old!</b><br>"
56 "This core needs at least client/core protocol version %1 (got: %2).<br>"
57 "Please consider upgrading your client.").arg(expected, actual);
58 _peer->dispatch(ClientDenied(errorString));
63 void CoreAuthHandler::startSsl()
66 QSslSocket *sslSocket = qobject_cast<QSslSocket *>(socket());
69 qDebug() << qPrintable(tr("Starting encryption for Client:")) << _peer->description();
70 connect(sslSocket, SIGNAL(sslErrors(const QList<QSslError> &)), SLOT(onSslErrors()));
71 sslSocket->startServerEncryption();
77 void CoreAuthHandler::onSslErrors()
79 QSslSocket *sslSocket = qobject_cast<QSslSocket *>(socket());
81 sslSocket->ignoreSslErrors();
86 bool CoreAuthHandler::checkClientRegistered()
88 if (!_clientRegistered) {
89 qWarning() << qPrintable(tr("Client")) << qPrintable(socket()->peerAddress().toString()) << qPrintable(tr("did not send an init message before trying to login, rejecting."));
90 _peer->dispatch(ClientDenied(tr("<b>Client not initialized!</b><br>You need to send an init message before trying to login.")));
98 void CoreAuthHandler::handle(const RegisterClient &msg)
100 // TODO: only in compat mode
103 if (Core::sslSupported() && msg.sslSupported)
106 QVariantList backends;
107 bool configured = Core::isConfigured();
109 backends = Core::backendInfo();
111 _peer->dispatch(ClientRegistered(Quassel::features(), configured, backends, useSsl, Core::instance()->startTime()));
112 // TODO: only in compat mode
116 _clientRegistered = true;
120 void CoreAuthHandler::handle(const SetupData &msg)
122 if (!checkClientRegistered())
125 QString result = Core::setup(msg.adminUser, msg.adminPassword, msg.backend, msg.setupData);
126 if (!result.isEmpty())
127 _peer->dispatch(SetupFailed(result));
129 _peer->dispatch(SetupDone());
133 void CoreAuthHandler::handle(const Login &msg)
135 if (!checkClientRegistered())
138 UserId uid = Core::validateUser(msg.user, msg.password);
140 _peer->dispatch(LoginFailed(tr("<b>Invalid username or password!</b><br>The username/password combination you supplied could not be found in the database.")));
143 _peer->dispatch(LoginSuccess());
145 quInfo() << qPrintable(tr("Client %1 initialized and authenticated successfully as \"%2\" (UserId: %3).").arg(socket()->peerAddress().toString(), msg.user, QString::number(uid.toInt())));
147 disconnect(socket(), 0, this, 0);
148 disconnect(_peer, 0, this, 0);
149 _peer->setParent(0); // Core needs to take care of this one now!
151 emit handshakeComplete(_peer, uid);