| 1 | var net = require('net'); |
| 2 | |
| 3 | var IdentdServer = module.exports = function(opts) { |
| 4 | |
| 5 | var that = this; |
| 6 | |
| 7 | var default_user_id = 'kiwi', |
| 8 | default_system_id = 'UNIX-KiwiIRC'; |
| 9 | |
| 10 | // Option defaults |
| 11 | opts = opts || {}; |
| 12 | opts.bind_addr = opts.bind_addr || '0.0.0.0'; |
| 13 | opts.bind_port = opts.bind_port || 113; |
| 14 | opts.system_id = opts.system_id || default_system_id; |
| 15 | opts.user_id = opts.user_id || default_user_id; |
| 16 | |
| 17 | |
| 18 | var server = net.createServer(function(socket) { |
| 19 | var buffer = ''; |
| 20 | |
| 21 | socket.on('data', function(data){ |
| 22 | var data_line, response; |
| 23 | |
| 24 | buffer += data.toString(); |
| 25 | |
| 26 | // If we exceeed 512 bytes, presume a flood and disconnect |
| 27 | if (buffer.length < 512) { |
| 28 | |
| 29 | // Wait until we have a full line of data before processing it |
| 30 | if (buffer.indexOf('\n') === -1) |
| 31 | return; |
| 32 | |
| 33 | // Get the first line of data and process it for a rsponse |
| 34 | data_line = buffer.split('\n')[0]; |
| 35 | response = that.processLine(data_line); |
| 36 | |
| 37 | } |
| 38 | |
| 39 | // Close down the socket while sending the response |
| 40 | socket.removeAllListeners(); |
| 41 | socket.end(response); |
| 42 | }); |
| 43 | |
| 44 | }); |
| 45 | |
| 46 | server.on('listening', function() { |
| 47 | console.log('Ident Server listening on ' + server.address().address + ':' + server.address().port); |
| 48 | }); |
| 49 | |
| 50 | |
| 51 | this.start = function() { |
| 52 | server.listen(opts.bind_port, opts.bind_addr); |
| 53 | }; |
| 54 | |
| 55 | this.stop = function(callback) { |
| 56 | server.close(callback); |
| 57 | }; |
| 58 | |
| 59 | |
| 60 | /** |
| 61 | * Process a line of data for an Identd response |
| 62 | * |
| 63 | * @param {String} The line of data to process |
| 64 | * @return {String} Data to send back to the Identd client |
| 65 | */ |
| 66 | this.processLine = function(line) { |
| 67 | var ports = line.split(','), |
| 68 | port_here = 0, |
| 69 | port_there = 0; |
| 70 | |
| 71 | // We need 2 port number to make this work |
| 72 | if (ports.length < 2) |
| 73 | return; |
| 74 | |
| 75 | port_here = parseInt(ports[0], 10); |
| 76 | port_there = parseInt(ports[1], 10); |
| 77 | |
| 78 | // Make sure we have both ports to work with |
| 79 | if (!port_here || !port_there) |
| 80 | return; |
| 81 | |
| 82 | if (typeof opts.user_id === 'function') { |
| 83 | user = (opts.user_id(port_here, port_there) || '').toString() || default_user_id; |
| 84 | } else { |
| 85 | user = opts.user_id.toString(); |
| 86 | } |
| 87 | |
| 88 | if (typeof opts.system_id === 'function') { |
| 89 | system = (opts.system_id(port_here, port_there) || '').toString() || default_system_id; |
| 90 | } else { |
| 91 | system = opts.system_id.toString(); |
| 92 | } |
| 93 | |
| 94 | return port_here.toString() + ' , ' + port_there.toString() + ' : USERID : ' + system + ' : ' + user; |
| 95 | }; |
| 96 | }; |