Improved MeshAgent and MeshCmd.

This commit is contained in:
Ylian Saint-Hilaire 2018-01-25 16:12:53 -08:00
parent c3144c097a
commit a5e5611cbe
17 changed files with 198 additions and 154 deletions

View File

@ -1,6 +1,7 @@
readme.txt
license.txt
package.json
sample-config.json
*.js
views/*
public/*

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -800,7 +800,7 @@ function createMeshCore(agent) {
}
case 'info': { // Return information about the agent and agent core module
response = 'Current Core: ' + obj.meshCoreInfo + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform Info: ' + process.platform + '.\r\nCapabilities: ' + obj.meshCoreCapabilities + '.\r\nServer URL: ' + mesh.ServerUrl + '.';
if (amtLmsState >= 0) { response += '\r\nBuilt -in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amtLmsState] + '.'; }
if (amtLmsState >= 0) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amtLmsState] + '.'; }
response += '\r\nModules: ' + JSON.stringify(addedModules) + '';
response += '\r\nServerConnected: ' + mesh.isControlChannelConnected + '';
var oldNodeId = db.Get('OldNodeId');

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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);

View File

@ -1,19 +1,3 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var MemoryStream = require('MemoryStream');
var WindowsWireless = new Buffer([
0x0A, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x5F, 0x53, 0x63, 0x61, 0x6E, 0x28, 0x29, 0x0A, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x77, 0x6C, 0x61, 0x6E,
@ -187,7 +171,8 @@ function AccessPoint(_ssid, _bssid, _lq)
}
AccessPoint.prototype.toString = function ()
{
return (this.ssid + " [" + this.bssid + "]: " + this.lq);
return ("[" + this.bssid + "]: " + this.ssid + " (" + this.lq + ")");
//return (this.ssid + " [" + this.bssid + "]: " + this.lq);
}
function WiFiScanner()
@ -232,12 +217,12 @@ function WiFiScanner()
}
if (wlan != null)
{
this.child = require('ILibProcessPipe').CreateProcess("/sbin/iwlist", "iwlist", wlan, "scan");
this.child = require('child_process').execFile('/sbin/iwlist', ['iwlist', wlan, 'scan']);
this.child.parent = this;
this.child.ms = new MemoryStream();
this.child.ms.parent = this.child;
this.child.on('data', function (buffer) { this.ms.write(buffer); });
this.child.on('end', function () { this.ms.end(); });
this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); });
this.child.on('exit', function () { this.ms.end(); });
this.child.ms.on('end', function ()
{
var str = this.buffer.toString();
@ -263,6 +248,11 @@ function WiFiScanner()
{
_lq = lnblock.slice(13,lnblock.length-4);
}
else if (lnblock.startsWith('Quality='))
{
_lq = lnblock.slice(8, 10);
var scale = lnblock.slice(11, 13);
}
}
this.parent.parent.emit('accessPoint', new AccessPoint(_ssid, _bssid, _lq));
}

View File

@ -83,7 +83,7 @@ function AMTScanner() {
return ((num >> 24) & 0xFF) + '.' + ((num >> 16) & 0xFF) + '.' + ((num >> 8) & 0xFF) + '.' + (num & 0xFF);
}
this.scan = function (rangestr, timeout, func) {
this.scan = function (rangestr, timeout) {
var iprange = this.parseIPv4Range(rangestr);
var rmcp = this.buildRmcpPing(0);
var server = this.dgram.createSocket({ type: 'udp4' });
@ -97,7 +97,6 @@ function AMTScanner() {
//console.log("Server closed");
server.close();
server.parent.emit('found', server.scanResults);
if (func != null) { func(server.scanResults); }
delete server;
}, timeout);
};

View File

@ -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);

View File

@ -49,7 +49,7 @@ function CreateMeshCentralServer() {
obj.currentVer = null;
obj.serverKey = new Buffer(obj.crypto.randomBytes(32), 'binary');
obj.loginCookieEncryptionKey = null;
try { obj.currentVer = JSON.parse(require('fs').readFileSync(obj.path.join(__dirname, 'package.json'), 'utf8')).version; } catch (e) { } // Fetch server version
try { obj.currentVer = JSON.parse(obj.fs.readFileSync(obj.path.join(__dirname, 'package.json'), 'utf8')).version; } catch (e) { } // Fetch server version
// Setup the default configuration and files paths
if ((__dirname.endsWith('/node_modules/meshcentral')) || (__dirname.endsWith('\\node_modules\\meshcentral')) || (__dirname.endsWith('/node_modules/meshcentral/')) || (__dirname.endsWith('\\node_modules\\meshcentral\\'))) {
@ -200,14 +200,18 @@ function CreateMeshCentralServer() {
if (obj.args.filespath) { obj.filespath = obj.args.filespath; }
// Read configuration file if present and change arguments.
if (require('fs').existsSync(obj.path.join(obj.datapath, 'config.json'))) {
var configFilePath = obj.path.join(obj.datapath, 'config.json');
if (obj.fs.existsSync(configFilePath)) {
// Load and validate the configuration file
try { obj.config = require(obj.path.join(obj.datapath, 'config.json')); } catch (e) { console.log('ERROR: Unable to parse ./data/config.json.'); return; }
try { obj.config = require(configFilePath); } catch (e) { console.log('ERROR: Unable to parse ' + configFilePath + '.'); return; }
if (obj.config.domains == null) { obj.config.domains = {}; }
for (var i in obj.config.domains) { if ((i.split('/').length > 1) || (i.split(' ').length > 1)) { console.log("ERROR: Error in config.json, domain names can't have spaces or /."); return; } }
// Set the command line arguments to the config file if they are not present
if (obj.config.settings) { for (var i in obj.config.settings) { if (obj.args[i] == null) obj.args[i] = obj.config.settings[i]; } }
} else {
// Copy the "sample-config.json" to give users a starting point
var sampleConfigPath = obj.path.join(__dirname, 'sample-config.json');
if (obj.fs.existsSync(sampleConfigPath)) { obj.fs.createReadStream(sampleConfigPath).pipe(obj.fs.createWriteStream(configFilePath)); }
}
obj.common.objKeysToLower(obj.config); // Lower case all keys in the config file
@ -399,12 +403,12 @@ function CreateMeshCentralServer() {
}
// Setup and start the MPS server
if (obj.args.lanonly != true) {
if ((obj.args.lanonly != true) && (obj.args.mpsport !== 0)) {
obj.mpsserver = require('./mpsserver.js').CreateMpsServer(obj, obj.db, obj.args, obj.certificates);
}
// Setup and start the legacy swarm server
if (obj.certificates.swarmserver != null) {
if ((obj.certificates.swarmserver != null) && (obj.args.swarmport !== 0)) {
if (obj.args.swarmport == null) { obj.args.swarmport = 8080; }
obj.swarmserver = require('./swarmserver.js').CreateSwarmServer(obj, obj.db, obj.args, obj.certificates);
}
@ -474,9 +478,8 @@ function CreateMeshCentralServer() {
if (restoreFile) {
obj.debug(1, 'Server stopped, updating settings: ' + restoreFile);
console.log('Updating settings folder...');
var fs = require('fs');
var unzip = require('unzip');
var rs = fs.createReadStream(restoreFile);
var rs = obj.fs.createReadStream(restoreFile);
rs.on('end', () => { setTimeout(function () { fs.unlinkSync(restoreFile); process.exit(123); }, 500); });
rs.pipe(unzip.Extract({ path: obj.datapath }));
} else {

View File

@ -878,7 +878,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
}
case 'inviteAgent':
{
if (obj.parent.parent.mailserver == null) return; // This operation requires the email server
if ((obj.parent.parent.mailserver == null) || (obj.args.lanonly == true)) return; // This operation requires the email server
if ((obj.parent.parent.certificates.CommonName == null) || (obj.parent.parent.certificates.CommonName == 'un-configured')) return; // Server name must be configured
if ((command.meshid.split('/').length != 3) || (command.meshid.split('/')[1] != domain.id)) return; // Invalid domain, operation only valid for current domain

View File

@ -1,6 +1,6 @@
{
"name": "meshcentral",
"version": "0.1.3-c",
"version": "0.1.3-d",
"keywords": [
"Remote Management",
"Intel AMT",

51
sample-config.json Normal file
View File

@ -0,0 +1,51 @@
{
"__comment__" : "This is a sample configuration file, edit a section and remove the _ in front of the name. Refer to the user's guide for details.",
"_settings": {
"MongoDb": "mongodb://127.0.0.1:27017/meshcentral",
"MongoDbCol": "meshcentral",
"Port": 443,
"RedirPort": 80,
"AllowLoginToken": true,
"AllowFraming": true
},
"_domains": {
"": {
"title": "MyServer",
"title2": "Servername",
"userQuota": 1048576,
"meshQuota": 248576,
"newAccounts": 1,
"footer": "<a href='https://twitter.com/mytwitter'>Twitter</a>"
},
"customer1": {
"dns": "customer1.myserver.com",
"title": "Customer1",
"title2": "TestServer",
"newAccounts": 1,
"auth": "sspi",
"footer": "Test"
},
"info": {
"share": "C:\\ExtraWebSite"
}
},
"_letsencrypt": {
"email": "myemail@myserver.com ",
"names": "myserver.com,customer1.myserver.com",
"rsaKeySize": 3072,
"production": false
},
"_peers": {
"serverId": "server1",
"servers": {
"server1": { "url": "wss://192.168.2.133:443/" },
"server2": { "url": "wss://192.168.1.106:443/" }
}
},
"_smtp": {
"host": "smtp.myserver.com",
"port": 25,
"from": "myemail@myserver.com",
"tls": false
}
}

View File

@ -684,7 +684,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
if (domain.userQuota == -1) { features += 8; } // No server files mode
if (obj.args.tlsoffload == true) { features += 16; } // No mutual-auth CIRA
if ((parent.config != null) && (parent.config.settings != null) && (parent.config.settings.allowframing == true)) { features += 32; } // Allow site within iframe
if ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName != 'un-configured')) { features += 64; } // Email invites
if ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName != 'un-configured') && (obj.args.lanonly != true)) { features += 64; } // Email invites
// Send the master web application
if ((!obj.args.user) && (obj.args.nousers != true) && (nologout == false)) { logoutcontrol += ' <a href=' + domain.url + 'logout?' + Math.random() + ' style=color:white>Logout</a>'; } // If a default user is in use or no user mode, don't display the logout button