MeshCentral/agents/modules_meshcmd_min/service-manager.min.js
2019-06-19 17:59:03 -07:00

1 line
12 KiB
JavaScript

function parseServiceStatus(d){var b={};var c=d.Deref(0,4).IntVal;b.isFileSystemDriver=((c&2)==2);b.isKernelDriver=((c&1)==1);b.isSharedProcess=((c&32)==32);b.isOwnProcess=((c&16)==16);b.isInteractive=((c&256)==256);switch(d.Deref((1*4),4).toBuffer().readUInt32LE()){case 5:b.state="CONTINUE_PENDING";break;case 6:b.state="PAUSE_PENDING";break;case 7:b.state="PAUSED";break;case 4:b.state="RUNNING";break;case 2:b.state="START_PENDING";break;case 3:b.state="STOP_PENDING";break;case 1:b.state="STOPPED";break}var a=d.Deref((2*4),4).toBuffer().readUInt32LE();b.controlsAccepted=[];if((a&16)==16){b.controlsAccepted.push("SERVICE_CONTROL_NETBINDADD");b.controlsAccepted.push("SERVICE_CONTROL_NETBINDREMOVE");b.controlsAccepted.push("SERVICE_CONTROL_NETBINDENABLE");b.controlsAccepted.push("SERVICE_CONTROL_NETBINDDISABLE")}if((a&8)==8){b.controlsAccepted.push("SERVICE_CONTROL_PARAMCHANGE")}if((a&2)==2){b.controlsAccepted.push("SERVICE_CONTROL_PAUSE");b.controlsAccepted.push("SERVICE_CONTROL_CONTINUE")}if((a&256)==256){b.controlsAccepted.push("SERVICE_CONTROL_PRESHUTDOWN")}if((a&4)==4){b.controlsAccepted.push("SERVICE_CONTROL_SHUTDOWN")}if((a&1)==1){b.controlsAccepted.push("SERVICE_CONTROL_STOP")}if((a&32)==32){b.controlsAccepted.push("SERVICE_CONTROL_HARDWAREPROFILECHANGE")}if((a&64)==64){b.controlsAccepted.push("SERVICE_CONTROL_POWEREVENT")}if((a&128)==128){b.controlsAccepted.push("SERVICE_CONTROL_SESSIONCHANGE")}b.pid=d.Deref((7*4),4).toBuffer().readUInt32LE();return(b)}function serviceManager(){this._ObjectID="service-manager";if(process.platform=="win32"){this.GM=require("_GenericMarshal");this.proxy=this.GM.CreateNativeProxy("Advapi32.dll");this.proxy.CreateMethod("OpenSCManagerA");this.proxy.CreateMethod("EnumServicesStatusExA");this.proxy.CreateMethod("OpenServiceA");this.proxy.CreateMethod("QueryServiceStatusEx");this.proxy.CreateMethod("ControlService");this.proxy.CreateMethod("StartServiceA");this.proxy.CreateMethod("CloseServiceHandle");this.proxy.CreateMethod("CreateServiceA");this.proxy.CreateMethod("ChangeServiceConfig2A");this.proxy.CreateMethod("DeleteService");this.proxy.CreateMethod("AllocateAndInitializeSid");this.proxy.CreateMethod("CheckTokenMembership");this.proxy.CreateMethod("FreeSid");this.proxy2=this.GM.CreateNativeProxy("Kernel32.dll");this.proxy2.CreateMethod("GetLastError");this.isAdmin=function e(){var j=this.GM.CreateVariable(6);j.toBuffer().writeInt8(5,5);var h=this.GM.CreatePointer();var g=false;if(this.proxy.AllocateAndInitializeSid(j,2,32,544,0,0,0,0,0,0,h).Val!=0){var i=this.GM.CreateInteger();if(this.proxy.CheckTokenMembership(0,h.Deref(),i).Val!=0){if(i.toBuffer().readUInt32LE()!=0){g=true}}this.proxy.FreeSid(h.Deref())}return g};this.getProgramFolder=function a(){if(require("os").arch()=="x64"){if(this.GM.PointerSize==4){return process.env["ProgramFiles(x86)"]}return process.env.ProgramFiles}return process.env.ProgramFiles};this.getServiceFolder=function b(){return this.getProgramFolder()+"\\mesh"};this.enumerateService=function(){var o=this.GM.CreatePointer();var k=this.GM.CreatePointer();var l=this.proxy.OpenSCManagerA(0,0,1|4);var h=this.GM.CreatePointer();var t=this.GM.CreatePointer();var q=this.GM.CreatePointer();var u=this.proxy.EnumServicesStatusExA(l,0,48,3,0,0,h,t,q,0);if(h.IntVal<=0){throw ("error enumerating services")}var v=h.IntVal;var s=this.GM.CreateVariable(v);this.proxy.EnumServicesStatusExA(l,0,48,3,s,v,h,t,q,0);console.log("servicesReturned",t.IntVal);var p=k._size;var g=36+(2*p);g+=((p-(g%p))%p);var r=[];for(var m=0;m<t.IntVal;++m){var w=s.Deref(m*g,g);var n={};n.name=w.Deref(0,p).Deref().String;n.displayName=w.Deref(p,p).Deref().String;n.status=parseServiceStatus(w.Deref(2*p,36));r.push(n)}this.proxy.CloseServiceHandle(l);return(r)};this.getService=function(k){var m=this.GM.CreateVariable(k);var l=this.GM.CreatePointer();var g=this.GM.CreateVariable(l._size);var j=this.proxy.OpenSCManagerA(0,0,1|4|32|16);if(j.Val==0){throw ("could not open ServiceManager")}var i=this.proxy.OpenServiceA(j,m,4|32|16|65536);if(i.Val!=0){var o=this.proxy.QueryServiceStatusEx(i,0,0,0,g);var n=this.GM.CreateVariable(g.toBuffer().readUInt32LE());o=this.proxy.QueryServiceStatusEx(i,0,n,n._size,g);if(o!=0){retVal={};retVal.status=parseServiceStatus(n);retVal._scm=j;retVal._service=i;retVal._GM=this.GM;retVal._proxy=this.proxy;require("events").inherits(retVal);retVal.on("~",function(){this._proxy.CloseServiceHandle(this);this._proxy.CloseServiceHandle(this._scm)});retVal.name=k;retVal.stop=function(){if(this.status.state=="RUNNING"){var h=this._GM.CreateVariable(36);var p=this._proxy.ControlService(this._service,1,h);if(p==0){throw (this.name+".stop() failed")}}else{throw ("cannot call "+this.name+".stop(), when current state is: "+this.status.state)}};retVal.start=function(){if(this.status.state=="STOPPED"){var h=this._proxy.StartServiceA(this._service,0,0);if(h==0){throw (this.name+".start() failed")}}else{throw ("cannot call "+this.name+".start(), when current state is: "+this.status.state)}};return(retVal)}else{}}this.proxy.CloseServiceHandle(j);throw ("could not find service: "+k)}}else{this.isAdmin=function e(){return(require("user-sessions").isRoot())}}this.installService=function d(r){if(process.platform=="win32"){if(!this.isAdmin()){throw ("Installing as Service, requires admin")}var l=this.getServiceFolder();if(!require("fs").existsSync(l)){require("fs").mkdirSync(l)}require("fs").copyFileSync(r.servicePath,l+"\\"+r.name+".exe");r.servicePath=l+"\\"+r.name+".exe";var w=this.GM.CreateVariable('"'+r.servicePath+'"');var o=this.proxy.OpenSCManagerA(0,0,2);if(o.Val==0){throw ("error opening SCManager")}var v=this.GM.CreateVariable(r.name);var j=this.GM.CreateVariable(r.name);var g=983551;var x;switch(r.startType){case"BOOT_START":x=0;break;case"SYSTEM_START":x=1;break;case"AUTO_START":x=2;break;case"DEMAND_START":x=3;break;default:x=4;break}var n=this.proxy.CreateServiceA(o,v,j,g,16|256,x,0,w,0,0,0,0,0);if(n.Val==0){this.proxy.CloseServiceHandle(o);throw ("Error Creating Service: "+this.proxy2.GetLastError().Val)}if(r.description){console.log(r.description);var k=this.GM.CreatePointer();k.Val=this.GM.CreateVariable(r.description);if(this.proxy.ChangeServiceConfig2A(n,1,k)==0){this.proxy.CloseServiceHandle(n);this.proxy.CloseServiceHandle(o);throw ("Unable to set description")}}this.proxy.CloseServiceHandle(n);this.proxy.CloseServiceHandle(o);return(this.getService(r.name))}if(process.platform=="linux"){if(!this.isAdmin()){throw ("Installing as Service, requires root")}switch(this.getServiceType()){case"init":require("fs").copyFileSync(r.servicePath,"/etc/init.d/"+r.name);console.log("copying "+r.servicePath);var q=require("fs").statSync("/etc/init.d/"+r.name).mode;q|=(require("fs").CHMOD_MODES.S_IXUSR|require("fs").CHMOD_MODES.S_IXGRP);require("fs").chmodSync("/etc/init.d/"+r.name,q);this._update=require("child_process").execFile("/bin/sh",["sh"],{type:require("child_process").SpawnTypes.TERM});this._update._moduleName=r.name;this._update.stdout.on("data",function(h){});this._update.stdin.write("update-rc.d "+r.name+" defaults\n");this._update.stdin.write("exit\n");this._update.waitExit();break;case"systemd":var u=r.description?r.description:"MeshCentral Agent";if(!require("fs").existsSync("/usr/local/mesh")){require("fs").mkdirSync("/usr/local/mesh")}require("fs").copyFileSync(r.servicePath,"/usr/local/mesh/"+r.name);var q=require("fs").statSync("/usr/local/mesh/"+r.name).mode;q|=(require("fs").CHMOD_MODES.S_IXUSR|require("fs").CHMOD_MODES.S_IXGRP);require("fs").chmodSync("/usr/local/mesh/"+r.name,q);require("fs").writeFileSync("/lib/systemd/system/"+r.name+".service","[Unit]\nDescription="+u+"\n[Service]\nExecStart=/usr/local/mesh/"+r.name+"\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias="+r.name+".service\n",{flags:"w"});this._update=require("child_process").execFile("/bin/sh",["sh"],{type:require("child_process").SpawnTypes.TERM});this._update._moduleName=r.name;this._update.stdout.on("data",function(h){});this._update.stdin.write("systemctl enable "+r.name+".service\n");this._update.stdin.write("exit\n");this._update.waitExit();break;default:break}}if(process.platform=="darwin"){if(!this.isAdmin()){throw ("Installing as Service, requires root")}var y=(r.stdout?("<key>StandardOutPath</key>\n<string>"+r.stdout+"</string>"):"");var i=(r.startType=="AUTO_START"?"<true/>":"<false/>");var s=" <key>ProgramArguments</key>\n";s+=" <array>\n";s+=(" <string>/usr/local/mesh_services/"+r.name+"/"+r.name+"</string>\n");if(r.parameters){for(var p in r.parameters){s+=(" <string>"+r.parameters[p]+"</string>\n")}}s+=" </array>\n";var t='<?xml version="1.0" encoding="UTF-8"?>\n';t+='<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n';t+='<plist version="1.0">\n';t+=" <dict>\n";t+=" <key>Label</key>\n";t+=(" <string>"+r.name+"</string>\n");t+=(s+"\n");t+=" <key>WorkingDirectory</key>\n";t+=(" <string>/usr/local/mesh_services/"+r.name+"</string>\n");t+=(y+"\n");t+=" <key>RunAtLoad</key>\n";t+=(i+"\n");t+=" </dict>\n";t+="</plist>";if(!require("fs").existsSync("/usr/local/mesh_services")){require("fs").mkdirSync("/usr/local/mesh_services")}if(!require("fs").existsSync("/Library/LaunchDaemons/"+r.name+".plist")){if(!require("fs").existsSync("/usr/local/mesh_services/"+r.name)){require("fs").mkdirSync("/usr/local/mesh_services/"+r.name)}if(r.binary){require("fs").writeFileSync("/usr/local/mesh_services/"+r.name+"/"+r.name,r.binary)}else{require("fs").copyFileSync(r.servicePath,"/usr/local/mesh_services/"+r.name+"/"+r.name)}require("fs").writeFileSync("/Library/LaunchDaemons/"+r.name+".plist",t);var q=require("fs").statSync("/usr/local/mesh_services/"+r.name+"/"+r.name).mode;q|=(require("fs").CHMOD_MODES.S_IXUSR|require("fs").CHMOD_MODES.S_IXGRP);require("fs").chmodSync("/usr/local/mesh_services/"+r.name+"/"+r.name,q)}else{throw ("Service: "+r.name+" already exists")}}};this.uninstallService=function f(i){if(!this.isAdmin()){throw ("Uninstalling a service, requires admin")}if(typeof(i)=="object"){i=i.name}if(process.platform=="win32"){var j=this.getService(i);if(j.status.state==undefined||j.status.state=="STOPPED"){if(this.proxy.DeleteService(j._service)==0){throw ("Uninstall Service for: "+i+", failed with error: "+this.proxy2.GetLastError())}else{try{require("fs").unlinkSync(this.getServiceFolder()+"\\"+i+".exe")}catch(h){}}}else{throw ("Cannot uninstall service: "+i+", because it is: "+j.status.state)}}else{if(process.platform=="linux"){switch(this.getServiceType()){case"init":this._update=require("child_process").execFile("/bin/sh",["sh"],{type:require("child_process").SpawnTypes.TERM});this._update.stdout.on("data",function(k){});this._update.stdin.write("service "+i+" stop\n");this._update.stdin.write("update-rc.d -f "+i+" remove\n");this._update.stdin.write("exit\n");this._update.waitExit();try{require("fs").unlinkSync("/etc/init.d/"+i);console.log(i+" uninstalled")}catch(h){console.log(i+" could not be uninstalled",h)}break;case"systemd":this._update=require("child_process").execFile("/bin/sh",["sh"],{type:require("child_process").SpawnTypes.TERM});this._update.stdout.on("data",function(k){});this._update.stdin.write("systemctl stop "+i+".service\n");this._update.stdin.write("systemctl disable "+i+".service\n");this._update.stdin.write("exit\n");this._update.waitExit();try{require("fs").unlinkSync("/usr/local/mesh/"+i);require("fs").unlinkSync("/lib/systemd/system/"+i+".service");console.log(i+" uninstalled")}catch(h){console.log(i+" could not be uninstalled",h)}break;default:break}}else{if(process.platform=="darwin"){if(require("fs").existsSync("/Library/LaunchDaemons/"+i+".plist")){var g=require("child_process").execFile("/bin/sh",["sh"]);g.stdout.on("data",function(k){});g.stdin.write("launchctl stop "+i+"\n");g.stdin.write("launchctl unload /Library/LaunchDaemons/"+i+".plist\n");g.stdin.write("exit\n");g.waitExit();try{require("fs").unlinkSync("/usr/local/mesh_services/"+i+"/"+i);require("fs").unlinkSync("/Library/LaunchDaemons/"+i+".plist")}catch(h){throw ("Error uninstalling service: "+i+" => "+h)}try{require("fs").rmdirSync("/usr/local/mesh_services/"+i)}catch(h){}}else{throw ("Service: "+i+" does not exist")}}}}};if(process.platform=="linux"){this.getServiceType=function c(){return(require("process-manager").getProcessInfo(1).Name)}}}module.exports=serviceManager;