diff --git a/exec/json-service.js b/exec/json-service.js index 0a6743238ef9d648b291598310eae44a9356d7c9..37ecc752a4ccf4a2bf2c990c1b6ad5b54c029497 100644 --- a/exec/json-service.js +++ b/exec/json-service.js @@ -56,7 +56,8 @@ var errors = { UNKNOWN_COMMAND:"Unknown command: %s", UNKNOWN_USER:"User not found: %s", SERVICE_OFFLINE:"Service offline", - MODULE_OFFLINE:"Module offline" + MODULE_OFFLINE:"Module offline", + IDENT_REQUIRED:"You must identify before using this command" }; /* server object */ @@ -175,11 +176,27 @@ service = new (function() { /* chat handler */ chat = new (function() { this.db = new JSONdb(system.data_dir+"chat.json"); + this.authenticated = []; + this.deny_hosts = []; + this.cycle = function() { this.db.cycle(); } this.process = function(client,packet) { switch(packet.func.toUpperCase()) { + case "IDENT": + this.ident(client.descriptor,packet.data); + break; + case "BAN": + if(!admin.verify(client,packet)) + break; + this.ban(client.remote_ip_address,packet.data.ip); + break; + case "UNBAN": + if(!admin.verify(client,packet)) + break; + this.unban(client.remote_ip_address,packet.data.ip); + break; case "QUERY": this.db.query(client,packet.data); break; @@ -188,7 +205,46 @@ chat = new (function() { break; } } + this.ident = function(descriptor,data) { + var username = data.username; + var pw = data.pw; + var usernum = system.matchuser(username); + if(usernum == 0) { + log(LOG_WARNING,"no such user: " + username); + return false; + } + var usr = new User(usernum); + var pass = md5_calc(usr.security.password,true); + + if(md5_calc(usr.security.password,true) != pw) { + log(LOG_WARNING,"failed pw attempt for user: " + username); + return false; + } + this.authenticated[descriptor] = usr; + log(LOG_DEBUG,"identified: " + username); + return true; + } + this.ban = function(descriptor,source,target) { + if(!this.authenticated[descriptor] || this.authenticated[descriptor].security.level < 90) + return false; + if(source == target) + return false; + log(LOG_WARNING,"ban added: " + target); + this.denyhosts[target] = true; + } + this.unban = function(descriptor,source,target) { + if(!this.authenticated[descriptor] || this.authenticated[descriptor].security.level < 90) + return false; + if(source == target) + return false; + log(LOG_WARNING,"ban removed: " + target); + delete this.denyhosts[target]; + } this.release = function(client) { + if(this.authenticated[client.id]) { + log(LOG_DEBUG,"releasing auth: " + client.id); + delete this.authenticated[client.id]; + } this.db.release(client); } log(LOG_DEBUG,"chat initialized"); @@ -201,21 +257,31 @@ admin = new (function() { this.process = function(client,packet) { switch(packet.func.toUpperCase()) { case "IDENT": - this.ident(client.descriptor,packet.data.username,packet.data.pw); + this.ident(client.descriptor,packet.data); break; case "RESTART": + if(!this.verify(client,packet)) + break; this.restart(client.descriptor); break; case "BAN": + if(!this.verify(client,packet)) + break; this.ban(client.remote_ip_address,packet.data.ip); break; case "UNBAN": + if(!this.verify(client,packet)) + break; this.unban(client.remote_ip_address,packet.data.ip); break; case "CLOSE": + if(!this.verify(client,packet)) + break; this.close(client.descriptor); break; case "OPEN": + if(!this.verify(client,packet)) + break; this.open(client.descriptor); break; default: @@ -230,7 +296,9 @@ admin = new (function() { delete this.authenticated[client.id]; } } - this.ident = function(descriptor,username,pw) { + this.ident = function(descriptor,data) { + var username = data.username; + var pw = data.pw; var usernum = system.matchuser(username); if(usernum == 0) { log(LOG_WARNING,"no such user: " + username); @@ -247,44 +315,41 @@ admin = new (function() { log(LOG_WARNING,"insufficient access: " + username); return false; } - this.authenticated[descriptor] = true; + this.authenticated[descriptor] = usr; log(LOG_DEBUG,"identified: " + username); return true; } this.close = function(descriptor) { - if(!this.authenticated[descriptor]) - return false; log(LOG_WARNING,"socket service offline"); service.online = false; } this.open = function(descriptor) { - if(!this.authenticated[descriptor]) - return false; log(LOG_WARNING,"socket service online"); service.online = true; } this.restart = function(descriptor) { - if(!this.authenticated[descriptor]) - return false; log(LOG_WARNING,"restarting service"); exit(); } this.ban = function(descriptor,source,target) { - if(!this.authenticated[descriptor]) - return false; if(source == target) return false; log(LOG_WARNING,"ban added: " + target); service.denyhosts[target] = true; } this.unban = function(descriptor,source,target) { - if(!this.authenticated[descriptor]) - return false; if(source == target) return false; log(LOG_WARNING,"ban removed: " + target); delete service.denyhosts[target]; } + this.verify = function(client,packet) { + if(!this.authenticated[client.id]) { + error(client,errors.IDENT_REQUIRED,packet.func); + return false; + } + return true; + } log(LOG_DEBUG,"admin initialized"); })(); @@ -325,36 +390,48 @@ engine = new (function() { case "QUERY": module.db.query(client,packet.data); break; + default: + error(client,errors.UNKNOWN_FUNCTION,packet.func); + break; case "IDENT": break; case "RELOAD": + if(!admin.verify(client,packet)) + break; module.queue.write("RELOAD"); module.init(); break; case "CLOSE": + if(!admin.verify(client,packet)) + break; module.online = false; break; case "OPEN": + if(!admin.verify(client,packet)) + break; module.online = true; break; case "READABLE": + if(!admin.verify(client,packet)) + break; if(module.db.settings.KEEP_READABLE) module.db.settings.KEEP_READABLE = false; else module.db.settings.KEEP_READABLE = true; break; case "SAVE": + if(!admin.verify(client,packet)) + break; module.db.save(); break; case "READONLY": + if(!admin.verify(client,packet)) + break; if(module.db.settings.READ_ONLY) module.db.settings.READ_ONLY = false; else module.db.settings.READ_ONLY = true; break; - default: - error(client,errors.UNKNOWN_FUNCTION,packet.func); - break; } } /* release clients from module authentication and subscription */