mirror of
https://github.com/thelounge/thelounge.git
synced 2024-05-23 08:32:15 +02:00
Identd: fix various issues
There's a bunch of sub optimal behavior from our ident server. For one, it allows user enumeration which we don't really want and it doesn't clean up connections that don't send any data. Fix that
This commit is contained in:
commit
0955d9df06
|
@ -1,9 +1,9 @@
|
|||
import log from "./log";
|
||||
import fs from "fs";
|
||||
import net, {Socket} from "net";
|
||||
import colors from "chalk";
|
||||
import Helper from "./helper";
|
||||
import Config from "./config";
|
||||
import log from "./log";
|
||||
|
||||
type Connection = {
|
||||
socket: Socket;
|
||||
|
@ -66,31 +66,56 @@ class Identification {
|
|||
|
||||
serverConnection(socket: Socket) {
|
||||
socket.on("error", (err: string) => log.error(`Identd socket error: ${err}`));
|
||||
socket.on("data", (data) => {
|
||||
socket.setTimeout(5000, () => {
|
||||
log.warn(
|
||||
`identd: no data received, closing connection to ${
|
||||
socket.remoteAddress || "undefined"
|
||||
}`
|
||||
);
|
||||
socket.destroy();
|
||||
});
|
||||
socket.once("data", (data) => {
|
||||
this.respondToIdent(socket, data);
|
||||
socket.end();
|
||||
});
|
||||
}
|
||||
|
||||
respondToIdent(socket: Socket, buffer: Buffer) {
|
||||
if (!socket.remoteAddress) {
|
||||
log.warn("identd: no remote address");
|
||||
return;
|
||||
}
|
||||
|
||||
const data = buffer.toString().split(",");
|
||||
|
||||
const lport = parseInt(data[0], 10) || 0;
|
||||
const fport = parseInt(data[1], 10) || 0;
|
||||
|
||||
if (lport < 1 || fport < 1 || lport > 65535 || fport > 65535) {
|
||||
log.warn(`identd: bogus request from ${socket.remoteAddress}`);
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug(`identd: remote ${socket.remoteAddress} query ${lport}, ${fport}`);
|
||||
|
||||
for (const connection of this.connections.values()) {
|
||||
if (connection.socket.remotePort === fport && connection.socket.localPort === lport) {
|
||||
return socket.write(
|
||||
`${lport}, ${fport} : USERID : TheLounge : ${connection.user}\r\n`
|
||||
);
|
||||
// we only want to respond if all the ip,port tuples match, to avoid user enumeration
|
||||
if (
|
||||
connection.socket.remotePort === fport &&
|
||||
connection.socket.localPort === lport &&
|
||||
socket.remoteAddress === connection.socket.remoteAddress &&
|
||||
socket.localAddress === connection.socket.localAddress
|
||||
) {
|
||||
const reply = `${lport}, ${fport} : USERID : TheLounge : ${connection.user}\r\n`;
|
||||
log.debug(`identd: reply is ${reply.trimEnd()}`);
|
||||
socket.write(reply);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
socket.write(`${lport}, ${fport} : ERROR : NO-USER\r\n`);
|
||||
const reply = `${lport}, ${fport} : ERROR : NO-USER\r\n`;
|
||||
log.debug(`identd: reply is ${reply.trimEnd()}`);
|
||||
socket.write(reply);
|
||||
}
|
||||
|
||||
addSocket(socket: Socket, user: string) {
|
||||
|
@ -127,8 +152,21 @@ class Identification {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!connection.socket.remoteAddress) {
|
||||
log.warn(`oidentd: socket has no remote address, will not respond to queries`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!connection.socket.localAddress) {
|
||||
log.warn(`oidentd: socket has no local address, will not respond to queries`);
|
||||
return;
|
||||
}
|
||||
|
||||
// we only want to respond if all the ip,port tuples match, to avoid user enumeration
|
||||
file +=
|
||||
`fport ${connection.socket.remotePort}` +
|
||||
`to ${connection.socket.remoteAddress}` +
|
||||
` fport ${connection.socket.remotePort}` +
|
||||
` from ${connection.socket.localAddress}` +
|
||||
` lport ${connection.socket.localPort}` +
|
||||
` { reply "${connection.user}" }\n`;
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue