From 898fed76c6ccdc3cd175be96369a6a6126c37c2c Mon Sep 17 00:00:00 2001 From: David White Date: Thu, 9 Oct 2014 16:46:12 +0100 Subject: [PATCH] Add initial support for identd --- config.js | 29 +++++++++++++++++++ src/client.js | 17 ++++++++++++ src/identd.js | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 src/identd.js diff --git a/config.js b/config.js index 4e41abb..dc3840d 100644 --- a/config.js +++ b/config.js @@ -176,5 +176,34 @@ module.exports = { // @default "" // certificate: "" + }, + + // + // Allows shout to run as an identd + // + // @type object + // @default {} + identd: { + // + // Enable Identd daemon + // + // @type boolean + // @default true + enable: true, + + // + // Port to listen for ident requests + // + // @type int + // @default 30113 + port: 30113, + + // + // Default user to return on unknown request + // if false, will return NOUSER + // + // @type string + // @default shout + default: "shout" } }; diff --git a/src/client.js b/src/client.js index 55ef099..a842ac3 100644 --- a/src/client.js +++ b/src/client.js @@ -8,6 +8,7 @@ var Network = require("./models/network"); var slate = require("slate-irc"); var tls = require("tls"); var Helper = require("./helper"); +var identd = require("./identd"); module.exports = Client; @@ -137,9 +138,25 @@ Client.prototype.connect = function(args) { }); }); + var nick = args.nick || "shout-user"; var username = args.username || nick; var realname = args.realname || "Shout User"; + var identdItem = null; + + stream.on("connect", function() { + identdItem = { + "remoteIp": stream.remoteAddress, + "remotePort": stream.remotePort, + "localPort": stream.localPort, + "username": username + }; + identd.addConnection(identdItem); + }); + + stream.on("close", function() { + identd.addConnection(identdItem); + }); var irc = slate(stream); diff --git a/src/identd.js b/src/identd.js new file mode 100644 index 0000000..7b5b147 --- /dev/null +++ b/src/identd.js @@ -0,0 +1,77 @@ +var _ = require("lodash"); +var net = require("net"); +var Helper = require("./helper"); + +function Identd() { + // used to store who is connecting... + this.connections = []; + this.server = null; + this.config = { + enabled: false, + port: 30113, + default: "shout" + }; +}; + +Identd.prototype.respond = function(remoteIp, localPort, remotePort) { + // Build the first part (always the same) + var response = localPort + ", " + remotePort + " : "; + var connection = _.where(this.connections, {"remoteIp": remoteIp, "remotePort": remotePort, "localPort": localPort}); + + if (connection.length > 0) { + // We have some connections, but we only want the first + connection = _.first(connection); + response += " USERID : UNIX : " + connection.username; + // We're done with that connection. Remove it + this.removeConnection(connection); + } else { + response += " ERROR : NOUSER"; + } + // responses must end with CR+LF + return response + "\r\n"; +}; + +Identd.prototype.parse = function(request) { + // myPort, theirPort\r\n + request = request.split(/,\s*/); + if (request.length == 2) { + var localPort = parseInt(request[0]), + remotePort = parseInt(request[1]); + } + return [localPort, remotePort]; +}; + +Identd.prototype.start = function(config) { + _.merge(this.config, config.identd); + + if (this.config.enabled) { + var self = this; + + // create the server + this.server = net.createServer(function(socket) { + socket.on('data', function(data) { + var parsed = this.parse(data); + // parse and generate a response + var response = this.respond(socket.remoteAddress, parsed[0], parsed[1]); + socket.write(response); + socket.end(); + }); + }); + console.log("Starting identd on " + this.config.port); + this.server.listen(this.config.port); + } + + return self; +}; + +Identd.prototype.addConnection = function(connection) { + if (this.config.enabled) + this.connections.push(connection); +}; + +Identd.prototype.removeConnection = function(connection) { + if (this.config.enabled) + this.connections = _.without(this.connections, connection); +}; + +module.exports = new Identd().start(Helper.getConfig());