MeshCentral/agents/modules_meshcore_min/service-manager.min.js

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(s){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(s.servicePath,l+"\\"+s.name+".exe");s.servicePath=l+"\\"+s.name+".exe";var x=this.GM.CreateVariable('"'+s.servicePath+'"');var o=this.proxy.OpenSCManagerA(0,0,2);if(o.Val==0){throw ("error opening SCManager")}var w=this.GM.CreateVariable(s.name);var j=this.GM.CreateVariable(s.name);var g=983551;var y;switch(s.startType){case"BOOT_START":y=0;break;case"SYSTEM_START":y=1;break;case"AUTO_START":y=2;break;case"DEMAND_START":y=3;break;default:y=4;break}var n=this.proxy.CreateServiceA(o,w,j,g,16|256,y,0,x,0,0,0,0,0);if(n.Val==0){this.proxy.CloseServiceHandle(o);throw ("Error Creating Service: "+this.proxy2.GetLastError().Val)}if(s.description){console.log(s.description);var k=this.GM.CreatePointer();k.Val=this.GM.CreateVariable(s.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(s.name))}if(process.platform=="linux"){if(!this.isAdmin()){throw ("Installing as Service, requires root")}switch(this.getServiceType()){case"init":require("fs").copyFileSync(s.servicePath,"/etc/init.d/"+s.name);console.log("copying "+s.servicePath);var q=require("fs").statSync("/etc/init.d/"+s.name).mode;q|=(require("fs").CHMOD_MODES.S_IXUSR|require("fs").CHMOD_MODES.S_IXGRP);require("fs").chmodSync("/etc/init.d/"+s.name,q);this._update=require("child_process").execFile("/bin/sh",["sh"],{type:require("child_process").SpawnTypes.TERM});this._update._moduleName=s.name;this._update.on("exit",function r(){console.log(this._moduleName+" installed");process.exit()});this._update.stdout.on("data",function(h){});this._update.stdin.write("update-rc.d "+s.name+" defaults\n");this._update.stdin.write("exit\n");break;case"systemd":var v=s.description?s.description:"MeshCentral Agent";if(!require("fs").existsSync("/usr/local/mesh")){require("fs").mkdirSync("/usr/local/mesh")}require("fs").copyFileSync(s.servicePath,"/usr/local/mesh/"+s.name);var q=require("fs").statSync("/usr/local/mesh/"+s.name).mode;q|=(require("fs").CHMOD_MODES.S_IXUSR|require("fs").CHMOD_MODES.S_IXGRP);require("fs").chmodSync("/usr/local/mesh/"+s.name,q);require("fs").writeFileSync("/lib/systemd/system/"+s.name+".service","[Unit]\nDescription="+v+"\n[Service]\nExecStart=/usr/local/mesh/"+s.name+"\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias="+s.name+".service\n",{flags:"w"});this._update=require("child_process").execFile("/bin/sh",["sh"],{type:require("child_process").SpawnTypes.TERM});this._update._moduleName=s.name;this._update.on("exit",function r(){console.log(this._moduleName+" installed");process.exit()});this._update.stdout.on("data",function(h){});this._update.stdin.write("systemctl enable "+s.name+".service\n");this._update.stdin.write("exit\n");break;default:break}}if(process.platform=="darwin"){if(!this.isAdmin()){throw ("Installing as Service, requires root")}var z=(s.stdout?("<key>StandardOutPath</key>\n<string>"+s.stdout+"</string>"):"");var i=(s.startType=="AUTO_START"?"<true/>":"<false/>");var t=" <key>ProgramArguments</key>\n";t+=" <array>\n";t+=(" <string>/usr/local/mesh_services/"+s.name+"/"+s.name+"</string>\n");if(s.parameters){for(var p in s.parameters){t+=(" <string>"+s.parameters[p]+"</string>\n")}}t+=" </array>\n";var u='<?xml version="1.0" encoding="UTF-8"?>\n';u+='<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n';u+='<plist version="1.0">\n';u+=" <dict>\n";u+=" <key>Label</key>\n";u+=(" <string>"+s.name+"</string>\n");u+=(t+"\n");u+=" <key>WorkingDirectory</key>\n";u+=(" <string>/usr/local/mesh_services/"+s.name+"</string>\n");u+=(z+"\n");u+=" <key>RunAtLoad</key>\n";u+=(i+"\n");u+=" </dict>\n";u+="</plist>";if(!require("fs").existsSync("/usr/local/mesh_services")){require("fs").mkdirSync("/usr/local/mesh_services")}if(!require("fs").existsSync("/Library/LaunchDaemons/"+s.name+".plist")){if(!require("fs").existsSync("/usr/local/mesh_services/"+s.name)){require("fs").mkdirSync("/usr/local/mesh_services/"+s.name)}if(s.binary){require("fs").writeFileSync("/usr/local/mesh_services/"+s.name+"/"+s.name,s.binary)}else{require("fs").copyFileSync(s.servicePath,"/usr/local/mesh_services/"+s.name+"/"+s.name)}require("fs").writeFileSync("/Library/LaunchDaemons/"+s.name+".plist",u);var q=require("fs").statSync("/usr/local/mesh_services/"+s.name+"/"+s.name).mode;q|=(require("fs").CHMOD_MODES.S_IXUSR|require("fs").CHMOD_MODES.S_IXGRP);require("fs").chmodSync("/usr/local/mesh_services/"+s.name+"/"+s.name,q)}else{throw ("Service: "+s.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 k=this.getService(i);if(k.status.state==undefined||k.status.state=="STOPPED"){if(this.proxy.DeleteService(k._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: "+k.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._svcname=i;this._update.on("exit",function j(){try{require("fs").unlinkSync("/etc/init.d/"+this._svcname);console.log(this._svcname+" uninstalled")}catch(l){console.log(this._svcname+" could not be uninstalled")}process.exit()});this._update.stdout.on("data",function(l){});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");break;case"systemd":this._update=require("child_process").execFile("/bin/sh",["sh"],{type:require("child_process").SpawnTypes.TERM});this._update._svcname=i;this._update.on("exit",function j(){try{require("fs").unlinkSync("/usr/local/mesh/"+this._svcname);require("fs").unlinkSync("/lib/systemd/system/"+this._svcname+".service");console.log(this._svcname+" uninstalled")}catch(l){console.log(this._svcname+" could not be uninstalled")}process.exit()});this._update.stdout.on("data",function(l){});this._update.stdin.write("systemctl stop "+i+".service\n");this._update.stdin.write("systemctl disable "+i+".service\n");this._update.stdin.write("exit\n");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(l){});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;