mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-04-07 05:10:25 -04:00
New MeshCmd, fixes MeshAgent registry values
This commit is contained in:
parent
8287997b2d
commit
835e03225d
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -84,15 +84,14 @@ function objToString(x, p, ret) {
|
|||||||
function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ' '; } return r; }
|
function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ' '; } return r; }
|
||||||
|
|
||||||
// Parse the incoming arguments
|
// Parse the incoming arguments
|
||||||
function run(argv)
|
function run(argv) {
|
||||||
{
|
|
||||||
if (meshCmdVersion[0] == '*') { meshCmdVersion = ''; } else { meshCmdVersion = ' v' + meshCmdVersion; }
|
if (meshCmdVersion[0] == '*') { meshCmdVersion = ''; } else { meshCmdVersion = ' v' + meshCmdVersion; }
|
||||||
var args = parceArguments(argv);
|
var args = parceArguments(argv);
|
||||||
//console.log(JSON.stringify(argv));
|
//console.log(JSON.stringify(argv));
|
||||||
//console.log('addedModules = ' + JSON.stringify(addedModules));
|
//console.log('addedModules = ' + JSON.stringify(addedModules));
|
||||||
var actionpath = 'meshaction.txt';
|
var actionpath = 'meshaction.txt';
|
||||||
if (args.actionfile != null) { actionpath = args.actionfile; }
|
if (args.actionfile != null) { actionpath = args.actionfile; }
|
||||||
var actions = ['HELP', 'ROUTE', 'AMTLMS', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG'];
|
var actions = ['HELP', 'ROUTE', 'MICROLMS', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG'];
|
||||||
|
|
||||||
// Load the action file
|
// Load the action file
|
||||||
var actionfile = null;
|
var actionfile = null;
|
||||||
@ -134,10 +133,10 @@ function run(argv)
|
|||||||
console.log('\r\nValid local actions:');
|
console.log('\r\nValid local actions:');
|
||||||
console.log(' SMBios - Display System Management BIOS tables for this computer.');
|
console.log(' SMBios - Display System Management BIOS tables for this computer.');
|
||||||
console.log(' RawSMBios - Display RAW System Management BIOS tables for this computer.');
|
console.log(' RawSMBios - Display RAW System Management BIOS tables for this computer.');
|
||||||
|
console.log(' MicroLMS - Run MicroLMS, allowing local access to Intel AMT.');
|
||||||
console.log(' AmtInfo - Show Intel AMT version and activation state.');
|
console.log(' AmtInfo - Show Intel AMT version and activation state.');
|
||||||
console.log(' AmtVersions - Show all Intel ME version information.');
|
console.log(' AmtVersions - Show all Intel ME version information.');
|
||||||
console.log(' AmtHashes - Show all Intel AMT trusted activation hashes.');
|
console.log(' AmtHashes - Show all Intel AMT trusted activation hashes.');
|
||||||
console.log(' AmtLMS - Run MicroLMS, allowing local access to Intel AMT.');
|
|
||||||
console.log(' AmtCCM - Activate Intel AMT into Client Control Mode.');
|
console.log(' AmtCCM - Activate Intel AMT into Client Control Mode.');
|
||||||
console.log(' AmtDeactivate - Deactivate Intel AMT if activated in Client Control mode.');
|
console.log(' AmtDeactivate - Deactivate Intel AMT if activated in Client Control mode.');
|
||||||
console.log('\r\nValid local or remote actions:');
|
console.log('\r\nValid local or remote actions:');
|
||||||
@ -176,10 +175,12 @@ function run(argv)
|
|||||||
console.log('AmtVersions will display all version information about Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtversions');
|
console.log('AmtVersions will display all version information about Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtversions');
|
||||||
} else if (action == 'amthashes') {
|
} else if (action == 'amthashes') {
|
||||||
console.log('Amthashes will display all trusted activations hashes for Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd amthashes');
|
console.log('Amthashes will display all trusted activations hashes for Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd amthashes');
|
||||||
} else if (action == 'amtlms') {
|
} else if ((action == 'microlms') || (action == 'lms') || (action == 'amtlms')) {
|
||||||
console.log('AmtLMS will state MicroLMS on this computer, allowing local access to Intel AMT on TCP ports 16992 and 16993 when applicable. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd amtlms');
|
console.log('Starts MicroLMS on this computer, allowing local access to Intel AMT on TCP ports 16992 and 16993 when applicable. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd microlms');
|
||||||
console.log('\r\nPossible arguments:\r\n');
|
console.log('\r\nPossible arguments:\r\n');
|
||||||
console.log(' --noconsole MeshCommander for LMS will no be available on port 16994.');
|
console.log(' --noconsole MeshCommander for LMS will no be available on port 16994.');
|
||||||
|
console.log('\r\nRun as a background service:\r\n');
|
||||||
|
console.log(' microlms install/uninstall/start/stop.');
|
||||||
} else if (action == 'amtccm') {
|
} else if (action == 'amtccm') {
|
||||||
console.log('AmtCCM will attempt to activate Intel AMT on this computer into client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be in "pre-provisioning" state for this command to work and a administrator password must be provided. Example usage:\r\n\r\n meshcmd amtccm --pass mypassword');
|
console.log('AmtCCM will attempt to activate Intel AMT on this computer into client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be in "pre-provisioning" state for this command to work and a administrator password must be provided. Example usage:\r\n\r\n meshcmd amtccm --pass mypassword');
|
||||||
} else if (action == 'amtdeactivate') {
|
} else if (action == 'amtdeactivate') {
|
||||||
@ -232,6 +233,8 @@ function run(argv)
|
|||||||
console.log('This action launched a local web server that hosts MeshCommander, a Intel AMT management console.');
|
console.log('This action launched a local web server that hosts MeshCommander, a Intel AMT management console.');
|
||||||
console.log('\r\nPossible arguments:\r\n');
|
console.log('\r\nPossible arguments:\r\n');
|
||||||
console.log(' --localport [port] Local port used for the web server, 3000 is default.');
|
console.log(' --localport [port] Local port used for the web server, 3000 is default.');
|
||||||
|
console.log('\r\nRun as a background service:\r\n');
|
||||||
|
console.log(' meshcommander install/uninstall/start/stop.');
|
||||||
} else if (action == 'amtauditlog') {
|
} else if (action == 'amtauditlog') {
|
||||||
console.log('AmtAuditLog action will fetch the local or remote audit log. If used localy, no username/password is required. Example usage:\r\n\r\n meshcmd amtauditlog --host 1.2.3.4 --user admin --pass mypassword --tls --output audit.json');
|
console.log('AmtAuditLog action will fetch the local or remote audit log. If used localy, no username/password is required. Example usage:\r\n\r\n meshcmd amtauditlog --host 1.2.3.4 --user admin --pass mypassword --tls --output audit.json');
|
||||||
console.log('\r\nPossible arguments:\r\n');
|
console.log('\r\nPossible arguments:\r\n');
|
||||||
@ -342,7 +345,7 @@ function run(argv)
|
|||||||
else if (mestate.ProvisioningState.stateStr == 'POST') { if (mestate.ProvisioningMode.modeStr == 'ENTERPRISE') { str += ', activated in ' + ["none", "client control mode", "admin control mode", "remote assistance mode"][mestate.controlmode.controlMode]; } else { str += ', activated in ' + mestate.ProvisioningMode.modeStr; } }
|
else if (mestate.ProvisioningState.stateStr == 'POST') { if (mestate.ProvisioningMode.modeStr == 'ENTERPRISE') { str += ', activated in ' + ["none", "client control mode", "admin control mode", "remote assistance mode"][mestate.controlmode.controlMode]; } else { str += ', activated in ' + mestate.ProvisioningMode.modeStr; } }
|
||||||
if (mestate.ehbc.EHBC == true) { str += ', EHBC enabled'; }
|
if (mestate.ehbc.EHBC == true) { str += ', EHBC enabled'; }
|
||||||
str += '.';
|
str += '.';
|
||||||
if (mestate.net0 != null) { str += '\r\nWired ' + ((mestate.net0.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net0.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net0.mac + (mestate.net0.address == '0.0.0.0'?'':(', ' + mestate.net0.address)); }
|
if (mestate.net0 != null) { str += '\r\nWired ' + ((mestate.net0.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net0.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net0.mac + (mestate.net0.address == '0.0.0.0' ? '' : (', ' + mestate.net0.address)); }
|
||||||
if (mestate.net1 != null) { str += '\r\nWireless ' + ((mestate.net1.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net1.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net1.mac + (mestate.net1.address == '0.0.0.0' ? '' : (', ' + mestate.net1.address)); }
|
if (mestate.net1 != null) { str += '\r\nWireless ' + ((mestate.net1.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net1.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net1.mac + (mestate.net1.address == '0.0.0.0' ? '' : (', ' + mestate.net1.address)); }
|
||||||
console.log(str + '.');
|
console.log(str + '.');
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -357,10 +360,10 @@ function run(argv)
|
|||||||
settings.localport = 16992;
|
settings.localport = 16992;
|
||||||
debug(1, "Settings: " + JSON.stringify(settings));
|
debug(1, "Settings: " + JSON.stringify(settings));
|
||||||
saveEntireAmtState();
|
saveEntireAmtState();
|
||||||
} else if (settings.action == 'amtlms') {
|
} else if ((settings.action == 'microlms') || (settings.action == 'amtlms') || (settings.action == 'lms')) {
|
||||||
// Start Intel AMT MicroLMS
|
// Start Intel AMT MicroLMS
|
||||||
startLms(function (state) {
|
startLms(function (state) {
|
||||||
console.log(['MicroLMS did not start. MicroLMS must run as administrator or LMS any already be active.', 'MicroLMS started.', 'MicroLMS started, MeshCommander on HTTP/16994.', 'MEI error'][state]); console.log('Press ctrl-c to exit.'); if (state == 0) { exit(0); }
|
console.log(['MicroLMS did not start. Must run as administrator or LMS already active.', 'MicroLMS started.', 'MicroLMS started, MeshCommander on HTTP/16994.', 'MEI error'][state]); console.log('Press ctrl-c to exit.'); if (state == 0) { exit(0); }
|
||||||
});
|
});
|
||||||
} else if (settings.action == 'amtscript') {
|
} else if (settings.action == 'amtscript') {
|
||||||
// Start running a MEScript
|
// Start running a MEScript
|
||||||
@ -436,7 +439,7 @@ function readAmtAuditLogEx2(stack, response, status) {
|
|||||||
} else {
|
} else {
|
||||||
var out = '';
|
var out = '';
|
||||||
for (var i in response) {
|
for (var i in response) {
|
||||||
var name = ((response[i].Initiator != '')?(response[i].Initiator + ': '):'')
|
var name = ((response[i].Initiator != '') ? (response[i].Initiator + ': ') : '')
|
||||||
out += (response[i].Time + ' - ' + name + response[i].Event + '\r\n');
|
out += (response[i].Time + ' - ' + name + response[i].Event + '\r\n');
|
||||||
}
|
}
|
||||||
if (settings.output == null) { console.log(out); } else { var file = fs.openSync(settings.output, 'w'); fs.writeSync(file, new Buffer(out, 'utf8')); fs.closeSync(file); }
|
if (settings.output == null) { console.log(out); } else { var file = fs.openSync(settings.output, 'w'); fs.writeSync(file, new Buffer(out, 'utf8')); fs.closeSync(file); }
|
||||||
@ -559,7 +562,7 @@ function activeToCCMEx(state) {
|
|||||||
function activeToCCMEx2(stack, name, responses, status) {
|
function activeToCCMEx2(stack, name, responses, status) {
|
||||||
if (status != 200) { console.log('Failed to fetch activation status, status ' + status); exit(1); }
|
if (status != 200) { console.log('Failed to fetch activation status, status ' + status); exit(1); }
|
||||||
else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { console.log('Client control mode activation not allowed'); exit(1); }
|
else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { console.log('Client control mode activation not allowed'); exit(1); }
|
||||||
else { osamtstack.IPS_HostBasedSetupService_Setup(2, md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + settings.password).substring(0,32), null, null, null, null, activeToCCMEx3); }
|
else { osamtstack.IPS_HostBasedSetupService_Setup(2, md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + settings.password).substring(0, 32), null, null, null, null, activeToCCMEx3); }
|
||||||
}
|
}
|
||||||
|
|
||||||
function activeToCCMEx3(stack, name, responses, status) {
|
function activeToCCMEx3(stack, name, responses, status) {
|
||||||
@ -624,7 +627,7 @@ function startMeScriptEx() {
|
|||||||
try { scriptData = fs.readFileSync(settings.script); } catch (e) { console.log('Unable to read script file (1): ' + settings.script + '.'); exit(1); return; }
|
try { scriptData = fs.readFileSync(settings.script); } catch (e) { console.log('Unable to read script file (1): ' + settings.script + '.'); exit(1); return; }
|
||||||
} else {
|
} else {
|
||||||
scriptData = settings.scriptJSON;
|
scriptData = settings.scriptJSON;
|
||||||
}
|
}
|
||||||
if (scriptData == null) { console.log('Unable to read script file (2): ' + settings.script + '.'); exit(1); return; }
|
if (scriptData == null) { console.log('Unable to read script file (2): ' + settings.script + '.'); exit(1); return; }
|
||||||
try { scriptData = JSON.parse(scriptData); } catch (e) { console.log('Unable to read script file (3): ' + settings.script + '.'); exit(1); return; }
|
try { scriptData = JSON.parse(scriptData); } catch (e) { console.log('Unable to read script file (3): ' + settings.script + '.'); exit(1); return; }
|
||||||
if (scriptData.mescript == null) { console.log('Unable to read script file (4): ' + settings.script + '.'); exit(1); return; }
|
if (scriptData.mescript == null) { console.log('Unable to read script file (4): ' + settings.script + '.'); exit(1); return; }
|
||||||
@ -634,7 +637,7 @@ function startMeScriptEx() {
|
|||||||
var script = scriptModule.setup(scriptData, {})
|
var script = scriptModule.setup(scriptData, {})
|
||||||
script.amtstack = amtstack;
|
script.amtstack = amtstack;
|
||||||
script.start();
|
script.start();
|
||||||
script.onCompleted = function () { exit(1);}
|
script.onCompleted = function () { exit(1); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -651,7 +654,7 @@ function saveEntireAmtState() {
|
|||||||
var transport = require('amt-wsman-duk');
|
var transport = require('amt-wsman-duk');
|
||||||
var wsman = require('amt-wsman');
|
var wsman = require('amt-wsman');
|
||||||
var amt = require('amt');
|
var amt = require('amt');
|
||||||
wsstack = new wsman(transport, settings.hostname, settings.tls?16993:16992, settings.username, settings.password, settings.tls);
|
wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
|
||||||
amtstack = new amt(wsstack);
|
amtstack = new amt(wsstack);
|
||||||
amtstack.onProcessChanged = onWsmanProcessChanged;
|
amtstack.onProcessChanged = onWsmanProcessChanged;
|
||||||
//var AllWsman = "AMT_GeneralSystemDefenseCapabilities".split(',');
|
//var AllWsman = "AMT_GeneralSystemDefenseCapabilities".split(',');
|
||||||
@ -769,7 +772,6 @@ function startLms(func) {
|
|||||||
amtLms = new lme_heci({ debug: settings.lmsdebug });
|
amtLms = new lme_heci({ debug: settings.lmsdebug });
|
||||||
amtLms.on('error', function (e) {
|
amtLms.on('error', function (e) {
|
||||||
console.log('LME connection failed', e);
|
console.log('LME connection failed', e);
|
||||||
|
|
||||||
setupMeiOsAdmin(func, amtLms.connected == false ? 0 : 3);
|
setupMeiOsAdmin(func, amtLms.connected == false ? 0 : 3);
|
||||||
});
|
});
|
||||||
amtLms.on('notify', function (data, options, str, code) {
|
amtLms.on('notify', function (data, options, str, code) {
|
||||||
@ -843,7 +845,7 @@ function startLms(func) {
|
|||||||
tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 1); }, 100);
|
tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 1); }, 100);
|
||||||
//console.logReferenceCount(tempTimer);
|
//console.logReferenceCount(tempTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,7 +959,7 @@ function processLmsControlData(data) {
|
|||||||
case 2: // Intel AMT MEI Unprovision (CMD = 2)
|
case 2: // Intel AMT MEI Unprovision (CMD = 2)
|
||||||
{ if (data.length < 6) break; amtMei.unprovision(data.readUInt32LE(2), function (status, socket) { var data = new Buffer(6); data.writeUInt16LE(2, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
|
{ if (data.length < 6) break; amtMei.unprovision(data.readUInt32LE(2), function (status, socket) { var data = new Buffer(6); data.writeUInt16LE(2, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
|
||||||
case 3: // Intel AMT MEI GetLocalSystemAccount (CMD = 3)
|
case 3: // Intel AMT MEI GetLocalSystemAccount (CMD = 3)
|
||||||
{ amtMei.getLocalSystemAccount(function (account, socket) {socket.write(Buffer.concat([Buffer.from('030000000000', 'hex'), account.raw])); }, this); break; }
|
{ amtMei.getLocalSystemAccount(function (account, socket) { socket.write(Buffer.concat([Buffer.from('030000000000', 'hex'), account.raw])); }, this); break; }
|
||||||
case 4: // Instruct Intel AMT to start remote configuration (CMD = 4)
|
case 4: // Instruct Intel AMT to start remote configuration (CMD = 4)
|
||||||
{ amtMei.startConfiguration(function (status, socket) { var data = new Buffer(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
|
{ amtMei.startConfiguration(function (status, socket) { var data = new Buffer(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
|
||||||
case 5: // Instruct Intel AMT to stop remote configuration (CMD = 5)
|
case 5: // Instruct Intel AMT to stop remote configuration (CMD = 5)
|
||||||
@ -1150,7 +1152,7 @@ function getAmtStorage(func, noretry) {
|
|||||||
// Fetch the Intel AMT storage document
|
// Fetch the Intel AMT storage document
|
||||||
function pushToStorage(name, linkname, data, func, ptr) {
|
function pushToStorage(name, linkname, data, func, ptr) {
|
||||||
if (ptr == null) { ptr = 0; }
|
if (ptr == null) { ptr = 0; }
|
||||||
var req = digest.request({ protocol: settings.protocol, method: "PUT", host: settings.hostname, path: ("/amt-storage/" + name + ((ptr != 0) ? '?append=' : '')), port: settings.localport } );
|
var req = digest.request({ protocol: settings.protocol, method: "PUT", host: settings.hostname, path: ("/amt-storage/" + name + ((ptr != 0) ? '?append=' : '')), port: settings.localport });
|
||||||
req.on('error', function (e) { console.log("Error occured: " + JSON.stringify(e)); if (func != null) { func(null); } });
|
req.on('error', function (e) { console.log("Error occured: " + JSON.stringify(e)); if (func != null) { func(null); } });
|
||||||
req.on('response', function (response) {
|
req.on('response', function (response) {
|
||||||
debug(1, 'Chunk Done', data.length, ptr);
|
debug(1, 'Chunk Done', data.length, ptr);
|
||||||
@ -1178,7 +1180,7 @@ function verifyStorage(name, data, func) {
|
|||||||
|
|
||||||
// Fetch the Intel AMT storage document
|
// Fetch the Intel AMT storage document
|
||||||
function deleteStorage(name, func, noretry) {
|
function deleteStorage(name, func, noretry) {
|
||||||
var req = digest.request({ protocol: settings.protocol, method: "DELETE", host: settings.hostname, path: "/amt-storage/" + name, port: settings.localport } );
|
var req = digest.request({ protocol: settings.protocol, method: "DELETE", host: settings.hostname, path: "/amt-storage/" + name, port: settings.localport });
|
||||||
req.on('error', function (e) { if ((e == 'Error: Socket was unexpectedly closed') && (noretry != true)) { deleteStorage(name, func, true); } else { if (func != null) { if (e.statusCode) { func(e.statusCode); } else { func(null); } } } });
|
req.on('error', function (e) { if ((e == 'Error: Socket was unexpectedly closed') && (noretry != true)) { deleteStorage(name, func, true); } else { if (func != null) { if (e.statusCode) { func(e.statusCode); } else { func(null); } } } });
|
||||||
req.on('response', function (response) { if (func != null) { func(response.statusCode); } });
|
req.on('response', function (response) { if (func != null) { func(response.statusCode); } });
|
||||||
req.end();
|
req.end();
|
||||||
@ -1203,69 +1205,39 @@ function removeItemFromArray(array, element) {
|
|||||||
var serviceName = null;
|
var serviceName = null;
|
||||||
var serviceOpSpecified = 0;
|
var serviceOpSpecified = 0;
|
||||||
|
|
||||||
for (var i in process.argv)
|
for (var i in process.argv) {
|
||||||
{
|
if ((process.argv[i].toLowerCase() == 'microlms') || (process.argv[i].toLowerCase() == 'amtlms') || (process.argv[i].toLowerCase() == 'lms')) { serviceName = 'MicroLMS'; break; }
|
||||||
if(process.argv[i].toLowerCase() == 'amtlms')
|
if ((process.argv[i].toLowerCase() == 'meshcommander') || (process.argv[i].toLowerCase() == 'commander')) { serviceName = 'MeshCommander'; break; }
|
||||||
{
|
|
||||||
serviceName = 'MeshCmd_Lms';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(process.argv[i].toLowerCase() == 'meshcommander')
|
|
||||||
{
|
|
||||||
serviceName = 'MeshCmd_Commander';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serviceName == null)
|
if (serviceName == null) {
|
||||||
{
|
for (var i in process.argv) {
|
||||||
for (var i in process.argv)
|
if ((process.argv[i].toLowerCase() == 'install') || (process.argv[i].toLowerCase() == 'uninstall')) {
|
||||||
{
|
console.log('In order to install/uninstall, a service type must be specified.');
|
||||||
if (process.argv[i] == '-install' || process.argv[i] == '-uninstall')
|
|
||||||
{
|
|
||||||
console.log('In order to Install/Uninstall, a service type must be specified');
|
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(process.execPath.includes('MeshCmd_Lms'))
|
if (process.execPath.includes('MicroLMS')) { serviceName = 'MicroLMS'; }
|
||||||
{
|
else if (process.execPath.includes('MeshCommander')) { serviceName = 'MeshCommander'; }
|
||||||
serviceName = 'MeshCmd_Lms';
|
else { serviceName = 'not_a_service'; }
|
||||||
}
|
|
||||||
else if(process.execPath.includes('MeshCmd_Commander'))
|
|
||||||
{
|
|
||||||
serviceName = 'MeshCmd_Commander';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
serviceName = 'not_a_service';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var serviceHost = require('serviceHost');
|
var serviceHost = require('serviceHost');
|
||||||
var meshcmdService = new serviceHost({ name: serviceName, startType: 'AUTO_START' });
|
var meshcmdService = new serviceHost({ name: serviceName, startType: 'AUTO_START' });
|
||||||
meshcmdService.on('serviceStart', function onStart()
|
|
||||||
{
|
// Called when the background service is started.
|
||||||
console.setDestination(console.Destinations.LOGFILE);
|
meshcmdService.on('serviceStart', function onStart() {
|
||||||
if (process.execPath.includes('MeshCmd_Lms'))
|
console.setDestination(console.Destinations.DISABLED); // Disable console.log().
|
||||||
{
|
if (process.execPath.includes('MicroLMS')) { run([process.execPath, 'microlms']); } //
|
||||||
run([process.execPath, 'AmtLms']);
|
else if (process.execPath.includes('MeshCommander')) { run([process.execPath, 'meshcommander']); }
|
||||||
}
|
else { console.log('Aborting Service Start, because unknown binary: ' + process.execPath); process.exit(1); }
|
||||||
else if(process.execPath.includes('MeshCmd_Commander'))
|
|
||||||
{
|
|
||||||
run([process.execPath, 'MeshCommander']);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
console.log('Aborting Service Start, because unknown binary: ' + process.execPath);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
meshcmdService.on('serviceStop', function onStop() { console.log('LMS Stopping'); process.exit(); });
|
|
||||||
meshcmdService.on('normalStart', function onNormalStart()
|
|
||||||
{
|
|
||||||
try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Called when the background service is stopping
|
||||||
|
meshcmdService.on('serviceStop', function onStop() { console.log('Stopping service'); process.exit(); }); // The console.log() is for debugging, will be ignored unless "console.setDestination()" is set.
|
||||||
|
|
||||||
|
// Called when the executable is not running as a service, run normally.
|
||||||
|
meshcmdService.on('normalStart', function onNormalStart() { try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); } });
|
||||||
meshcmdService.run();
|
meshcmdService.run();
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,22 +1,20 @@
|
|||||||
|
|
||||||
var SERVICE_WIN32 = 0x00000010 | 0x00000020;
|
var SERVICE_WIN32 = 0x00000010 | 0x00000020;
|
||||||
var SERVICE_STATE = { STOPPED: 0x00000001, SERVICE_START_PENDING: 0x00000002, SERVICE_STOP_PENDING: 0x00000003, RUNNING: 0x00000004 };
|
var SERVICE_STATE = { STOPPED: 0x00000001, SERVICE_START_PENDING: 0x00000002, SERVICE_STOP_PENDING: 0x00000003, RUNNING: 0x00000004 };
|
||||||
var SERVICE_ACCEPT = {SERVICE_ACCEPT_STOP: 0x00000001, SERVICE_ACCEPT_SHUTDOWN: 0x00000004};
|
var SERVICE_ACCEPT = { SERVICE_ACCEPT_STOP: 0x00000001, SERVICE_ACCEPT_SHUTDOWN: 0x00000004 };
|
||||||
var SERVICE_CONTROL = {SERVICE_CONTROL_SHUTDOWN: 0x00000005, SERVICE_CONTROL_STOP: 0x00000001};
|
var SERVICE_CONTROL = { SERVICE_CONTROL_SHUTDOWN: 0x00000005, SERVICE_CONTROL_STOP: 0x00000001 };
|
||||||
var NO_ERROR = 0;
|
var NO_ERROR = 0;
|
||||||
|
|
||||||
var serviceManager = require('serviceManager');
|
var serviceManager = require('serviceManager');
|
||||||
|
|
||||||
function serviceHost(serviceName)
|
function serviceHost(serviceName) {
|
||||||
{
|
|
||||||
this._ObjectID = 'serviceHost';
|
this._ObjectID = 'serviceHost';
|
||||||
var emitterUtils = require('events').inherits(this);
|
var emitterUtils = require('events').inherits(this);
|
||||||
emitterUtils.createEvent('serviceStart');
|
emitterUtils.createEvent('serviceStart');
|
||||||
emitterUtils.createEvent('serviceStop');
|
emitterUtils.createEvent('serviceStop');
|
||||||
emitterUtils.createEvent('normalStart');
|
emitterUtils.createEvent('normalStart');
|
||||||
|
|
||||||
if (process.platform == 'win32')
|
if (process.platform == 'win32') {
|
||||||
{
|
|
||||||
this.GM = require('_GenericMarshal');
|
this.GM = require('_GenericMarshal');
|
||||||
this.Advapi = this.GM.CreateNativeProxy('Advapi32.dll');
|
this.Advapi = this.GM.CreateNativeProxy('Advapi32.dll');
|
||||||
this.Advapi.CreateMethod({ method: 'StartServiceCtrlDispatcherA', threadDispatch: 1 });
|
this.Advapi.CreateMethod({ method: 'StartServiceCtrlDispatcherA', threadDispatch: 1 });
|
||||||
@ -33,8 +31,7 @@ function serviceHost(serviceName)
|
|||||||
this._ServiceMain = this.GM.GetGenericGlobalCallback(2);
|
this._ServiceMain = this.GM.GetGenericGlobalCallback(2);
|
||||||
this._ServiceMain.Parent = this;
|
this._ServiceMain.Parent = this;
|
||||||
this._ServiceMain.GM = this.GM;
|
this._ServiceMain.GM = this.GM;
|
||||||
this._ServiceMain.on('GlobalCallback', function onGlobalCallback(argc, argv)
|
this._ServiceMain.on('GlobalCallback', function onGlobalCallback(argc, argv) {
|
||||||
{
|
|
||||||
//ToDo: Check to make sure this is for us
|
//ToDo: Check to make sure this is for us
|
||||||
|
|
||||||
this.Parent._ServiceStatus = this.GM.CreateVariable(28);
|
this.Parent._ServiceStatus = this.GM.CreateVariable(28);
|
||||||
@ -52,8 +49,7 @@ function serviceHost(serviceName)
|
|||||||
this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_WIN32);
|
this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_WIN32);
|
||||||
this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.SERVICE_STOPPED, 4);
|
this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.SERVICE_STOPPED, 4);
|
||||||
this.Parent._ServiceStatusHandle = this.Parent.Advapi.RegisterServiceCtrlHandlerA(this.Parent._ServiceName, this.Parent._ServiceControlHandler);
|
this.Parent._ServiceStatusHandle = this.Parent.Advapi.RegisterServiceCtrlHandlerA(this.Parent._ServiceName, this.Parent._ServiceControlHandler);
|
||||||
if(this.Parent._ServiceStatusHandle.Val == 0)
|
if (this.Parent._ServiceStatusHandle.Val == 0) {
|
||||||
{
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,8 +63,7 @@ function serviceHost(serviceName)
|
|||||||
this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus);
|
this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus);
|
||||||
|
|
||||||
this.Parent.Ole32.CoInitializeEx(0, 2);
|
this.Parent.Ole32.CoInitializeEx(0, 2);
|
||||||
this.Parent.on('~', function OnServiceHostFinalizer()
|
this.Parent.on('~', function OnServiceHostFinalizer() {
|
||||||
{
|
|
||||||
var GM = require('_GenericMarshal');
|
var GM = require('_GenericMarshal');
|
||||||
var Advapi = GM.CreateNativeProxy('Advapi32.dll');
|
var Advapi = GM.CreateNativeProxy('Advapi32.dll');
|
||||||
Advapi.CreateMethod('SetServiceStatus');
|
Advapi.CreateMethod('SetServiceStatus');
|
||||||
@ -92,10 +87,8 @@ function serviceHost(serviceName)
|
|||||||
this._ServiceControlHandler = this.GM.GetGenericGlobalCallback(1);
|
this._ServiceControlHandler = this.GM.GetGenericGlobalCallback(1);
|
||||||
this._ServiceControlHandler.Parent = this;
|
this._ServiceControlHandler.Parent = this;
|
||||||
this._ServiceControlHandler.GM = this.GM;
|
this._ServiceControlHandler.GM = this.GM;
|
||||||
this._ServiceControlHandler.on('GlobalCallback', function onServiceControlHandler(code)
|
this._ServiceControlHandler.on('GlobalCallback', function onServiceControlHandler(code) {
|
||||||
{
|
switch (code.Val) {
|
||||||
switch (code.Val)
|
|
||||||
{
|
|
||||||
case SERVICE_CONTROL.SERVICE_CONTROL_SHUTDOWN:
|
case SERVICE_CONTROL.SERVICE_CONTROL_SHUTDOWN:
|
||||||
case SERVICE_CONTROL.SERVICE_CONTROL_STOP:
|
case SERVICE_CONTROL.SERVICE_CONTROL_STOP:
|
||||||
this.Parent.emit('serviceStop');
|
this.Parent.emit('serviceStop');
|
||||||
@ -113,54 +106,42 @@ function serviceHost(serviceName)
|
|||||||
{
|
{
|
||||||
throw ('Must specify either ServiceName or Options');
|
throw ('Must specify either ServiceName or Options');
|
||||||
}
|
}
|
||||||
if (!this._ServiceOptions.servicePath)
|
if (!this._ServiceOptions.servicePath) {
|
||||||
{
|
|
||||||
this._ServiceOptions.servicePath = process.execPath;
|
this._ServiceOptions.servicePath = process.execPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.run = function run()
|
this.run = function run() {
|
||||||
{
|
|
||||||
var serviceOperation = 0;
|
var serviceOperation = 0;
|
||||||
|
|
||||||
for(var i = 0; i<process.argv.length; ++i)
|
for (var i = 0; i < process.argv.length; ++i) {
|
||||||
{
|
switch (process.argv[i].toLowerCase()) {
|
||||||
switch(process.argv[i])
|
case 'install':
|
||||||
{
|
|
||||||
case '-install':
|
|
||||||
if (!this._svcManager) { this._svcManager = new serviceManager(); }
|
if (!this._svcManager) { this._svcManager = new serviceManager(); }
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
this._svcManager.installService(this._ServiceOptions);
|
this._svcManager.installService(this._ServiceOptions);
|
||||||
}
|
} catch (e) {
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
console.log(e);
|
console.log(e);
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
if (process.platform == 'win32')
|
if (process.platform == 'win32') {
|
||||||
{
|
|
||||||
// Only do this on Windows, becuase Linux is async... It'll complete later
|
// Only do this on Windows, becuase Linux is async... It'll complete later
|
||||||
console.log(this._ServiceOptions.name + ' installed');
|
console.log(this._ServiceOptions.name + ' installed.');
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
i = process.argv.length;
|
i = process.argv.length;
|
||||||
serviceOperation = 1;
|
serviceOperation = 1;
|
||||||
break;
|
break;
|
||||||
case '-uninstall':
|
case 'uninstall':
|
||||||
if (!this._svcManager) { this._svcManager = new serviceManager(); }
|
if (!this._svcManager) { this._svcManager = new serviceManager(); }
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
this._svcManager.uninstallService(this._ServiceOptions);
|
this._svcManager.uninstallService(this._ServiceOptions);
|
||||||
}
|
} catch (e) {
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
console.log(e);
|
console.log(e);
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
if (process.platform == 'win32')
|
if (process.platform == 'win32') {
|
||||||
{
|
|
||||||
// Only do this on Windows, becuase Linux is async... It'll complete later
|
// Only do this on Windows, becuase Linux is async... It'll complete later
|
||||||
console.log(this._ServiceOptions.name + ' uninstalled');
|
console.log(this._ServiceOptions.name + ' uninstalled.');
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
i = process.argv.length;
|
i = process.argv.length;
|
||||||
@ -170,55 +151,46 @@ function serviceHost(serviceName)
|
|||||||
case '-d':
|
case '-d':
|
||||||
if (!this._svcManager) { this._svcManager = new serviceManager(); }
|
if (!this._svcManager) { this._svcManager = new serviceManager(); }
|
||||||
this._svcManager.getService(this._ServiceOptions.name).start();
|
this._svcManager.getService(this._ServiceOptions.name).start();
|
||||||
console.log(this._ServiceOptions.name + ' starting...');
|
console.log(this._ServiceOptions.name + ' starting.');
|
||||||
process.exit();
|
process.exit();
|
||||||
break;
|
break;
|
||||||
case 'stop':
|
case 'stop':
|
||||||
case '-s':
|
case '-s':
|
||||||
if (!this._svcManager) { this._svcManager = new serviceManager(); }
|
if (!this._svcManager) { this._svcManager = new serviceManager(); }
|
||||||
this._svcManager.getService(this._ServiceOptions.name).stop();
|
this._svcManager.getService(this._ServiceOptions.name).stop();
|
||||||
console.log(this._ServiceOptions.name + ' stopping...');
|
console.log(this._ServiceOptions.name + ' stopping.');
|
||||||
process.exit();
|
process.exit();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.platform == 'win32')
|
if (process.platform == 'win32') {
|
||||||
{
|
|
||||||
var serviceTable = this.GM.CreateVariable(4 * this.GM.PointerSize);
|
var serviceTable = this.GM.CreateVariable(4 * this.GM.PointerSize);
|
||||||
this._ServiceName.pointerBuffer().copy(serviceTable.toBuffer());
|
this._ServiceName.pointerBuffer().copy(serviceTable.toBuffer());
|
||||||
this._ServiceMain.pointerBuffer().copy(serviceTable.toBuffer(), this.GM.PointerSize);
|
this._ServiceMain.pointerBuffer().copy(serviceTable.toBuffer(), this.GM.PointerSize);
|
||||||
this._sscd = this.Advapi.StartServiceCtrlDispatcherA(serviceTable);
|
this._sscd = this.Advapi.StartServiceCtrlDispatcherA(serviceTable);
|
||||||
this._sscd.parent = this;
|
this._sscd.parent = this;
|
||||||
this._sscd.on('done', function OnStartServiceCtrlDispatcherA(retVal) {
|
this._sscd.on('done', function OnStartServiceCtrlDispatcherA(retVal) {
|
||||||
if (retVal.Val == 0)
|
if (retVal.Val == 0) { this.parent.emit('normalStart'); }
|
||||||
{
|
|
||||||
this.parent.emit('normalStart');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var moduleName = this._ServiceOptions ? this._ServiceOptions.name : process.execPath.substring(1 + process.execPath.lastIndexOf('/'));
|
var moduleName = this._ServiceOptions ? this._ServiceOptions.name : process.execPath.substring(1 + process.execPath.lastIndexOf('/'));
|
||||||
|
|
||||||
for (var i = 0; i < process.argv.length; ++i)
|
for (var i = 0; i < process.argv.length; ++i) {
|
||||||
{
|
switch (process.argv[i].toLowerCase()) {
|
||||||
switch(process.argv[i])
|
|
||||||
{
|
|
||||||
case 'start':
|
case 'start':
|
||||||
case '-d':
|
case '-d':
|
||||||
var child = require('child_process').execFile(process.execPath, [moduleName], { type: require('child_process').SpawnTypes.DETACHED });
|
var child = require('child_process').execFile(process.execPath, [moduleName], { type: require('child_process').SpawnTypes.DETACHED });
|
||||||
var pstream = null;
|
var pstream = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
pstream = require('fs').createWriteStream('/var/run/' + moduleName + '.pid', { flags: 'w' });
|
pstream = require('fs').createWriteStream('/var/run/' + moduleName + '.pid', { flags: 'w' });
|
||||||
}
|
}
|
||||||
catch(e)
|
catch (e) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
if (pstream == null)
|
if (pstream == null) {
|
||||||
{
|
|
||||||
pstream = require('fs').createWriteStream('.' + moduleName + '.pid', { flags: 'w' });
|
pstream = require('fs').createWriteStream('.' + moduleName + '.pid', { flags: 'w' });
|
||||||
}
|
}
|
||||||
pstream.end(child.pid.toString());
|
pstream.end(child.pid.toString());
|
||||||
@ -229,33 +201,26 @@ function serviceHost(serviceName)
|
|||||||
case 'stop':
|
case 'stop':
|
||||||
case '-s':
|
case '-s':
|
||||||
var pid = null;
|
var pid = null;
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' }));
|
pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' }));
|
||||||
require('fs').unlinkSync('/var/run/' + moduleName + '.pid');
|
require('fs').unlinkSync('/var/run/' + moduleName + '.pid');
|
||||||
}
|
}
|
||||||
catch(e)
|
catch (e) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
if(pid == null)
|
if (pid == null) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' }));
|
pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' }));
|
||||||
require('fs').unlinkSync('.' + moduleName + '.pid');
|
require('fs').unlinkSync('.' + moduleName + '.pid');
|
||||||
}
|
}
|
||||||
catch(e)
|
catch (e) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pid)
|
if (pid) {
|
||||||
{
|
|
||||||
process.kill(pid);
|
process.kill(pid);
|
||||||
console.log(moduleName + ' stopped');
|
console.log(moduleName + ' stopped');
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
console.log(moduleName + ' not running');
|
console.log(moduleName + ' not running');
|
||||||
}
|
}
|
||||||
process.exit();
|
process.exit();
|
||||||
@ -263,56 +228,30 @@ function serviceHost(serviceName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(serviceOperation == 0)
|
if (serviceOperation == 0) {
|
||||||
{
|
|
||||||
// This is non-windows, so we need to check how this binary was started to determine if this was a service start
|
// This is non-windows, so we need to check how this binary was started to determine if this was a service start
|
||||||
|
|
||||||
// Start by checking if we were started with start/stop
|
// Start by checking if we were started with start/stop
|
||||||
var pid = null;
|
var pid = null;
|
||||||
try
|
try { pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' })); } catch (e) { }
|
||||||
{
|
if (pid == null) { try { pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' })); } catch (e) { } }
|
||||||
pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' }));
|
|
||||||
}
|
if (pid != null && pid == process.pid) {
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
if (pid == null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' }));
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid != null && pid == process.pid)
|
|
||||||
{
|
|
||||||
this.emit('serviceStart');
|
this.emit('serviceStart');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Now we need to check if we were started with systemd
|
// Now we need to check if we were started with systemd
|
||||||
if (require('processManager').getProcessInfo(1).Name == 'systemd')
|
if (require('processManager').getProcessInfo(1).Name == 'systemd') {
|
||||||
{
|
|
||||||
this._checkpid = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
|
this._checkpid = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
|
||||||
this._checkpid.result = '';
|
this._checkpid.result = '';
|
||||||
this._checkpid.parent = this;
|
this._checkpid.parent = this;
|
||||||
this._checkpid.on('exit', function onCheckPIDExit()
|
this._checkpid.on('exit', function onCheckPIDExit() {
|
||||||
{
|
|
||||||
var lines = this.result.split('\r\n');
|
var lines = this.result.split('\r\n');
|
||||||
for (i in lines)
|
for (i in lines) {
|
||||||
{
|
if (lines[i].startsWith(' Main PID:')) {
|
||||||
if(lines[i].startsWith(' Main PID:'))
|
|
||||||
{
|
|
||||||
var tokens = lines[i].split(' ');
|
var tokens = lines[i].split(' ');
|
||||||
if (parseInt(tokens[3]) == process.pid)
|
if (parseInt(tokens[3]) == process.pid) {
|
||||||
{
|
|
||||||
this.parent.emit('serviceStart');
|
this.parent.emit('serviceStart');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
this.parent.emit('normalStart');
|
this.parent.emit('normalStart');
|
||||||
}
|
}
|
||||||
delete this.parent._checkpid;
|
delete this.parent._checkpid;
|
||||||
@ -326,8 +265,7 @@ function serviceHost(serviceName)
|
|||||||
this._checkpid.stdin.write("systemctl status " + moduleName + " | grep 'Main PID:'\n");
|
this._checkpid.stdin.write("systemctl status " + moduleName + " | grep 'Main PID:'\n");
|
||||||
this._checkpid.stdin.write('exit\n');
|
this._checkpid.stdin.write('exit\n');
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
// This isn't even a systemd platform, so this couldn't have been a service start
|
// This isn't even a systemd platform, so this couldn't have been a service start
|
||||||
this.emit('normalStart');
|
this.emit('normalStart');
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
function parseServiceStatus(token)
|
function parseServiceStatus(token) {
|
||||||
{
|
|
||||||
var j = {};
|
var j = {};
|
||||||
var serviceType = token.Deref(0, 4).IntVal;
|
var serviceType = token.Deref(0, 4).IntVal;
|
||||||
j.isFileSystemDriver = ((serviceType & 0x00000002) == 0x00000002);
|
j.isFileSystemDriver = ((serviceType & 0x00000002) == 0x00000002);
|
||||||
@ -9,8 +8,7 @@ function parseServiceStatus(token)
|
|||||||
j.isSharedProcess = ((serviceType & 0x00000020) == 0x00000020);
|
j.isSharedProcess = ((serviceType & 0x00000020) == 0x00000020);
|
||||||
j.isOwnProcess = ((serviceType & 0x00000010) == 0x00000010);
|
j.isOwnProcess = ((serviceType & 0x00000010) == 0x00000010);
|
||||||
j.isInteractive = ((serviceType & 0x00000100) == 0x00000100);
|
j.isInteractive = ((serviceType & 0x00000100) == 0x00000100);
|
||||||
switch (token.Deref((1 * 4), 4).toBuffer().readUInt32LE())
|
switch (token.Deref((1 * 4), 4).toBuffer().readUInt32LE()) {
|
||||||
{
|
|
||||||
case 0x00000005:
|
case 0x00000005:
|
||||||
j.state = 'CONTINUE_PENDING';
|
j.state = 'CONTINUE_PENDING';
|
||||||
break;
|
break;
|
||||||
@ -35,8 +33,7 @@ function parseServiceStatus(token)
|
|||||||
}
|
}
|
||||||
var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE();
|
var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE();
|
||||||
j.controlsAccepted = [];
|
j.controlsAccepted = [];
|
||||||
if ((controlsAccepted & 0x00000010) == 0x00000010)
|
if ((controlsAccepted & 0x00000010) == 0x00000010) {
|
||||||
{
|
|
||||||
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDADD');
|
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDADD');
|
||||||
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDREMOVE');
|
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDREMOVE');
|
||||||
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDENABLE');
|
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDENABLE');
|
||||||
@ -54,10 +51,8 @@ function parseServiceStatus(token)
|
|||||||
return (j);
|
return (j);
|
||||||
}
|
}
|
||||||
|
|
||||||
function serviceManager()
|
function serviceManager() {
|
||||||
{
|
if (process.platform == 'win32') {
|
||||||
if (process.platform == 'win32')
|
|
||||||
{
|
|
||||||
this.GM = require('_GenericMarshal');
|
this.GM = require('_GenericMarshal');
|
||||||
this.proxy = this.GM.CreateNativeProxy('Advapi32.dll');
|
this.proxy = this.GM.CreateNativeProxy('Advapi32.dll');
|
||||||
this.proxy.CreateMethod('OpenSCManagerA');
|
this.proxy.CreateMethod('OpenSCManagerA');
|
||||||
@ -83,40 +78,31 @@ function serviceManager()
|
|||||||
var AdministratorsGroup = this.GM.CreatePointer();
|
var AdministratorsGroup = this.GM.CreatePointer();
|
||||||
var admin = false;
|
var admin = false;
|
||||||
|
|
||||||
if (this.proxy.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0)
|
if (this.proxy.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0) {
|
||||||
{
|
|
||||||
var member = this.GM.CreateInteger();
|
var member = this.GM.CreateInteger();
|
||||||
if (this.proxy.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0)
|
if (this.proxy.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0) {
|
||||||
{
|
|
||||||
if (member.toBuffer().readUInt32LE() != 0) { admin = true; }
|
if (member.toBuffer().readUInt32LE() != 0) { admin = true; }
|
||||||
}
|
}
|
||||||
this.proxy.FreeSid(AdministratorsGroup.Deref());
|
this.proxy.FreeSid(AdministratorsGroup.Deref());
|
||||||
}
|
}
|
||||||
return admin;
|
return admin;
|
||||||
};
|
};
|
||||||
this.getServiceFolder = function getServiceFolder()
|
this.getServiceFolder = function getServiceFolder() {
|
||||||
{
|
|
||||||
var destinationFolder = null;
|
var destinationFolder = null;
|
||||||
if (require('os').arch() == 'x64')
|
if (require('os').arch() == 'x64') {
|
||||||
{
|
|
||||||
// 64 bit Windows
|
// 64 bit Windows
|
||||||
if (this.GM.PointerSize == 4)
|
if (this.GM.PointerSize == 4) {
|
||||||
{
|
|
||||||
// 32 Bit App
|
// 32 Bit App
|
||||||
destinationFolder = process.env['ProgramFiles(x86)'];
|
destinationFolder = process.env['ProgramFiles(x86)'];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// 64 bit App
|
// 64 bit App
|
||||||
destinationFolder = process.env['ProgramFiles'];
|
destinationFolder = process.env['ProgramFiles'];
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// 32 bit Windows
|
// 32 bit Windows
|
||||||
destinationFolder = process.env['ProgramFiles'];
|
destinationFolder = process.env['ProgramFiles'];
|
||||||
}
|
}
|
||||||
return (destinationFolder + '\\mesh');
|
return (destinationFolder + '\\Open Source\\MeshCmd');
|
||||||
};
|
};
|
||||||
|
|
||||||
this.enumerateService = function () {
|
this.enumerateService = function () {
|
||||||
@ -129,9 +115,7 @@ function serviceManager()
|
|||||||
var resumeHandle = this.GM.CreatePointer();
|
var resumeHandle = this.GM.CreatePointer();
|
||||||
//var services = this.proxy.CreateVariable(262144);
|
//var services = this.proxy.CreateVariable(262144);
|
||||||
var success = this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, 0x00, 0x00, bytesNeeded, servicesReturned, resumeHandle, 0x00);
|
var success = this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, 0x00, 0x00, bytesNeeded, servicesReturned, resumeHandle, 0x00);
|
||||||
if (bytesNeeded.IntVal <= 0) {
|
if (bytesNeeded.IntVal <= 0) { throw('Error enumerating services'); }
|
||||||
throw ('error enumerating services');
|
|
||||||
}
|
|
||||||
var sz = bytesNeeded.IntVal;
|
var sz = bytesNeeded.IntVal;
|
||||||
var services = this.GM.CreateVariable(sz);
|
var services = this.GM.CreateVariable(sz);
|
||||||
this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, services, sz, bytesNeeded, servicesReturned, resumeHandle, 0x00);
|
this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, services, sz, bytesNeeded, servicesReturned, resumeHandle, 0x00);
|
||||||
@ -157,7 +141,7 @@ function serviceManager()
|
|||||||
var ptr = this.GM.CreatePointer();
|
var ptr = this.GM.CreatePointer();
|
||||||
var bytesNeeded = this.GM.CreateVariable(ptr._size);
|
var bytesNeeded = this.GM.CreateVariable(ptr._size);
|
||||||
var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0001 | 0x0004 | 0x0020 | 0x0010);
|
var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0001 | 0x0004 | 0x0020 | 0x0010);
|
||||||
if (handle.Val == 0) { throw ('could not open ServiceManager'); }
|
if (handle.Val == 0) { throw('Could not open ServiceManager'); }
|
||||||
var h = this.proxy.OpenServiceA(handle, serviceName, 0x0004 | 0x0020 | 0x0010 | 0x00010000);
|
var h = this.proxy.OpenServiceA(handle, serviceName, 0x0004 | 0x0020 | 0x0010 | 0x00010000);
|
||||||
if (h.Val != 0) {
|
if (h.Val != 0) {
|
||||||
var success = this.proxy.QueryServiceStatusEx(h, 0, 0, 0, bytesNeeded);
|
var success = this.proxy.QueryServiceStatusEx(h, 0, 0, 0, bytesNeeded);
|
||||||
@ -182,51 +166,46 @@ function serviceManager()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw ('cannot call ' + this.name + '.stop(), when current state is: ' + this.status.state);
|
throw ('Cannot call ' + this.name + '.stop(), when current state is: ' + this.status.state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
retVal.start = function () {
|
retVal.start = function () {
|
||||||
if (this.status.state == 'STOPPED') {
|
if (this.status.state == 'STOPPED') {
|
||||||
var success = this._proxy.StartServiceA(this._service, 0, 0);
|
var success = this._proxy.StartServiceA(this._service, 0, 0);
|
||||||
if (success == 0) {
|
if (success == 0) { throw (this.name + '.start() failed'); }
|
||||||
throw (this.name + '.start() failed');
|
} else {
|
||||||
}
|
throw ('Cannot call ' + this.name + '.start(), when current state is: ' + this.status.state);
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw ('cannot call ' + this.name + '.start(), when current state is: ' + this.status.state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (retVal);
|
return (retVal);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.proxy.CloseServiceHandle(handle);
|
this.proxy.CloseServiceHandle(handle);
|
||||||
throw ('could not find service: ' + name);
|
throw ('Could not find service: ' + name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.installService = function installService(options)
|
this.installService = function installService(options) {
|
||||||
{
|
if (process.platform == 'win32') {
|
||||||
if (process.platform == 'win32')
|
if (!this.isAdmin()) { throw ('Installing as Service, requires administrator permissions.'); }
|
||||||
{
|
|
||||||
if (!this.isAdmin()) { throw ('Installing as Service, requires admin'); }
|
|
||||||
|
|
||||||
// Before we start, we need to copy the binary to the right place
|
// Before we start, we need to copy the binary to the right place
|
||||||
var folder = this.getServiceFolder();
|
var folder = this.getServiceFolder();
|
||||||
if (!require('fs').existsSync(folder)) { require('fs').mkdirSync(folder); }
|
if (!require('fs').existsSync(folder)) { require('fs').mkdirSync(folder); }
|
||||||
require('fs').copyFileSync(options.servicePath, folder + '\\' + options.name + '.exe');
|
require('fs').copyFileSync(options.servicePath, folder + '\\' + options.name + '.exe');
|
||||||
options.servicePath = folder + '\\' + options.name + '.exe';
|
options.servicePath = folder + '\\' + options.name + '.exe';
|
||||||
|
console.log('Installing to "' + options.servicePath + '"');
|
||||||
|
|
||||||
var servicePath = this.GM.CreateVariable('"' + options.servicePath + '"');
|
var servicePath = this.GM.CreateVariable('"' + options.servicePath + '"');
|
||||||
var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0002);
|
var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0002);
|
||||||
if (handle.Val == 0) { throw ('error opening SCManager'); }
|
if (handle.Val == 0) { throw ('Error opening SCManager'); }
|
||||||
var serviceName = this.GM.CreateVariable(options.name);
|
var serviceName = this.GM.CreateVariable(options.name);
|
||||||
var displayName = this.GM.CreateVariable(options.name);
|
var displayName = this.GM.CreateVariable(options.name);
|
||||||
var allAccess = 0x000F01FF;
|
var allAccess = 0x000F01FF;
|
||||||
var serviceType;
|
var serviceType;
|
||||||
|
|
||||||
|
|
||||||
switch (options.startType) {
|
switch (options.startType) {
|
||||||
case 'BOOT_START':
|
case 'BOOT_START':
|
||||||
@ -264,13 +243,11 @@ function serviceManager()
|
|||||||
this.proxy.CloseServiceHandle(handle);
|
this.proxy.CloseServiceHandle(handle);
|
||||||
return (this.getService(options.name));
|
return (this.getService(options.name));
|
||||||
}
|
}
|
||||||
if(process.platform == 'linux')
|
if (process.platform == 'linux') {
|
||||||
{
|
switch (this.getServiceType()) {
|
||||||
switch (this.getServiceType())
|
|
||||||
{
|
|
||||||
case 'init':
|
case 'init':
|
||||||
require('fs').copyFileSync(options.servicePath, '/etc/init.d/' + options.name);
|
require('fs').copyFileSync(options.servicePath, '/etc/init.d/' + options.name);
|
||||||
console.log('copying ' + options.servicePath);
|
console.log('Copying ' + options.servicePath);
|
||||||
var m = require('fs').statSync('/etc/init.d/' + options.name).mode;
|
var m = require('fs').statSync('/etc/init.d/' + options.name).mode;
|
||||||
m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP);
|
m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP);
|
||||||
require('fs').chmodSync('/etc/init.d/' + options.name, m);
|
require('fs').chmodSync('/etc/init.d/' + options.name, m);
|
||||||
@ -305,40 +282,25 @@ function serviceManager()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.uninstallService = function uninstallService(name)
|
this.uninstallService = function uninstallService(name) {
|
||||||
{
|
|
||||||
if (typeof (name) == 'object') { name = name.name; }
|
if (typeof (name) == 'object') { name = name.name; }
|
||||||
if (process.platform == 'win32')
|
if (process.platform == 'win32') {
|
||||||
{
|
if (!this.isAdmin()) { throw ('Uninstalling a service, requires administrator permissions.'); }
|
||||||
if (!this.isAdmin()) { throw ('Uninstalling a service, requires admin'); }
|
|
||||||
|
|
||||||
var service = this.getService(name);
|
var service = this.getService(name);
|
||||||
if (service.status.state == undefined || service.status.state == 'STOPPED')
|
if (service.status.state == undefined || service.status.state == 'STOPPED') {
|
||||||
{
|
if (this.proxy.DeleteService(service._service) == 0) {
|
||||||
if (this.proxy.DeleteService(service._service) == 0)
|
|
||||||
{
|
|
||||||
throw ('Uninstall Service for: ' + name + ', failed with error: ' + this.proxy2.GetLastError());
|
throw ('Uninstall Service for: ' + name + ', failed with error: ' + this.proxy2.GetLastError());
|
||||||
}
|
} else {
|
||||||
else
|
try { require('fs').unlinkSync(this.getServiceFolder() + '\\' + name + '.exe'); } catch (e) { }
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
require('fs').unlinkSync(this.getServiceFolder() + '\\' + name + '.exe');
|
|
||||||
}
|
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
throw ('Cannot uninstall service: ' + name + ', because it is: ' + service.status.state);
|
throw ('Cannot uninstall service: ' + name + ', because it is: ' + service.status.state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(process.platform == 'linux')
|
else if (process.platform == 'linux') {
|
||||||
{
|
switch (this.getServiceType()) {
|
||||||
switch (this.getServiceType())
|
|
||||||
{
|
|
||||||
case 'init':
|
case 'init':
|
||||||
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
|
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
|
||||||
this._update._svcname = name;
|
this._update._svcname = name;
|
||||||
@ -346,11 +308,7 @@ function serviceManager()
|
|||||||
try {
|
try {
|
||||||
require('fs').unlinkSync('/etc/init.d/' + this._svcname);
|
require('fs').unlinkSync('/etc/init.d/' + this._svcname);
|
||||||
console.log(this._svcname + ' uninstalled');
|
console.log(this._svcname + ' uninstalled');
|
||||||
|
} catch (e) { console.log(this._svcname + ' could not be uninstalled'); }
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.log(this._svcname + ' could not be uninstalled')
|
|
||||||
}
|
|
||||||
process.exit();
|
process.exit();
|
||||||
});
|
});
|
||||||
this._update.stdout.on('data', function (chunk) { });
|
this._update.stdout.on('data', function (chunk) { });
|
||||||
@ -366,10 +324,7 @@ function serviceManager()
|
|||||||
require('fs').unlinkSync('/usr/local/mesh/' + this._svcname);
|
require('fs').unlinkSync('/usr/local/mesh/' + this._svcname);
|
||||||
require('fs').unlinkSync('/lib/systemd/system/' + this._svcname + '.service');
|
require('fs').unlinkSync('/lib/systemd/system/' + this._svcname + '.service');
|
||||||
console.log(this._svcname + ' uninstalled');
|
console.log(this._svcname + ' uninstalled');
|
||||||
}
|
} catch (e) { console.log(this._svcname + ' could not be uninstalled'); }
|
||||||
catch (e) {
|
|
||||||
console.log(this._svcname + ' could not be uninstalled')
|
|
||||||
}
|
|
||||||
process.exit();
|
process.exit();
|
||||||
});
|
});
|
||||||
this._update.stdout.on('data', function (chunk) { });
|
this._update.stdout.on('data', function (chunk) { });
|
||||||
@ -382,10 +337,8 @@ function serviceManager()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(process.platform == 'linux')
|
if (process.platform == 'linux') {
|
||||||
{
|
this.getServiceType = function getServiceType() {
|
||||||
this.getServiceType = function getServiceType()
|
|
||||||
{
|
|
||||||
return (require('processManager').getProcessInfo(1).Name);
|
return (require('processManager').getProcessInfo(1).Name);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "meshcentral",
|
"name": "meshcentral",
|
||||||
"version": "0.1.5-u",
|
"version": "0.1.5-v",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Remote Management",
|
"Remote Management",
|
||||||
"Intel AMT",
|
"Intel AMT",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user