Added agent installation invite using email.

This commit is contained in:
Ylian Saint-Hilaire 2018-01-23 14:15:59 -08:00
parent 65f99a3c31
commit c3144c097a
19 changed files with 387 additions and 151 deletions

View File

@ -21,8 +21,16 @@
<PropertyGroup Condition="'$(Configuration)' == 'Release'" /> <PropertyGroup Condition="'$(Configuration)' == 'Release'" />
<ItemGroup> <ItemGroup>
<Compile Include="agents\meshcore.js" /> <Compile Include="agents\meshcore.js" />
<Compile Include="agents\modules_meshcmd\amt-0.2.0.js" />
<Compile Include="agents\modules_meshcmd\amt-scanner.js" />
<Compile Include="agents\modules_meshcmd\amt-script-0.2.0.js" />
<Compile Include="agents\modules_meshcmd\amt-wsman-0.2.0.js" />
<Compile Include="agents\modules_meshcmd\amt-wsman-duk-0.2.0.js" />
<Compile Include="agents\modules_meshcmd\amt_heci.js" /> <Compile Include="agents\modules_meshcmd\amt_heci.js" />
<Compile Include="agents\modules_meshcmd\lme_heci.js" />
<Compile Include="agents\modules_meshcore\amt-scanner.js" />
<Compile Include="agents\modules_meshcore\amt_heci.js" /> <Compile Include="agents\modules_meshcore\amt_heci.js" />
<Compile Include="agents\modules_meshcore\lme_heci.js" />
<Compile Include="agents\modules_meshcore\WifiScanner.js" /> <Compile Include="agents\modules_meshcore\WifiScanner.js" />
<Compile Include="agents\tinycore.js" /> <Compile Include="agents\tinycore.js" />
<Compile Include="amtevents.js" /> <Compile Include="amtevents.js" />

View File

@ -719,6 +719,7 @@ function createMeshCore(agent) {
// Other side received websocket end of data marker, start sending data on WebRTC channel // Other side received websocket end of data marker, start sending data on WebRTC channel
if (this.httprequest.protocol == 1) { // Terminal if (this.httprequest.protocol == 1) { // Terminal
this.httprequest.process.stdout.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. this.httprequest.process.stdout.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
this.httprequest.process.stderr.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
} else if (this.httprequest.protocol == 2) { // Desktop } else if (this.httprequest.protocol == 2) { // Desktop
this.httprequest.desktop.kvm.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. this.httprequest.desktop.kvm.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
} }
@ -731,12 +732,15 @@ function createMeshCore(agent) {
this.webrtc.on('dataChannel', function (rtcchannel) { this.webrtc.on('dataChannel', function (rtcchannel) {
sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol); sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol);
rtcchannel.xrtc = this; rtcchannel.xrtc = this;
rtcchannel.websocket = this.websocket;
this.rtcchannel = rtcchannel; this.rtcchannel = rtcchannel;
this.rtcchannel.on('data', onTunnelWebRTCControlData); this.websocket.rtcchannel = rtcchannel;
this.rtcchannel.on('end', function () { sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed'); }); this.websocket.rtcchannel.on('data', onTunnelWebRTCControlData);
this.websocket.rtcchannel.on('end', function () { sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed'); });
if (this.websocket.httprequest.protocol == 1) { // Terminal if (this.websocket.httprequest.protocol == 1) { // Terminal
// This is a terminal data stream, unpipe the terminal now and indicate to the other side that terminal data will no longer be received over WebSocket // This is a terminal data stream, unpipe the terminal now and indicate to the other side that terminal data will no longer be received over WebSocket
this.websocket.httprequest.process.stdout.unpipe(this.websocket); this.websocket.httprequest.process.stdout.unpipe(this.websocket);
this.websocket.httprequest.process.stderr.unpipe(this.websocket);
this.websocket.write("{\"type\":\"webrtc1\"}"); // End of data marker this.websocket.write("{\"type\":\"webrtc1\"}"); // End of data marker
} else if (this.websocket.httprequest.protocol == 2) { // Desktop } else if (this.websocket.httprequest.protocol == 2) { // Desktop
// This is a KVM data stream, unpipe the KVM now and indicate to the other side that KVM data will no longer be received over WebSocket // This is a KVM data stream, unpipe the KVM now and indicate to the other side that KVM data will no longer be received over WebSocket

View File

@ -1,3 +1,19 @@
/*
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.
*/
/** /**
* @fileoverview Intel(r) AMT Communication StackXX * @fileoverview Intel(r) AMT Communication StackXX
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire

View File

@ -1,3 +1,19 @@
/*
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.
*/
/** /**
* @description Meshcentral Intel AMT Local Scanner * @description Meshcentral Intel AMT Local Scanner
* @author Ylian Saint-Hilaire & Joko Sastriawan * @author Ylian Saint-Hilaire & Joko Sastriawan

View File

@ -1,3 +1,19 @@
/*
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.
*/
/** /**
* @fileoverview Script Compiler / Decompiler / Runner * @fileoverview Script Compiler / Decompiler / Runner
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire

View File

@ -1,3 +1,19 @@
/*
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.
*/
/** /**
* @description Intel(r) AMT WSMAN Stack * @description Intel(r) AMT WSMAN Stack
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire

View File

@ -1,4 +1,20 @@
/** /*
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.
*/
/**
* @description WSMAN communication using duktape http * @description WSMAN communication using duktape http
* @author Ylian Saint-Hilaire * @author Ylian Saint-Hilaire
* @version v0.2.0c * @version v0.2.0c

View File

@ -1,3 +1,19 @@
/*
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 Q = require('queue'); var Q = require('queue');
function amt_heci() { function amt_heci() {

View File

@ -1,3 +1,18 @@
/*
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 MemoryStream = require('MemoryStream');
var lme_id = 0; var lme_id = 0;
@ -151,7 +166,7 @@ function lme_heci() {
} }
this[name][port] = require('net').createServer(); this[name][port] = require('net').createServer();
this[name][port].HECI = this; this[name][port].HECI = this;
this[name][port].listen({ port: port }); this[name][port].listen({ port: port, host: '127.0.0.1' });
this[name][port].on('connection', function (socket) { this[name][port].on('connection', function (socket) {
//console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort); //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);

View File

@ -1,3 +1,19 @@
/*
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 MemoryStream = require('MemoryStream');
var WindowsWireless = new Buffer([ 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, 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,

View File

@ -1,3 +1,19 @@
/*
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.
*/
/** /**
* @description Meshcentral Intel AMT Local Scanner * @description Meshcentral Intel AMT Local Scanner
* @author Ylian Saint-Hilaire & Joko Sastriawan * @author Ylian Saint-Hilaire & Joko Sastriawan

View File

@ -1,3 +1,19 @@
/*
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 Q = require('queue'); var Q = require('queue');
function amt_heci() { function amt_heci() {

View File

@ -1,3 +1,18 @@
/*
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 MemoryStream = require('MemoryStream');
var lme_id = 0; var lme_id = 0;
@ -21,8 +36,7 @@ var APF_CHANNEL_CLOSE = 97;
var APF_PROTOCOLVERSION = 192; var APF_PROTOCOLVERSION = 192;
function lme_object() function lme_object() {
{
this.ourId = ++lme_id; this.ourId = ++lme_id;
this.amtId = -1; this.amtId = -1;
this.LME_CHANNEL_STATUS = 'LME_CS_FREE'; this.LME_CHANNEL_STATUS = 'LME_CS_FREE';
@ -32,12 +46,11 @@ function lme_object()
this.errorCount = 0; this.errorCount = 0;
} }
function stream_bufferedWrite() function stream_bufferedWrite() {
{
var emitterUtils = require('events').inherits(this); var emitterUtils = require('events').inherits(this);
this.buffer = []; this.buffer = [];
this._readCheckImmediate = undefined; this._readCheckImmediate = undefined;
// Writable Events // Writable Events
emitterUtils.createEvent('close'); emitterUtils.createEvent('close');
emitterUtils.createEvent('drain'); emitterUtils.createEvent('drain');
@ -45,21 +58,17 @@ function stream_bufferedWrite()
emitterUtils.createEvent('finish'); emitterUtils.createEvent('finish');
emitterUtils.createEvent('pipe'); emitterUtils.createEvent('pipe');
emitterUtils.createEvent('unpipe'); emitterUtils.createEvent('unpipe');
// Readable Events // Readable Events
emitterUtils.createEvent('readable'); emitterUtils.createEvent('readable');
this.isEmpty = function () this.isEmpty = function () {
{
return (this.buffer.length == 0); return (this.buffer.length == 0);
}; };
this.isWaiting = function () this.isWaiting = function () {
{
return (this._readCheckImmediate == undefined); return (this._readCheckImmediate == undefined);
}; };
this.write = function (chunk) this.write = function (chunk) {
{ for (var args in arguments) {
for (var args in arguments)
{
if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; } if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; }
} }
var tmp = Buffer.alloc(chunk.length); var tmp = Buffer.alloc(chunk.length);
@ -68,41 +77,34 @@ function stream_bufferedWrite()
this.emit('readable'); this.emit('readable');
return (this.buffer.length == 0 ? true : false); return (this.buffer.length == 0 ? true : false);
}; };
this.read = function () this.read = function () {
{
var size = arguments.length == 0 ? undefined : arguments[0]; var size = arguments.length == 0 ? undefined : arguments[0];
var bytesRead = 0; var bytesRead = 0;
var list = []; var list = [];
while((size == undefined || bytesRead < size) && this.buffer.length > 0) while ((size == undefined || bytesRead < size) && this.buffer.length > 0) {
{
var len = this.buffer[0].data.length - this.buffer[0].offset; var len = this.buffer[0].data.length - this.buffer[0].offset;
var offset = this.buffer[0].offset; var offset = this.buffer[0].offset;
if(len > (size - bytesRead)) if (len > (size - bytesRead)) {
{
// Only reading a subset // Only reading a subset
list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead)); list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead));
this.buffer[0].offset += (size - bytesRead); this.buffer[0].offset += (size - bytesRead);
bytesRead += (size - bytesRead); bytesRead += (size - bytesRead);
} }
else else {
{
// Reading the entire thing // Reading the entire thing
list.push(this.buffer[0].data.slice(offset)); list.push(this.buffer[0].data.slice(offset));
bytesRead += len; bytesRead += len;
this.buffer.shift(); this.buffer.shift();
} }
} }
this._readCheckImmediate = setImmediate(function (buffered) this._readCheckImmediate = setImmediate(function (buffered) {
{
buffered._readCheckImmediate = undefined; buffered._readCheckImmediate = undefined;
if(buffered.buffer.length == 0) if (buffered.buffer.length == 0) {
{
// drained // drained
buffered.emit('drain'); buffered.emit('drain');
} }
else else {
{
// not drained // not drained
buffered.emit('readable'); buffered.emit('readable');
} }
@ -112,38 +114,33 @@ function stream_bufferedWrite()
} }
function lme_heci() function lme_heci() {
{
var emitterUtils = require('events').inherits(this); var emitterUtils = require('events').inherits(this);
emitterUtils.createEvent('error'); emitterUtils.createEvent('error');
emitterUtils.createEvent('connect'); emitterUtils.createEvent('connect');
var heci = require('heci'); var heci = require('heci');
this.INITIAL_RXWINDOW_SIZE = 4096; this.INITIAL_RXWINDOW_SIZE = 4096;
this._LME = heci.create(); this._LME = heci.create();
this._LME.LMS = this; this._LME.LMS = this;
this._LME.on('error', function (e) { this.LMS.emit('error', e); }); this._LME.on('error', function (e) { this.LMS.emit('error', e); });
this._LME.on('connect', function () this._LME.on('connect', function () {
{
this.LMS.emit('connect'); this.LMS.emit('connect');
this.on('data', function (chunk) this.on('data', function (chunk) {
{
// this = HECI // this = HECI
var cmd = chunk.readUInt8(0); var cmd = chunk.readUInt8(0);
switch(cmd) switch (cmd) {
{
default: default:
//console.log('Received ' + chunk.length + ' bytes of data for LMS'); //console.log('Received ' + chunk.length + ' bytes of data for LMS');
//console.log('Command = ' + cmd); //console.log('Command = ' + cmd);
break; break;
case APF_SERVICE_REQUEST: case APF_SERVICE_REQUEST:
var nameLen = chunk.readUInt32BE(1); var nameLen = chunk.readUInt32BE(1);
var name = chunk.slice(5, nameLen + 5); var name = chunk.slice(5, nameLen + 5);
//console.log("Service Request for: " + name); //console.log("Service Request for: " + name);
if (name == 'pfwd@amt.intel.com' || name == 'auth@amt.intel.com') if (name == 'pfwd@amt.intel.com' || name == 'auth@amt.intel.com') {
{
var outBuffer = Buffer.alloc(5 + nameLen); var outBuffer = Buffer.alloc(5 + nameLen);
outBuffer.writeUInt8(6, 0); outBuffer.writeUInt8(6, 0);
outBuffer.writeUInt32BE(nameLen, 1); outBuffer.writeUInt32BE(nameLen, 1);
@ -151,30 +148,26 @@ function lme_heci()
this.write(outBuffer); this.write(outBuffer);
//console.log('Answering APF_SERVICE_REQUEST'); //console.log('Answering APF_SERVICE_REQUEST');
} }
else else {
{
//console.log('UNKNOWN APF_SERVICE_REQUEST'); //console.log('UNKNOWN APF_SERVICE_REQUEST');
} }
break; break;
case APF_GLOBAL_REQUEST: case APF_GLOBAL_REQUEST:
var nameLen = chunk.readUInt32BE(1); var nameLen = chunk.readUInt32BE(1);
var name = chunk.slice(5, nameLen + 5).toString(); var name = chunk.slice(5, nameLen + 5).toString();
switch(name) switch (name) {
{
case 'tcpip-forward': case 'tcpip-forward':
var len = chunk.readUInt32BE(nameLen + 6); var len = chunk.readUInt32BE(nameLen + 6);
var port = chunk.readUInt32BE(nameLen + 10 + len); var port = chunk.readUInt32BE(nameLen + 10 + len);
//console.log("[" + chunk.length + "/" + len + "] APF_GLOBAL_REQUEST for: " + name + " on port " + port); //console.log("[" + chunk.length + "/" + len + "] APF_GLOBAL_REQUEST for: " + name + " on port " + port);
if (this[name] == undefined) if (this[name] == undefined) {
{
this[name] = {}; this[name] = {};
} }
this[name][port] = require('net').createServer(); this[name][port] = require('net').createServer();
this[name][port].HECI = this; this[name][port].HECI = this;
this[name][port].listen({ port: port }); this[name][port].listen({ port: port, host: '127.0.0.1' });
this[name][port].on('connection', function (socket) this[name][port].on('connection', function (socket) {
{
//console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort); //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);
}); });
@ -192,54 +185,48 @@ function lme_heci()
break; break;
} }
break; break;
case APF_CHANNEL_OPEN_CONFIRMATION: case APF_CHANNEL_OPEN_CONFIRMATION:
var rChannel = chunk.readUInt32BE(1); var rChannel = chunk.readUInt32BE(1);
var sChannel = chunk.readUInt32BE(5); var sChannel = chunk.readUInt32BE(5);
var wSize = chunk.readUInt32BE(9); var wSize = chunk.readUInt32BE(9);
//console.log('rChannel/' + rChannel + ', sChannel/' + sChannel + ', wSize/' + wSize); //console.log('rChannel/' + rChannel + ', sChannel/' + sChannel + ', wSize/' + wSize);
if (this.sockets[rChannel] != undefined) if (this.sockets[rChannel] != undefined) {
{ this.sockets[rChannel].lme.amtId = sChannel;
this.sockets[rChannel].lme.amtId = sChannel; this.sockets[rChannel].lme.rxWindow = wSize;
this.sockets[rChannel].lme.rxWindow = wSize; this.sockets[rChannel].lme.txWindow = wSize;
this.sockets[rChannel].lme.txWindow = wSize; this.sockets[rChannel].lme.LME_CHANNEL_STATUS = 'LME_CS_CONNECTED';
this.sockets[rChannel].lme.LME_CHANNEL_STATUS = 'LME_CS_CONNECTED'; //console.log('LME_CS_CONNECTED');
//console.log('LME_CS_CONNECTED'); this.sockets[rChannel].bufferedStream = new stream_bufferedWrite();
this.sockets[rChannel].bufferedStream = new stream_bufferedWrite(); this.sockets[rChannel].bufferedStream.socket = this.sockets[rChannel];
this.sockets[rChannel].bufferedStream.socket = this.sockets[rChannel]; this.sockets[rChannel].bufferedStream.on('readable', function () {
this.sockets[rChannel].bufferedStream.on('readable', function () if (this.socket.lme.txWindow > 0) {
{ var buffer = this.read(this.socket.lme.txWindow);
if(this.socket.lme.txWindow > 0) var packet = Buffer.alloc(9 + buffer.length);
{ packet.writeUInt8(APF_CHANNEL_DATA, 0);
var buffer = this.read(this.socket.lme.txWindow); packet.writeUInt32BE(this.socket.lme.amtId, 1);
var packet = Buffer.alloc(9 + buffer.length); packet.writeUInt32BE(buffer.length, 5);
packet.writeUInt8(APF_CHANNEL_DATA, 0); buffer.copy(packet, 9);
packet.writeUInt32BE(this.socket.lme.amtId, 1); this.socket.lme.txWindow -= buffer.length;
packet.writeUInt32BE(buffer.length, 5); this.socket.HECI.write(packet);
buffer.copy(packet, 9); }
this.socket.lme.txWindow -= buffer.length; });
this.socket.HECI.write(packet); this.sockets[rChannel].bufferedStream.on('drain', function () {
} this.socket.resume();
}); });
this.sockets[rChannel].bufferedStream.on('drain', function () this.sockets[rChannel].on('data', function (chunk) {
{ if (!this.bufferedStream.write(chunk)) { this.pause(); }
this.socket.resume(); });
}); this.sockets[rChannel].on('end', function () {
this.sockets[rChannel].on('data', function (chunk) var outBuffer = Buffer.alloc(5);
{ outBuffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
if (!this.bufferedStream.write(chunk)) { this.pause(); } outBuffer.writeUInt32BE(this.lme.amtId, 1);
}); this.HECI.write(outBuffer);
this.sockets[rChannel].on('end', function () });
{ this.sockets[rChannel].resume();
var outBuffer = Buffer.alloc(5); }
outBuffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
outBuffer.writeUInt32BE(this.lme.amtId, 1); break;
this.HECI.write(outBuffer); case APF_PROTOCOLVERSION:
});
this.sockets[rChannel].resume();
}
break;
case APF_PROTOCOLVERSION:
var major = chunk.readUInt32BE(1); var major = chunk.readUInt32BE(1);
var minor = chunk.readUInt32BE(5); var minor = chunk.readUInt32BE(5);
var reason = chunk.readUInt32BE(9); var reason = chunk.readUInt32BE(9);
@ -254,16 +241,13 @@ function lme_heci()
case APF_CHANNEL_WINDOW_ADJUST: case APF_CHANNEL_WINDOW_ADJUST:
var rChannelId = chunk.readUInt32BE(1); var rChannelId = chunk.readUInt32BE(1);
var bytesToAdd = chunk.readUInt32BE(5); var bytesToAdd = chunk.readUInt32BE(5);
if (this.sockets[rChannelId] != undefined) if (this.sockets[rChannelId] != undefined) {
{
this.sockets[rChannelId].lme.txWindow += bytesToAdd; this.sockets[rChannelId].lme.txWindow += bytesToAdd;
if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) {
{
this.sockets[rChannelId].bufferedStream.emit('readable'); this.sockets[rChannelId].bufferedStream.emit('readable');
} }
} }
else else {
{
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST'); //console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST');
} }
break; break;
@ -271,11 +255,9 @@ function lme_heci()
var rChannelId = chunk.readUInt32BE(1); var rChannelId = chunk.readUInt32BE(1);
var dataLen = chunk.readUInt32BE(5); var dataLen = chunk.readUInt32BE(5);
var data = chunk.slice(9, 9 + dataLen); var data = chunk.slice(9, 9 + dataLen);
if (this.sockets[rChannelId] != undefined) if (this.sockets[rChannelId] != undefined) {
{
this.sockets[rChannelId].pendingBytes.push(data.length); this.sockets[rChannelId].pendingBytes.push(data.length);
this.sockets[rChannelId].write(data, function () this.sockets[rChannelId].write(data, function () {
{
var written = this.pendingBytes.shift(); var written = this.pendingBytes.shift();
var outBuffer = Buffer.alloc(9); var outBuffer = Buffer.alloc(9);
outBuffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0); outBuffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
@ -284,35 +266,31 @@ function lme_heci()
this.HECI.write(outBuffer); this.HECI.write(outBuffer);
}); });
} }
else else {
{
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA'); //console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA');
} }
break; break;
case APF_CHANNEL_CLOSE: case APF_CHANNEL_CLOSE:
var rChannelId = chunk.readUInt32BE(1); var rChannelId = chunk.readUInt32BE(1);
if (this.sockets[rChannelId] != undefined) if (this.sockets[rChannelId] != undefined) {
{ this.sockets[rChannelId].end();
this.sockets[rChannelId].end();
var amtId = this.sockets[rChannelId].lme.amtId; var amtId = this.sockets[rChannelId].lme.amtId;
var buffer = Buffer.alloc(5); var buffer = Buffer.alloc(5);
delete this.sockets[rChannelId]; delete this.sockets[rChannelId];
buffer.writeUInt8(APF_CHANNEL_CLOSE, 0); buffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
buffer.writeUInt32BE(amtId, 1); buffer.writeUInt32BE(amtId, 1);
this.write(buffer); this.write(buffer);
} }
else else {
{
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE'); //console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE');
} }
break; break;
} }
}); });
}); });
this.bindDuplexStream = function (duplexStream, remoteFamily, localPort) this.bindDuplexStream = function (duplexStream, remoteFamily, localPort) {
{
var socket = duplexStream; var socket = duplexStream;
//console.log('New [' + remoteFamily + '] Virtual Connection/' + socket.localPort); //console.log('New [' + remoteFamily + '] Virtual Connection/' + socket.localPort);
socket.pendingBytes = []; socket.pendingBytes = [];
@ -327,19 +305,16 @@ function lme_heci()
buffer.writeUInt32BE(socket.lme.ourId); buffer.writeUInt32BE(socket.lme.ourId);
buffer.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE); buffer.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE);
buffer.writeUInt32BE(0xFFFFFFFF); buffer.writeUInt32BE(0xFFFFFFFF);
for (var i = 0; i < 2; ++i) for (var i = 0; i < 2; ++i) {
{ if (remoteFamily == 'IPv6') {
if (remoteFamily == 'IPv6')
{
buffer.writeUInt32BE(3); buffer.writeUInt32BE(3);
buffer.write('::1'); buffer.write('::1');
} }
else else {
{
buffer.writeUInt32BE(9); buffer.writeUInt32BE(9);
buffer.write('127.0.0.1'); buffer.write('127.0.0.1');
} }
buffer.writeUInt32BE(localPort); buffer.writeUInt32BE(localPort);
} }
this._LME.write(buffer.buffer); this._LME.write(buffer.buffer);
@ -347,7 +322,7 @@ function lme_heci()
this._LME.sockets[socket.lme.ourId] = socket; this._LME.sockets[socket.lme.ourId] = socket;
socket.pause(); socket.pause();
}; };
this._LME.connect(heci.GUIDS.LME, { noPipeline: 0 }); this._LME.connect(heci.GUIDS.LME, { noPipeline: 0 });
} }

View File

@ -148,10 +148,11 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
} }
} }
else if (cmdid == 15) { // MeshCommand_AgentTag else if (cmdid == 15) { // MeshCommand_AgentTag
ChangeAgentTag(msg.substring(2)); var tag = msg.substring(2);
while (tag.charCodeAt(tag.length - 1) == 0) { tag = tag.substring(0, tag.length - 1); } // Remove end-of-line zeros.
ChangeAgentTag(tag);
} }
} } else if (obj.authenticated < 2) { // We are not authenticated
else if (obj.authenticated < 2) { // We are not authenticated
var cmd = obj.common.ReadShort(msg, 0); var cmd = obj.common.ReadShort(msg, 0);
if (cmd == 1) { if (cmd == 1) {
// Agent authentication request // Agent authentication request

View File

@ -26,6 +26,14 @@ module.exports.CreateMeshMain = function (parent) {
var accountResetMailHtml = '<div style="font-family:Arial,Helvetica,sans-serif"><table style="background-color:#003366;color:lightgray;width:100%" cellpadding=8><tr><td><b style="font-size:20px;font-family:Arial,Helvetica,sans-serif">[[[SERVERNAME]]] - Verification</b></td></tr></table><p>Hi [[[USERNAME]]], <a href="[[[SERVERURL]]]">[[[SERVERNAME]]]</a> is requesting an account password reset, click on the following link to complete the process.</p><p style="margin-left:30px"><a href="[[[CALLBACKURL]]]">Click here to reset your account password.</a></p>If you did not initiate this request, please ignore this mail.</div>'; var accountResetMailHtml = '<div style="font-family:Arial,Helvetica,sans-serif"><table style="background-color:#003366;color:lightgray;width:100%" cellpadding=8><tr><td><b style="font-size:20px;font-family:Arial,Helvetica,sans-serif">[[[SERVERNAME]]] - Verification</b></td></tr></table><p>Hi [[[USERNAME]]], <a href="[[[SERVERURL]]]">[[[SERVERNAME]]]</a> is requesting an account password reset, click on the following link to complete the process.</p><p style="margin-left:30px"><a href="[[[CALLBACKURL]]]">Click here to reset your account password.</a></p>If you did not initiate this request, please ignore this mail.</div>';
var accountResetMailText = '[[[SERVERNAME]]] - Account Reset\r\n\r\nHi [[[USERNAME]]], [[[SERVERNAME]]] ([[[SERVERURL]]]) is requesting an account password reset. Nagivate to the following link to complete the process: [[[CALLBACKURL]]]\r\nIf you did not initiate this request, please ignore this mail.\r\n'; var accountResetMailText = '[[[SERVERNAME]]] - Account Reset\r\n\r\nHi [[[USERNAME]]], [[[SERVERNAME]]] ([[[SERVERURL]]]) is requesting an account password reset. Nagivate to the following link to complete the process: [[[CALLBACKURL]]]\r\nIf you did not initiate this request, please ignore this mail.\r\n';
// Default account invite mail
var accountInviteSubject = '[[[SERVERNAME]]] - Agent Installation Invitation';
var accountInviteMailHtml = '<div style="font-family:Arial,Helvetica,sans-serif"><table style="background-color:#003366;color:lightgray;width:100%" cellpadding=8><tr><td><b style="font-size:20px;font-family:Arial,Helvetica,sans-serif">[[[SERVERNAME]]] - Agent Installation</b></td></tr></table><p>User [[[USERNAME]]] on server <a href="[[[SERVERURL]]]">[[[SERVERNAME]]]</a> is requesting that you install a remote management agent. WARNING: this will allow the requester to <u>take control of your computer</u>. If you wish to do this, click on the following link to download the agent.</p><p style="margin-left:30px"><a href="[[[CALLBACKURL]]]">Click here to download the MeshAgent for Windows.</a></p>If you did not know about this request, please ignore this mail.</div>';
var accountInviteMailText = '[[[SERVERNAME]]] - Agent Installation Invitation\r\n\r\nUser [[[USERNAME]]] on server [[[SERVERNAME]]] ([[[SERVERURL]]]) is requesting you install a remote management agent. WARNING: This will allow the requester to take control of your computer. If you wish to do this, click on the following link to download the agent: [[[CALLBACKURL]]]\r\nIf you do not know about this request, please ignore this mail.\r\n';
function EscapeHtml(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
function EscapeHtmlBreaks(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/\r/g, '<br />').replace(/\n/g, '').replace(/\t/g, '&nbsp;&nbsp;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
// Setup mail server // Setup mail server
var options = { host: parent.config.smtp.host, secure: (parent.config.smtp.tls == true), tls: { rejectUnauthorized: false } }; var options = { host: parent.config.smtp.host, secure: (parent.config.smtp.tls == true), tls: { rejectUnauthorized: false } };
if (parent.config.smtp.port != null) { options.port = parent.config.smtp.port; } if (parent.config.smtp.port != null) { options.port = parent.config.smtp.port; }
@ -33,7 +41,7 @@ module.exports.CreateMeshMain = function (parent) {
obj.smtpServer = nodemailer.createTransport(options); obj.smtpServer = nodemailer.createTransport(options);
// Perform all e-mail substitution // Perform all e-mail substitution
function mailReplacements(text, domain, username, email, cookie) { function mailReplacements(text, domain, username, email, options) {
var url; var url;
if (domain.dns == null) { if (domain.dns == null) {
// Default domain or subdomain of the default. // Default domain or subdomain of the default.
@ -42,7 +50,10 @@ module.exports.CreateMeshMain = function (parent) {
// Domain with a DNS name. // Domain with a DNS name.
url = 'http' + ((obj.parent.args.notls == null) ? 's' : '') + '://' + domain.dns + ':' + obj.parent.args.port + domain.url; url = 'http' + ((obj.parent.args.notls == null) ? 's' : '') + '://' + domain.dns + ':' + obj.parent.args.port + domain.url;
} }
if (cookie != null) { text = text.split('[[[CALLBACKURL]]]').join(url + 'checkmail?c=' + cookie) } if (options) {
if (options.cookie != null) { text = text.split('[[[CALLBACKURL]]]').join(url + 'checkmail?c=' + options.cookie) }
if (options.meshid != null) { text = text.split('[[[CALLBACKURL]]]').join(url + 'meshagents?id=3&meshid=' + options.meshid.split('/')[2] + '&tag=mailto:' + EscapeHtml(email)) }
}
return text.split('[[[USERNAME]]]').join(username).split('[[[SERVERURL]]]').join(url).split('[[[SERVERNAME]]]').join(domain.title); return text.split('[[[USERNAME]]]').join(username).split('[[[SERVERURL]]]').join(url).split('[[[SERVERNAME]]]').join(domain.title);
} }
@ -54,17 +65,24 @@ module.exports.CreateMeshMain = function (parent) {
// Send account check mail // Send account check mail
obj.sendAccountCheckMail = function (domain, username, email) { obj.sendAccountCheckMail = function (domain, username, email) {
if ((parent.certificates == null) || (parent.certificates.CommonName == null)) return; // If the server name is not set, no reset possible. if ((parent.certificates == null) || (parent.certificates.CommonName == null) || (parent.certificates.CommonName == 'un-configured')) return; // If the server name is not set, no reset possible.
var cookie = obj.parent.encodeCookie({ u: domain.id + '/' + username, e: email, a: 1 }, obj.mailCookieEncryptionKey); var cookie = obj.parent.encodeCookie({ u: domain.id + '/' + username, e: email, a: 1 }, obj.mailCookieEncryptionKey);
obj.pendingMails.push({ to: email, from: parent.config.smtp.from, subject: mailReplacements(accountCheckSubject, domain, username, email), text: mailReplacements(accountCheckMailText, domain, username, email, cookie), html: mailReplacements(accountCheckMailHtml, domain, username, email, cookie) }); obj.pendingMails.push({ to: email, from: parent.config.smtp.from, subject: mailReplacements(accountCheckSubject, domain, username, email), text: mailReplacements(accountCheckMailText, domain, username, email, { cookie: cookie }), html: mailReplacements(accountCheckMailHtml, domain, username, email, { cookie: cookie }) });
sendNextMail(); sendNextMail();
} }
// Send account reset mail // Send account reset mail
obj.sendAccountResetMail = function (domain, username, email) { obj.sendAccountResetMail = function (domain, username, email) {
if ((parent.certificates == null) || (parent.certificates.CommonName == null)) return; // If the server name is not set, don't validate the email address. if ((parent.certificates == null) || (parent.certificates.CommonName == null) || (parent.certificates.CommonName == 'un-configured')) return; // If the server name is not set, don't validate the email address.
var cookie = obj.parent.encodeCookie({ u: domain.id + '/' + username, e: email, a: 2 }, obj.mailCookieEncryptionKey); var cookie = obj.parent.encodeCookie({ u: domain.id + '/' + username, e: email, a: 2 }, obj.mailCookieEncryptionKey);
obj.pendingMails.push({ to: email, from: parent.config.smtp.from, subject: mailReplacements(accountResetSubject, domain, username, email), text: mailReplacements(accountResetMailText, domain, username, email, cookie), html: mailReplacements(accountResetMailHtml, domain, username, email, cookie) }); obj.pendingMails.push({ to: email, from: parent.config.smtp.from, subject: mailReplacements(accountResetSubject, domain, username, email), text: mailReplacements(accountResetMailText, domain, username, email, { cookie: cookie }), html: mailReplacements(accountResetMailHtml, domain, username, email, { cookie: cookie }) });
sendNextMail();
}
// Send agent invite mail
obj.sendAgentInviteMail = function (domain, username, email, meshid) {
if ((parent.certificates == null) || (parent.certificates.CommonName == null) || (parent.certificates.CommonName == 'un-configured')) return; // If the server name is not set, can't do this.
obj.pendingMails.push({ to: email, from: parent.config.smtp.from, subject: mailReplacements(accountInviteSubject, domain, username, email), text: mailReplacements(accountInviteMailText, domain, username, email, { meshid: meshid }), html: mailReplacements(accountInviteMailHtml, domain, username, email, { meshid: meshid }) });
sendNextMail(); sendNextMail();
} }

View File

@ -427,7 +427,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
if ((command.meshtype == 1) || (command.meshtype == 2)) { if ((command.meshtype == 1) || (command.meshtype == 2)) {
// Create a type 1 agent-less Intel AMT mesh. // Create a type 1 agent-less Intel AMT mesh.
obj.parent.crypto.randomBytes(48, function (err, buf) { obj.parent.crypto.randomBytes(48, function (err, buf) {
var meshid = 'mesh/' + domain.id + '/' + buf.toString('base64').replace(/\+/g, '@').replace(/\//g, '$');; var meshid = 'mesh/' + domain.id + '/' + buf.toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
var links = {} var links = {}
links[user._id] = { name: user.name, rights: 0xFFFFFFFF }; links[user._id] = { name: user.name, rights: 0xFFFFFFFF };
var mesh = { type: 'mesh', _id: meshid, name: command.meshname, mtype: command.meshtype, desc: command.desc, domain: domain.id, links: links }; var mesh = { type: 'mesh', _id: meshid, name: command.meshname, mtype: command.meshtype, desc: command.desc, domain: domain.id, links: links };
@ -876,6 +876,25 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
}); });
break; break;
} }
case 'inviteAgent':
{
if (obj.parent.parent.mailserver == null) 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
// Get the mesh
var mesh = obj.parent.meshes[command.meshid];
if (mesh) {
if (mesh.mtype != 2) return; // This operation is only allowed for mesh type 2, agent mesh
// Check if this user has rights to do this
//if (mesh.links[user._id] == null || ((mesh.links[user._id].rights & 4) == 0)) return;
// Perform email invitation
obj.parent.parent.mailserver.sendAgentInviteMail(domain, user.name, command.email, command.meshid);
}
break;
}
} }
}); });

View File

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

View File

@ -1283,9 +1283,10 @@
} }
function ondockeydown(e) { function ondockeydown(e) {
if (!xxdialogMode && xxcurrentView == 11 && desktop) return desktop.m.handleKeyDown(e); if (!xxdialogMode && xxcurrentView == 11 && desktop) { return desktop.m.handleKeyDown(e); }
if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) return terminal.m.TermHandleKeyDown(e); if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) { return terminal.m.TermHandleKeyDown(e); }
if (!xxdialogMode && xxcurrentView == 13 && e.keyCode == 116 && p13filetree != null) { haltEvent(e); return false; } // F5 Refresh on files if (!xxdialogMode && xxcurrentView == 13 && e.keyCode == 116 && p13filetree != null) { haltEvent(e); return false; } // F5 Refresh on files
if (!xxdialogMode && xxcurrentView == 15) { return agentConsoleHandleKeys(e); }
if (xxdialogMode || xxcurrentView != 1 || e.ctrlKey == true || e.altKey == true || e.metaKey == true) return; if (xxdialogMode || xxcurrentView != 1 || e.ctrlKey == true || e.altKey == true || e.metaKey == true) return;
var processed = 0; var processed = 0;
if (Q('viewselect').value < 3) { if (Q('viewselect').value < 3) {
@ -1460,6 +1461,9 @@
} }
if (mesh.mtype == 2) { if (mesh.mtype == 2) {
r += ' <a style=cursor:pointer;font-size:10px title="Add a new computer to this mesh by installing the mesh agent." onclick=addAgentToMesh(\"' + mesh._id + '\")>Add Agent</a>'; r += ' <a style=cursor:pointer;font-size:10px title="Add a new computer to this mesh by installing the mesh agent." onclick=addAgentToMesh(\"' + mesh._id + '\")>Add Agent</a>';
if (features & 64) {
r += ' <a style=cursor:pointer;font-size:10px title="Invite someone to install the mesh agent." onclick=inviteAgentToMesh(\"' + mesh._id + '\")>Invite</a>';
}
} }
return r; return r;
} }
@ -1568,6 +1572,33 @@
QV('dlgAddCira2', val == 2); QV('dlgAddCira2', val == 2);
} }
// Return true is the input string looks like an email address
function checkEmail(str) {
var x = str.split('@');
var ok = ((x.length == 2) && (x[0].length > 0) && (x[1].split('.').length > 1) && (x[1].length > 2));
if (ok == true) { var y = x[1].split('.'); for (var i in y) { if (y[i].length == 0) { ok = false; } } }
return ok;
}
function inviteAgentToMesh(meshid) {
if (xxdialogMode) return;
var mesh = meshes[meshid];
var meshidx = meshid.substring(5);
if (meshidx[0] == '/') meshidx = meshidx.substring(1);
var x = "Invite someone to install the mesh agent. An email with be sent with the link to the mesh agent installation for " + EscapeHtml(mesh.name) + ".<br /><br />";
x += addHtmlValue('E-Mail', '<input id=agentInviteEmail style=width:240px onkeyup=validateAgentInvite()></input>');
setDialogMode(2, "Invite Mesh Agent", 3, performAgentInvite, x, meshid);
validateAgentInvite();
}
function validateAgentInvite() {
QE('idx_dlgOkButton', checkEmail(Q('agentInviteEmail').value));
}
function performAgentInvite(button, meshid) {
meshserver.Send({ action: 'inviteAgent', meshid: meshid, email: Q('agentInviteEmail').value });
}
function addAgentToMesh(meshid) { function addAgentToMesh(meshid) {
if (xxdialogMode) return; if (xxdialogMode) return;
var mesh = meshes[meshid]; var mesh = meshes[meshid];
@ -1580,7 +1611,7 @@
//x += "<div id=agins_windows>To add a new computer to mesh " + EscapeHtml(mesh.name) + ", download the mesh agent and configuration file and install the agent on the computer to manage.<br /><br />"; //x += "<div id=agins_windows>To add a new computer to mesh " + EscapeHtml(mesh.name) + ", download the mesh agent and configuration file and install the agent on the computer to manage.<br /><br />";
x += "<div id=agins_windows>To add a new computer to mesh " + EscapeHtml(mesh.name) + ", download the mesh agent and install it the computer to manage. This agent has server and mesh information embedded within it.<br /><br />"; x += "<div id=agins_windows>To add a new computer to mesh " + EscapeHtml(mesh.name) + ", download the mesh agent and install it the computer to manage. This agent has server and mesh information embedded within it.<br /><br />";
x += addHtmlValue('Mesh Agent', '<a href="meshagents?id=3&meshid=' + meshid.split('/')[2] + '" target="_blank">Windows executable (.exe)</a>'); x += addHtmlValue('Mesh Agent', '<a href="meshagents?id=3&meshid=' + meshid.split('/')[2] + '" target="_blank">Windows executable (.exe)</a>');
//x += addHtmlValue('Settings File', '<a href="meshsettings?id=' + meshid.split('/')[2] + '" target="_blank">' + EscapeHtml(mesh.name) + ' settings (.msh)</a>'); if (debugmode == true) { x += addHtmlValue('Settings File', '<a href="meshsettings?id=' + meshid.split('/')[2] + '" target="_blank">' + EscapeHtml(mesh.name) + ' settings (.msh)</a>'); }
x += "</div>"; x += "</div>";
// Linux agent install // Linux agent install
@ -2491,7 +2522,9 @@
// Attribute: Mesh Agent Tag // Attribute: Mesh Agent Tag
if ((node.agent != null) && (node.agent.tag != null)) { if ((node.agent != null) && (node.agent.tag != null)) {
x += addDeviceAttribute('Agent Tag', node.agent.tag); var tag = EscapeHtml(node.agent.tag);
if (tag.startsWith('mailto:')) { tag = '<a href="' + tag + '">' + tag.substring(7) + '</a>'; }
x += addDeviceAttribute('Agent Tag', tag);
} }
// Attribute: Intel AMT // Attribute: Intel AMT
@ -3664,7 +3697,6 @@
if (e.keyCode == 13 && consoleFocus == 0) { p15consoleSend(e); processed = 1; } if (e.keyCode == 13 && consoleFocus == 0) { p15consoleSend(e); processed = 1; }
else if (e.keyCode == 8 && consoleFocus == 0) { var x = box.value; box.value = x.substring(0, x.length - 1); processed = 1; } else if (e.keyCode == 8 && consoleFocus == 0) { var x = box.value; box.value = x.substring(0, x.length - 1); processed = 1; }
else if (e.keyCode == 27) { box.value = ''; processed = 1; } else if (e.keyCode == 27) { box.value = ''; processed = 1; }
else if (e.key.length === 1 && consoleFocus == 0) { box.value = ((box.value + e.key)); processed = 1; }
else if ((e.keyCode == 38) || (e.keyCode == 40)) { // Arrow up || Arrow down else if ((e.keyCode == 38) || (e.keyCode == 40)) { // Arrow up || Arrow down
var hindex = consoleHistory.indexOf(box.value); var hindex = consoleHistory.indexOf(box.value);
//console.log(hindex, consoleHistory); //console.log(hindex, consoleHistory);
@ -3673,12 +3705,27 @@
else if ((e.keyCode == 40) && (hindex == 0)) { box.value = ''; } else if ((e.keyCode == 40) && (hindex == 0)) { box.value = ''; }
processed = 1; processed = 1;
} }
else if (e.key.length === 1) {
//box.value = ((box.value + e.key));
insertTextAtCursor(box, e.key);
processed = 1;
}
} else { } else {
if (e.charCode != 0 && consoleFocus == 0) { box.value = ((box.value + String.fromCharCode(e.charCode))); processed = 1; } if (e.charCode != 0 && consoleFocus == 0) { box.value = ((box.value + String.fromCharCode(e.charCode))); processed = 1; }
} }
if (processed > 0) { return haltEvent(e); } if (processed > 0) { return haltEvent(e); }
} }
// Insert text at the cursor location on the
function insertTextAtCursor(ctrl, val) {
if (document.selection) { ctrl.focus(); sel = document.selection.createRange(); sel.text = val; }
else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
var start = ctrl.selectionStart, end = ctrl.selectionEnd;
ctrl.value = ctrl.value.substring(0, start) + val + ctrl.value.substring(end, ctrl.value.length);
ctrl.setSelectionRange(end + 1, end + 1);
} else { ctrl.value += myValue; }
}
var consoleNode; var consoleNode;
function setupConsole() { function setupConsole() {
// Setup the console // Setup the console

View File

@ -675,6 +675,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
user = obj.users[req.session.userid] user = obj.users[req.session.userid]
logoutcontrol = 'Welcome ' + user.name + '.'; logoutcontrol = 'Welcome ' + user.name + '.';
} }
// Give the web page a list of supported server features
var features = 0; var features = 0;
if (obj.args.wanonly == true) { features += 1; } // WAN-only mode if (obj.args.wanonly == true) { features += 1; } // WAN-only mode
if (obj.args.lanonly == true) { features += 2; } // LAN-only mode if (obj.args.lanonly == true) { features += 2; } // LAN-only mode
@ -682,6 +684,9 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
if (domain.userQuota == -1) { features += 8; } // No server files mode if (domain.userQuota == -1) { features += 8; } // No server files mode
if (obj.args.tlsoffload == true) { features += 16; } // No mutual-auth CIRA 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 ((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
// 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 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
res.render(obj.path.join(__dirname, 'views/default'), { viewmode: viewmode, currentNode: currentNode, logoutControl: logoutcontrol, title: domain.title, title2: domain.title2, domainurl: domain.url, domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: args.port, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, mpspass: args.mpspass, webcerthash: obj.webCertificateHashBase64, footer: (domain.footer == null) ? '' : domain.footer }); res.render(obj.path.join(__dirname, 'views/default'), { viewmode: viewmode, currentNode: currentNode, logoutControl: logoutcontrol, title: domain.title, title2: domain.title2, domainurl: domain.url, domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: args.port, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, mpspass: args.mpspass, webcerthash: obj.webCertificateHashBase64, footer: (domain.footer == null) ? '' : domain.footer });
} else { } else {
@ -1426,7 +1431,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
if (xdomain != '') xdomain += "/"; if (xdomain != '') xdomain += "/";
var meshsettings = "MeshName=" + mesh.name + "\r\nMeshType=" + mesh.mtype + "\r\nMeshID=0x" + meshidhex + "\r\nServerID=" + serveridhex + "\r\n"; var meshsettings = "MeshName=" + mesh.name + "\r\nMeshType=" + mesh.mtype + "\r\nMeshID=0x" + meshidhex + "\r\nServerID=" + serveridhex + "\r\n";
if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + getWebServerName(domain) + ":" + obj.args.port + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; } if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + getWebServerName(domain) + ":" + obj.args.port + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; }
if (req.query.tag != true) { meshsettings += "Tag=" + req.query.tag + "\r\n"; }
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=' + argentInfo.rname }); res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=' + argentInfo.rname });
obj.parent.exeHandler.streamExeWithMeshPolicy({ platform: 'win32', sourceFileName: obj.parent.meshAgentBinaries[req.query.id].path, destinationStream: res, msh: meshsettings, peinfo: obj.parent.meshAgentBinaries[req.query.id].pe }); obj.parent.exeHandler.streamExeWithMeshPolicy({ platform: 'win32', sourceFileName: obj.parent.meshAgentBinaries[req.query.id].path, destinationStream: res, msh: meshsettings, peinfo: obj.parent.meshAgentBinaries[req.query.id].pe });
}); });