mirror of
https://github.com/thelounge/thelounge.git
synced 2024-05-23 16:42:15 +02:00
ident: only respond if the ip,port tuples match
Per RFC 1413, The uniquely identifying tuple includes not only the ports, but also both addresses. If multiple connections happen to use the same local port number (which is possible if the addresses differ), the username of the first is returned for all, resulting in the wrong ident for all but the first. By not checking the connection address, the information becomes public. Because there is only relatively small number of local ports, and the remote ports are likely to be either 6667 or 6697, it becomes trivial to enumerate all the users. Co-Authored-By: Juerd Waalboer <juerd@tnx.nl>
This commit is contained in:
parent
4819406af5
commit
0e48014d5a
|
@ -73,24 +73,41 @@ class Identification {
|
|||
}
|
||||
|
||||
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 +144,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