New MeshCmd, fixes MeshAgent registry values
Ylian Saint-Hilaire committed
Apr 4, 2018 at 12:08 UTC
835e03225d1edb916f3cbbd20a163abdca3a93ac
10 files changed
+142
-279
agents/MeshCmd-signed.exe
Binary files a/agents/MeshCmd-signed.exe and b/agents/MeshCmd-signed.exe differ
agents/MeshCmd64-signed.exe
Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ
agents/MeshService-signed.exe
Binary files a/agents/MeshService-signed.exe and b/agents/MeshService-signed.exe differ
agents/MeshService.exe
Binary files a/agents/MeshService.exe and b/agents/MeshService.exe differ
agents/MeshService64-signed.exe
Binary files a/agents/MeshService64-signed.exe and b/agents/MeshService64-signed.exe differ
agents/MeshService64.exe
Binary files a/agents/MeshService64.exe and b/agents/MeshService64.exe differ
agents/meshcmd.js
+43
-71
@@ -84,15 +84,14 @@ function objToString(x, p, ret) {
84
function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ' '; } return r; }
85
86
// Parse the incoming arguments
87
-function run(argv)
88
-{
87
+function run(argv) {
88
if (meshCmdVersion[0] == '*') { meshCmdVersion = ''; } else { meshCmdVersion = ' v' + meshCmdVersion; }
89
var args = parceArguments(argv);
90
//console.log(JSON.stringify(argv));
91
//console.log('addedModules = ' + JSON.stringify(addedModules));
92
var actionpath = 'meshaction.txt';
93
if (args.actionfile != null) { actionpath = args.actionfile; }
95
- var actions = ['HELP', 'ROUTE', 'AMTLMS', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG'];
94
+ var actions = ['HELP', 'ROUTE', 'MICROLMS', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG'];
95
96
// Load the action file
97
var actionfile = null;
@@ -134,10 +133,10 @@ function run(argv)
133
console.log('\r\nValid local actions:');
134
console.log(' SMBios - Display System Management BIOS tables for this computer.');
135
console.log(' RawSMBios - Display RAW System Management BIOS tables for this computer.');
136
+ console.log(' MicroLMS - Run MicroLMS, allowing local access to Intel AMT.');
137
console.log(' AmtInfo - Show Intel AMT version and activation state.');
138
console.log(' AmtVersions - Show all Intel ME version information.');
139
console.log(' AmtHashes - Show all Intel AMT trusted activation hashes.');
140
- console.log(' AmtLMS - Run MicroLMS, allowing local access to Intel AMT.');
140
console.log(' AmtCCM - Activate Intel AMT into Client Control Mode.');
141
console.log(' AmtDeactivate - Deactivate Intel AMT if activated in Client Control mode.');
142
console.log('\r\nValid local or remote actions:');
@@ -176,10 +175,12 @@ function run(argv)
175
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');
176
} else if (action == 'amthashes') {
177
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');
179
- } else if (action == 'amtlms') {
180
- 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');
178
+ } else if ((action == 'microlms') || (action == 'lms') || (action == 'amtlms')) {
179
+ 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');
180
console.log('\r\nPossible arguments:\r\n');
181
console.log(' --noconsole MeshCommander for LMS will no be available on port 16994.');
182
+ console.log('\r\nRun as a background service:\r\n');
183
+ console.log(' microlms install/uninstall/start/stop.');
184
} else if (action == 'amtccm') {
185
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');
186
} else if (action == 'amtdeactivate') {
@@ -232,6 +233,8 @@ function run(argv)
233
console.log('This action launched a local web server that hosts MeshCommander, a Intel AMT management console.');
234
console.log('\r\nPossible arguments:\r\n');
235
console.log(' --localport [port] Local port used for the web server, 3000 is default.');
236
+ console.log('\r\nRun as a background service:\r\n');
237
+ console.log(' meshcommander install/uninstall/start/stop.');
238
} else if (action == 'amtauditlog') {
239
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');
240
console.log('\r\nPossible arguments:\r\n');
@@ -342,7 +345,7 @@ function run(argv)
345
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; } }
346
if (mestate.ehbc.EHBC == true) { str += ', EHBC enabled'; }
347
str += '.';
345
- 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)); }
348
+ 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)); }
349
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)); }
350
console.log(str + '.');
351
exit(1);
@@ -357,10 +360,10 @@ function run(argv)
360
settings.localport = 16992;
361
debug(1, "Settings: " + JSON.stringify(settings));
362
saveEntireAmtState();
360
- } else if (settings.action == 'amtlms') {
363
+ } else if ((settings.action == 'microlms') || (settings.action == 'amtlms') || (settings.action == 'lms')) {
364
// Start Intel AMT MicroLMS
365
startLms(function (state) {
363
- 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); }
366
+ 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); }
367
});
368
} else if (settings.action == 'amtscript') {
369
// Start running a MEScript
@@ -436,7 +439,7 @@ function readAmtAuditLogEx2(stack, response, status) {
439
} else {
440
var out = '';
441
for (var i in response) {
439
- var name = ((response[i].Initiator != '')?(response[i].Initiator + ': '):'')
442
+ var name = ((response[i].Initiator != '') ? (response[i].Initiator + ': ') : '')
443
out += (response[i].Time + ' - ' + name + response[i].Event + '\r\n');
444
}
445
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) {
562
function activeToCCMEx2(stack, name, responses, status) {
563
if (status != 200) { console.log('Failed to fetch activation status, status ' + status); exit(1); }
564
else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { console.log('Client control mode activation not allowed'); exit(1); }
562
- else { osamtstack.IPS_HostBasedSetupService_Setup(2, md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + settings.password).substring(0,32), null, null, null, null, activeToCCMEx3); }
565
+ else { osamtstack.IPS_HostBasedSetupService_Setup(2, md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + settings.password).substring(0, 32), null, null, null, null, activeToCCMEx3); }
566
}
567
568
function activeToCCMEx3(stack, name, responses, status) {
@@ -624,7 +627,7 @@ function startMeScriptEx() {
627
try { scriptData = fs.readFileSync(settings.script); } catch (e) { console.log('Unable to read script file (1): ' + settings.script + '.'); exit(1); return; }
628
} else {
629
scriptData = settings.scriptJSON;
627
- }
630
+ }
631
if (scriptData == null) { console.log('Unable to read script file (2): ' + settings.script + '.'); exit(1); return; }
632
try { scriptData = JSON.parse(scriptData); } catch (e) { console.log('Unable to read script file (3): ' + settings.script + '.'); exit(1); return; }
633
if (scriptData.mescript == null) { console.log('Unable to read script file (4): ' + settings.script + '.'); exit(1); return; }
@@ -634,7 +637,7 @@ function startMeScriptEx() {
637
var script = scriptModule.setup(scriptData, {})
638
script.amtstack = amtstack;
639
script.start();
637
- script.onCompleted = function () { exit(1);}
640
+ script.onCompleted = function () { exit(1); }
641
}
642
643
@@ -651,7 +654,7 @@ function saveEntireAmtState() {
654
var transport = require('amt-wsman-duk');
655
var wsman = require('amt-wsman');
656
var amt = require('amt');
654
- wsstack = new wsman(transport, settings.hostname, settings.tls?16993:16992, settings.username, settings.password, settings.tls);
657
+ wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
658
amtstack = new amt(wsstack);
659
amtstack.onProcessChanged = onWsmanProcessChanged;
660
//var AllWsman = "AMT_GeneralSystemDefenseCapabilities".split(',');
@@ -769,7 +772,6 @@ function startLms(func) {
772
amtLms = new lme_heci({ debug: settings.lmsdebug });
773
amtLms.on('error', function (e) {
774
console.log('LME connection failed', e);
772
-
775
setupMeiOsAdmin(func, amtLms.connected == false ? 0 : 3);
776
});
777
amtLms.on('notify', function (data, options, str, code) {
@@ -843,7 +845,7 @@ function startLms(func) {
845
tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 1); }, 100);
846
//console.logReferenceCount(tempTimer);
847
}
846
-
848
+
849
});
850
}
851
@@ -957,7 +959,7 @@ function processLmsControlData(data) {
959
case 2: // Intel AMT MEI Unprovision (CMD = 2)
960
{ 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; }
961
case 3: // Intel AMT MEI GetLocalSystemAccount (CMD = 3)
960
- { amtMei.getLocalSystemAccount(function (account, socket) {socket.write(Buffer.concat([Buffer.from('030000000000', 'hex'), account.raw])); }, this); break; }
962
+ { amtMei.getLocalSystemAccount(function (account, socket) { socket.write(Buffer.concat([Buffer.from('030000000000', 'hex'), account.raw])); }, this); break; }
963
case 4: // Instruct Intel AMT to start remote configuration (CMD = 4)
964
{ amtMei.startConfiguration(function (status, socket) { var data = new Buffer(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
965
case 5: // Instruct Intel AMT to stop remote configuration (CMD = 5)
@@ -1150,7 +1152,7 @@ function getAmtStorage(func, noretry) {
1152
// Fetch the Intel AMT storage document
1153
function pushToStorage(name, linkname, data, func, ptr) {
1154
if (ptr == null) { ptr = 0; }
1153
- var req = digest.request({ protocol: settings.protocol, method: "PUT", host: settings.hostname, path: ("/amt-storage/" + name + ((ptr != 0) ? '?append=' : '')), port: settings.localport } );
1155
+ var req = digest.request({ protocol: settings.protocol, method: "PUT", host: settings.hostname, path: ("/amt-storage/" + name + ((ptr != 0) ? '?append=' : '')), port: settings.localport });
1156
req.on('error', function (e) { console.log("Error occured: " + JSON.stringify(e)); if (func != null) { func(null); } });
1157
req.on('response', function (response) {
1158
debug(1, 'Chunk Done', data.length, ptr);
@@ -1178,7 +1180,7 @@ function verifyStorage(name, data, func) {
1180
1181
// Fetch the Intel AMT storage document
1182
function deleteStorage(name, func, noretry) {
1181
- var req = digest.request({ protocol: settings.protocol, method: "DELETE", host: settings.hostname, path: "/amt-storage/" + name, port: settings.localport } );
1183
+ var req = digest.request({ protocol: settings.protocol, method: "DELETE", host: settings.hostname, path: "/amt-storage/" + name, port: settings.localport });
1184
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); } } } });
1185
req.on('response', function (response) { if (func != null) { func(response.statusCode); } });
1186
req.end();
@@ -1203,69 +1205,39 @@ function removeItemFromArray(array, element) {
1205
var serviceName = null;
1206
var serviceOpSpecified = 0;
1207
1206
-for (var i in process.argv)
1207
-{
1208
- if(process.argv[i].toLowerCase() == 'amtlms')
1209
- {
1210
- serviceName = 'MeshCmd_Lms';
1211
- break;
1212
- }
1213
- if(process.argv[i].toLowerCase() == 'meshcommander')
1214
- {
1215
- serviceName = 'MeshCmd_Commander';
1216
- break;
1217
- }
1208
+for (var i in process.argv) {
1209
+ if ((process.argv[i].toLowerCase() == 'microlms') || (process.argv[i].toLowerCase() == 'amtlms') || (process.argv[i].toLowerCase() == 'lms')) { serviceName = 'MicroLMS'; break; }
1210
+ if ((process.argv[i].toLowerCase() == 'meshcommander') || (process.argv[i].toLowerCase() == 'commander')) { serviceName = 'MeshCommander'; break; }
1211
}
1212
1220
-if (serviceName == null)
1221
-{
1222
- for (var i in process.argv)
1223
- {
1224
- if (process.argv[i] == '-install' || process.argv[i] == '-uninstall')
1225
- {
1226
- console.log('In order to Install/Uninstall, a service type must be specified');
1213
+if (serviceName == null) {
1214
+ for (var i in process.argv) {
1215
+ if ((process.argv[i].toLowerCase() == 'install') || (process.argv[i].toLowerCase() == 'uninstall')) {
1216
+ console.log('In order to install/uninstall, a service type must be specified.');
1217
process.exit();
1218
}
1219
}
1230
- if(process.execPath.includes('MeshCmd_Lms'))
1231
- {
1232
- serviceName = 'MeshCmd_Lms';
1233
- }
1234
- else if(process.execPath.includes('MeshCmd_Commander'))
1235
- {
1236
- serviceName = 'MeshCmd_Commander';
1237
- }
1238
- else
1239
- {
1240
- serviceName = 'not_a_service';
1241
- }
1220
+ if (process.execPath.includes('MicroLMS')) { serviceName = 'MicroLMS'; }
1221
+ else if (process.execPath.includes('MeshCommander')) { serviceName = 'MeshCommander'; }
1222
+ else { serviceName = 'not_a_service'; }
1223
}
1224
1225
var serviceHost = require('serviceHost');
1226
var meshcmdService = new serviceHost({ name: serviceName, startType: 'AUTO_START' });
1246
-meshcmdService.on('serviceStart', function onStart()
1247
-{
1248
- console.setDestination(console.Destinations.LOGFILE);
1249
- if (process.execPath.includes('MeshCmd_Lms'))
1250
- {
1251
- run([process.execPath, 'AmtLms']);
1252
- }
1253
- else if(process.execPath.includes('MeshCmd_Commander'))
1254
- {
1255
- run([process.execPath, 'MeshCommander']);
1256
- }
1257
- else
1258
- {
1259
- console.log('Aborting Service Start, because unknown binary: ' + process.execPath);
1260
- process.exit(1);
1261
- }
1262
-});
1263
-meshcmdService.on('serviceStop', function onStop() { console.log('LMS Stopping'); process.exit(); });
1264
-meshcmdService.on('normalStart', function onNormalStart()
1265
-{
1266
- try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); }
1227
+
1228
+// Called when the background service is started.
1229
+meshcmdService.on('serviceStart', function onStart() {
1230
+ console.setDestination(console.Destinations.DISABLED); // Disable console.log().
1231
+ if (process.execPath.includes('MicroLMS')) { run([process.execPath, 'microlms']); } //
1232
+ else if (process.execPath.includes('MeshCommander')) { run([process.execPath, 'meshcommander']); }
1233
+ else { console.log('Aborting Service Start, because unknown binary: ' + process.execPath); process.exit(1); }
1234
});
1235
1236
+// Called when the background service is stopping
1237
+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.
1238
+
1239
+// Called when the executable is not running as a service, run normally.
1240
+meshcmdService.on('normalStart', function onNormalStart() { try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); } });
1241
meshcmdService.run();
1242
1243
agents/modules_meshcmd/serviceHost.js
+54
-116
@@ -1,22 +1,20 @@
1
2
var SERVICE_WIN32 = 0x00000010 | 0x00000020;
3
var SERVICE_STATE = { STOPPED: 0x00000001, SERVICE_START_PENDING: 0x00000002, SERVICE_STOP_PENDING: 0x00000003, RUNNING: 0x00000004 };
4
-var SERVICE_ACCEPT = {SERVICE_ACCEPT_STOP: 0x00000001, SERVICE_ACCEPT_SHUTDOWN: 0x00000004};
5
-var SERVICE_CONTROL = {SERVICE_CONTROL_SHUTDOWN: 0x00000005, SERVICE_CONTROL_STOP: 0x00000001};
4
+var SERVICE_ACCEPT = { SERVICE_ACCEPT_STOP: 0x00000001, SERVICE_ACCEPT_SHUTDOWN: 0x00000004 };
5
+var SERVICE_CONTROL = { SERVICE_CONTROL_SHUTDOWN: 0x00000005, SERVICE_CONTROL_STOP: 0x00000001 };
6
var NO_ERROR = 0;
7
8
var serviceManager = require('serviceManager');
9
10
-function serviceHost(serviceName)
11
-{
10
+function serviceHost(serviceName) {
11
this._ObjectID = 'serviceHost';
12
var emitterUtils = require('events').inherits(this);
13
emitterUtils.createEvent('serviceStart');
14
emitterUtils.createEvent('serviceStop');
15
emitterUtils.createEvent('normalStart');
16
18
- if (process.platform == 'win32')
19
- {
17
+ if (process.platform == 'win32') {
18
this.GM = require('_GenericMarshal');
19
this.Advapi = this.GM.CreateNativeProxy('Advapi32.dll');
20
this.Advapi.CreateMethod({ method: 'StartServiceCtrlDispatcherA', threadDispatch: 1 });
@@ -33,8 +31,7 @@ function serviceHost(serviceName)
31
this._ServiceMain = this.GM.GetGenericGlobalCallback(2);
32
this._ServiceMain.Parent = this;
33
this._ServiceMain.GM = this.GM;
36
- this._ServiceMain.on('GlobalCallback', function onGlobalCallback(argc, argv)
37
- {
34
+ this._ServiceMain.on('GlobalCallback', function onGlobalCallback(argc, argv) {
35
//ToDo: Check to make sure this is for us
36
37
this.Parent._ServiceStatus = this.GM.CreateVariable(28);
@@ -52,8 +49,7 @@ function serviceHost(serviceName)
49
this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_WIN32);
50
this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.SERVICE_STOPPED, 4);
51
this.Parent._ServiceStatusHandle = this.Parent.Advapi.RegisterServiceCtrlHandlerA(this.Parent._ServiceName, this.Parent._ServiceControlHandler);
55
- if(this.Parent._ServiceStatusHandle.Val == 0)
56
- {
52
+ if (this.Parent._ServiceStatusHandle.Val == 0) {
53
process.exit(1);
54
}
55
@@ -67,8 +63,7 @@ function serviceHost(serviceName)
63
this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus);
64
65
this.Parent.Ole32.CoInitializeEx(0, 2);
70
- this.Parent.on('~', function OnServiceHostFinalizer()
71
- {
66
+ this.Parent.on('~', function OnServiceHostFinalizer() {
67
var GM = require('_GenericMarshal');
68
var Advapi = GM.CreateNativeProxy('Advapi32.dll');
69
Advapi.CreateMethod('SetServiceStatus');
@@ -92,10 +87,8 @@ function serviceHost(serviceName)
87
this._ServiceControlHandler = this.GM.GetGenericGlobalCallback(1);
88
this._ServiceControlHandler.Parent = this;
89
this._ServiceControlHandler.GM = this.GM;
95
- this._ServiceControlHandler.on('GlobalCallback', function onServiceControlHandler(code)
96
- {
97
- switch (code.Val)
98
- {
90
+ this._ServiceControlHandler.on('GlobalCallback', function onServiceControlHandler(code) {
91
+ switch (code.Val) {
92
case SERVICE_CONTROL.SERVICE_CONTROL_SHUTDOWN:
93
case SERVICE_CONTROL.SERVICE_CONTROL_STOP:
94
this.Parent.emit('serviceStop');
@@ -113,54 +106,42 @@ function serviceHost(serviceName)
106
{
107
throw ('Must specify either ServiceName or Options');
108
}
116
- if (!this._ServiceOptions.servicePath)
117
- {
109
+ if (!this._ServiceOptions.servicePath) {
110
this._ServiceOptions.servicePath = process.execPath;
111
}
120
-
121
- this.run = function run()
122
- {
112
+
113
+ this.run = function run() {
114
var serviceOperation = 0;
115
125
- for(var i = 0; i<process.argv.length; ++i)
126
- {
127
- switch(process.argv[i])
128
- {
129
- case '-install':
116
+ for (var i = 0; i < process.argv.length; ++i) {
117
+ switch (process.argv[i].toLowerCase()) {
118
+ case 'install':
119
if (!this._svcManager) { this._svcManager = new serviceManager(); }
131
- try
132
- {
120
+ try {
121
this._svcManager.installService(this._ServiceOptions);
134
- }
135
- catch(e)
136
- {
122
+ } catch (e) {
123
console.log(e);
124
process.exit();
125
}
140
- if (process.platform == 'win32')
141
- {
126
+ if (process.platform == 'win32') {
127
// Only do this on Windows, becuase Linux is async... It'll complete later
143
- console.log(this._ServiceOptions.name + ' installed');
128
+ console.log(this._ServiceOptions.name + ' installed.');
129
process.exit();
130
}
131
i = process.argv.length;
132
serviceOperation = 1;
133
break;
149
- case '-uninstall':
134
+ case 'uninstall':
135
if (!this._svcManager) { this._svcManager = new serviceManager(); }
151
- try
152
- {
136
+ try {
137
this._svcManager.uninstallService(this._ServiceOptions);
154
- }
155
- catch(e)
156
- {
138
+ } catch (e) {
139
console.log(e);
140
process.exit();
141
}
160
- if (process.platform == 'win32')
161
- {
142
+ if (process.platform == 'win32') {
143
// Only do this on Windows, becuase Linux is async... It'll complete later
163
- console.log(this._ServiceOptions.name + ' uninstalled');
144
+ console.log(this._ServiceOptions.name + ' uninstalled.');
145
process.exit();
146
}
147
i = process.argv.length;
@@ -170,55 +151,46 @@ function serviceHost(serviceName)
151
case '-d':
152
if (!this._svcManager) { this._svcManager = new serviceManager(); }
153
this._svcManager.getService(this._ServiceOptions.name).start();
173
- console.log(this._ServiceOptions.name + ' starting...');
154
+ console.log(this._ServiceOptions.name + ' starting.');
155
process.exit();
156
break;
157
case 'stop':
158
case '-s':
159
if (!this._svcManager) { this._svcManager = new serviceManager(); }
160
this._svcManager.getService(this._ServiceOptions.name).stop();
180
- console.log(this._ServiceOptions.name + ' stopping...');
161
+ console.log(this._ServiceOptions.name + ' stopping.');
162
process.exit();
163
break;
164
165
}
166
}
167
187
- if (process.platform == 'win32')
188
- {
168
+ if (process.platform == 'win32') {
169
var serviceTable = this.GM.CreateVariable(4 * this.GM.PointerSize);
170
this._ServiceName.pointerBuffer().copy(serviceTable.toBuffer());
171
this._ServiceMain.pointerBuffer().copy(serviceTable.toBuffer(), this.GM.PointerSize);
172
this._sscd = this.Advapi.StartServiceCtrlDispatcherA(serviceTable);
173
this._sscd.parent = this;
174
this._sscd.on('done', function OnStartServiceCtrlDispatcherA(retVal) {
195
- if (retVal.Val == 0)
196
- {
197
- this.parent.emit('normalStart');
198
- }
175
+ if (retVal.Val == 0) { this.parent.emit('normalStart'); }
176
});
177
return;
178
}
202
-
179
+
180
var moduleName = this._ServiceOptions ? this._ServiceOptions.name : process.execPath.substring(1 + process.execPath.lastIndexOf('/'));
181
205
- for (var i = 0; i < process.argv.length; ++i)
206
- {
207
- switch(process.argv[i])
208
- {
182
+ for (var i = 0; i < process.argv.length; ++i) {
183
+ switch (process.argv[i].toLowerCase()) {
184
case 'start':
185
case '-d':
186
var child = require('child_process').execFile(process.execPath, [moduleName], { type: require('child_process').SpawnTypes.DETACHED });
187
var pstream = null;
213
- try
214
- {
188
+ try {
189
pstream = require('fs').createWriteStream('/var/run/' + moduleName + '.pid', { flags: 'w' });
190
}
217
- catch(e)
218
- {
191
+ catch (e) {
192
}
220
- if (pstream == null)
221
- {
193
+ if (pstream == null) {
194
pstream = require('fs').createWriteStream('.' + moduleName + '.pid', { flags: 'w' });
195
}
196
pstream.end(child.pid.toString());
@@ -229,33 +201,26 @@ function serviceHost(serviceName)
201
case 'stop':
202
case '-s':
203
var pid = null;
232
- try
233
- {
204
+ try {
205
pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' }));
206
require('fs').unlinkSync('/var/run/' + moduleName + '.pid');
207
}
237
- catch(e)
238
- {
208
+ catch (e) {
209
}
240
- if(pid == null)
241
- {
242
- try
243
- {
210
+ if (pid == null) {
211
+ try {
212
pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' }));
213
require('fs').unlinkSync('.' + moduleName + '.pid');
214
}
247
- catch(e)
248
- {
215
+ catch (e) {
216
}
217
}
218
252
- if(pid)
253
- {
219
+ if (pid) {
220
process.kill(pid);
221
console.log(moduleName + ' stopped');
222
}
257
- else
258
- {
223
+ else {
224
console.log(moduleName + ' not running');
225
}
226
process.exit();
@@ -263,56 +228,30 @@ function serviceHost(serviceName)
228
}
229
}
230
266
- if(serviceOperation == 0)
267
- {
231
+ if (serviceOperation == 0) {
232
// This is non-windows, so we need to check how this binary was started to determine if this was a service start
233
234
// Start by checking if we were started with start/stop
235
var pid = null;
272
- try
273
- {
274
- pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' }));
275
- }
276
- catch (e)
277
- {
278
- }
279
- if (pid == null)
280
- {
281
- try
282
- {
283
- pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' }));
284
- }
285
- catch (e)
286
- {
287
- }
288
- }
289
-
290
- if (pid != null && pid == process.pid)
291
- {
236
+ try { pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' })); } catch (e) { }
237
+ if (pid == null) { try { pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' })); } catch (e) { } }
238
+
239
+ if (pid != null && pid == process.pid) {
240
this.emit('serviceStart');
293
- }
294
- else
295
- {
241
+ } else {
242
// Now we need to check if we were started with systemd
297
- if (require('processManager').getProcessInfo(1).Name == 'systemd')
298
- {
243
+ if (require('processManager').getProcessInfo(1).Name == 'systemd') {
244
this._checkpid = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
245
this._checkpid.result = '';
246
this._checkpid.parent = this;
302
- this._checkpid.on('exit', function onCheckPIDExit()
303
- {
247
+ this._checkpid.on('exit', function onCheckPIDExit() {
248
var lines = this.result.split('\r\n');
305
- for (i in lines)
306
- {
307
- if(lines[i].startsWith(' Main PID:'))
308
- {
249
+ for (i in lines) {
250
+ if (lines[i].startsWith(' Main PID:')) {
251
var tokens = lines[i].split(' ');
310
- if (parseInt(tokens[3]) == process.pid)
311
- {
252
+ if (parseInt(tokens[3]) == process.pid) {
253
this.parent.emit('serviceStart');
313
- }
314
- else
315
- {
254
+ } else {
255
this.parent.emit('normalStart');
256
}
257
delete this.parent._checkpid;
@@ -326,8 +265,7 @@ function serviceHost(serviceName)
265
this._checkpid.stdin.write("systemctl status " + moduleName + " | grep 'Main PID:'\n");
266
this._checkpid.stdin.write('exit\n');
267
}
329
- else
330
- {
268
+ else {
269
// This isn't even a systemd platform, so this couldn't have been a service start
270
this.emit('normalStart');
271
}
agents/modules_meshcmd/serviceManager.js
+44
-91
@@ -1,7 +1,6 @@
1
2
3
-function parseServiceStatus(token)
4
-{
3
+function parseServiceStatus(token) {
4
var j = {};
5
var serviceType = token.Deref(0, 4).IntVal;
6
j.isFileSystemDriver = ((serviceType & 0x00000002) == 0x00000002);
@@ -9,8 +8,7 @@ function parseServiceStatus(token)
8
j.isSharedProcess = ((serviceType & 0x00000020) == 0x00000020);
9
j.isOwnProcess = ((serviceType & 0x00000010) == 0x00000010);
10
j.isInteractive = ((serviceType & 0x00000100) == 0x00000100);
12
- switch (token.Deref((1 * 4), 4).toBuffer().readUInt32LE())
13
- {
11
+ switch (token.Deref((1 * 4), 4).toBuffer().readUInt32LE()) {
12
case 0x00000005:
13
j.state = 'CONTINUE_PENDING';
14
break;
@@ -35,8 +33,7 @@ function parseServiceStatus(token)
33
}
34
var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE();
35
j.controlsAccepted = [];
38
- if ((controlsAccepted & 0x00000010) == 0x00000010)
39
- {
36
+ if ((controlsAccepted & 0x00000010) == 0x00000010) {
37
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDADD');
38
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDREMOVE');
39
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDENABLE');
@@ -54,10 +51,8 @@ function parseServiceStatus(token)
51
return (j);
52
}
53
57
-function serviceManager()
58
-{
59
- if (process.platform == 'win32')
60
- {
54
+function serviceManager() {
55
+ if (process.platform == 'win32') {
56
this.GM = require('_GenericMarshal');
57
this.proxy = this.GM.CreateNativeProxy('Advapi32.dll');
58
this.proxy.CreateMethod('OpenSCManagerA');
@@ -83,40 +78,31 @@ function serviceManager()
78
var AdministratorsGroup = this.GM.CreatePointer();
79
var admin = false;
80
86
- if (this.proxy.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0)
87
- {
81
+ if (this.proxy.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0) {
82
var member = this.GM.CreateInteger();
89
- if (this.proxy.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0)
90
- {
83
+ if (this.proxy.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0) {
84
if (member.toBuffer().readUInt32LE() != 0) { admin = true; }
85
}
86
this.proxy.FreeSid(AdministratorsGroup.Deref());
87
}
88
return admin;
89
};
97
- this.getServiceFolder = function getServiceFolder()
98
- {
90
+ this.getServiceFolder = function getServiceFolder() {
91
var destinationFolder = null;
100
- if (require('os').arch() == 'x64')
101
- {
92
+ if (require('os').arch() == 'x64') {
93
// 64 bit Windows
103
- if (this.GM.PointerSize == 4)
104
- {
94
+ if (this.GM.PointerSize == 4) {
95
// 32 Bit App
96
destinationFolder = process.env['ProgramFiles(x86)'];
107
- }
108
- else
109
- {
97
+ } else {
98
// 64 bit App
99
destinationFolder = process.env['ProgramFiles'];
100
}
113
- }
114
- else
115
- {
101
+ } else {
102
// 32 bit Windows
103
destinationFolder = process.env['ProgramFiles'];
104
}
119
- return (destinationFolder + '\\mesh');
105
+ return (destinationFolder + '\\Open Source\\MeshCmd');
106
};
107
108
this.enumerateService = function () {
@@ -129,9 +115,7 @@ function serviceManager()
115
var resumeHandle = this.GM.CreatePointer();
116
//var services = this.proxy.CreateVariable(262144);
117
var success = this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, 0x00, 0x00, bytesNeeded, servicesReturned, resumeHandle, 0x00);
132
- if (bytesNeeded.IntVal <= 0) {
133
- throw ('error enumerating services');
134
- }
118
+ if (bytesNeeded.IntVal <= 0) { throw('Error enumerating services'); }
119
var sz = bytesNeeded.IntVal;
120
var services = this.GM.CreateVariable(sz);
121
this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, services, sz, bytesNeeded, servicesReturned, resumeHandle, 0x00);
@@ -157,7 +141,7 @@ function serviceManager()
141
var ptr = this.GM.CreatePointer();
142
var bytesNeeded = this.GM.CreateVariable(ptr._size);
143
var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0001 | 0x0004 | 0x0020 | 0x0010);
160
- if (handle.Val == 0) { throw ('could not open ServiceManager'); }
144
+ if (handle.Val == 0) { throw('Could not open ServiceManager'); }
145
var h = this.proxy.OpenServiceA(handle, serviceName, 0x0004 | 0x0020 | 0x0010 | 0x00010000);
146
if (h.Val != 0) {
147
var success = this.proxy.QueryServiceStatusEx(h, 0, 0, 0, bytesNeeded);
@@ -182,51 +166,46 @@ function serviceManager()
166
}
167
}
168
else {
185
- throw ('cannot call ' + this.name + '.stop(), when current state is: ' + this.status.state);
169
+ throw ('Cannot call ' + this.name + '.stop(), when current state is: ' + this.status.state);
170
}
171
}
172
retVal.start = function () {
173
if (this.status.state == 'STOPPED') {
174
var success = this._proxy.StartServiceA(this._service, 0, 0);
191
- if (success == 0) {
192
- throw (this.name + '.start() failed');
193
- }
194
- }
195
- else {
196
- throw ('cannot call ' + this.name + '.start(), when current state is: ' + this.status.state);
175
+ if (success == 0) { throw (this.name + '.start() failed'); }
176
+ } else {
177
+ throw ('Cannot call ' + this.name + '.start(), when current state is: ' + this.status.state);
178
}
179
}
180
return (retVal);
200
- }
201
- else {
181
+ } else {
182
183
}
184
}
185
186
this.proxy.CloseServiceHandle(handle);
207
- throw ('could not find service: ' + name);
187
+ throw ('Could not find service: ' + name);
188
}
189
}
210
- this.installService = function installService(options)
211
- {
212
- if (process.platform == 'win32')
213
- {
214
- if (!this.isAdmin()) { throw ('Installing as Service, requires admin'); }
190
+ this.installService = function installService(options) {
191
+ if (process.platform == 'win32') {
192
+ if (!this.isAdmin()) { throw ('Installing as Service, requires administrator permissions.'); }
193
194
// Before we start, we need to copy the binary to the right place
195
var folder = this.getServiceFolder();
196
if (!require('fs').existsSync(folder)) { require('fs').mkdirSync(folder); }
197
require('fs').copyFileSync(options.servicePath, folder + '\\' + options.name + '.exe');
198
options.servicePath = folder + '\\' + options.name + '.exe';
199
+ console.log('Installing to "' + options.servicePath + '"');
200
201
var servicePath = this.GM.CreateVariable('"' + options.servicePath + '"');
202
var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0002);
224
- if (handle.Val == 0) { throw ('error opening SCManager'); }
203
+ if (handle.Val == 0) { throw ('Error opening SCManager'); }
204
var serviceName = this.GM.CreateVariable(options.name);
205
var displayName = this.GM.CreateVariable(options.name);
206
var allAccess = 0x000F01FF;
207
var serviceType;
229
-
208
+
209
210
switch (options.startType) {
211
case 'BOOT_START':
@@ -264,13 +243,11 @@ function serviceManager()
243
this.proxy.CloseServiceHandle(handle);
244
return (this.getService(options.name));
245
}
267
- if(process.platform == 'linux')
268
- {
269
- switch (this.getServiceType())
270
- {
246
+ if (process.platform == 'linux') {
247
+ switch (this.getServiceType()) {
248
case 'init':
249
require('fs').copyFileSync(options.servicePath, '/etc/init.d/' + options.name);
273
- console.log('copying ' + options.servicePath);
250
+ console.log('Copying ' + options.servicePath);
251
var m = require('fs').statSync('/etc/init.d/' + options.name).mode;
252
m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP);
253
require('fs').chmodSync('/etc/init.d/' + options.name, m);
@@ -305,40 +282,25 @@ function serviceManager()
282
}
283
}
284
}
308
- this.uninstallService = function uninstallService(name)
309
- {
285
+ this.uninstallService = function uninstallService(name) {
286
if (typeof (name) == 'object') { name = name.name; }
311
- if (process.platform == 'win32')
312
- {
313
- if (!this.isAdmin()) { throw ('Uninstalling a service, requires admin'); }
287
+ if (process.platform == 'win32') {
288
+ if (!this.isAdmin()) { throw ('Uninstalling a service, requires administrator permissions.'); }
289
290
var service = this.getService(name);
316
- if (service.status.state == undefined || service.status.state == 'STOPPED')
317
- {
318
- if (this.proxy.DeleteService(service._service) == 0)
319
- {
291
+ if (service.status.state == undefined || service.status.state == 'STOPPED') {
292
+ if (this.proxy.DeleteService(service._service) == 0) {
293
throw ('Uninstall Service for: ' + name + ', failed with error: ' + this.proxy2.GetLastError());
321
- }
322
- else
323
- {
324
- try
325
- {
326
- require('fs').unlinkSync(this.getServiceFolder() + '\\' + name + '.exe');
327
- }
328
- catch(e)
329
- {
330
- }
294
+ } else {
295
+ try { require('fs').unlinkSync(this.getServiceFolder() + '\\' + name + '.exe'); } catch (e) { }
296
}
297
}
333
- else
334
- {
298
+ else {
299
throw ('Cannot uninstall service: ' + name + ', because it is: ' + service.status.state);
300
}
301
}
338
- else if(process.platform == 'linux')
339
- {
340
- switch (this.getServiceType())
341
- {
302
+ else if (process.platform == 'linux') {
303
+ switch (this.getServiceType()) {
304
case 'init':
305
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
306
this._update._svcname = name;
@@ -346,11 +308,7 @@ function serviceManager()
308
try {
309
require('fs').unlinkSync('/etc/init.d/' + this._svcname);
310
console.log(this._svcname + ' uninstalled');
349
-
350
- }
351
- catch (e) {
352
- console.log(this._svcname + ' could not be uninstalled')
353
- }
311
+ } catch (e) { console.log(this._svcname + ' could not be uninstalled'); }
312
process.exit();
313
});
314
this._update.stdout.on('data', function (chunk) { });
@@ -366,10 +324,7 @@ function serviceManager()
324
require('fs').unlinkSync('/usr/local/mesh/' + this._svcname);
325
require('fs').unlinkSync('/lib/systemd/system/' + this._svcname + '.service');
326
console.log(this._svcname + ' uninstalled');
369
- }
370
- catch (e) {
371
- console.log(this._svcname + ' could not be uninstalled')
372
- }
327
+ } catch (e) { console.log(this._svcname + ' could not be uninstalled'); }
328
process.exit();
329
});
330
this._update.stdout.on('data', function (chunk) { });
@@ -382,10 +337,8 @@ function serviceManager()
337
}
338
}
339
}
385
- if(process.platform == 'linux')
386
- {
387
- this.getServiceType = function getServiceType()
388
- {
340
+ if (process.platform == 'linux') {
341
+ this.getServiceType = function getServiceType() {
342
return (require('processManager').getProcessInfo(1).Name);
343
};
344
}
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.1.5-u",
3
+ "version": "0.1.5-v",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",