mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-02-12 11:01:52 +00:00
Added improved KVM support to MeshCmd.exe and MeshAgent
This commit is contained in:
parent
2a54ebf9b9
commit
3dafa39e79
16 changed files with 1890 additions and 42 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -877,7 +877,7 @@ function startLms(func) {
|
|||
});
|
||||
amtLms.on('notify', function (data, options, str, code) {
|
||||
if (code == 'iAMT0052-3') {
|
||||
kvmGetData(true);
|
||||
kvmGetData();
|
||||
} else if (str != null) {
|
||||
var notify = { date: Date.now(), str: str, code: code };
|
||||
lmsNotifications.push(notify);
|
||||
|
@ -960,11 +960,18 @@ function setupMeiOsAdmin(func, state) {
|
|||
if (func) { func(state); }
|
||||
//var AllWsman = "CIM_SoftwareIdentity,IPS_SecIOService,IPS_ScreenSettingData,IPS_ProvisioningRecordLog,IPS_HostBasedSetupService,IPS_HostIPSettings,IPS_IPv6PortSettings".split(',');
|
||||
//osamtstack.BatchEnum(null, AllWsman, startLmsWsmanResponse, null, true);
|
||||
|
||||
//*************************************
|
||||
//tempTimer = setInterval(function () { kvmGetData(true); }, 2000);
|
||||
//kvmGetData(false);
|
||||
//kvmSetData(JSON.stringify({ action: 'restart', ver: 1 }));
|
||||
|
||||
// Setup KVM data channel if this is Intel AMT 12 or above
|
||||
amtMei.getVersion(function (x) {
|
||||
var amtver = null;
|
||||
try { for (var i in x.Versions) { if (x.Versions[i].Description == 'AMT') amtver = parseInt(x.Versions[i].Version.split('.')[0]); } } catch (e) {}
|
||||
if ((amtver != null) && (amtver >= 12)) {
|
||||
kvmGetData('skip'); // Clear any previous data, this is a dummy read to about handling old data.
|
||||
tempTimer = setInterval(function () { kvmGetData(); }, 2000); // Start polling for KVM data.
|
||||
kvmSetData(JSON.stringify({ action: 'restart', ver: 1 })); // Send a restart command to advise the console if present that MicroLMS just started.
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -973,20 +980,19 @@ function kvmGetData(tag) {
|
|||
}
|
||||
|
||||
function kvmDataGetResponse(stack, name, response, status, tag) {
|
||||
if ((tag == true) && (status == 200) && (response.Body.ReturnValue == 0)) {
|
||||
if ((tag != 'skip') && (status == 200) && (response.Body.ReturnValue == 0)) {
|
||||
var val = null;
|
||||
try { val = Buffer.from(response.Body.DataMessage, 'base64').toString(); } catch (e) { return }
|
||||
if (val != null) kvmProcessData(response.Body.RealmsBitmap, response.Body.MessageId, val);
|
||||
if (val != null) { kvmProcessData(response.Body.RealmsBitmap, response.Body.MessageId, val); }
|
||||
}
|
||||
}
|
||||
|
||||
var webRtcDesktop = null;
|
||||
function kvmProcessData(realms, messageId, val) {
|
||||
//console.log('kvmProcessData', val);
|
||||
var data = null;
|
||||
try { data = JSON.parse(val) } catch (e) { }
|
||||
if ((data != null) && (data.action)) {
|
||||
if (data.action == 'present') { kvmSetData(JSON.stringify({ action: 'present', ver: 1 })); }
|
||||
if (data.action == 'present') { kvmSetData(JSON.stringify({ action: 'present', ver: 1, platform: process.platform })); }
|
||||
if (data.action == 'offer') {
|
||||
webRtcDesktop = {};
|
||||
var rtc = require('ILibWebRTC');
|
||||
|
@ -997,9 +1003,10 @@ function kvmProcessData(realms, messageId, val) {
|
|||
webRtcDesktop.rtcchannel = rtcchannel;
|
||||
var kvmmodule = require('meshDesktop');
|
||||
webRtcDesktop.kvm = kvmmodule.getRemoteDesktopStream();
|
||||
webRtcDesktop.kvm.pipe(webRtcDesktop.rtcchannel, { end: false });
|
||||
webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm, { end: false });
|
||||
webRtcDesktop.kvm.pipe(webRtcDesktop.rtcchannel, { dataTypeSkip: 1, end: false });
|
||||
webRtcDesktop.rtcchannel.on('end', function () { webRtcCleanUp(); });
|
||||
webRtcDesktop.rtcchannel.on('data', function (x) { kvmCtrlData(this, x); });
|
||||
webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm, { dataTypeSkip: 1, end: false });
|
||||
//webRtcDesktop.kvm.on('end', function () { console.log('WebRTC DataChannel closed2'); webRtcCleanUp(); });
|
||||
//webRtcDesktop.rtcchannel.on('data', function (data) { console.log('WebRTC data: ' + data); });
|
||||
});
|
||||
|
@ -1008,6 +1015,190 @@ function kvmProcessData(realms, messageId, val) {
|
|||
}
|
||||
}
|
||||
|
||||
// Polyfill path.join
|
||||
var path = {
|
||||
join: function () {
|
||||
var x = [];
|
||||
for (var i in arguments) {
|
||||
var w = arguments[i];
|
||||
if (w != null) {
|
||||
while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
|
||||
if (i != 0) {
|
||||
while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); }
|
||||
}
|
||||
x.push(w);
|
||||
}
|
||||
}
|
||||
if (x.length == 0) return '/';
|
||||
return x.join('/');
|
||||
}
|
||||
};
|
||||
|
||||
// Get a formated response for a given directory path
|
||||
function getDirectoryInfo(reqpath) {
|
||||
var response = { path: reqpath, dir: [] };
|
||||
if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) {
|
||||
// List all the drives in the root, or the root itself
|
||||
var results = null;
|
||||
try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
|
||||
//console.log('a', objToString(results, 0, ' '));
|
||||
if (results != null) {
|
||||
for (var i = 0; i < results.length; ++i) {
|
||||
var drive = { n: results[i].name, t: 1 };
|
||||
if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons.
|
||||
response.dir.push(drive);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// List all the files and folders in this path
|
||||
if (reqpath == '') { reqpath = '/'; }
|
||||
var xpath = path.join(reqpath, '*');
|
||||
var results = null;
|
||||
|
||||
try { results = fs.readdirSync(xpath); } catch (e) { }
|
||||
if (results != null) {
|
||||
for (var i = 0; i < results.length; ++i) {
|
||||
if ((results[i] != '.') && (results[i] != '..')) {
|
||||
var stat = null, p = path.join(reqpath, results[i]);
|
||||
try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date
|
||||
if ((stat != null) && (stat != undefined)) {
|
||||
if (stat.isDirectory() == true) {
|
||||
response.dir.push({ n: results[i], t: 2, d: stat.mtime });
|
||||
} else {
|
||||
response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
// Process KVM control channel data
|
||||
function kvmCtrlData(channel, cmd) {
|
||||
if (cmd.length > 0 && cmd.charCodeAt(0) != 123) {
|
||||
// This is upload data
|
||||
if (this.fileupload != null) {
|
||||
cmd = Buffer.from(cmd, 'base64');
|
||||
var header = cmd.readUInt32BE(0);
|
||||
if ((header == 0x01000000) || (header == 0x01000001)) {
|
||||
fs.writeSync(this.fileupload.fp, cmd.slice(4));
|
||||
channel.write({ action: 'upload', sub: 'ack', reqid: this.fileupload.reqid });
|
||||
if (header == 0x01000001) { fs.closeSync(this.fileupload.fp); this.fileupload = null; } // Close the file
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//console.log('KVM Ctrl Data', cmd);
|
||||
|
||||
try { cmd = JSON.parse(cmd); } catch (ex) { console.error('Invalid JSON: ' + cmd); return; }
|
||||
if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
|
||||
switch (cmd.action) {
|
||||
case 'ls': {
|
||||
/*
|
||||
// Close the watcher if required
|
||||
var samepath = ((this.httprequest.watcher != undefined) && (cmd.path == this.httprequest.watcher.path));
|
||||
if ((this.httprequest.watcher != undefined) && (samepath == false)) {
|
||||
//console.log('Closing watcher: ' + this.httprequest.watcher.path);
|
||||
//this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!!
|
||||
delete this.httprequest.watcher;
|
||||
}
|
||||
*/
|
||||
|
||||
// Send the folder content to the browser
|
||||
var response = getDirectoryInfo(cmd.path);
|
||||
if (cmd.reqid != undefined) { response.reqid = cmd.reqid; }
|
||||
channel.write(response);
|
||||
|
||||
/*
|
||||
// Start the directory watcher
|
||||
if ((cmd.path != '') && (samepath == false)) {
|
||||
var watcher = fs.watch(cmd.path, onFileWatcher);
|
||||
watcher.tunnel = this.httprequest;
|
||||
watcher.path = cmd.path;
|
||||
this.httprequest.watcher = watcher;
|
||||
//console.log('Starting watcher: ' + this.httprequest.watcher.path);
|
||||
}
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case 'mkdir': {
|
||||
// Create a new empty folder
|
||||
fs.mkdirSync(cmd.path);
|
||||
break;
|
||||
}
|
||||
case 'rm': {
|
||||
// Remove many files or folders
|
||||
for (var i in cmd.delfiles) {
|
||||
var fullpath = path.join(cmd.path, cmd.delfiles[i]);
|
||||
try { fs.unlinkSync(fullpath); } catch (e) { console.log(e); }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'rename': {
|
||||
// Rename a file or folder
|
||||
var oldfullpath = path.join(cmd.path, cmd.oldname);
|
||||
var newfullpath = path.join(cmd.path, cmd.newname);
|
||||
try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); }
|
||||
break;
|
||||
}
|
||||
case 'download': {
|
||||
// Download a file, to browser
|
||||
var sendNextBlock = 0;
|
||||
if (cmd.sub == 'start') { // Setup the download
|
||||
if (this.filedownload != null) { channel.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||||
this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
|
||||
try { this.filedownload.f = fs.openSync(this.filedownload.path, 'rbN'); } catch (e) { channel.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||||
if (this.filedownload) { channel.write({ action: 'download', sub: 'start', id: cmd.id }); }
|
||||
} else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands
|
||||
if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; }
|
||||
}
|
||||
// Send the next download block(s)
|
||||
while (sendNextBlock > 0) {
|
||||
sendNextBlock--;
|
||||
var buf = new Buffer(4096);
|
||||
var len = fs.readSync(this.filedownload.f, buf, 4, 4092, null);
|
||||
this.filedownload.ptr += len;
|
||||
if (len < 4092) { buf.writeInt32BE(0x01000001, 0); fs.closeSync(this.filedownload.f); delete this.filedownload; sendNextBlock = 0; } else { buf.writeInt32BE(0x01000000, 0); }
|
||||
channel.write(buf.slice(0, len + 4).toString('base64')); // Write as Base64
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'upload': {
|
||||
// Upload a file, from browser
|
||||
if (cmd.sub == 'start') { // Start the upload
|
||||
if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); }
|
||||
if (!cmd.path || !cmd.name) break;
|
||||
this.fileupload = { reqid: cmd.reqid };
|
||||
var filepath = path.join(cmd.path, cmd.name);
|
||||
try { this.fileupload.fp = fs.openSync(filepath, 'wbN'); } catch (e) { }
|
||||
if (this.fileupload.fp) { channel.write({ action: 'upload', sub: 'start', reqid: this.fileupload.reqid }); } else { this.fileupload = null; channel.write({ action: 'upload', sub: 'error', reqid: this.fileupload.reqid }); }
|
||||
}
|
||||
else if (cmd.sub == 'cancel') { // Stop the upload
|
||||
if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); this.fileupload = null; }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'copy': {
|
||||
// Copy a bunch of files from scpath to dspath
|
||||
for (var i in cmd.names) {
|
||||
var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
|
||||
if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'move': {
|
||||
// Move a bunch of files from scpath to dspath
|
||||
for (var i in cmd.names) {
|
||||
var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
|
||||
if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function webRtcCleanUp() {
|
||||
if (webRtcDesktop == null) return;
|
||||
if (webRtcDesktop.rtcchannel) {
|
||||
|
|
|
@ -1335,12 +1335,16 @@ function createMeshCore(agent) {
|
|||
var lme_heci = require('amt-lme');
|
||||
amtLmsState = 1;
|
||||
amtLms = new lme_heci();
|
||||
amtLms.on('error', function (e) { amtLmsState = 0; amtLms = null; });
|
||||
amtLms.on('connect', function () { amtLmsState = 2; });
|
||||
amtLms.on('error', function (e) { amtLmsState = 0; amtLms = null; obj.setupMeiOsAdmin(null, 1); });
|
||||
amtLms.on('connect', function () { amtLmsState = 2; obj.setupMeiOsAdmin(null, 2); });
|
||||
//amtLms.on('bind', function (map) { });
|
||||
amtLms.on('notify', function (data, options, str) {
|
||||
if (str != null) { sendConsoleText('Intel AMT LMS: ' + str); }
|
||||
handleAmtNotification(data);
|
||||
amtLms.on('notify', function (data, options, str, code) {
|
||||
if (code == 'iAMT0052-3') {
|
||||
kvmGetData();
|
||||
} else {
|
||||
//if (str != null) { sendConsoleText('Intel AMT LMS: ' + str); }
|
||||
handleAmtNotification(data);
|
||||
}
|
||||
});
|
||||
} catch (e) { amtLmsState = -1; amtLms = null; }
|
||||
|
||||
|
@ -1369,10 +1373,288 @@ function createMeshCore(agent) {
|
|||
s.end = onWebSocketClosed;
|
||||
s.data = onWebSocketData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// KVM Data Channel
|
||||
//
|
||||
|
||||
obj.setupMeiOsAdmin = function(func, state) {
|
||||
amtMei.getLocalSystemAccount(function (x) {
|
||||
var transport = require('amt-wsman-duk');
|
||||
var wsman = require('amt-wsman');
|
||||
var amt = require('amt');
|
||||
oswsstack = new wsman(transport, '127.0.0.1', 16992, x.user, x.pass, false);
|
||||
obj.osamtstack = new amt(oswsstack);
|
||||
if (func) { func(state); }
|
||||
//var AllWsman = "CIM_SoftwareIdentity,IPS_SecIOService,IPS_ScreenSettingData,IPS_ProvisioningRecordLog,IPS_HostBasedSetupService,IPS_HostIPSettings,IPS_IPv6PortSettings".split(',');
|
||||
//obj.osamtstack.BatchEnum(null, AllWsman, startLmsWsmanResponse, null, true);
|
||||
//*************************************
|
||||
// Setup KVM data channel if this is Intel AMT 12 or above
|
||||
amtMei.getVersion(function (x) {
|
||||
var amtver = null;
|
||||
try { for (var i in x.Versions) { if (x.Versions[i].Description == 'AMT') amtver = parseInt(x.Versions[i].Version.split('.')[0]); } } catch (e) { }
|
||||
if ((amtver != null) && (amtver >= 12)) {
|
||||
obj.kvmGetData('skip'); // Clear any previous data, this is a dummy read to about handling old data.
|
||||
obj.kvmTempTimer = setInterval(function () { obj.kvmGetData(); }, 2000); // Start polling for KVM data.
|
||||
obj.kvmSetData(JSON.stringify({ action: 'restart', ver: 1 })); // Send a restart command to advise the console if present that MicroLMS just started.
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
obj.kvmGetData = function(tag) {
|
||||
obj.osamtstack.IPS_KVMRedirectionSettingData_DataChannelRead(obj.kvmDataGetResponse, tag);
|
||||
}
|
||||
|
||||
obj.kvmDataGetResponse = function (stack, name, response, status, tag) {
|
||||
if ((tag != 'skip') && (status == 200) && (response.Body.ReturnValue == 0)) {
|
||||
var val = null;
|
||||
try { val = Buffer.from(response.Body.DataMessage, 'base64').toString(); } catch (e) { return }
|
||||
if (val != null) { obj.kvmProcessData(response.Body.RealmsBitmap, response.Body.MessageId, val); }
|
||||
}
|
||||
}
|
||||
|
||||
var webRtcDesktop = null;
|
||||
obj.kvmProcessData = function (realms, messageId, val) {
|
||||
var data = null;
|
||||
try { data = JSON.parse(val) } catch (e) { }
|
||||
if ((data != null) && (data.action)) {
|
||||
if (data.action == 'present') { obj.kvmSetData(JSON.stringify({ action: 'present', ver: 1, platform: process.platform })); }
|
||||
if (data.action == 'offer') {
|
||||
webRtcDesktop = {};
|
||||
var rtc = require('ILibWebRTC');
|
||||
webRtcDesktop.webrtc = rtc.createConnection();
|
||||
webRtcDesktop.webrtc.on('connected', function () { });
|
||||
webRtcDesktop.webrtc.on('disconnected', function () { webRtcCleanUp(); });
|
||||
webRtcDesktop.webrtc.on('dataChannel', function (rtcchannel) {
|
||||
webRtcDesktop.rtcchannel = rtcchannel;
|
||||
webRtcDesktop.kvm = mesh.getRemoteDesktopStream();
|
||||
webRtcDesktop.kvm.pipe(webRtcDesktop.rtcchannel, { dataTypeSkip: 1, end: false });
|
||||
webRtcDesktop.rtcchannel.on('end', function () { obj.webRtcCleanUp(); });
|
||||
webRtcDesktop.rtcchannel.on('data', function (x) { obj.kvmCtrlData(this, x); });
|
||||
webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm, { dataTypeSkip: 1, end: false });
|
||||
//webRtcDesktop.kvm.on('end', function () { console.log('WebRTC DataChannel closed2'); webRtcCleanUp(); });
|
||||
//webRtcDesktop.rtcchannel.on('data', function (data) { console.log('WebRTC data: ' + data); });
|
||||
});
|
||||
obj.kvmSetData(JSON.stringify({ action: 'answer', ver: 1, sdp: webRtcDesktop.webrtc.setOffer(data.sdp) }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Polyfill path.join
|
||||
var path = {
|
||||
join: function () {
|
||||
var x = [];
|
||||
for (var i in arguments) {
|
||||
var w = arguments[i];
|
||||
if (w != null) {
|
||||
while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
|
||||
if (i != 0) { while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } }
|
||||
x.push(w);
|
||||
}
|
||||
}
|
||||
if (x.length == 0) return '/';
|
||||
return x.join('/');
|
||||
}
|
||||
};
|
||||
|
||||
// Get a formated response for a given directory path
|
||||
obj.getDirectoryInfo = function(reqpath) {
|
||||
var response = { path: reqpath, dir: [] };
|
||||
if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) {
|
||||
// List all the drives in the root, or the root itself
|
||||
var results = null;
|
||||
try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
|
||||
//console.log('a', objToString(results, 0, ' '));
|
||||
if (results != null) {
|
||||
for (var i = 0; i < results.length; ++i) {
|
||||
var drive = { n: results[i].name, t: 1 };
|
||||
if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons.
|
||||
response.dir.push(drive);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// List all the files and folders in this path
|
||||
if (reqpath == '') { reqpath = '/'; }
|
||||
var xpath = path.join(reqpath, '*');
|
||||
var results = null;
|
||||
|
||||
try { results = fs.readdirSync(xpath); } catch (e) { }
|
||||
if (results != null) {
|
||||
for (var i = 0; i < results.length; ++i) {
|
||||
if ((results[i] != '.') && (results[i] != '..')) {
|
||||
var stat = null, p = path.join(reqpath, results[i]);
|
||||
try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date
|
||||
if ((stat != null) && (stat != undefined)) {
|
||||
if (stat.isDirectory() == true) {
|
||||
response.dir.push({ n: results[i], t: 2, d: stat.mtime });
|
||||
} else {
|
||||
response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
// Process KVM control channel data
|
||||
obj.kvmCtrlData = function(channel, cmd) {
|
||||
if (cmd.length > 0 && cmd.charCodeAt(0) != 123) {
|
||||
// This is upload data
|
||||
if (this.fileupload != null) {
|
||||
cmd = Buffer.from(cmd, 'base64');
|
||||
var header = cmd.readUInt32BE(0);
|
||||
if ((header == 0x01000000) || (header == 0x01000001)) {
|
||||
fs.writeSync(this.fileupload.fp, cmd.slice(4));
|
||||
channel.write({ action: 'upload', sub: 'ack', reqid: this.fileupload.reqid });
|
||||
if (header == 0x01000001) { fs.closeSync(this.fileupload.fp); this.fileupload = null; } // Close the file
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//console.log('KVM Ctrl Data', cmd);
|
||||
|
||||
try { cmd = JSON.parse(cmd); } catch (ex) { console.error('Invalid JSON: ' + cmd); return; }
|
||||
if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
|
||||
switch (cmd.action) {
|
||||
case 'ls': {
|
||||
/*
|
||||
// Close the watcher if required
|
||||
var samepath = ((this.httprequest.watcher != undefined) && (cmd.path == this.httprequest.watcher.path));
|
||||
if ((this.httprequest.watcher != undefined) && (samepath == false)) {
|
||||
//console.log('Closing watcher: ' + this.httprequest.watcher.path);
|
||||
//this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!!
|
||||
delete this.httprequest.watcher;
|
||||
}
|
||||
*/
|
||||
|
||||
// Send the folder content to the browser
|
||||
var response = getDirectoryInfo(cmd.path);
|
||||
if (cmd.reqid != undefined) { response.reqid = cmd.reqid; }
|
||||
channel.write(response);
|
||||
|
||||
/*
|
||||
// Start the directory watcher
|
||||
if ((cmd.path != '') && (samepath == false)) {
|
||||
var watcher = fs.watch(cmd.path, onFileWatcher);
|
||||
watcher.tunnel = this.httprequest;
|
||||
watcher.path = cmd.path;
|
||||
this.httprequest.watcher = watcher;
|
||||
//console.log('Starting watcher: ' + this.httprequest.watcher.path);
|
||||
}
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case 'mkdir': {
|
||||
// Create a new empty folder
|
||||
fs.mkdirSync(cmd.path);
|
||||
break;
|
||||
}
|
||||
case 'rm': {
|
||||
// Remove many files or folders
|
||||
for (var i in cmd.delfiles) {
|
||||
var fullpath = path.join(cmd.path, cmd.delfiles[i]);
|
||||
try { fs.unlinkSync(fullpath); } catch (e) { console.log(e); }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'rename': {
|
||||
// Rename a file or folder
|
||||
try { fs.renameSync(path.join(cmd.path, cmd.oldname), path.join(cmd.path, cmd.newname)); } catch (e) { console.log(e); }
|
||||
break;
|
||||
}
|
||||
case 'download': {
|
||||
// Download a file, to browser
|
||||
var sendNextBlock = 0;
|
||||
if (cmd.sub == 'start') { // Setup the download
|
||||
if (this.filedownload != null) { channel.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||||
this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
|
||||
try { this.filedownload.f = fs.openSync(this.filedownload.path, 'rbN'); } catch (e) { channel.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||||
if (this.filedownload) { channel.write({ action: 'download', sub: 'start', id: cmd.id }); }
|
||||
} else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands
|
||||
if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; }
|
||||
}
|
||||
// Send the next download block(s)
|
||||
while (sendNextBlock > 0) {
|
||||
sendNextBlock--;
|
||||
var buf = new Buffer(4096);
|
||||
var len = fs.readSync(this.filedownload.f, buf, 4, 4092, null);
|
||||
this.filedownload.ptr += len;
|
||||
if (len < 4092) { buf.writeInt32BE(0x01000001, 0); fs.closeSync(this.filedownload.f); delete this.filedownload; sendNextBlock = 0; } else { buf.writeInt32BE(0x01000000, 0); }
|
||||
channel.write(buf.slice(0, len + 4).toString('base64')); // Write as Base64
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'upload': {
|
||||
// Upload a file, from browser
|
||||
if (cmd.sub == 'start') { // Start the upload
|
||||
if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); }
|
||||
if (!cmd.path || !cmd.name) break;
|
||||
this.fileupload = { reqid: cmd.reqid };
|
||||
var filepath = path.join(cmd.path, cmd.name);
|
||||
try { this.fileupload.fp = fs.openSync(filepath, 'wbN'); } catch (e) { }
|
||||
if (this.fileupload.fp) { channel.write({ action: 'upload', sub: 'start', reqid: this.fileupload.reqid }); } else { this.fileupload = null; channel.write({ action: 'upload', sub: 'error', reqid: this.fileupload.reqid }); }
|
||||
}
|
||||
else if (cmd.sub == 'cancel') { // Stop the upload
|
||||
if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); this.fileupload = null; }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'copy': {
|
||||
// Copy a bunch of files from scpath to dspath
|
||||
for (var i in cmd.names) {
|
||||
var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
|
||||
if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'move': {
|
||||
// Move a bunch of files from scpath to dspath
|
||||
for (var i in cmd.names) {
|
||||
var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
|
||||
if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
obj.webRtcCleanUp = function() {
|
||||
if (webRtcDesktop == null) return;
|
||||
if (webRtcDesktop.rtcchannel) {
|
||||
try { webRtcDesktop.rtcchannel.close(); } catch (e) { }
|
||||
try { webRtcDesktop.rtcchannel.removeAllListeners('data'); } catch (e) { }
|
||||
try { webRtcDesktop.rtcchannel.removeAllListeners('end'); } catch (e) { }
|
||||
delete webRtcDesktop.rtcchannel;
|
||||
}
|
||||
if (webRtcDesktop.webrtc) {
|
||||
try { webRtcDesktop.webrtc.close(); } catch (e) { }
|
||||
try { webRtcDesktop.webrtc.removeAllListeners('connected'); } catch (e) { }
|
||||
try { webRtcDesktop.webrtc.removeAllListeners('disconnected'); } catch (e) { }
|
||||
try { webRtcDesktop.webrtc.removeAllListeners('dataChannel'); } catch (e) { }
|
||||
delete webRtcDesktop.webrtc;
|
||||
}
|
||||
if (webRtcDesktop.kvm) {
|
||||
try { webRtcDesktop.kvm.end(); } catch (e) { }
|
||||
delete webRtcDesktop.kvm;
|
||||
}
|
||||
webRtcDesktop = null;
|
||||
}
|
||||
|
||||
obj.kvmSetData = function(x) {
|
||||
obj.osamtstack.IPS_KVMRedirectionSettingData_DataChannelWrite(Buffer.from(x).toString('base64'), function () { });
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
//
|
||||
// Module startup
|
||||
//
|
||||
|
||||
var xexports = null, mainMeshCore = null;
|
||||
try { xexports = module.exports; } catch (e) { }
|
||||
|
||||
|
|
|
@ -46,12 +46,12 @@ CheckInstallAgent() {
|
|||
# echo "Detecting computer type..."
|
||||
machinetype=$( uname -m )
|
||||
machineid=0
|
||||
if [ $machinetype == 'x86_64' ]
|
||||
if [ $machinetype == 'x86_64' ] || [ $machinetype == 'amd64' ]
|
||||
then
|
||||
# Linux x86, 64 bit
|
||||
machineid=6
|
||||
fi
|
||||
if [ $machinetype == 'x86' ]
|
||||
if [ $machinetype == 'x86' ] || [ $machinetype == 'i686' ]
|
||||
then
|
||||
# Linux x86, 32 bit
|
||||
machineid=5
|
||||
|
|
144
agents/modules_meshcore/amt-wsman-duk.js
Normal file
144
agents/modules_meshcore/amt-wsman-duk.js
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
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
|
||||
* @author Ylian Saint-Hilaire
|
||||
* @version v0.2.0c
|
||||
*/
|
||||
|
||||
// Construct a WSMAN communication object
|
||||
function CreateWsmanComm(/*host, port, user, pass, tls, extra*/)
|
||||
{
|
||||
var obj = {};
|
||||
obj.PendingAjax = []; // List of pending AJAX calls. When one frees up, another will start.
|
||||
obj.ActiveAjaxCount = 0; // Number of currently active AJAX calls
|
||||
obj.MaxActiveAjaxCount = 1; // Maximum number of activate AJAX calls at the same time.
|
||||
obj.FailAllError = 0; // Set this to non-zero to fail all AJAX calls with that error status, 999 causes responses to be silent.
|
||||
obj.digest = null;
|
||||
obj.RequestCount = 0;
|
||||
|
||||
if (arguments.length == 1 && typeof(arguments[0] == 'object'))
|
||||
{
|
||||
obj.host = arguments[0].host;
|
||||
obj.port = arguments[0].port;
|
||||
obj.authToken = arguments[0].authToken;
|
||||
obj.tls = arguments[0].tls;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.host = arguments[0];
|
||||
obj.port = arguments[1];
|
||||
obj.user = arguments[2];
|
||||
obj.pass = arguments[3];
|
||||
obj.tls = arguments[4];
|
||||
}
|
||||
|
||||
|
||||
// Private method
|
||||
// pri = priority, if set to 1, the call is high priority and put on top of the stack.
|
||||
obj.PerformAjax = function (postdata, callback, tag, pri, url, action) {
|
||||
if ((obj.ActiveAjaxCount == 0 || ((obj.ActiveAjaxCount < obj.MaxActiveAjaxCount) && (obj.challengeParams != null))) && obj.PendingAjax.length == 0) {
|
||||
// There are no pending AJAX calls, perform the call now.
|
||||
obj.PerformAjaxEx(postdata, callback, tag, url, action);
|
||||
} else {
|
||||
// If this is a high priority call, put this call in front of the array, otherwise put it in the back.
|
||||
if (pri == 1) { obj.PendingAjax.unshift([postdata, callback, tag, url, action]); } else { obj.PendingAjax.push([postdata, callback, tag, url, action]); }
|
||||
}
|
||||
}
|
||||
|
||||
// Private method
|
||||
obj.PerformNextAjax = function () {
|
||||
if (obj.ActiveAjaxCount >= obj.MaxActiveAjaxCount || obj.PendingAjax.length == 0) return;
|
||||
var x = obj.PendingAjax.shift();
|
||||
obj.PerformAjaxEx(x[0], x[1], x[2], x[3], x[4]);
|
||||
obj.PerformNextAjax();
|
||||
}
|
||||
|
||||
// Private method
|
||||
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
|
||||
|
||||
// We are in a DukTape environement
|
||||
if (obj.digest == null)
|
||||
{
|
||||
if (obj.authToken)
|
||||
{
|
||||
obj.digest = require('http-digest').create({ authToken: obj.authToken });
|
||||
}
|
||||
else
|
||||
{
|
||||
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, 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]);
|
||||
} else {
|
||||
response.acc = '';
|
||||
response.on('data', function (data2) { this.acc += data2; });
|
||||
response.on('end', function () { obj.gotNextMessages(response.acc, 'success', { status: response.statusCode }, [postdata, callback, tag]); });
|
||||
}
|
||||
});
|
||||
|
||||
// Send POST body, this work with binary.
|
||||
req.end(postdata);
|
||||
obj.ActiveAjaxCount++;
|
||||
return req;
|
||||
}
|
||||
|
||||
// AJAX specific private method
|
||||
obj.pendingAjaxCall = [];
|
||||
|
||||
// Private method
|
||||
obj.gotNextMessages = function (data, status, request, callArgs) {
|
||||
obj.ActiveAjaxCount--;
|
||||
if (obj.FailAllError == 999) return;
|
||||
//console.log("RECV: " + data); // DEBUG
|
||||
if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
|
||||
if (request.status != 200) { callArgs[1](null, request.status, callArgs[2]); return; }
|
||||
callArgs[1](data, 200, callArgs[2]);
|
||||
obj.PerformNextAjax();
|
||||
}
|
||||
|
||||
// Private method
|
||||
obj.gotNextMessagesError = function (request, status, errorThrown, callArgs) {
|
||||
obj.ActiveAjaxCount--;
|
||||
if (obj.FailAllError == 999) return;
|
||||
if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
|
||||
//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();
|
||||
}
|
||||
|
||||
// Cancel all pending queries with given status
|
||||
obj.CancelAllQueries = function (s) {
|
||||
while (obj.PendingAjax.length > 0) { var x = obj.PendingAjax.shift(); x[1](null, s, x[2]); }
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
module.exports = CreateWsmanComm;
|
211
agents/modules_meshcore/amt-wsman.js
Normal file
211
agents/modules_meshcore/amt-wsman.js
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
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
|
||||
* @author Ylian Saint-Hilaire
|
||||
* @version v0.2.0
|
||||
*/
|
||||
|
||||
// Construct a MeshServer object
|
||||
function WsmanStackCreateService(/*CreateWsmanComm, host, port, user, pass, tls, extra*/)
|
||||
{
|
||||
var obj = {_ObjectID: 'WSMAN'};
|
||||
//obj.onDebugMessage = null; // Set to a function if you want to get debug messages.
|
||||
obj.NextMessageId = 1; // Next message number, used to label WSMAN calls.
|
||||
obj.Address = '/wsman';
|
||||
obj.xmlParser = require('amt-xml');
|
||||
|
||||
if (arguments.length == 1 && typeof (arguments[0] == 'object'))
|
||||
{
|
||||
var CreateWsmanComm = arguments[0].transport;
|
||||
if (CreateWsmanComm) { obj.comm = new CreateWsmanComm(arguments[0]); }
|
||||
}
|
||||
else
|
||||
{
|
||||
var CreateWsmanComm = arguments[0];
|
||||
if (CreateWsmanComm) { obj.comm = new CreateWsmanComm(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]); }
|
||||
}
|
||||
|
||||
obj.PerformAjax = function PerformAjax(postdata, callback, tag, pri, namespaces) {
|
||||
if (namespaces == null) namespaces = '';
|
||||
obj.comm.PerformAjax('<?xml version=\"1.0\" encoding=\"utf-8\"?><Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns=\"http://www.w3.org/2003/05/soap-envelope\" ' + namespaces + '><Header><a:Action>' + postdata, function (data, status, tag) {
|
||||
if (status != 200) { callback(obj, null, { Header: { HttpError: status } }, status, tag); return; }
|
||||
var wsresponse = obj.xmlParser.ParseWsman(data);
|
||||
if (!wsresponse || wsresponse == null) { callback(obj, null, { Header: { HttpError: status } }, 601, tag); } else { callback(obj, wsresponse.Header["ResourceURI"], wsresponse, 200, tag); }
|
||||
}, tag, pri);
|
||||
}
|
||||
|
||||
// Private method
|
||||
//obj.Debug = function (msg) { /*console.log(msg);*/ }
|
||||
|
||||
// Cancel all pending queries with given status
|
||||
obj.CancelAllQueries = function CancelAllQueries(s) { obj.comm.CancelAllQueries(s); }
|
||||
|
||||
// Get the last element of a URI string
|
||||
obj.GetNameFromUrl = function (resuri) {
|
||||
var x = resuri.lastIndexOf("/");
|
||||
return (x == -1)?resuri:resuri.substring(x + 1);
|
||||
}
|
||||
|
||||
// Perform a WSMAN Subscribe operation
|
||||
obj.ExecSubscribe = function ExecSubscribe(resuri, delivery, url, callback, tag, pri, selectors, opaque, user, pass) {
|
||||
var digest = "", digest2 = "", opaque = "";
|
||||
if (user != null && pass != null) { digest = '<t:IssuedTokens xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:se="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><t:RequestSecurityTokenResponse><t:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</t:TokenType><t:RequestedSecurityToken><se:UsernameToken><se:Username>' + user + '</se:Username><se:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText">' + pass + '</se:Password></se:UsernameToken></t:RequestedSecurityToken></t:RequestSecurityTokenResponse></t:IssuedTokens>'; digest2 = '<w:Auth Profile="http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/http/digest"/>'; }
|
||||
if (opaque != null) { opaque = '<a:ReferenceParameters><m:arg>' + opaque + '</m:arg></a:ReferenceParameters>'; }
|
||||
if (delivery == 'PushWithAck') { delivery = 'dmtf.org/wbem/wsman/1/wsman/PushWithAck'; } else if (delivery == 'Push') { delivery = 'xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push'; }
|
||||
var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + digest + '</Header><Body><e:Subscribe><e:Delivery Mode="http://schemas.' + delivery + '"><e:NotifyTo><a:Address>' + url + '</a:Address>' + opaque + '</e:NotifyTo>' + digest2 + '</e:Delivery></e:Subscribe>';
|
||||
obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:m="http://x.com"');
|
||||
}
|
||||
|
||||
// Perform a WSMAN UnSubscribe operation
|
||||
obj.ExecUnSubscribe = function ExecUnSubscribe(resuri, callback, tag, pri, selectors) {
|
||||
var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + '</Header><Body><e:Unsubscribe/>';
|
||||
obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"');
|
||||
}
|
||||
|
||||
// Perform a WSMAN PUT operation
|
||||
obj.ExecPut = function ExecPut(resuri, putobj, callback, tag, pri, selectors) {
|
||||
var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Put</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + '</Header><Body>' + _PutObjToBodyXml(resuri, putobj);
|
||||
obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN CREATE operation
|
||||
obj.ExecCreate = function ExecCreate(resuri, putobj, callback, tag, pri, selectors) {
|
||||
var objname = obj.GetNameFromUrl(resuri);
|
||||
var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><g:" + objname + " xmlns:g=\"" + resuri + "\">";
|
||||
for (var n in putobj) { data += "<g:" + n + ">" + putobj[n] + "</g:" + n + ">" }
|
||||
obj.PerformAjax(data + "</g:" + objname + "></Body></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN DELETE operation
|
||||
obj.ExecDelete = function ExecDelete(resuri, putobj, callback, tag, pri) {
|
||||
var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(putobj) + "</Header><Body /></Envelope>";
|
||||
obj.PerformAjax(data, callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN GET operation
|
||||
obj.ExecGet = function ExecGet(resuri, callback, tag, pri) {
|
||||
obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body /></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN method call operation
|
||||
obj.ExecMethod = function ExecMethod(resuri, method, args, callback, tag, pri, selectors) {
|
||||
var argsxml = "";
|
||||
for (var i in args) { if (args[i] != null) { if (Array.isArray(args[i])) { for (var x in args[i]) { argsxml += "<r:" + i + ">" + args[i][x] + "</r:" + i + ">"; } } else { argsxml += "<r:" + i + ">" + args[i] + "</r:" + i + ">"; } } }
|
||||
obj.ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors);
|
||||
}
|
||||
|
||||
// Perform a WSMAN method call operation. The arguments are already formatted in XML.
|
||||
obj.ExecMethodXml = function ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors) {
|
||||
obj.PerformAjax(resuri + "/" + method + "</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><r:" + method + '_INPUT' + " xmlns:r=\"" + resuri + "\">" + argsxml + "</r:" + method + "_INPUT></Body></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN ENUM operation
|
||||
obj.ExecEnum = function ExecEnum(resuri, callback, tag, pri) {
|
||||
obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Enumerate xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\" /></Body></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN PULL operation
|
||||
obj.ExecPull = function ExecPull(resuri, enumctx, callback, tag, pri) {
|
||||
obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\"><EnumerationContext>" + enumctx + "</EnumerationContext><MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters></Pull></Body></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
function _PutObjToBodyXml(resuri, putObj) {
|
||||
if (!resuri || putObj == null) return '';
|
||||
var objname = obj.GetNameFromUrl(resuri);
|
||||
var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';
|
||||
|
||||
for (var prop in putObj) {
|
||||
if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue;
|
||||
if (putObj[prop] == null || typeof putObj[prop] === 'function') continue;
|
||||
if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) {
|
||||
result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>';
|
||||
var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector'];
|
||||
if (Array.isArray(selectorArray)) {
|
||||
for (var i=0; i< selectorArray.length; i++) {
|
||||
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
|
||||
}
|
||||
}
|
||||
else {
|
||||
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
|
||||
}
|
||||
result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>';
|
||||
}
|
||||
else {
|
||||
if (Array.isArray(putObj[prop])) {
|
||||
for (var i = 0; i < putObj[prop].length; i++) {
|
||||
result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>';
|
||||
}
|
||||
} else {
|
||||
result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result += '</r:' + objname + '>';
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
convert
|
||||
{ @Name: 'InstanceID', @AttrName: 'Attribute Value'}
|
||||
into
|
||||
' Name="InstanceID" AttrName="Attribute Value" '
|
||||
*/
|
||||
function _ObjectToXmlAttributes(objWithAttributes) {
|
||||
if(!objWithAttributes) return '';
|
||||
var result = ' ';
|
||||
for (var propName in objWithAttributes) {
|
||||
if (!objWithAttributes.hasOwnProperty(propName) || propName.indexOf('@') !== 0) continue;
|
||||
result += propName.substring(1) + '="' + objWithAttributes[propName] + '" ';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function _PutObjToSelectorsXml(selectorSet) {
|
||||
if (!selectorSet) return '';
|
||||
if (typeof selectorSet == 'string') return selectorSet;
|
||||
if (selectorSet['InstanceID']) return "<w:SelectorSet><w:Selector Name=\"InstanceID\">" + selectorSet['InstanceID'] + "</w:Selector></w:SelectorSet>";
|
||||
var result = '<w:SelectorSet>';
|
||||
for(var propName in selectorSet) {
|
||||
if (!selectorSet.hasOwnProperty(propName)) continue;
|
||||
result += '<w:Selector Name="' + propName + '">';
|
||||
if (selectorSet[propName]['ReferenceParameters']) {
|
||||
result += '<a:EndpointReference>';
|
||||
result += '<a:Address>' + selectorSet[propName]['Address'] + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + selectorSet[propName]['ReferenceParameters']['ResourceURI'] + '</w:ResourceURI><w:SelectorSet>';
|
||||
var selectorArray = selectorSet[propName]['ReferenceParameters']['SelectorSet']['Selector'];
|
||||
if (Array.isArray(selectorArray)) {
|
||||
for (var i = 0; i < selectorArray.length; i++) {
|
||||
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
|
||||
}
|
||||
} else {
|
||||
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
|
||||
}
|
||||
result += '</w:SelectorSet></a:ReferenceParameters></a:EndpointReference>';
|
||||
} else {
|
||||
result += selectorSet[propName];
|
||||
}
|
||||
result += '</w:Selector>';
|
||||
}
|
||||
result += '</w:SelectorSet>';
|
||||
return result;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
module.exports = WsmanStackCreateService;
|
1018
agents/modules_meshcore/amt.js
Normal file
1018
agents/modules_meshcore/amt.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -73,7 +73,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||
if (typeof msg == 'object') { msg = msg.toString('binary'); } // TODO: Could change this entire method to use Buffer instead of binary string
|
||||
|
||||
if (obj.authenticated == 2) { // We are authenticated
|
||||
if (msg.charCodeAt(0) == 123) { processAgentData(msg); }
|
||||
if ((obj.agentUpdate == null) && (msg.charCodeAt(0) == 123)) { processAgentData(msg); } // Only process JSON messages if meshagent update is not in progress
|
||||
if (msg.length < 2) return;
|
||||
var cmdid = obj.common.ReadShort(msg, 0);
|
||||
if (cmdid == 11) { // MeshCommand_CoreModuleHash
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.1.8-g",
|
||||
"version": "0.1.8-k",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
|
BIN
public/images/link5.png
Normal file
BIN
public/images/link5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 218 B |
|
@ -311,7 +311,7 @@
|
|||
<tr>
|
||||
<td style=width:auto valign=top>
|
||||
<div id="p10title">
|
||||
<h1><span id=p10deviceName></span> - General</h1>
|
||||
<h1>General - <span id=p10deviceName></span></h1>
|
||||
</div>
|
||||
<div id=p10html></div>
|
||||
</td>
|
||||
|
@ -327,7 +327,7 @@
|
|||
</div>
|
||||
<div id=p11 style=display:none>
|
||||
<div id="p11title">
|
||||
<h1 id=p11deviceNameHeader><span id=p11deviceName></span> - Desktop</h1>
|
||||
<h1 id=p11deviceNameHeader>Desktop - <span id=p11deviceName></span></h1>
|
||||
</div>
|
||||
<div id="p14warning" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showFeaturesDlg()">
|
||||
<div class=icon2 style="float:left;margin:7px"></div>
|
||||
|
@ -406,7 +406,7 @@
|
|||
</table>
|
||||
</div>
|
||||
<div id=p12 style=display:none>
|
||||
<div id="p12title"><h1><span id=p12deviceName></span> - Terminal</h1></div>
|
||||
<div id="p12title"><h1>Terminal - <span id=p12deviceName></span></h1></div>
|
||||
<div id="p12warning" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick=showFeaturesDlg()>
|
||||
<div class="icon2" style="float:left;margin:7px"></div>
|
||||
<div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Intel® AMT Redirection port or KVM feature is disabled<span id="p14warninga">, click here to enable it.</span></div>
|
||||
|
@ -461,7 +461,7 @@
|
|||
</table>
|
||||
</div>
|
||||
<div id=p13 style=display:none>
|
||||
<div id="p13title"><h1><span id=p13deviceName></span> - Files</h1></div>
|
||||
<div id="p13title"><h1>Files - <span id=p13deviceName></span></h1></div>
|
||||
<table id="p13toolbar" style="width: 100%" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td style="background-color:#C0C0C0;border-bottom:2px solid black;padding:2px">
|
||||
|
@ -518,11 +518,11 @@
|
|||
</table>
|
||||
</div>
|
||||
<div id=p14 style=display:none>
|
||||
<div id="p14title"><h1><span id=p14deviceName></span> - Intel® AMT</h1></div>
|
||||
<div id="p14title"><h1>Intel® AMT - <span id=p14deviceName></span></h1></div>
|
||||
<iframe id=p14iframe style="width:100%;height:650px;border:0;overflow:hidden" src="/commander.htm"></iframe>
|
||||
</div>
|
||||
<div id=p15 style=display:none>
|
||||
<div id="p15title"><h1><span id=p15deviceName></span> - Console</h1></div>
|
||||
<div id="p15title"><h1>Console - <span id=p15deviceName></span></h1></div>
|
||||
<table cellpadding=0 cellspacing=0 style="width:100%;padding:0px;padding:0px;margin-top:0px">
|
||||
<tr>
|
||||
<td style=background:#C0C0C0>
|
||||
|
@ -559,7 +559,7 @@
|
|||
</table>
|
||||
</div>
|
||||
<div id=p16 style=display:none>
|
||||
<div id="p16title"><h1><span id=p16deviceName></span> - Events</h1></div>
|
||||
<div id="p16title"><h1>Events - <span id=p16deviceName></span></h1></div>
|
||||
<div style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px>
|
||||
<div class=style7 style=width:16px;height:100%;float:left> </div>
|
||||
<div class=h1 style=height:100%;float:left> </div>
|
||||
|
@ -2116,20 +2116,22 @@
|
|||
if (x == '') {
|
||||
for (var d in nodes) { nodes[d].v = true; }
|
||||
} else {
|
||||
var rs = x.split(/\s+/).join('|'), rx = new RegExp(rs);
|
||||
for (var d in nodes) {
|
||||
nodes[d].v = (rx.test(nodes[d].name.toLowerCase())) || (nodes[d].rnamel != null && rx.test(nodes[d].rnamel.toLowerCase()));
|
||||
if ((nodes[d].v == false) && nodes[d].tags) {
|
||||
for (var s in nodes[d].tags) {
|
||||
if (rx.test(nodes[d].tags[s].toLowerCase())) {
|
||||
nodes[d].v = true;
|
||||
break;
|
||||
} else {
|
||||
nodes[d].v = false;
|
||||
try {
|
||||
var rs = x.split(/\s+/).join('|'), rx = new RegExp(rs); // In some cases (like +), this can throw an exception.
|
||||
for (var d in nodes) {
|
||||
nodes[d].v = (rx.test(nodes[d].name.toLowerCase())) || (nodes[d].rnamel != null && rx.test(nodes[d].rnamel.toLowerCase()));
|
||||
if ((nodes[d].v == false) && nodes[d].tags) {
|
||||
for (var s in nodes[d].tags) {
|
||||
if (rx.test(nodes[d].tags[s].toLowerCase())) {
|
||||
nodes[d].v = true;
|
||||
break;
|
||||
} else {
|
||||
nodes[d].v = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ex) { for (var d in nodes) { nodes[d].v = true; } }
|
||||
}
|
||||
updateDevices();
|
||||
}
|
||||
|
@ -2819,7 +2821,7 @@
|
|||
// Add node name
|
||||
var nname = EscapeHtml(node.name);
|
||||
if (nname.length == 0) { nname = '<i>None</i>'; }
|
||||
if ((meshrights & 4) != 0) { nname = '<span onclick=showEditNodeValueDialog(0) style=cursor:pointer>' + nname + '</span>'; }
|
||||
if ((meshrights & 4) != 0) { nname = '<span title="Click here to edit the server-side device name" onclick=showEditNodeValueDialog(0) style=cursor:pointer>' + nname + ' <img src="images/link5.png" /></span>'; }
|
||||
QH('p10deviceName', nname);
|
||||
QH('p11deviceName', nname);
|
||||
QH('p12deviceName', nname);
|
||||
|
@ -4084,7 +4086,7 @@
|
|||
QV('p13bigfail', false);
|
||||
QV('p13bigok', false);
|
||||
} else {
|
||||
p13dragtimer = setTimeout("QV('p13bigfail',false);QV('p13bigok',false);p13dragtimer=null;", 200);
|
||||
p13dragtimer = setTimeout(function () { QV('p13bigfail',false); QV('p13bigok',false); p13dragtimer=null; }, 10);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5041,7 +5043,7 @@
|
|||
QV('bigok', false);
|
||||
//QV('p5fileCatchAllInput', false);
|
||||
} else {
|
||||
p5dragtimer = setTimeout("QV('bigfail',false);QV('bigok',false);p5dragtimer=null;", 200);
|
||||
p5dragtimer = setTimeout(function () { QV('bigfail',false); QV('bigok',false); p5dragtimer=null; }, 10);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue