1 /***************************************************************************
2 * Copyright (C) 2005-2018 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 ***************************************************************************/
23 #include "corenetwork.h"
24 #include "identserver.h"
26 IdentServer::IdentServer(bool strict, QObject *parent) : QObject(parent), _strict(strict) {
27 connect(&_server, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
28 connect(&_v6server, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
31 IdentServer::~IdentServer() = default;
33 bool IdentServer::startListening() {
34 uint16_t port = 10113;
37 if (_v6server.listen(QHostAddress("::1"), port)) {
38 quInfo() << qPrintable(
39 tr("Listening for identd clients on IPv6 %1 port %2")
41 .arg(_v6server.serverPort())
47 if (_server.listen(QHostAddress("127.0.0.1"), port)) {
50 quInfo() << qPrintable(
51 tr("Listening for identd clients on IPv4 %1 port %2")
53 .arg(_server.serverPort())
58 quError() << qPrintable(
59 tr("Identd could not open any network interfaces to listen on! No identd functionality will be available"));
65 void IdentServer::stopListening(const QString &msg) {
66 bool wasListening = false;
67 if (_server.isListening()) {
71 if (_v6server.isListening()) {
77 quInfo() << "No longer listening for identd clients.";
79 quInfo() << qPrintable(msg);
83 void IdentServer::incomingConnection() {
84 auto *server = qobject_cast<QTcpServer *>(sender());
86 while (server->hasPendingConnections()) {
87 QTcpSocket *socket = server->nextPendingConnection();
88 connect(socket, SIGNAL(readyRead()), this, SLOT(respond()));
92 void IdentServer::respond() {
93 auto *socket = qobject_cast<QTcpSocket *>(sender());
96 if (socket->canReadLine()) {
97 QByteArray s = socket->readLine();
98 if (s.endsWith("\r\n"))
100 else if (s.endsWith("\n"))
103 QList<QByteArray> split = s.split(',');
105 bool success = false;
108 if (!split.empty()) {
109 localPort = split[0].toUShort(&success, 10);
114 if (_connections.contains(localPort)) {
115 user = _connections[localPort];
123 data += s + " : USERID : Quassel : " + user + "\r\n";
125 data += s + " : ERROR : NO-USER\r\n";
128 socket->write(data.toUtf8());
131 socket->deleteLater();
136 bool IdentServer::addSocket(const CoreIdentity *identity, const QHostAddress &localAddress, quint16 localPort,
137 const QHostAddress &peerAddress, quint16 peerPort) {
138 Q_UNUSED(localAddress)
139 Q_UNUSED(peerAddress)
142 const CoreNetwork *network = qobject_cast<CoreNetwork *>(sender());
143 _connections[localPort] = network->coreSession()->strictCompliantIdent(identity);;
148 //! not yet implemented
149 bool IdentServer::removeSocket(const CoreIdentity *identity, const QHostAddress &localAddress, quint16 localPort,
150 const QHostAddress &peerAddress, quint16 peerPort) {
152 Q_UNUSED(localAddress)
153 Q_UNUSED(peerAddress)
156 _connections.remove(localPort);