diff --git a/exec/fingerservice.js b/exec/fingerservice.js index 423714b76531f44787053bbb2dda2c24186e9a33..2d5aa20b122385cba0db7ab8b1bfacf8fd790a06 100644 --- a/exec/fingerservice.js +++ b/exec/fingerservice.js @@ -6,12 +6,27 @@ // Finger 79 0-unlimited 0 fingerservice.js +// Add -n to the configuration line to eliminate user age and gender +// information from the query results. + +// !WARNING! +// Finger is an open protocol utilizing no forms of authorization +// or authentication. FINGER IS A KNOWN AND ACCEPTED SECURITY RISK. +// Detailed information about your system and its users is made +// available to ANYONE using this service. If there is anything in +// this script that you do not want to be made available to anyone +// and everyone, please comment-out (using /* and */) that portion +// of the script. + +const VERSION="Synchronet Finger Service Version 1.00a"; + +var include_age_gender=true; + load("nodedefs.js"); -// This is just an example of how you access command-line args for(i=0;i<argc;i++) - log(format("argv[%d]=%s",i,argv[i])); -// End of example :-) + if(argv[i].toLowerCase()=="-n") + include_age_gender = false; // Write a string to the client socket function write(str) @@ -19,8 +34,36 @@ function write(str) client.socket.send(str); } -// Get Finger Request -request = client.socket.recvline(128 /*maxlen*/, 3 /*timeout*/); +// Write a crlf terminated string to the client socket +function writeln(str) +{ + write(str + "\r\n"); +} + +// Send the contents of a text file to the client socket +function send_file(fname) +{ + f = new File(fname); + if(!f.open("r")) + return; + txt = f.readAll(); + f.close(); + for(l in txt) + writeln(txt[l]); +} + +// Returns true if a connection on the local 'port' was succesful +function test_port(port) +{ + sock = new Socket(); + success = sock.connect("localhost",port); + sock.close(); + + return(success); +} + +// Get Finger Request (the main entry point) +request = client.socket.recvline(128 /*maxlen*/, 10 /*timeout*/); if(request==null) { log("!TIMEOUT waiting for request"); @@ -30,18 +73,21 @@ if(request==null) { log(format("client request: '%s'",request)); if(request.substr(0,2).toUpperCase()=="/W") // "higher level of verbosity" - request=request.slice(2); + request=request.slice(2); // ignored... while(request.charAt(0)==' ') // skip prepended spaces request=request.slice(1); -if(request=="") { /* no specific user requested, give list of active users */ +if(request=="") { // no specific user requested, give list of active users log("client requested active user list"); - write(format("%-25.25s %-40.40s Age Sex Node\r\n" - ,"User","Action")); + write(format("%-25.25s %-40.40s %7s Node\r\n" + ,"User","Action",include_age_gender ? "Age Sex":"")); var dashes="----------------------------------------"; - write(format("%-25.25s %-40.40s %.3s %.3s %.4s\r\n" - ,dashes,dashes,dashes,dashes,dashes)); + write(format("%-25.25s %-40.40s %3.3s %3.3s %4.4s\r\n" + ,dashes,dashes + ,include_age_gender ? dashes : "" + ,include_age_gender ? dashes : "" + ,dashes)); var user = new User(1); for(n=0;n<system.node_list.length;n++) { if(system.node_list[n].status!=NODE_INUSE) @@ -49,17 +95,89 @@ if(request=="") { /* no specific user requested, give list of active users */ user.number=system.node_list[n].useron; var action=format(NodeAction[system.node_list[n].action] ,system.node_list[n].aux); - write(format("%-25.25s %-40.40s %3d %3s %4d\r\n" + write(format("%-25.25s %-40.40s %3s %3s %4d\r\n" ,user.alias ,action - ,user.age - ,user.gender + ,include_age_gender ? user.age.toString() : "" + ,include_age_gender ? user.gender : "" ,n+1 )); } exit(); } +if(request.charAt(0)=='?') { // Handle "special" requests + request=request.slice(1); + switch(request.toLowerCase()) { + + case "ver": + writeln(VERSION); + writeln(system.version_notice + system.revision); + writeln("Compiled " + system.compiled_when + " with " + system.compiled_with); + writeln(system.js_version); + writeln(system.os_version); + break; + + case "time": + writeln(system.timestr() + " " + system.zonestr()); + break; + + case "logon.lst": + send_file(system.data_dir + "logon.lst"); + break; + + case "auto.msg": + send_file(system.data_dir + "msgs/auto.msg"); + break; + + case "stats": /* Statistics */ + for(i in system.stats) + writeln(i + " = " + system.stats[i]); + break; + + case "nodelist": + var user = new User(1); + for(n=0;n<system.node_list.length;n++) { + write(format("Node %2d ",n+1)); + if(system.node_list[n].status==NODE_INUSE) { + user.number=system.node_list[n].useron; + write(format("%s (%u %s) ", user.alias, user.age, user.gender)); + write(format(NodeAction[system.node_list[n].action],system.node_list[n].aux)); + } else + write(format(NodeStatus[system.node_list[n].status],system.node_list[n].aux)); + + write("\r\n"); + } + break; + + case "caps": /* Capabilities */ + if(test_port(23)) + writeln("Telnet"); + if(test_port(513)) + writeln("RLogin"); + if(test_port(21)) + writeln("FTP"); + if(test_port(25)) + writeln("SMTP"); + if(test_port(110)) + writeln("POP3"); + if(test_port(119)) + writeln("NNTP"); + if(test_port(80)) + writeln("HTTP"); + if(test_port(6667)) + writeln("IRC"); + break; + + default: + log(format("!UNSUPPORTED SPECIAL REQUEST: '%s'",request)); + break; + } + exit(); +} + +// User info is handled here + var usernum=Number(request); if(!usernum) { var at = request.indexOf('@'); @@ -82,9 +200,18 @@ write(format("Site: %s\r\n" ,system.inetaddr)); write(format("Login name: %-30s In real life: %s\r\n" ,user.alias,user.name)); -write(format("Shell: %s\r\n",user.command_shell)); -write(format("Last login %s via %s from %s [%s]\r\n" +write(format("From: %s\r\n",user.location)); +if(include_age_gender) { + birth=format("Birth: %s (Age: %u years)" + ,user.birthdate,user.age); + write(format("%-42s Gender: %s\r\n" + ,birth,user.gender)); +} +write(format("Shell: %-34s Editor: %s\r\n" + ,user.command_shell,user.editor)); +write(format("Last login %s %s\r\nvia %s from %s [%s]\r\n" ,system.timestr(user.stats.laston_date) + ,system.zonestr() ,user.connection ,user.host_name ,user.ip_address));