Skip to content

Commit

Permalink
Identd: fix various issues
Browse files Browse the repository at this point in the history
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
  • Loading branch information
brunnre8 committed May 12, 2024
2 parents 45c2fc8 + 29fcc2d commit 0955d9d
Showing 1 changed file with 46 additions and 8 deletions.
54 changes: 46 additions & 8 deletions server/identification.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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`;
});
Expand Down

0 comments on commit 0955d9d

Please sign in to comment.