mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-03-09 15:40:18 +00:00
Improved MeshAgent and MeshCmd.
This commit is contained in:
parent
c3144c097a
commit
a5e5611cbe
17 changed files with 198 additions and 154 deletions
|
@ -467,18 +467,18 @@ function AmtStackCreateService(wsmanStack) {
|
|||
obj.AMT_MessageLog_PositionToFirstRecord(_GetMessageLog0, [func, tag, []]);
|
||||
}
|
||||
function _GetMessageLog0(stack, name, responses, status, tag) {
|
||||
if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2]); return; }
|
||||
if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; }
|
||||
obj.AMT_MessageLog_GetRecords(responses.Body["IterationIdentifier"], 390, _GetMessageLog1, tag);
|
||||
}
|
||||
function _GetMessageLog1(stack, name, responses, status, tag) {
|
||||
if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2]); return; }
|
||||
if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; }
|
||||
var i, j, x, e, AmtMessages = tag[2], t = new Date(), TimeStamp, ra = responses.Body["RecordArray"];
|
||||
if (typeof ra === 'string') { responses.Body["RecordArray"] = [responses.Body["RecordArray"]]; }
|
||||
|
||||
for (i in ra) {
|
||||
e = Buffer.from(ra[i], 'base64');
|
||||
if (e != null) {
|
||||
TimeStamp = ReadIntXBuf(e, 0);
|
||||
TimeStamp = ReadIntX(e, 0);
|
||||
if ((TimeStamp > 0) && (TimeStamp < 0xFFFFFFFF)) {
|
||||
x = { 'DeviceAddress': e[4], 'EventSensorType': e[5], 'EventType': e[6], 'EventOffset': e[7], 'EventSourceType': e[8], 'EventSeverity': e[9], 'SensorNumber': e[10], 'Entity': e[11], 'EntityInstance': e[12], 'EventData': [], 'Time': new Date((TimeStamp + (t.getTimezoneOffset() * 60)) * 1000) };
|
||||
for (j = 13; j < 21; j++) { x['EventData'].push(e[j]); }
|
||||
|
@ -678,17 +678,17 @@ function AmtStackCreateService(wsmanStack) {
|
|||
// TODO: Just put some of them here, but many more still need to be added, helpful link here:
|
||||
// https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Fsecurityadminevents.htm
|
||||
obj.GetAuditLogExtendedDataStr = function (id, data) {
|
||||
if ((id == 1602 || id == 1604) && data.charCodeAt(0) == 0) { return data.substring(2, 2 + data.charCodeAt(1)); } // ACL Entry Added/Removed (Digest)
|
||||
if (id == 1603) { if (data.charCodeAt(1) == 0) { return data.substring(3); } return null; } // ACL Entry Modified
|
||||
if (id == 1605) { return ["Invalid ME access", "Invalid MEBx access"][data.charCodeAt(0)]; } // ACL Access with Invalid Credentials
|
||||
if (id == 1606) { var r = ["Disabled", "Enabled"][data.charCodeAt(0)]; if (data.charCodeAt(1) == 0) { r += ", " + data.substring(3); } return r;} // ACL Entry State
|
||||
if (id == 1607) { return "Remote " + ["NoAuth", "ServerAuth", "MutualAuth"][data.charCodeAt(0)] + ", Local " + ["NoAuth", "ServerAuth", "MutualAuth"][data.charCodeAt(1)]; } // TLS State Changed
|
||||
if (id == 1617) { return obj.RealmNames[ReadInt(data, 0)] + ", " + ["NoAuth", "Auth", "Disabled"][data.charCodeAt(4)]; } // Set Realm Authentication Mode
|
||||
if (id == 1619) { return ["BIOS", "MEBx", "Local MEI", "Local WSMAN", "Remote WSAMN"][data.charCodeAt(0)]; } // Intel AMT Unprovisioning Started
|
||||
if ((id == 1602 || id == 1604) && data[0] == 0) { return data.splice(2, 2 + data[1]).toString(); } // ACL Entry Added/Removed (Digest)
|
||||
if (id == 1603) { if (data[1] == 0) { return data.splice(3).toString(); } return null; } // ACL Entry Modified
|
||||
if (id == 1605) { return ["Invalid ME access", "Invalid MEBx access"][data[0]]; } // ACL Access with Invalid Credentials
|
||||
if (id == 1606) { var r = ["Disabled", "Enabled"][data[0]]; if (data[1] == 0) { r += ", " + data[3]; } return r; } // ACL Entry State
|
||||
if (id == 1607) { return "Remote " + ["NoAuth", "ServerAuth", "MutualAuth"][data[0]] + ", Local " + ["NoAuth", "ServerAuth", "MutualAuth"][data[1]]; } // TLS State Changed
|
||||
if (id == 1617) { return obj.RealmNames[ReadInt(data, 0)] + ", " + ["NoAuth", "Auth", "Disabled"][data[4]]; } // Set Realm Authentication Mode
|
||||
if (id == 1619) { return ["BIOS", "MEBx", "Local MEI", "Local WSMAN", "Remote WSAMN"][data[0]]; } // Intel AMT Unprovisioning Started
|
||||
if (id == 1900) { return "From " + ReadShort(data, 0) + "." + ReadShort(data, 2) + "." + ReadShort(data, 4) + "." + ReadShort(data, 6) + " to " + ReadShort(data, 8) + "." + ReadShort(data, 10) + "." + ReadShort(data, 12) + "." + ReadShort(data, 14); } // Firmware Updated
|
||||
if (id == 2100) { var t4 = new Date(); t4.setTime(ReadInt(data, 0) * 1000 + (new Date().getTimezoneOffset() * 60000)); return t4.toLocaleString(); } // Intel AMT Time Set
|
||||
if (id == 3000) { return "From " + ["None", "KVM", "All"][data.charCodeAt(0)] + " to " + ["None", "KVM", "All"][data.charCodeAt(1)]; } // Opt-In Policy Change
|
||||
if (id == 3001) { return ["Success", "Failed 3 times"][data.charCodeAt(0)]; } // Send Consent Code Event
|
||||
if (id == 3000) { return "From " + ["None", "KVM", "All"][data[0]] + " to " + ["None", "KVM", "All"][data[1]]; } // Opt-In Policy Change
|
||||
if (id == 3001) { return ["Success", "Failed 3 times"][data[0]]; } // Send Consent Code Event
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -697,22 +697,15 @@ function AmtStackCreateService(wsmanStack) {
|
|||
}
|
||||
|
||||
function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; }
|
||||
function ReadShort(v, p) { return (v.charCodeAt(p) << 8) + v.charCodeAt(p + 1); }
|
||||
function ReadInt(v, p) { return (v.charCodeAt(p) * 0x1000000) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
|
||||
function ReadIntX(v, p) { return (v.charCodeAt(p + 3) * 0x1000000) + (v.charCodeAt(p + 2) << 16) + (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
|
||||
function ReadIntXBuf(v, p) { return (v[p + 3] * 0x1000000) + (v[p + 2] << 16) + (v[p + 1] << 8) + v[p]; }
|
||||
function ReadShort(v, p) { return (v[p] << 8) + v[p + 1]; }
|
||||
function ReadInt(v, p) { return (v[p] * 0x1000000) + (v[p + 1] << 16) + (v[p + 2] << 8) + v[p + 3]; } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
|
||||
function ReadIntX(v, p) { return (v[p + 3] * 0x1000000) + (v[p + 2] << 16) + (v[p + 1] << 8) + v[p]; }
|
||||
function btoa(x) { return Buffer.from(x).toString('base64'); }
|
||||
function atob(x) {
|
||||
var z = null;
|
||||
try {
|
||||
z = Buffer.from(x, 'base64').toString();
|
||||
} catch (e) { console.log(e); }
|
||||
return z;
|
||||
}
|
||||
function atob(x) { var z = null; try { z = Buffer.from(x, 'base64').toString(); } catch (e) { console.log(e); } return z; }
|
||||
|
||||
function _GetAuditLog0(stack, name, responses, status, tag) {
|
||||
if (status != 200) { tag[0](obj, [], status); return; }
|
||||
var ptr, i, e, x, r = tag[1], t = new Date(), TimeStamp;
|
||||
var ptr, i, e, es, x, r = tag[1], t = new Date(), TimeStamp;
|
||||
|
||||
if (responses.Body['RecordsReturned'] > 0) {
|
||||
responses.Body['EventRecords'] = MakeToArray(responses.Body['EventRecords']);
|
||||
|
@ -720,11 +713,13 @@ function AmtStackCreateService(wsmanStack) {
|
|||
for (i in responses.Body['EventRecords']) {
|
||||
e = null;
|
||||
try {
|
||||
e = atob(responses.Body['EventRecords'][i]);
|
||||
} catch (e) {
|
||||
console.log(e + " " + responses.Body['EventRecords'][i])
|
||||
es = atob(responses.Body['EventRecords'][i]);
|
||||
e = new Buffer(es);
|
||||
} catch (ex) {
|
||||
console.log(ex + " " + responses.Body['EventRecords'][i])
|
||||
}
|
||||
x = { 'AuditAppID': ReadShort(e, 0), 'EventID': ReadShort(e, 2), 'InitiatorType': e.charCodeAt(4) };
|
||||
|
||||
x = { 'AuditAppID': ReadShort(e, 0), 'EventID': ReadShort(e, 2), 'InitiatorType': e[4] };
|
||||
x['AuditApp'] = _AmtAuditStringTable[x['AuditAppID']];
|
||||
x['Event'] = _AmtAuditStringTable[(x['AuditAppID'] * 100) + x['EventID']];
|
||||
if (!x['Event']) x['Event'] = '#' + x['EventID'];
|
||||
|
@ -732,15 +727,15 @@ function AmtStackCreateService(wsmanStack) {
|
|||
// Read and process the initiator
|
||||
if (x['InitiatorType'] == 0) {
|
||||
// HTTP digest
|
||||
var userlen = e.charCodeAt(5);
|
||||
x['Initiator'] = e.substring(6, 6 + userlen);
|
||||
var userlen = e[5];
|
||||
x['Initiator'] = e.slice(6, 6 + userlen).toString();
|
||||
ptr = 6 + userlen;
|
||||
}
|
||||
if (x['InitiatorType'] == 1) {
|
||||
// Kerberos
|
||||
x['KerberosUserInDomain'] = ReadInt(e, 5);
|
||||
var userlen = e.charCodeAt(9);
|
||||
x['Initiator'] = GetSidString(e.substring(10, 10 + userlen));
|
||||
var userlen = e[9];
|
||||
x['Initiator'] = GetSidString(e.slice(10, 10 + userlen));
|
||||
ptr = 10 + userlen;
|
||||
}
|
||||
if (x['InitiatorType'] == 2) {
|
||||
|
@ -753,23 +748,23 @@ function AmtStackCreateService(wsmanStack) {
|
|||
x['Initiator'] = '<i>KVM Default Port</i>';
|
||||
ptr = 5;
|
||||
}
|
||||
|
||||
|
||||
// Read timestamp
|
||||
TimeStamp = ReadInt(e, ptr);
|
||||
x['Time'] = new Date((TimeStamp + (t.getTimezoneOffset() * 60)) * 1000);
|
||||
ptr += 4;
|
||||
|
||||
|
||||
// Read network access
|
||||
x['MCLocationType'] = e.charCodeAt(ptr++);
|
||||
var netlen = e.charCodeAt(ptr++);
|
||||
x['NetAddress'] = e.substring(ptr, ptr + netlen);
|
||||
x['MCLocationType'] = e[ptr++];
|
||||
var netlen = e[ptr++];
|
||||
|
||||
x['NetAddress'] = e.slice(ptr, ptr + netlen).toString();
|
||||
|
||||
// Read extended data
|
||||
ptr += netlen;
|
||||
var exlen = e.charCodeAt(ptr++);
|
||||
x['Ex'] = e.substring(ptr, ptr + exlen);
|
||||
var exlen = e[ptr++];
|
||||
x['Ex'] = e.slice(ptr, ptr + exlen);
|
||||
x['ExStr'] = obj.GetAuditLogExtendedDataStr((x['AuditAppID'] * 100) + x['EventID'], x['Ex']);
|
||||
|
||||
r.push(x);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ function CreateWsmanComm(host, port, user, pass, tls, extra) {
|
|||
obj.pass = pass;
|
||||
obj.tls = tls;
|
||||
obj.digest = null;
|
||||
obj.RequestCount = 0;
|
||||
|
||||
// Private method
|
||||
// pri = priority, if set to 1, the call is high priority and put on top of the stack.
|
||||
|
@ -58,13 +59,16 @@ function CreateWsmanComm(host, port, user, pass, tls, extra) {
|
|||
obj.PerformAjaxEx = function (postdata, callback, tag, url, action) {
|
||||
if (obj.FailAllError != 0) { if (obj.FailAllError != 999) { obj.gotNextMessagesError({ status: obj.FailAllError }, 'error', null, [postdata, callback, tag]); } return; }
|
||||
if (!postdata) postdata = "";
|
||||
// console.log("SEND: " + postdata); // DEBUG
|
||||
//console.log("SEND: " + postdata); // DEBUG
|
||||
|
||||
// We are in a DukTape environement
|
||||
if (obj.digest == null) { obj.digest = require('http-digest').create(obj.user, obj.pass); obj.digest.http = require('http'); }
|
||||
var request = { protocol: (obj.tls == 1 ? 'https:' : 'http:'), method: 'POST', host: obj.host, path: '/wsman', port: obj.port };
|
||||
var req = obj.digest.request(request,
|
||||
function (response) {
|
||||
var request = { protocol: (obj.tls == 1 ? 'https:' : 'http:'), method: 'POST', host: obj.host, path: '/wsman', port: obj.port, rejectUnauthorized: false, checkServerIdentity: function (cert) { console.log('checkServerIdentity', JSON.stringify(cert)); } };
|
||||
var req = obj.digest.request(request);
|
||||
//console.log('Request ' + (obj.RequestCount++));
|
||||
req.on('error', function (e) { obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); });
|
||||
req.on('response', function (response) {
|
||||
//console.log('Response: ' + response.statusCode);
|
||||
if (response.statusCode != 200) {
|
||||
console.log('ERR:' + JSON.stringify(response));
|
||||
obj.gotNextMessagesError({ status: response.statusCode }, 'error', null, [postdata, callback, tag]);
|
||||
|
@ -74,11 +78,11 @@ function CreateWsmanComm(host, port, user, pass, tls, extra) {
|
|||
response.on('end', function () { obj.gotNextMessages(response.acc, 'success', { status: response.statusCode }, [postdata, callback, tag]); });
|
||||
}
|
||||
});
|
||||
req.on('error', function (e) { console.log(JSON.stringify(e)); obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); });
|
||||
|
||||
// Send POST body, this work with binary.
|
||||
req.write(postdata);
|
||||
req.end();
|
||||
obj.ActiveAjaxCount++;
|
||||
return req;
|
||||
}
|
||||
|
||||
|
@ -101,7 +105,7 @@ function CreateWsmanComm(host, port, user, pass, tls, extra) {
|
|||
obj.ActiveAjaxCount--;
|
||||
if (obj.FailAllError == 999) return;
|
||||
if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
|
||||
// if (s != 200) { console.log("ERROR, status=" + status + "\r\n\r\nreq=" + callArgs[0]); } // Debug: Display the request & response if something did not work.
|
||||
//if (status != 200) { console.log("ERROR, status=" + status + "\r\n\r\nreq=" + callArgs[0]); } // Debug: Display the request & response if something did not work.
|
||||
if (obj.FailAllError != 999) { callArgs[1]({ Header: { HttpError: request.status } }, request.status, callArgs[2]); }
|
||||
obj.PerformNextAjax();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
|
||||
var MemoryStream = require('MemoryStream');
|
||||
var lme_id = 0;
|
||||
var lme_port_offset = 0; // Debug: Set this to "-100" to bind to 16892 & 16893 and IN_ADDRANY. This is for LMS debugging.
|
||||
|
||||
|
||||
var APF_DISCONNECT = 1;
|
||||
|
@ -68,9 +69,7 @@ function stream_bufferedWrite() {
|
|||
return (this._readCheckImmediate == undefined);
|
||||
};
|
||||
this.write = function (chunk) {
|
||||
for (var args in arguments) {
|
||||
if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; }
|
||||
}
|
||||
for (var args in arguments) { if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; } }
|
||||
var tmp = Buffer.alloc(chunk.length);
|
||||
chunk.copy(tmp);
|
||||
this.buffer.push({ offset: 0, data: tmp });
|
||||
|
@ -90,8 +89,7 @@ function stream_bufferedWrite() {
|
|||
list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead));
|
||||
this.buffer[0].offset += (size - bytesRead);
|
||||
bytesRead += (size - bytesRead);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Reading the entire thing
|
||||
list.push(this.buffer[0].data.slice(offset));
|
||||
bytesRead += len;
|
||||
|
@ -101,12 +99,9 @@ function stream_bufferedWrite() {
|
|||
this._readCheckImmediate = setImmediate(function (buffered) {
|
||||
buffered._readCheckImmediate = undefined;
|
||||
if (buffered.buffer.length == 0) {
|
||||
// drained
|
||||
buffered.emit('drain');
|
||||
}
|
||||
else {
|
||||
// not drained
|
||||
buffered.emit('readable');
|
||||
buffered.emit('drain'); // Drained
|
||||
} else {
|
||||
buffered.emit('readable'); // Not drained
|
||||
}
|
||||
}, this);
|
||||
return (Buffer.concat(list));
|
||||
|
@ -114,11 +109,13 @@ function stream_bufferedWrite() {
|
|||
}
|
||||
|
||||
|
||||
function lme_heci() {
|
||||
function lme_heci(options) {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('connect');
|
||||
|
||||
if (options.debug == true) { lme_port_offset = -100; } // LMS debug mode
|
||||
|
||||
var heci = require('heci');
|
||||
this.INITIAL_RXWINDOW_SIZE = 4096;
|
||||
|
||||
|
@ -147,8 +144,7 @@ function lme_heci() {
|
|||
outBuffer.write(name.toString(), 5);
|
||||
this.write(outBuffer);
|
||||
//console.log('Answering APF_SERVICE_REQUEST');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//console.log('UNKNOWN APF_SERVICE_REQUEST');
|
||||
}
|
||||
break;
|
||||
|
@ -166,10 +162,14 @@ function lme_heci() {
|
|||
}
|
||||
this[name][port] = require('net').createServer();
|
||||
this[name][port].HECI = this;
|
||||
this[name][port].listen({ port: port, host: '127.0.0.1' });
|
||||
if (lme_port_offset == 0) {
|
||||
this[name][port].listen({ port: port, host: '127.0.0.1' }); // Normal mode
|
||||
} else {
|
||||
this[name][port].listen({ port: (port + lme_port_offset) }); // Debug mode
|
||||
}
|
||||
this[name][port].on('connection', function (socket) {
|
||||
//console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort);
|
||||
this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort);
|
||||
this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort - lme_port_offset);
|
||||
});
|
||||
var outBuffer = Buffer.alloc(5);
|
||||
outBuffer.writeUInt8(81, 0);
|
||||
|
@ -246,8 +246,7 @@ function lme_heci() {
|
|||
if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) {
|
||||
this.sockets[rChannelId].bufferedStream.emit('readable');
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST');
|
||||
}
|
||||
break;
|
||||
|
@ -265,8 +264,7 @@ function lme_heci() {
|
|||
outBuffer.writeUInt32BE(written, 5);
|
||||
this.HECI.write(outBuffer);
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA');
|
||||
}
|
||||
break;
|
||||
|
@ -281,8 +279,7 @@ function lme_heci() {
|
|||
buffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
|
||||
buffer.writeUInt32BE(amtId, 1);
|
||||
this.write(buffer);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE');
|
||||
}
|
||||
break;
|
||||
|
@ -309,12 +306,10 @@ function lme_heci() {
|
|||
if (remoteFamily == 'IPv6') {
|
||||
buffer.writeUInt32BE(3);
|
||||
buffer.write('::1');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
buffer.writeUInt32BE(9);
|
||||
buffer.write('127.0.0.1');
|
||||
}
|
||||
|
||||
buffer.writeUInt32BE(localPort);
|
||||
}
|
||||
this._LME.write(buffer.buffer);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue