Improved MicroLMS and MeshCmd.
This commit is contained in:
parent
dd6c66d91d
commit
682573d262
|
@ -69,6 +69,7 @@
|
|||
<Compile Include="public\scripts\meshcentral.js" />
|
||||
<Compile Include="redirserver.js" />
|
||||
<Compile Include="webserver.js" />
|
||||
<Content Include="LICENSE" />
|
||||
<Content Include="package.json" />
|
||||
<Content Include="public\clickonce\minirouter\Application Files\MeshMiniRouter_1_0_0_70\MeshMiniRouter.application" />
|
||||
<Content Include="public\clickonce\minirouter\Application Files\MeshMiniRouter_1_0_0_70\MeshMiniRouter.exe.config.deploy" />
|
||||
|
@ -165,6 +166,7 @@
|
|||
<Content Include="public\styles\font-awesome\scss\_variables.scss" />
|
||||
<Content Include="public\styles\style.css" />
|
||||
<Content Include="readme.txt" />
|
||||
<Content Include="sample-config.json" />
|
||||
<Content Include="SourceFileList.txt" />
|
||||
<Content Include="views\default.handlebars" />
|
||||
<Content Include="views\download.handlebars" />
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -73,7 +73,7 @@ function createMeshCore(agent) {
|
|||
|
||||
// Try to load up the MEI module
|
||||
try {
|
||||
var amtMeiLib = require('amt_heci');
|
||||
var amtMeiLib = require('amt-mei');
|
||||
amtMeiConnected = 1;
|
||||
amtMei = new amtMeiLib();
|
||||
amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; sendPeriodicServerUpdate(); });
|
||||
|
@ -82,7 +82,7 @@ function createMeshCore(agent) {
|
|||
|
||||
// Try to load up the WIFI scanner
|
||||
try {
|
||||
var wifiScannerLib = require('WifiScanner');
|
||||
var wifiScannerLib = require('wifi-scanner');
|
||||
wifiScanner = new wifiScannerLib();
|
||||
wifiScanner.on('accessPoint', function (data) { sendConsoleText(JSON.stringify(data)); });
|
||||
} catch (e) { wifiScannerLib = null; wifiScanner = null; }
|
||||
|
@ -1211,7 +1211,7 @@ function createMeshCore(agent) {
|
|||
|
||||
// Launch LMS
|
||||
try {
|
||||
var lme_heci = require('lme_heci');
|
||||
var lme_heci = require('amt-lme');
|
||||
amtLmsState = 1;
|
||||
amtLms = new lme_heci();
|
||||
amtLms.on('error', function (e) { amtLmsState = 0; amtLms = null; });
|
||||
|
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
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 lme_id = 0; // Our next channel identifier
|
||||
var lme_port_offset = 0; // Debug: Set this to "-100" to bind to 16892 & 16893 and IN_ADDRANY. This is for LMS debugging.
|
||||
|
||||
// Documented in: https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/HTMLDocuments/MPSDocuments/Intel%20AMT%20Port%20Forwarding%20Protocol%20Reference%20Manual.pdf
|
||||
var APF_DISCONNECT = 1;
|
||||
var APF_SERVICE_REQUEST = 5;
|
||||
var APF_SERVICE_ACCEPT = 6;
|
||||
var APF_USERAUTH_REQUEST = 50;
|
||||
var APF_USERAUTH_FAILURE = 51;
|
||||
var APF_USERAUTH_SUCCESS = 52;
|
||||
var APF_GLOBAL_REQUEST = 80;
|
||||
var APF_REQUEST_SUCCESS = 81;
|
||||
var APF_REQUEST_FAILURE = 82;
|
||||
var APF_CHANNEL_OPEN = 90;
|
||||
var APF_CHANNEL_OPEN_CONFIRMATION = 91;
|
||||
var APF_CHANNEL_OPEN_FAILURE = 92;
|
||||
var APF_CHANNEL_WINDOW_ADJUST = 93;
|
||||
var APF_CHANNEL_DATA = 94;
|
||||
var APF_CHANNEL_CLOSE = 97;
|
||||
var APF_PROTOCOLVERSION = 192;
|
||||
|
||||
|
||||
function lme_object() {
|
||||
this.ourId = ++lme_id;
|
||||
this.amtId = -1;
|
||||
this.LME_CHANNEL_STATUS = 'LME_CS_FREE';
|
||||
this.txWindow = 0;
|
||||
this.rxWindow = 0;
|
||||
this.localPort = 0;
|
||||
this.errorCount = 0;
|
||||
}
|
||||
|
||||
function stream_bufferedWrite() {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
this.buffer = [];
|
||||
this._readCheckImmediate = undefined;
|
||||
|
||||
// Writable Events
|
||||
emitterUtils.createEvent('close');
|
||||
emitterUtils.createEvent('drain');
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('finish');
|
||||
emitterUtils.createEvent('pipe');
|
||||
emitterUtils.createEvent('unpipe');
|
||||
|
||||
// Readable Events
|
||||
emitterUtils.createEvent('readable');
|
||||
this.isEmpty = function () {
|
||||
return (this.buffer.length == 0);
|
||||
};
|
||||
this.isWaiting = function () {
|
||||
return (this._readCheckImmediate == undefined);
|
||||
};
|
||||
this.write = function (chunk) {
|
||||
for (var args in arguments) { if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; } }
|
||||
var tmp = Buffer.alloc(chunk.length);
|
||||
chunk.copy(tmp);
|
||||
this.buffer.push({ offset: 0, data: tmp });
|
||||
this.emit('readable');
|
||||
return (this.buffer.length == 0 ? true : false);
|
||||
};
|
||||
this.read = function () {
|
||||
var size = arguments.length == 0 ? undefined : arguments[0];
|
||||
var bytesRead = 0;
|
||||
var list = [];
|
||||
while ((size == undefined || bytesRead < size) && this.buffer.length > 0) {
|
||||
var len = this.buffer[0].data.length - this.buffer[0].offset;
|
||||
var offset = this.buffer[0].offset;
|
||||
|
||||
if (len > (size - bytesRead)) {
|
||||
// Only reading a subset
|
||||
list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead));
|
||||
this.buffer[0].offset += (size - bytesRead);
|
||||
bytesRead += (size - bytesRead);
|
||||
} else {
|
||||
// Reading the entire thing
|
||||
list.push(this.buffer[0].data.slice(offset));
|
||||
bytesRead += len;
|
||||
this.buffer.shift();
|
||||
}
|
||||
}
|
||||
this._readCheckImmediate = setImmediate(function (buffered) {
|
||||
buffered._readCheckImmediate = undefined;
|
||||
if (buffered.buffer.length == 0) {
|
||||
buffered.emit('drain'); // Drained
|
||||
} else {
|
||||
buffered.emit('readable'); // Not drained
|
||||
}
|
||||
}, this);
|
||||
return (Buffer.concat(list));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function lme_heci(options) {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('connect');
|
||||
emitterUtils.createEvent('notify');
|
||||
|
||||
if (options.debug == true) { lme_port_offset = -100; } // LMS debug mode
|
||||
|
||||
var heci = require('heci');
|
||||
this.INITIAL_RXWINDOW_SIZE = 4096;
|
||||
|
||||
this._LME = heci.create();
|
||||
this._LME.LMS = this;
|
||||
this._LME.on('error', function (e) { this.LMS.emit('error', e); });
|
||||
this._LME.on('connect', function () {
|
||||
this.LMS.emit('connect');
|
||||
this.on('data', function (chunk) {
|
||||
// this = HECI
|
||||
var cmd = chunk.readUInt8(0);
|
||||
//console.log('LME Command ' + cmd + ', ' + chunk.length + ' byte(s).');
|
||||
|
||||
switch (cmd) {
|
||||
default:
|
||||
console.log('Unhandled LME Command ' + cmd + ', ' + chunk.length + ' byte(s).');
|
||||
break;
|
||||
case APF_SERVICE_REQUEST:
|
||||
var nameLen = chunk.readUInt32BE(1);
|
||||
var name = chunk.slice(5, nameLen + 5);
|
||||
//console.log("Service Request for: " + name);
|
||||
if (name == 'pfwd@amt.intel.com' || name == 'auth@amt.intel.com') {
|
||||
var outBuffer = Buffer.alloc(5 + nameLen);
|
||||
outBuffer.writeUInt8(6, 0);
|
||||
outBuffer.writeUInt32BE(nameLen, 1);
|
||||
outBuffer.write(name.toString(), 5);
|
||||
this.write(outBuffer);
|
||||
//console.log('Answering APF_SERVICE_REQUEST');
|
||||
} else {
|
||||
//console.log('UNKNOWN APF_SERVICE_REQUEST');
|
||||
}
|
||||
break;
|
||||
case APF_GLOBAL_REQUEST:
|
||||
var nameLen = chunk.readUInt32BE(1);
|
||||
var name = chunk.slice(5, nameLen + 5).toString();
|
||||
|
||||
switch (name) {
|
||||
case 'tcpip-forward':
|
||||
var len = chunk.readUInt32BE(nameLen + 6);
|
||||
var port = chunk.readUInt32BE(nameLen + 10 + len);
|
||||
//console.log("[" + chunk.length + "/" + len + "] APF_GLOBAL_REQUEST for: " + name + " on port " + port);
|
||||
if (this[name] == undefined) { this[name] = {}; }
|
||||
if (this[name][port] != null) { // Close the existing binding
|
||||
for (var i in this.sockets) {
|
||||
var channel = this.sockets[i];
|
||||
if (channel.localPort == port) { this.sockets[i].end(); delete this.sockets[i]; } // Close this socket
|
||||
}
|
||||
}
|
||||
if (this[name][port] == null) { // Bind a new server socket if not already present
|
||||
this[name][port] = require('net').createServer();
|
||||
this[name][port].HECI = this;
|
||||
if (lme_port_offset == 0) {
|
||||
this[name][port].listen({ port: port, host: '127.0.0.1' }); // Normal mode
|
||||
} else {
|
||||
this[name][port].listen({ port: (port + lme_port_offset) }); // Debug mode
|
||||
}
|
||||
this[name][port].on('connection', function (socket) {
|
||||
//console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort);
|
||||
this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort - lme_port_offset);
|
||||
});
|
||||
}
|
||||
var outBuffer = Buffer.alloc(5);
|
||||
outBuffer.writeUInt8(81, 0);
|
||||
outBuffer.writeUInt32BE(port, 1);
|
||||
this.write(outBuffer);
|
||||
break;
|
||||
case 'cancel-tcpip-forward':
|
||||
var outBuffer = Buffer.alloc(1);
|
||||
outBuffer.writeUInt8(APF_REQUEST_SUCCESS, 0);
|
||||
this.write(outBuffer);
|
||||
break;
|
||||
case 'udp-send-to@amt.intel.com':
|
||||
var outBuffer = Buffer.alloc(1);
|
||||
outBuffer.writeUInt8(APF_REQUEST_FAILURE, 0);
|
||||
this.write(outBuffer);
|
||||
break;
|
||||
default:
|
||||
//console.log("Unknown APF_GLOBAL_REQUEST for: " + name);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case APF_CHANNEL_OPEN_CONFIRMATION:
|
||||
var rChannel = chunk.readUInt32BE(1);
|
||||
var sChannel = chunk.readUInt32BE(5);
|
||||
var wSize = chunk.readUInt32BE(9);
|
||||
//console.log('rChannel/' + rChannel + ', sChannel/' + sChannel + ', wSize/' + wSize);
|
||||
if (this.sockets[rChannel] != undefined) {
|
||||
this.sockets[rChannel].lme.amtId = sChannel;
|
||||
this.sockets[rChannel].lme.rxWindow = wSize;
|
||||
this.sockets[rChannel].lme.txWindow = wSize;
|
||||
this.sockets[rChannel].lme.LME_CHANNEL_STATUS = 'LME_CS_CONNECTED';
|
||||
//console.log('LME_CS_CONNECTED');
|
||||
this.sockets[rChannel].bufferedStream = new stream_bufferedWrite();
|
||||
this.sockets[rChannel].bufferedStream.socket = this.sockets[rChannel];
|
||||
this.sockets[rChannel].bufferedStream.on('readable', function () {
|
||||
if (this.socket.lme.txWindow > 0) {
|
||||
var buffer = this.read(this.socket.lme.txWindow);
|
||||
var packet = Buffer.alloc(9 + buffer.length);
|
||||
packet.writeUInt8(APF_CHANNEL_DATA, 0);
|
||||
packet.writeUInt32BE(this.socket.lme.amtId, 1);
|
||||
packet.writeUInt32BE(buffer.length, 5);
|
||||
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].on('data', function (chunk) {
|
||||
if (!this.bufferedStream.write(chunk)) { this.pause(); }
|
||||
});
|
||||
this.sockets[rChannel].on('end', function () {
|
||||
var outBuffer = Buffer.alloc(5);
|
||||
outBuffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
|
||||
outBuffer.writeUInt32BE(this.lme.amtId, 1);
|
||||
this.HECI.write(outBuffer);
|
||||
});
|
||||
this.sockets[rChannel].resume();
|
||||
}
|
||||
|
||||
break;
|
||||
case APF_PROTOCOLVERSION:
|
||||
var major = chunk.readUInt32BE(1);
|
||||
var minor = chunk.readUInt32BE(5);
|
||||
var reason = chunk.readUInt32BE(9);
|
||||
var outBuffer = Buffer.alloc(93);
|
||||
outBuffer.writeUInt8(192, 0);
|
||||
outBuffer.writeUInt32BE(1, 1);
|
||||
outBuffer.writeUInt32BE(0, 5);
|
||||
outBuffer.writeUInt32BE(reason, 9);
|
||||
//console.log('Answering PROTOCOL_VERSION');
|
||||
this.write(outBuffer);
|
||||
break;
|
||||
case APF_CHANNEL_WINDOW_ADJUST:
|
||||
var rChannelId = chunk.readUInt32BE(1);
|
||||
var bytesToAdd = chunk.readUInt32BE(5);
|
||||
if (this.sockets[rChannelId] != undefined) {
|
||||
this.sockets[rChannelId].lme.txWindow += bytesToAdd;
|
||||
if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) {
|
||||
this.sockets[rChannelId].bufferedStream.emit('readable');
|
||||
}
|
||||
} else {
|
||||
console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST');
|
||||
}
|
||||
break;
|
||||
case APF_CHANNEL_DATA:
|
||||
var rChannelId = chunk.readUInt32BE(1);
|
||||
var dataLen = chunk.readUInt32BE(5);
|
||||
var data = chunk.slice(9, 9 + dataLen);
|
||||
if (this.sockets[rChannelId] != undefined) {
|
||||
this.sockets[rChannelId].pendingBytes.push(data.length);
|
||||
this.sockets[rChannelId].write(data, function () {
|
||||
var written = this.pendingBytes.shift();
|
||||
//console.log('adjust', this.lme.amtId, written);
|
||||
var outBuffer = Buffer.alloc(9);
|
||||
outBuffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
|
||||
outBuffer.writeUInt32BE(this.lme.amtId, 1);
|
||||
outBuffer.writeUInt32BE(written, 5);
|
||||
this.HECI.write(outBuffer);
|
||||
});
|
||||
} else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) {
|
||||
var channel = this.insockets[rChannelId];
|
||||
if (channel.data == null) { channel.data = data.toString(); } else { channel.data += data.toString(); }
|
||||
channel.rxWindow += dataLen;
|
||||
//console.log('IN DATA', channel.rxWindow, channel.data.length, dataLen, channel.amtId, data.toString());
|
||||
var httpData = parseHttp(channel.data);
|
||||
if ((httpData != null) || (channel.data.length >= 8000)) {
|
||||
// Event the http data
|
||||
this.LMS.emit('notify', httpData, channel.options);
|
||||
|
||||
// Send channel close
|
||||
var buffer = Buffer.alloc(5);
|
||||
buffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
|
||||
buffer.writeUInt32BE(amtId, 1);
|
||||
this.write(buffer);
|
||||
} else {
|
||||
if (channel.rxWindow > 6000) {
|
||||
// Send window adjust
|
||||
var buffer = Buffer.alloc(9);
|
||||
buffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
|
||||
buffer.writeUInt32BE(channel.amtId, 1);
|
||||
buffer.writeUInt32BE(channel.rxWindow, 5);
|
||||
this.write(buffer);
|
||||
channel.rxWindow = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA');
|
||||
}
|
||||
break;
|
||||
case APF_CHANNEL_CLOSE:
|
||||
var rChannelId = chunk.readUInt32BE(1);
|
||||
if (this.sockets[rChannelId] != undefined) {
|
||||
this.sockets[rChannelId].end();
|
||||
var amtId = this.sockets[rChannelId].lme.amtId;
|
||||
var buffer = Buffer.alloc(5);
|
||||
delete this.sockets[rChannelId];
|
||||
|
||||
buffer.writeUInt8(APF_CHANNEL_CLOSE, 0); // ????????????????????????????
|
||||
buffer.writeUInt32BE(amtId, 1);
|
||||
this.write(buffer);
|
||||
} else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) {
|
||||
delete this.insockets[rChannelId];
|
||||
// Should I send a close back????
|
||||
} else {
|
||||
console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE');
|
||||
}
|
||||
break;
|
||||
case APF_CHANNEL_OPEN:
|
||||
var nameLen = chunk.readUInt32BE(1);
|
||||
var name = chunk.slice(5, nameLen + 5).toString();
|
||||
var channelSender = chunk.readUInt32BE(nameLen + 5);
|
||||
var initialWindowSize = chunk.readUInt32BE(nameLen + 9);
|
||||
var hostToConnectLen = chunk.readUInt32BE(nameLen + 17);
|
||||
var hostToConnect = chunk.slice(nameLen + 21, nameLen + 21 + hostToConnectLen).toString();
|
||||
var portToConnect = chunk.readUInt32BE(nameLen + 21 + hostToConnectLen);
|
||||
var originatorIpLen = chunk.readUInt32BE(nameLen + 25 + hostToConnectLen);
|
||||
var originatorIp = chunk.slice(nameLen + 29 + hostToConnectLen, nameLen + 29 + hostToConnectLen + originatorIpLen).toString();
|
||||
var originatorPort = chunk.readUInt32BE(nameLen + 29 + hostToConnectLen + originatorIpLen);
|
||||
//console.log('APF_CHANNEL_OPEN', name, channelSender, initialWindowSize, 'From: ' + originatorIp + ':' + originatorPort, 'To: ' + hostToConnect + ':' + portToConnect);
|
||||
|
||||
if (this.insockets == null) { this.insockets = {}; }
|
||||
var ourId = ++lme_id;
|
||||
var insocket = new lme_object();
|
||||
insocket.ourId = ourId;
|
||||
insocket.amtId = channelSender;
|
||||
insocket.txWindow = initialWindowSize;
|
||||
insocket.rxWindow = 0;
|
||||
insocket.options = { target: hostToConnect, targetPort: portToConnect, source: originatorIp, sourcePort: originatorPort };
|
||||
this.insockets[ourId] = insocket;
|
||||
|
||||
var buffer = Buffer.alloc(17);
|
||||
buffer.writeUInt8(APF_CHANNEL_OPEN_CONFIRMATION, 0);
|
||||
buffer.writeUInt32BE(channelSender, 1); // Intel AMT sender channel
|
||||
buffer.writeUInt32BE(ourId, 5); // Our receiver channel id
|
||||
buffer.writeUInt32BE(4000, 9); // Initial Window Size
|
||||
buffer.writeUInt32BE(0xFFFFFFFF, 13); // Reserved
|
||||
this.write(buffer);
|
||||
|
||||
/*
|
||||
var buffer = Buffer.alloc(17);
|
||||
buffer.writeUInt8(APF_CHANNEL_OPEN_FAILURE, 0);
|
||||
buffer.writeUInt32BE(channelSender, 1); // Intel AMT sender channel
|
||||
buffer.writeUInt32BE(2, 5); // Reason code
|
||||
buffer.writeUInt32BE(0, 9); // Reserved
|
||||
buffer.writeUInt32BE(0, 13); // Reserved
|
||||
this.write(buffer);
|
||||
console.log('Sent APF_CHANNEL_OPEN_FAILURE', channelSender);
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.bindDuplexStream = function (duplexStream, remoteFamily, localPort) {
|
||||
var socket = duplexStream;
|
||||
//console.log('New [' + remoteFamily + '] Virtual Connection/' + socket.localPort);
|
||||
socket.pendingBytes = [];
|
||||
socket.HECI = this._LME;
|
||||
socket.LMS = this;
|
||||
socket.lme = new lme_object();
|
||||
socket.lme.Socket = socket;
|
||||
socket.localPort = localPort;
|
||||
var buffer = new MemoryStream();
|
||||
buffer.writeUInt8(0x5A);
|
||||
buffer.writeUInt32BE(15);
|
||||
buffer.write('forwarded-tcpip');
|
||||
buffer.writeUInt32BE(socket.lme.ourId);
|
||||
buffer.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE);
|
||||
buffer.writeUInt32BE(0xFFFFFFFF);
|
||||
for (var i = 0; i < 2; ++i) {
|
||||
if (remoteFamily == 'IPv6') {
|
||||
buffer.writeUInt32BE(3);
|
||||
buffer.write('::1');
|
||||
} else {
|
||||
buffer.writeUInt32BE(9);
|
||||
buffer.write('127.0.0.1');
|
||||
}
|
||||
buffer.writeUInt32BE(localPort);
|
||||
}
|
||||
this._LME.write(buffer.buffer);
|
||||
if (this._LME.sockets == undefined) { this._LME.sockets = {}; }
|
||||
this._LME.sockets[socket.lme.ourId] = socket;
|
||||
socket.pause();
|
||||
};
|
||||
|
||||
this._LME.connect(heci.GUIDS.LME, { noPipeline: 0 });
|
||||
}
|
||||
|
||||
function parseHttp(httpData) {
|
||||
var i = httpData.indexOf('\r\n\r\n');
|
||||
if ((i == -1) || (httpData.length < (i + 2))) { return null; }
|
||||
var headers = require('http-headers')(httpData.substring(0, i), true);
|
||||
var contentLength = parseInt(headers['content-length']);
|
||||
if (httpData.length >= contentLength + i + 4) { return httpData.substring(i + 4, i + 4 + contentLength); }
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = lme_heci;
|
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
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');
|
||||
|
||||
function amt_heci() {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('connect');
|
||||
|
||||
var heci = require('heci');
|
||||
|
||||
this._amt = heci.create();
|
||||
this._amt.BiosVersionLen = 65;
|
||||
this._amt.UnicodeStringLen = 20;
|
||||
|
||||
this._amt.rq = new Q();
|
||||
this._amt.Parent = this;
|
||||
this._amt.on('error', function (e) { this.Parent.emit('error', e); });
|
||||
this._amt.on('connect', function () {
|
||||
this.Parent.emit('connect');
|
||||
this.on('data', function (chunk) {
|
||||
//console.log("Received: " + chunk.length + " bytes");
|
||||
var header = this.Parent.getCommand(chunk);
|
||||
//console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
|
||||
|
||||
var user = this.rq.deQueue();
|
||||
var params = user.optional;
|
||||
var callback = user.func;
|
||||
|
||||
params.unshift(header);
|
||||
callback.apply(this.Parent, params);
|
||||
});
|
||||
});
|
||||
this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
|
||||
|
||||
this.getCommand = function (chunk) {
|
||||
var command = chunk.length == 0 ? (this._amt.rq.peekQueue().cmd | 0x800000) : chunk.readUInt32LE(4);
|
||||
var ret = { IsResponse: (command & 0x800000) == 0x800000 ? true : false, Command: (command & 0x7FFFFF), Status: chunk.length != 0 ? chunk.readUInt32LE(12) : -1, Data: chunk.length != 0 ? chunk.slice(16) : null };
|
||||
return (ret);
|
||||
};
|
||||
|
||||
this.sendCommand = function () {
|
||||
if (arguments.length < 3 || typeof (arguments[0]) != 'number' || typeof (arguments[1]) != 'object' || typeof (arguments[2]) != 'function') { throw ('invalid parameters'); }
|
||||
var args = [];
|
||||
for (var i = 3; i < arguments.length; ++i) { args.push(arguments[i]); }
|
||||
|
||||
this._amt.rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args });
|
||||
|
||||
var header = Buffer.from('010100000000000000000000', 'hex');
|
||||
header.writeUInt32LE(arguments[0] | 0x04000000, 4);
|
||||
header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8);
|
||||
|
||||
this._amt.write(arguments[1] == null ? header : Buffer.concat([header, arguments[1]]));
|
||||
}
|
||||
|
||||
this.getVersion = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(26, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, this._amt.BiosVersionLen), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4);
|
||||
for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen) ; ++i) {
|
||||
val.Versions[i] = { Description: v.slice(2, v.readUInt16LE(0) + 2).toString(), Version: v.slice(4 + this._amt.UnicodeStringLen, 4 + this._amt.UnicodeStringLen + v.readUInt16LE(2 + this._amt.UnicodeStringLen)).toString() };
|
||||
v = v.slice(4 + (2 * this._amt.UnicodeStringLen));
|
||||
}
|
||||
opt.unshift(val);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
|
||||
this.getProvisioningState = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(17, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.state = header.Data.readUInt32LE(0);
|
||||
if (result.state < 3) { result.stateStr = ["PRE", "IN", "POST"][result.state]; }
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getProvisioningMode = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(8, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.mode = header.Data.readUInt32LE(0);
|
||||
if (result.mode < 4) { result.modeStr = ["NONE", "ENTERPRISE", "SMALL_BUSINESS", "REMOTE_ASSISTANCE"][result.mode]; }
|
||||
result.legacy = header.Data.readUInt32LE(4) == 0 ? false : true;
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getEHBCState = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(132, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
opt.unshift({ EHBC: header.Data.readUInt32LE(0) != 0 });
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getControlMode = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(107, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.controlMode = header.Data.readUInt32LE(0);
|
||||
if (result.controlMode < 3) { result.controlModeStr = ["NONE_RPAT", "CLIENT", "ADMIN", "REMOTE_ASSISTANCE"][result.controlMode]; }
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getMACAddresses = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(37, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
opt.unshift({ DedicatedMAC: header.Data.slice(0, 6).toString('hex:'), HostMAC: header.Data.slice(6, 12).toString('hex:') });
|
||||
} else { opt.unshift({ DedicatedMAC: null, HostMAC: null }); }
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getDnsSuffix = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(54, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var resultLen = header.Data.readUInt16LE(0);
|
||||
if (resultLen > 0) { opt.unshift(header.Data.slice(2, 2 + resultLen).toString()); } else { opt.unshift(null); }
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getHashHandles = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x2C, null, function (header, fn, opt) {
|
||||
var result = [];
|
||||
if (header.Status == 0) {
|
||||
var resultLen = header.Data.readUInt32LE(0);
|
||||
for (var i = 0; i < resultLen; ++i) {
|
||||
result.push(header.Data.readUInt32LE(4 + (4 * i)));
|
||||
}
|
||||
}
|
||||
opt.unshift(result);
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getCertHashEntry = function (handle, callback) {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
|
||||
var data = new Buffer(4);
|
||||
data.writeUInt32LE(handle, 0);
|
||||
|
||||
this.sendCommand(0x2D, data, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.isDefault = header.Data.readUInt32LE(0);
|
||||
result.isActive = header.Data.readUInt32LE(4);
|
||||
result.hashAlgorithm = header.Data.readUInt8(72);
|
||||
if (result.hashAlgorithm < 4) {
|
||||
result.hashAlgorithmStr = ["MD5", "SHA1", "SHA256", "SHA512"][result.hashAlgorithm];
|
||||
result.hashAlgorithmSize = [16, 20, 32, 64][result.hashAlgorithm];
|
||||
result.certificateHash = header.Data.slice(8, 8 + result.hashAlgorithmSize).toString('hex');
|
||||
}
|
||||
result.name = header.Data.slice(73 + 2, 73 + 2 + header.Data.readUInt16LE(73)).toString();
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getCertHashEntries = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
|
||||
this.getHashHandles(function (handles, fn, opt) {
|
||||
var entries = [];
|
||||
this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
|
||||
}, callback, optional);
|
||||
};
|
||||
this._getHashEntrySink = function (result, fn, opt, entries, handles) {
|
||||
entries.push(result);
|
||||
if (handles.length > 0) {
|
||||
this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
|
||||
} else {
|
||||
opt.unshift(entries);
|
||||
fn.apply(this, opt);
|
||||
}
|
||||
}
|
||||
this.getLocalSystemAccount = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt) {
|
||||
if (header.Data.length == 68) { opt.unshift({ user: header.Data.slice(0, 34).toString(), pass: header.Data.slice(34, 67).toString(), raw: header.Data }); } else { opt.unshift(null); }
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
this.unprovision = function (mode, callback) {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
var data = new Buffer(4);
|
||||
data.writeUInt32LE(mode, 0);
|
||||
this.sendCommand(16, data, function (header, fn, opt) {
|
||||
opt.unshift(header.Status);
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
this.startConfiguration = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x29, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.stopConfiguration = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x5E, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.openUserInitiatedConnection = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x44, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.closeUserInitiatedConnection = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x45, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.getRemoteAccessConnectionStatus = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x46, data, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var hostname = v.slice(14, header.Data.readUInt16LE(12) + 14).toString()
|
||||
opt.unshift({ status: header.Status, networkStatus: header.Data.readUInt32LE(0), remoteAccessStatus: header.Data.readUInt32LE(4), remoteAccessTrigger: header.Data.readUInt32LE(8), mpsHostname: hostname, raw: header.Data });
|
||||
} else {
|
||||
opt.unshift({ status: header.Status });
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
this.getProtocolVersion = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { opt.push(arguments[i]); }
|
||||
|
||||
heci.doIoctl(heci.IOCTL.HECI_VERSION, Buffer.alloc(5), Buffer.alloc(5), function (status, buffer, self, fn, opt) {
|
||||
if (status == 0) {
|
||||
var result = buffer.readUInt8(0).toString() + '.' + buffer.readUInt8(1).toString() + '.' + buffer.readUInt8(2).toString() + '.' + buffer.readUInt16BE(3).toString();
|
||||
opt.unshift(result);
|
||||
fn.apply(self, opt);
|
||||
}
|
||||
else {
|
||||
opt.unshift(null);
|
||||
fn.apply(self, opt);
|
||||
}
|
||||
}, this, callback, optional);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = amt_heci;
|
|
@ -0,0 +1,456 @@
|
|||
/*
|
||||
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
|
||||
* @author Ylian Saint-Hilaire
|
||||
* @version v0.1.0e
|
||||
*/
|
||||
|
||||
// Core functions
|
||||
script_functionTable1 = ['nop', 'jump', 'set', 'print', 'dialog', 'getitem', 'substr', 'indexof', 'split', 'join', 'length', 'jsonparse', 'jsonstr', 'add', 'substract', 'parseint', 'wsbatchenum', 'wsput', 'wscreate', 'wsdelete', 'wsexec', 'scriptspeed', 'wssubscribe', 'wsunsubscribe', 'readchar', 'signwithdummyca'];
|
||||
|
||||
// functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
script_functionTable2 = ['encodeuri', 'decodeuri', 'passwordcheck', 'atob', 'btoa', 'hex2str', 'str2hex', 'random', 'md5', 'maketoarray', 'readshort', 'readshortx', 'readint', 'readsint', 'readintx', 'shorttostr', 'shorttostrx', 'inttostr', 'inttostrx'];
|
||||
|
||||
// functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
script_functionTableX2 = [encodeURI, decodeURI, passwordcheck, window.atob.bind(window), window.btoa.bind(window), hex2rstr, rstr2hex, random, rstr_md5, MakeToArray, ReadShort, ReadShortX, ReadInt, ReadSInt, ReadIntX, ShortToStr, ShortToStrX, IntToStr, IntToStrX];
|
||||
|
||||
// Optional functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
script_functionTable3 = ['pullsystemstatus', 'pulleventlog', 'pullauditlog', 'pullcertificates', 'pullwatchdog', 'pullsystemdefense', 'pullhardware', 'pulluserinfo', 'pullremoteaccess', 'highlightblock', 'disconnect', 'getsidstring', 'getsidbytearray', 'pulleventsubscriptions'];
|
||||
|
||||
// Optional functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
script_functionTableX3 = [
|
||||
PullSystemStatus
|
||||
,
|
||||
// ###BEGIN###{EventLog}
|
||||
PullEventLog
|
||||
// ###END###{EventLog}
|
||||
,
|
||||
// ###BEGIN###{AuditLog}
|
||||
PullAuditLog
|
||||
// ###END###{AuditLog}
|
||||
,
|
||||
// ###BEGIN###{Certificates}
|
||||
PullCertificates
|
||||
// ###END###{Certificates}
|
||||
,
|
||||
// ###BEGIN###{AgentPresence}
|
||||
PullWatchdog
|
||||
// ###END###{AgentPresence}
|
||||
,
|
||||
// ###BEGIN###{SystemDefense}
|
||||
PullSystemDefense
|
||||
// ###END###{SystemDefense}
|
||||
,
|
||||
// ###BEGIN###{HardwareInfo}
|
||||
PullHardware
|
||||
// ###END###{HardwareInfo}
|
||||
,
|
||||
PullUserInfo
|
||||
,
|
||||
// ###BEGIN###{RemoteAccess}
|
||||
PullRemoteAccess
|
||||
// ###END###{RemoteAccess}
|
||||
,
|
||||
// ###BEGIN###{Scripting-Editor}
|
||||
script_HighlightBlock
|
||||
// ###END###{Scripting-Editor}
|
||||
,
|
||||
// ###BEGIN###{ComputerSelector}
|
||||
disconnect
|
||||
// ###END###{ComputerSelector}
|
||||
,
|
||||
function (runner, x) { return GetSidString(x); }
|
||||
,
|
||||
function (runner, x) { return GetSidByteArray(x); }
|
||||
,
|
||||
// ###BEGIN###{EventSubscriptions}
|
||||
PullEventSubscriptions
|
||||
// ###END###{EventSubscriptions}
|
||||
];
|
||||
|
||||
// Setup the script state
|
||||
function script_setup(binary, startvars) {
|
||||
var obj = { startvars:startvars };
|
||||
if (binary.length < 6) { console.error('Invalid script length'); return null; } // Script must have at least 6 byte header
|
||||
if (ReadInt(binary, 0) != 0x247D2945) { console.error('Invalid binary script'); return null; } // Check the script magic header
|
||||
if (ReadShort(binary, 4) > 1) { console.error('Unsupported script version'); return null; } // Check the script version
|
||||
obj.script = binary.substring(6);
|
||||
// obj.onStep;
|
||||
// obj.onConsole;
|
||||
|
||||
// Reset the script to the start
|
||||
obj.reset = function (stepspeed) {
|
||||
obj.stop();
|
||||
obj.ip = 0;
|
||||
obj.variables = startvars;
|
||||
obj.state = 1;
|
||||
}
|
||||
|
||||
// Start the script
|
||||
obj.start = function (stepspeed) {
|
||||
obj.stop();
|
||||
obj.stepspeed = stepspeed;
|
||||
if (stepspeed > 0) { obj.timer = setInterval(function () { obj.step() }, stepspeed); }
|
||||
}
|
||||
|
||||
// Stop the script
|
||||
obj.stop = function () {
|
||||
if (obj.timer != null) { clearInterval(obj.timer); }
|
||||
obj.timer = null;
|
||||
obj.stepspeed = 0;
|
||||
}
|
||||
|
||||
// function used to load and store variable values
|
||||
obj.getVar = function (name) { if (name == undefined) return undefined; return obj.getVarEx(name.split('.'), obj.variables); }
|
||||
obj.getVarEx = function (name, val) { try { if (name == undefined) return undefined; if (name.length == 0) return val; return obj.getVarEx(name.slice(1), val[name[0]]); } catch (e) { return null; } }
|
||||
obj.setVar = function (name, val) { obj.setVarEx(name.split('.'), obj.variables, val); }
|
||||
obj.setVarEx = function (name, vars, val) { if (name.length == 1) { vars[name[0]] = val; } else { obj.setVarEx(name.slice(1), vars[name[0]], val); } }
|
||||
|
||||
// Run the script one step forward
|
||||
obj.step = function () {
|
||||
if (obj.state != 1) return;
|
||||
if (obj.ip < obj.script.length) {
|
||||
var cmdid = ReadShort(obj.script, obj.ip);
|
||||
var cmdlen = ReadShort(obj.script, obj.ip + 2);
|
||||
var argcount = ReadShort(obj.script, obj.ip + 4);
|
||||
var argptr = obj.ip + 6;
|
||||
var args = [];
|
||||
|
||||
// Clear all temp variables (This is optional)
|
||||
for (var i in obj.variables) { if (i.startsWith('__')) { delete obj.variables[i]; } }
|
||||
|
||||
// Loop on each argument, moving forward by the argument length each time
|
||||
for (var i = 0; i < argcount; i++) {
|
||||
var arglen = ReadShort(obj.script, argptr);
|
||||
var argval = obj.script.substring(argptr + 2, argptr + 2 + arglen);
|
||||
var argtyp = argval.charCodeAt(0);
|
||||
argval = argval.substring(1);
|
||||
if (argtyp < 2) {
|
||||
// Get the value and replace all {var} with variable values
|
||||
while (argval.split("{").length > 1) { var t = argval.split("{").pop().split("}").shift(); argval = argval.replace('{' + t + '}', obj.getVar(t)); }
|
||||
if (argtyp == 1) { obj.variables['__' + i] = decodeURI(argval); argval = '__' + i; } // If argtyp is 1, this is a literal. Store in temp variable.
|
||||
args.push(argval);
|
||||
}
|
||||
if (argtyp == 2 || argtyp == 3) {
|
||||
obj.variables['__' + i] = ReadSInt(argval, 0);
|
||||
args.push('__' + i);
|
||||
}
|
||||
argptr += (2 + arglen);
|
||||
}
|
||||
|
||||
// Move instruction pointer forward by command size
|
||||
obj.ip += cmdlen;
|
||||
|
||||
// Get all variable values
|
||||
var argsval = [];
|
||||
for (var i = 0; i < 10; i++) { argsval.push(obj.getVar(args[i])); }
|
||||
var storeInArg0;
|
||||
|
||||
try {
|
||||
if (cmdid < 10000) {
|
||||
// Lets run the actual command
|
||||
switch (cmdid) {
|
||||
case 0: // nop
|
||||
break;
|
||||
case 1: // jump(label) or jump(label, a, compare, b)
|
||||
if (argsval[2]) {
|
||||
if (
|
||||
(argsval[2] == '<' && argsval[1] < argsval[3]) ||
|
||||
(argsval[2] == '<=' && argsval[1] <= argsval[3]) ||
|
||||
(argsval[2] == '!=' && argsval[1] != argsval[3]) ||
|
||||
(argsval[2] == '=' && argsval[1] == argsval[3]) ||
|
||||
(argsval[2] == '>=' && argsval[1] >= argsval[3]) ||
|
||||
(argsval[2] == '>' && argsval[1] > argsval[3])
|
||||
) { obj.ip = argsval[0]; }
|
||||
} else {
|
||||
obj.ip = argsval[0]; // Set the instruction pointer to the new location in the script
|
||||
}
|
||||
break;
|
||||
case 2: // set(variable, value)
|
||||
if (args[1] == undefined) delete obj.variables[args[0]]; else obj.setVar(args[0], argsval[1]);
|
||||
break;
|
||||
case 3: // print(message)
|
||||
if (obj.onConsole) { obj.onConsole(obj.toString(argsval[0]), obj); } else { console.log(obj.toString(argsval[0])); }
|
||||
// Q(obj.consoleid).value += () + '\n'); Q(obj.console).scrollTop = Q(obj.console).scrollHeight;
|
||||
break;
|
||||
case 4: // dialog(title, content, buttons)
|
||||
obj.state = 2;
|
||||
obj.dialog = true;
|
||||
setDialogMode(11, argsval[0], argsval[2], obj.xxStepDialogOk, argsval[1], obj);
|
||||
break;
|
||||
case 5: // getitem(a, b, c)
|
||||
for (var i in argsval[1]) { if (argsval[1][i][argsval[2]] == argsval[3]) { storeInArg0 = i; } };
|
||||
break;
|
||||
case 6: // substr(variable_dest, variable_src, index, len)
|
||||
storeInArg0 = argsval[1].substr(argsval[2], argsval[3]);
|
||||
break;
|
||||
case 7: // indexOf(variable_dest, variable_src, index, len)
|
||||
storeInArg0 = argsval[1].indexOf(argsval[2]);
|
||||
break;
|
||||
case 8: // split(variable_dest, variable_src, separator)
|
||||
storeInArg0 = argsval[1].split(argsval[2]);
|
||||
break;
|
||||
case 9: // join(variable_dest, variable_src, separator)
|
||||
storeInArg0 = argsval[1].join(argsval[2]);
|
||||
break;
|
||||
case 10: // length(variable_dest, variable_src)
|
||||
storeInArg0 = argsval[1].length;
|
||||
break;
|
||||
case 11: // jsonparse(variable_dest, json)
|
||||
storeInArg0 = JSON.parse(argsval[1]);
|
||||
break;
|
||||
case 12: // jsonstr(variable_dest, variable_src)
|
||||
storeInArg0 = JSON.stringify(argsval[1]);
|
||||
break;
|
||||
case 13: // add(variable_dest, variable_src, value)
|
||||
storeInArg0 = (argsval[1] + argsval[2]);
|
||||
break;
|
||||
case 14: // substract(variable_dest, variable_src, value)
|
||||
storeInArg0 = (argsval[1] - argsval[2]);
|
||||
break;
|
||||
case 15: // parseInt(variable_dest, variable_src)
|
||||
storeInArg0 = parseInt(argsval[1]);
|
||||
break;
|
||||
case 16: // wsbatchenum(name, objectList)
|
||||
obj.state = 2;
|
||||
obj.amtstack.BatchEnum(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
|
||||
break;
|
||||
case 17: // wsput(name, args)
|
||||
obj.state = 2;
|
||||
obj.amtstack.Put(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
|
||||
break;
|
||||
case 18: // wscreate(name, args)
|
||||
obj.state = 2;
|
||||
obj.amtstack.Create(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
|
||||
break;
|
||||
case 19: // wsdelete(name, args)
|
||||
obj.state = 2;
|
||||
obj.amtstack.Delete(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
|
||||
break;
|
||||
case 20: // wsexec(name, method, args, selectors)
|
||||
obj.state = 2;
|
||||
obj.amtstack.Exec(argsval[0], argsval[1], argsval[2], obj.xxWsmanReturn, obj, 0, argsval[3]);
|
||||
break;
|
||||
case 21: // Script Speed
|
||||
obj.stepspeed = argsval[0];
|
||||
if (obj.timer != null) { clearInterval(obj.timer); obj.timer = setInterval(function () { obj.step() }, obj.stepspeed); }
|
||||
break;
|
||||
case 22: // wssubscribe(name, delivery, url, selectors, opaque, user, pass)
|
||||
obj.state = 2;
|
||||
obj.amtstack.Subscribe(argsval[0], argsval[1], argsval[2], obj.xxWsmanReturn, obj, 0, argsval[3], argsval[4], argsval[5], argsval[6]);
|
||||
break;
|
||||
case 23: // wsunsubscribe(name, selectors)
|
||||
obj.state = 2;
|
||||
obj.amtstack.UnSubscribe(argsval[0], obj.xxWsmanReturn, obj, 0, argsval[1]);
|
||||
break;
|
||||
case 24: // readchar(str, pos)
|
||||
console.log(argsval[1], argsval[2], argsval[1].charCodeAt(argsval[2]));
|
||||
storeInArg0 = argsval[1].charCodeAt(argsval[2]);
|
||||
break;
|
||||
case 25: // signWithDummyCa
|
||||
// ###BEGIN###{Certificates}
|
||||
obj.state = 2;
|
||||
// DERKey, xxCaPrivateKey, certattributes, issuerattributes
|
||||
amtcert_signWithCaKey(argsval[0], null, argsval[1], { 'CN': 'Untrusted Root Certificate' }, obj.xxSignWithDummyCaReturn);
|
||||
// ###END###{Certificates}
|
||||
break;
|
||||
default: {
|
||||
obj.state = 9;
|
||||
console.error("Script Error, unknown command: " + cmdid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cmdid < 20000) {
|
||||
// functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
storeInArg0 = script_functionTableX2[cmdid - 10000](argsval[1], argsval[2], argsval[3], argsval[4], argsval[5], argsval[6]);
|
||||
} else {
|
||||
// Optional functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
if (script_functionTableX3 && script_functionTableX3[cmdid - 20000]) {
|
||||
storeInArg0 = script_functionTableX3[cmdid - 20000](obj, argsval[1], argsval[2], argsval[3], argsval[4], argsval[5], argsval[6]); // Note that optional calls start with "obj" as first argument.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (storeInArg0 != undefined) obj.setVar(args[0], storeInArg0);
|
||||
} catch (e) {
|
||||
if (typeof e == 'object') { e = e.message; }
|
||||
obj.setVar('_exception', e);
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.state == 1 && obj.ip >= obj.script.length) { obj.state = 0; obj.stop(); }
|
||||
if (obj.onStep) obj.onStep(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
obj.xxStepDialogOk = function (button) {
|
||||
obj.variables['DialogSelect'] = button;
|
||||
obj.state = 1;
|
||||
obj.dialog = false;
|
||||
if (obj.onStep) obj.onStep(obj);
|
||||
}
|
||||
|
||||
// ###BEGIN###{**ClosureAdvancedMode}
|
||||
obj.xxWsmanReturnFix = function (x) {
|
||||
if (!x || x == null) return;
|
||||
if (x.Header) { x['Header'] = x.Header; delete x.Header; }
|
||||
if (x.Body) { x['Body'] = x.Body; delete x.Body; }
|
||||
if (x.Responses) { x['Responses'] = x.Responses; delete x.Responses; }
|
||||
if (x.Response) { x['Response'] = x.Response; delete x.Response; }
|
||||
if (x.ReturnValueStr) { x['ReturnValueStr'] = x.ReturnValueStr; delete x.ReturnValueStr; }
|
||||
}
|
||||
// ###END###{**ClosureAdvancedMode}
|
||||
|
||||
obj.xxWsmanReturn = function (stack, name, responses, status) {
|
||||
// ###BEGIN###{**ClosureAdvancedMode}
|
||||
// This is required when Google Closure is used
|
||||
if (responses) {
|
||||
obj.xxWsmanReturnFix(responses);
|
||||
for (var i in responses) {
|
||||
obj.xxWsmanReturnFix(responses[i]);
|
||||
for (var j in responses[i]) { obj.xxWsmanReturnFix(responses[i][j]); }
|
||||
}
|
||||
}
|
||||
// ###END###{**ClosureAdvancedMode}
|
||||
obj.setVar(name, responses);
|
||||
obj.setVar('wsman_result', status);
|
||||
obj.setVar('wsman_result_str', ((httpErrorTable[status]) ? (httpErrorTable[status]) : ('Error #' + status)));
|
||||
obj.state = 1;
|
||||
if (obj.onStep) obj.onStep(obj);
|
||||
}
|
||||
|
||||
// ###BEGIN###{Certificates}
|
||||
obj.xxSignWithDummyCaReturn = function (cert) {
|
||||
obj.setVar('signed_cert', btoa(_arrayBufferToString(cert)));
|
||||
obj.state = 1;
|
||||
if (obj.onStep) obj.onStep(obj);
|
||||
}
|
||||
// ###END###{Certificates}
|
||||
|
||||
obj.toString = function (x) { if (typeof x == 'object') return JSON.stringify(x); return x; }
|
||||
|
||||
obj.reset();
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Argument types: 0 = Variable, 1 = String, 2 = Integer, 3 = Label
|
||||
function script_compile(script, onmsg) {
|
||||
var r = '', scriptlines = script.split('\n'), labels = {}, labelswap = [], swaps = [];
|
||||
// Go thru each script line and encode it
|
||||
for (var i in scriptlines) {
|
||||
var scriptline = scriptlines[i];
|
||||
if (scriptline.startsWith('##SWAP ')) { var x = scriptline.split(' '); if (x.length == 3) { swaps[x[1]] = x[2]; } } // Add a swap instance
|
||||
if (scriptline[0] == '#' || scriptline.length == 0) continue; // Skip comments & blank lines
|
||||
for (var x in swaps) { scriptline = scriptline.split(x).join(swaps[x]); } // Apply all swaps
|
||||
var keywords = scriptline.match(/"[^"]*"|[^\s"]+/g);
|
||||
if (keywords.length == 0) continue; // Skip blank lines
|
||||
if (scriptline[0] == ':') { labels[keywords[0].toUpperCase()] = r.length; continue; } // Mark a label position
|
||||
var funcIndex = script_functionTable1.indexOf(keywords[0].toLowerCase());
|
||||
if (funcIndex == -1) { funcIndex = script_functionTable2.indexOf(keywords[0].toLowerCase()); if (funcIndex >= 0) funcIndex += 10000; }
|
||||
if (funcIndex == -1) { funcIndex = script_functionTable3.indexOf(keywords[0].toLowerCase()); if (funcIndex >= 0) funcIndex += 20000; } // Optional methods
|
||||
if (funcIndex == -1) { if (onmsg) { onmsg("Unabled to compile, unknown command: " + keywords[0]); } return ''; }
|
||||
// Encode CommandId, CmdSize, ArgCount, Arg1Len, Arg1, Arg2Len, Arg2...
|
||||
var cmd = ShortToStr(keywords.length - 1);
|
||||
for (var j in keywords) {
|
||||
if (j == 0) continue;
|
||||
if (keywords[j][0] == ':') {
|
||||
labelswap.push([keywords[j], r.length + cmd.length + 7]); // Add a label swap
|
||||
cmd += ShortToStr(5) + String.fromCharCode(3) + IntToStr(0xFFFFFFFF); // Put an empty label
|
||||
} else {
|
||||
var argint = parseInt(keywords[j]);
|
||||
if (argint == keywords[j]) {
|
||||
cmd += ShortToStr(5) + String.fromCharCode(2) + IntToStr(argint);
|
||||
} else {
|
||||
if (keywords[j][0] == '"' && keywords[j][keywords[j].length - 1] == '"') {
|
||||
cmd += ShortToStr(keywords[j].length - 1) + String.fromCharCode(1) + keywords[j].substring(1, keywords[j].length - 1);
|
||||
} else {
|
||||
cmd += ShortToStr(keywords[j].length + 1) + String.fromCharCode(0) + keywords[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cmd = ShortToStr(funcIndex) + ShortToStr(cmd.length + 4) + cmd;
|
||||
r += cmd;
|
||||
}
|
||||
// Perform all the needed label swaps
|
||||
for (i in labelswap) {
|
||||
var label = labelswap[i][0].toUpperCase(), position = labelswap[i][1], target = labels[label];
|
||||
if (target == undefined) { if (onmsg) { onmsg("Unabled to compile, unknown label: " + label); } return ''; }
|
||||
r = r.substr(0, position) + IntToStr(target) + r.substr(position + 4);
|
||||
}
|
||||
return IntToStr(0x247D2945) + ShortToStr(1) + r;
|
||||
}
|
||||
|
||||
// Decompile the script, intended for debugging only
|
||||
function script_decompile(binary, onecmd) {
|
||||
var r = '', ptr = 6, labelcount = 0, labels = {};
|
||||
if (onecmd >= 0) {
|
||||
ptr = onecmd; // If we are decompiling just one command, set the ptr to that command.
|
||||
} else {
|
||||
if (binary.length < 6) { return '# Invalid script length'; }
|
||||
var magic = ReadInt(binary, 0);
|
||||
var version = ReadShort(binary, 4);
|
||||
if (magic != 0x247D2945) { return '# Invalid binary script: ' + magic; }
|
||||
if (version != 1) { return '# Invalid script version'; }
|
||||
}
|
||||
// Loop on each command, moving forward by the command length each time.
|
||||
while (ptr < binary.length) {
|
||||
var cmdid = ReadShort(binary, ptr);
|
||||
var cmdlen = ReadShort(binary, ptr + 2);
|
||||
var argcount = ReadShort(binary, ptr + 4);
|
||||
var argptr = ptr + 6;
|
||||
var argstr = '';
|
||||
if (!(onecmd >= 0)) r += ":label" + (ptr - 6) + "\n";
|
||||
// Loop on each argument, moving forward by the argument length each time
|
||||
for (var i = 0; i < argcount; i++) {
|
||||
var arglen = ReadShort(binary, argptr);
|
||||
var argval = binary.substring(argptr + 2, argptr + 2 + arglen);
|
||||
var argtyp = argval.charCodeAt(0);
|
||||
if (argtyp == 0) { argstr += ' ' + argval.substring(1); } // Variable
|
||||
else if (argtyp == 1) { argstr += ' \"' + argval.substring(1) + '\"'; } // String
|
||||
else if (argtyp == 2) { argstr += ' ' + ReadInt(argval, 1); } // Integer
|
||||
else if (argtyp == 3) { // Label
|
||||
var target = ReadInt(argval, 1);
|
||||
var label = labels[target];
|
||||
if (!label) { label = ":label" + target; labels[label] = target; }
|
||||
argstr += ' ' + label;
|
||||
}
|
||||
argptr += (2 + arglen);
|
||||
}
|
||||
// Go in the script function table to decode the function
|
||||
if (cmdid < 10000) {
|
||||
r += script_functionTable1[cmdid] + argstr + "\n";
|
||||
} else {
|
||||
if (cmdid >= 20000) {
|
||||
r += script_functionTable3[cmdid - 20000] + argstr + "\n"; // Optional methods
|
||||
} else {
|
||||
r += script_functionTable2[cmdid - 10000] + argstr + "\n";
|
||||
}
|
||||
}
|
||||
ptr += cmdlen;
|
||||
if (onecmd >= 0) return r; // If we are decompiling just one command, exit now
|
||||
}
|
||||
// Remove all unused labels
|
||||
var scriptlines = r.split('\n');
|
||||
r = '';
|
||||
for (var i in scriptlines) {
|
||||
var line = scriptlines[i];
|
||||
if (line[0] != ':') { r += line + '\n'; } else { if (labels[line]) { r += line + '\n'; } }
|
||||
}
|
||||
return r;
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
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.host = host;
|
||||
obj.port = port;
|
||||
obj.user = user;
|
||||
obj.pass = pass;
|
||||
obj.tls = tls;
|
||||
obj.digest = null;
|
||||
obj.RequestCount = 0;
|
||||
|
||||
// Private method
|
||||
// pri = priority, if set to 1, the call is high priority and put on top of the stack.
|
||||
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) { 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.write(postdata);
|
||||
req.end();
|
||||
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;
|
|
@ -0,0 +1,332 @@
|
|||
/*
|
||||
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 = {};
|
||||
//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.comm = new CreateWsmanComm(host, port, user, pass, tls, extra);
|
||||
|
||||
obj.PerformAjax = function (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.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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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);
|
||||
}
|
||||
|
||||
// Private method
|
||||
obj.ParseWsman = function (xml) {
|
||||
try {
|
||||
if (!xml.childNodes) xml = _turnToXml(xml);
|
||||
var r = { Header:{} }, header = xml.getElementsByTagName("Header")[0], t;
|
||||
if (!header) header = xml.getElementsByTagName("a:Header")[0];
|
||||
if (!header) return null;
|
||||
for (var i = 0; i < header.childNodes.length; i++) {
|
||||
var child = header.childNodes[i];
|
||||
r.Header[child.localName] = child.textContent;
|
||||
}
|
||||
var body = xml.getElementsByTagName("Body")[0];
|
||||
if (!body) body = xml.getElementsByTagName("a:Body")[0];
|
||||
if (!body) return null;
|
||||
if (body.childNodes.length > 0) {
|
||||
t = body.childNodes[0].localName;
|
||||
if (t.indexOf("_OUTPUT") == t.length - 7) { t = t.substring(0, t.length - 7); }
|
||||
r.Header['Method'] = t;
|
||||
r.Body = _ParseWsmanRec(body.childNodes[0]);
|
||||
}
|
||||
return r;
|
||||
} catch (e) {
|
||||
console.log("Unable to parse XML: " + xml);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Private method
|
||||
function _ParseWsmanRec(node) {
|
||||
var data, r = {};
|
||||
for (var i = 0; i < node.childNodes.length; i++) {
|
||||
var child = node.childNodes[i];
|
||||
if ((child.childElementCount == null) || (child.childElementCount == 0)) { data = child.textContent; } else { data = _ParseWsmanRec(child); }
|
||||
if (data == 'true') data = true; // Convert 'true' into true
|
||||
if (data == 'false') data = false; // Convert 'false' into false
|
||||
if ((parseInt(data) + '') === data) data = parseInt(data); // Convert integers
|
||||
|
||||
var childObj = data;
|
||||
if ((child.attributes != null) && (child.attributes.length > 0)) {
|
||||
childObj = { 'Value': data };
|
||||
for(var j = 0; j < child.attributes.length; j++) {
|
||||
childObj['@' + child.attributes[j].name] = child.attributes[j].value;
|
||||
}
|
||||
}
|
||||
|
||||
if (r[child.localName] instanceof Array) { r[child.localName].push(childObj); }
|
||||
else if (r[child.localName] == null) { r[child.localName] = childObj; }
|
||||
else { r[child.localName] = [r[child.localName], childObj]; }
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// This is a drop-in replacement to _turnToXml() that works without xml parser dependency.
|
||||
Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : null); } });
|
||||
function _treeBuilder() {
|
||||
this.tree = [];
|
||||
this.push = function (element) { this.tree.push(element); };
|
||||
this.pop = function () { var element = this.tree.pop(); if (this.tree.length > 0) { var x = this.tree.peek(); x.childNodes.push(element); x.childElementCount = x.childNodes.length; } return (element); };
|
||||
this.peek = function () { return (this.tree.peek()); }
|
||||
this.addNamespace = function (prefix, namespace) { this.tree.peek().nsTable[prefix] = namespace; if (this.tree.peek().attributes.length > 0) { for (var i = 0; i < this.tree.peek().attributes; ++i) { var a = this.tree.peek().attributes[i]; if (prefix == '*' && a.name == a.localName) { a.namespace = namespace; } else if (prefix != '*' && a.name != a.localName) { var pfx = a.name.split(':')[0]; if (pfx == prefix) { a.namespace = namespace; } } } } }
|
||||
this.getNamespace = function (prefix) { for (var i = this.tree.length - 1; i >= 0; --i) { if (this.tree[i].nsTable[prefix] != null) { return (this.tree[i].nsTable[prefix]); } } return null; }
|
||||
}
|
||||
function _turnToXml(text) { if (text == null) return null; return ({ childNodes: [_turnToXmlRec(text)], getElementsByTagName: _getElementsByTagName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS }); }
|
||||
function _getElementsByTagNameNS(ns, name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name && (node.namespace == ns || ns == '*')) { ret.push(node); } }); return ret; }
|
||||
function _getElementsByTagName(name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name) { ret.push(node); } }); return ret; }
|
||||
function _getChildElementsByTagName(name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name) { ret.push(this.childNodes[node]); } } } return (ret); }
|
||||
function _getChildElementsByTagNameNS(ns, name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name && (ns == '*' || this.childNodes[node].namespace == ns)) { ret.push(this.childNodes[node]); } } } return (ret); }
|
||||
function _xmlTraverseAllRec(nodes, func) { for (var i in nodes) { func(nodes[i]); if (nodes[i].childNodes) { _xmlTraverseAllRec(nodes[i].childNodes, func); } } }
|
||||
function _turnToXmlRec(text) {
|
||||
var elementStack = new _treeBuilder(), lastElement = null, x1 = text.split('<'), ret = [], element = null, currentElementName = null;
|
||||
for (var i in x1) {
|
||||
var x2 = x1[i].split('>'), x3 = x2[0].split(' '), elementName = x3[0];
|
||||
if ((elementName.length > 0) && (elementName[0] != '?')) {
|
||||
if (elementName[0] != '/') {
|
||||
var attributes = [], localName, localname2 = elementName.split(' ')[0].split(':'), localName = (localname2.length > 1) ? localname2[1] : localname2[0];
|
||||
Object.defineProperty(attributes, "get",
|
||||
{
|
||||
value: function () {
|
||||
if (arguments.length == 1) {
|
||||
for (var a in this) { if (this[a].name == arguments[0]) { return (this[a]); } }
|
||||
}
|
||||
else if (arguments.length == 2) {
|
||||
for (var a in this) { if (this[a].name == arguments[1] && (arguments[0] == '*' || this[a].namespace == arguments[0])) { return (this[a]); } }
|
||||
}
|
||||
else {
|
||||
throw ('attributes.get(): Invalid number of parameters');
|
||||
}
|
||||
}
|
||||
});
|
||||
elementStack.push({ name: elementName, localName: localName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS, getChildElementsByTagNameNS: _getChildElementsByTagNameNS, attributes: attributes, childNodes: [], nsTable: {} });
|
||||
// Parse Attributes
|
||||
if (x3.length > 0) {
|
||||
var skip = false;
|
||||
for (var j in x3) {
|
||||
if (x3[j] == '/') {
|
||||
// This is an empty Element
|
||||
elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
|
||||
elementStack.peek().textContent = '';
|
||||
lastElement = elementStack.pop();
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
var k = x3[j].indexOf('=');
|
||||
if (k > 0) {
|
||||
var attrName = x3[j].substring(0, k);
|
||||
var attrValue = x3[j].substring(k + 2, x3[j].length - 1);
|
||||
var attrNS = elementStack.getNamespace('*');
|
||||
|
||||
if (attrName == 'xmlns') {
|
||||
elementStack.addNamespace('*', attrValue);
|
||||
attrNS = attrValue;
|
||||
} else if (attrName.startsWith('xmlns:')) {
|
||||
elementStack.addNamespace(attrName.substring(6), attrValue);
|
||||
} else {
|
||||
var ax = attrName.split(':');
|
||||
if (ax.length == 2) { attrName = ax[1]; attrNS = elementStack.getNamespace(ax[0]); }
|
||||
}
|
||||
var x = { name: attrName, value: attrValue }
|
||||
if (attrNS != null) x.namespace = attrNS;
|
||||
elementStack.peek().attributes.push(x);
|
||||
}
|
||||
}
|
||||
if (skip) { continue; }
|
||||
}
|
||||
elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
|
||||
if (x2[1]) { elementStack.peek().textContent = x2[1]; }
|
||||
} else { lastElement = elementStack.pop(); }
|
||||
}
|
||||
}
|
||||
return lastElement;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
module.exports = WsmanStackCreateService;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
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 lme_id = 0;
|
||||
var lme_port_offset = 0; // Debug: Set this to "-100" to bind to 16892 & 16893 and IN_ADDRANY. This is for LMS debugging.
|
||||
|
||||
|
||||
var APF_DISCONNECT = 1;
|
||||
var APF_SERVICE_REQUEST = 5;
|
||||
var APF_SERVICE_ACCEPT = 6;
|
||||
var APF_USERAUTH_REQUEST = 50;
|
||||
var APF_USERAUTH_FAILURE = 51;
|
||||
var APF_USERAUTH_SUCCESS = 52;
|
||||
var APF_GLOBAL_REQUEST = 80;
|
||||
var APF_REQUEST_SUCCESS = 81;
|
||||
var APF_REQUEST_FAILURE = 82;
|
||||
var APF_CHANNEL_OPEN = 90;
|
||||
var APF_CHANNEL_OPEN_CONFIRMATION = 91;
|
||||
var APF_CHANNEL_OPEN_FAILURE = 92;
|
||||
var APF_CHANNEL_WINDOW_ADJUST = 93;
|
||||
var APF_CHANNEL_DATA = 94;
|
||||
var APF_CHANNEL_CLOSE = 97;
|
||||
var APF_PROTOCOLVERSION = 192;
|
||||
|
||||
|
||||
function lme_object() {
|
||||
this.ourId = ++lme_id;
|
||||
this.amtId = -1;
|
||||
this.LME_CHANNEL_STATUS = 'LME_CS_FREE';
|
||||
this.txWindow = 0;
|
||||
this.rxWindow = 0;
|
||||
this.localPort = 0;
|
||||
this.errorCount = 0;
|
||||
}
|
||||
|
||||
function stream_bufferedWrite() {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
this.buffer = [];
|
||||
this._readCheckImmediate = undefined;
|
||||
|
||||
// Writable Events
|
||||
emitterUtils.createEvent('close');
|
||||
emitterUtils.createEvent('drain');
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('finish');
|
||||
emitterUtils.createEvent('pipe');
|
||||
emitterUtils.createEvent('unpipe');
|
||||
|
||||
// Readable Events
|
||||
emitterUtils.createEvent('readable');
|
||||
this.isEmpty = function () {
|
||||
return (this.buffer.length == 0);
|
||||
};
|
||||
this.isWaiting = function () {
|
||||
return (this._readCheckImmediate == undefined);
|
||||
};
|
||||
this.write = function (chunk) {
|
||||
for (var args in arguments) { if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; } }
|
||||
var tmp = Buffer.alloc(chunk.length);
|
||||
chunk.copy(tmp);
|
||||
this.buffer.push({ offset: 0, data: tmp });
|
||||
this.emit('readable');
|
||||
return (this.buffer.length == 0 ? true : false);
|
||||
};
|
||||
this.read = function () {
|
||||
var size = arguments.length == 0 ? undefined : arguments[0];
|
||||
var bytesRead = 0;
|
||||
var list = [];
|
||||
while ((size == undefined || bytesRead < size) && this.buffer.length > 0) {
|
||||
var len = this.buffer[0].data.length - this.buffer[0].offset;
|
||||
var offset = this.buffer[0].offset;
|
||||
|
||||
if (len > (size - bytesRead)) {
|
||||
// Only reading a subset
|
||||
list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead));
|
||||
this.buffer[0].offset += (size - bytesRead);
|
||||
bytesRead += (size - bytesRead);
|
||||
} else {
|
||||
// Reading the entire thing
|
||||
list.push(this.buffer[0].data.slice(offset));
|
||||
bytesRead += len;
|
||||
this.buffer.shift();
|
||||
}
|
||||
}
|
||||
this._readCheckImmediate = setImmediate(function (buffered) {
|
||||
buffered._readCheckImmediate = undefined;
|
||||
if (buffered.buffer.length == 0) {
|
||||
buffered.emit('drain'); // Drained
|
||||
} else {
|
||||
buffered.emit('readable'); // Not drained
|
||||
}
|
||||
}, this);
|
||||
return (Buffer.concat(list));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function lme_heci(options) {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('connect');
|
||||
|
||||
if (options.debug == true) { lme_port_offset = -100; } // LMS debug mode
|
||||
|
||||
var heci = require('heci');
|
||||
this.INITIAL_RXWINDOW_SIZE = 4096;
|
||||
|
||||
this._LME = heci.create();
|
||||
this._LME.LMS = this;
|
||||
this._LME.on('error', function (e) { this.LMS.emit('error', e); });
|
||||
this._LME.on('connect', function () {
|
||||
this.LMS.emit('connect');
|
||||
this.on('data', function (chunk) {
|
||||
// this = HECI
|
||||
var cmd = chunk.readUInt8(0);
|
||||
|
||||
switch (cmd) {
|
||||
default:
|
||||
//console.log('Received ' + chunk.length + ' bytes of data for LMS');
|
||||
//console.log('Command = ' + cmd);
|
||||
break;
|
||||
case APF_SERVICE_REQUEST:
|
||||
var nameLen = chunk.readUInt32BE(1);
|
||||
var name = chunk.slice(5, nameLen + 5);
|
||||
//console.log("Service Request for: " + name);
|
||||
if (name == 'pfwd@amt.intel.com' || name == 'auth@amt.intel.com') {
|
||||
var outBuffer = Buffer.alloc(5 + nameLen);
|
||||
outBuffer.writeUInt8(6, 0);
|
||||
outBuffer.writeUInt32BE(nameLen, 1);
|
||||
outBuffer.write(name.toString(), 5);
|
||||
this.write(outBuffer);
|
||||
//console.log('Answering APF_SERVICE_REQUEST');
|
||||
} else {
|
||||
//console.log('UNKNOWN APF_SERVICE_REQUEST');
|
||||
}
|
||||
break;
|
||||
case APF_GLOBAL_REQUEST:
|
||||
var nameLen = chunk.readUInt32BE(1);
|
||||
var name = chunk.slice(5, nameLen + 5).toString();
|
||||
|
||||
switch (name) {
|
||||
case 'tcpip-forward':
|
||||
var len = chunk.readUInt32BE(nameLen + 6);
|
||||
var port = chunk.readUInt32BE(nameLen + 10 + len);
|
||||
//console.log("[" + chunk.length + "/" + len + "] APF_GLOBAL_REQUEST for: " + name + " on port " + port);
|
||||
if (this[name] == undefined) {
|
||||
this[name] = {};
|
||||
}
|
||||
this[name][port] = require('net').createServer();
|
||||
this[name][port].HECI = this;
|
||||
if (lme_port_offset == 0) {
|
||||
this[name][port].listen({ port: port, host: '127.0.0.1' }); // Normal mode
|
||||
} else {
|
||||
this[name][port].listen({ port: (port + lme_port_offset) }); // Debug mode
|
||||
}
|
||||
this[name][port].on('connection', function (socket) {
|
||||
//console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort);
|
||||
this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort - lme_port_offset);
|
||||
});
|
||||
var outBuffer = Buffer.alloc(5);
|
||||
outBuffer.writeUInt8(81, 0);
|
||||
outBuffer.writeUInt32BE(port, 1);
|
||||
this.write(outBuffer);
|
||||
break;
|
||||
case 'cancel-tcpip-forward':
|
||||
break;
|
||||
case 'udp-send-to@amt.intel.com':
|
||||
break;
|
||||
default:
|
||||
//console.log("Unknown APF_GLOBAL_REQUEST for: " + name);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case APF_CHANNEL_OPEN_CONFIRMATION:
|
||||
var rChannel = chunk.readUInt32BE(1);
|
||||
var sChannel = chunk.readUInt32BE(5);
|
||||
var wSize = chunk.readUInt32BE(9);
|
||||
//console.log('rChannel/' + rChannel + ', sChannel/' + sChannel + ', wSize/' + wSize);
|
||||
if (this.sockets[rChannel] != undefined) {
|
||||
this.sockets[rChannel].lme.amtId = sChannel;
|
||||
this.sockets[rChannel].lme.rxWindow = wSize;
|
||||
this.sockets[rChannel].lme.txWindow = wSize;
|
||||
this.sockets[rChannel].lme.LME_CHANNEL_STATUS = 'LME_CS_CONNECTED';
|
||||
//console.log('LME_CS_CONNECTED');
|
||||
this.sockets[rChannel].bufferedStream = new stream_bufferedWrite();
|
||||
this.sockets[rChannel].bufferedStream.socket = this.sockets[rChannel];
|
||||
this.sockets[rChannel].bufferedStream.on('readable', function () {
|
||||
if (this.socket.lme.txWindow > 0) {
|
||||
var buffer = this.read(this.socket.lme.txWindow);
|
||||
var packet = Buffer.alloc(9 + buffer.length);
|
||||
packet.writeUInt8(APF_CHANNEL_DATA, 0);
|
||||
packet.writeUInt32BE(this.socket.lme.amtId, 1);
|
||||
packet.writeUInt32BE(buffer.length, 5);
|
||||
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].on('data', function (chunk) {
|
||||
if (!this.bufferedStream.write(chunk)) { this.pause(); }
|
||||
});
|
||||
this.sockets[rChannel].on('end', function () {
|
||||
var outBuffer = Buffer.alloc(5);
|
||||
outBuffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
|
||||
outBuffer.writeUInt32BE(this.lme.amtId, 1);
|
||||
this.HECI.write(outBuffer);
|
||||
});
|
||||
this.sockets[rChannel].resume();
|
||||
}
|
||||
|
||||
break;
|
||||
case APF_PROTOCOLVERSION:
|
||||
var major = chunk.readUInt32BE(1);
|
||||
var minor = chunk.readUInt32BE(5);
|
||||
var reason = chunk.readUInt32BE(9);
|
||||
var outBuffer = Buffer.alloc(93);
|
||||
outBuffer.writeUInt8(192, 0);
|
||||
outBuffer.writeUInt32BE(1, 1);
|
||||
outBuffer.writeUInt32BE(0, 5);
|
||||
outBuffer.writeUInt32BE(reason, 9);
|
||||
//console.log('Answering PROTOCOL_VERSION');
|
||||
this.write(outBuffer);
|
||||
break;
|
||||
case APF_CHANNEL_WINDOW_ADJUST:
|
||||
var rChannelId = chunk.readUInt32BE(1);
|
||||
var bytesToAdd = chunk.readUInt32BE(5);
|
||||
if (this.sockets[rChannelId] != undefined) {
|
||||
this.sockets[rChannelId].lme.txWindow += bytesToAdd;
|
||||
if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) {
|
||||
this.sockets[rChannelId].bufferedStream.emit('readable');
|
||||
}
|
||||
} else {
|
||||
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST');
|
||||
}
|
||||
break;
|
||||
case APF_CHANNEL_DATA:
|
||||
var rChannelId = chunk.readUInt32BE(1);
|
||||
var dataLen = chunk.readUInt32BE(5);
|
||||
var data = chunk.slice(9, 9 + dataLen);
|
||||
if (this.sockets[rChannelId] != undefined) {
|
||||
this.sockets[rChannelId].pendingBytes.push(data.length);
|
||||
this.sockets[rChannelId].write(data, function () {
|
||||
var written = this.pendingBytes.shift();
|
||||
var outBuffer = Buffer.alloc(9);
|
||||
outBuffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
|
||||
outBuffer.writeUInt32BE(this.lme.amtId, 1);
|
||||
outBuffer.writeUInt32BE(written, 5);
|
||||
this.HECI.write(outBuffer);
|
||||
});
|
||||
} else {
|
||||
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA');
|
||||
}
|
||||
break;
|
||||
case APF_CHANNEL_CLOSE:
|
||||
var rChannelId = chunk.readUInt32BE(1);
|
||||
if (this.sockets[rChannelId] != undefined) {
|
||||
this.sockets[rChannelId].end();
|
||||
var amtId = this.sockets[rChannelId].lme.amtId;
|
||||
var buffer = Buffer.alloc(5);
|
||||
delete this.sockets[rChannelId];
|
||||
|
||||
buffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
|
||||
buffer.writeUInt32BE(amtId, 1);
|
||||
this.write(buffer);
|
||||
} else {
|
||||
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE');
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.bindDuplexStream = function (duplexStream, remoteFamily, localPort) {
|
||||
var socket = duplexStream;
|
||||
//console.log('New [' + remoteFamily + '] Virtual Connection/' + socket.localPort);
|
||||
socket.pendingBytes = [];
|
||||
socket.HECI = this._LME;
|
||||
socket.LMS = this;
|
||||
socket.lme = new lme_object();
|
||||
socket.lme.Socket = socket;
|
||||
var buffer = new MemoryStream();
|
||||
buffer.writeUInt8(0x5A);
|
||||
buffer.writeUInt32BE(15);
|
||||
buffer.write('forwarded-tcpip');
|
||||
buffer.writeUInt32BE(socket.lme.ourId);
|
||||
buffer.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE);
|
||||
buffer.writeUInt32BE(0xFFFFFFFF);
|
||||
for (var i = 0; i < 2; ++i) {
|
||||
if (remoteFamily == 'IPv6') {
|
||||
buffer.writeUInt32BE(3);
|
||||
buffer.write('::1');
|
||||
} else {
|
||||
buffer.writeUInt32BE(9);
|
||||
buffer.write('127.0.0.1');
|
||||
}
|
||||
buffer.writeUInt32BE(localPort);
|
||||
}
|
||||
this._LME.write(buffer.buffer);
|
||||
if (this._LME.sockets == undefined) { this._LME.sockets = {}; }
|
||||
this._LME.sockets[socket.lme.ourId] = socket;
|
||||
socket.pause();
|
||||
};
|
||||
|
||||
this._LME.connect(heci.GUIDS.LME, { noPipeline: 0 });
|
||||
}
|
||||
|
||||
module.exports = lme_heci;
|
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
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');
|
||||
|
||||
function amt_heci() {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('connect');
|
||||
|
||||
var heci = require('heci');
|
||||
|
||||
this._amt = heci.create();
|
||||
this._amt.BiosVersionLen = 65;
|
||||
this._amt.UnicodeStringLen = 20;
|
||||
|
||||
this._amt.rq = new Q();
|
||||
this._amt.Parent = this;
|
||||
this._amt.on('error', function (e) { this.Parent.emit('error', e); });
|
||||
this._amt.on('connect', function () {
|
||||
this.Parent.emit('connect');
|
||||
this.on('data', function (chunk) {
|
||||
//console.log("Received: " + chunk.length + " bytes");
|
||||
var header = this.Parent.getCommand(chunk);
|
||||
//console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
|
||||
|
||||
var user = this.rq.deQueue();
|
||||
var params = user.optional;
|
||||
var callback = user.func;
|
||||
|
||||
params.unshift(header);
|
||||
callback.apply(this.Parent, params);
|
||||
});
|
||||
});
|
||||
this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
|
||||
|
||||
this.getCommand = function (chunk) {
|
||||
var command = chunk.length == 0 ? (this._amt.rq.peekQueue().cmd | 0x800000) : chunk.readUInt32LE(4);
|
||||
var ret = { IsResponse: (command & 0x800000) == 0x800000 ? true : false, Command: (command & 0x7FFFFF), Status: chunk.length != 0 ? chunk.readUInt32LE(12) : -1, Data: chunk.length != 0 ? chunk.slice(16) : null };
|
||||
return (ret);
|
||||
};
|
||||
|
||||
this.sendCommand = function () {
|
||||
if (arguments.length < 3 || typeof (arguments[0]) != 'number' || typeof (arguments[1]) != 'object' || typeof (arguments[2]) != 'function') { throw ('invalid parameters'); }
|
||||
var args = [];
|
||||
for (var i = 3; i < arguments.length; ++i) { args.push(arguments[i]); }
|
||||
|
||||
this._amt.rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args });
|
||||
|
||||
var header = Buffer.from('010100000000000000000000', 'hex');
|
||||
header.writeUInt32LE(arguments[0] | 0x04000000, 4);
|
||||
header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8);
|
||||
|
||||
this._amt.write(arguments[1] == null ? header : Buffer.concat([header, arguments[1]]));
|
||||
}
|
||||
|
||||
this.getVersion = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(26, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, this._amt.BiosVersionLen), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4);
|
||||
for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen) ; ++i) {
|
||||
val.Versions[i] = { Description: v.slice(2, v.readUInt16LE(0) + 2).toString(), Version: v.slice(4 + this._amt.UnicodeStringLen, 4 + this._amt.UnicodeStringLen + v.readUInt16LE(2 + this._amt.UnicodeStringLen)).toString() };
|
||||
v = v.slice(4 + (2 * this._amt.UnicodeStringLen));
|
||||
}
|
||||
opt.unshift(val);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
|
||||
this.getProvisioningState = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(17, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.state = header.Data.readUInt32LE(0);
|
||||
if (result.state < 3) { result.stateStr = ["PRE", "IN", "POST"][result.state]; }
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getProvisioningMode = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(8, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.mode = header.Data.readUInt32LE(0);
|
||||
if (result.mode < 4) { result.modeStr = ["NONE", "ENTERPRISE", "SMALL_BUSINESS", "REMOTE_ASSISTANCE"][result.mode]; }
|
||||
result.legacy = header.Data.readUInt32LE(4) == 0 ? false : true;
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getEHBCState = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(132, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
opt.unshift({ EHBC: header.Data.readUInt32LE(0) != 0 });
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getControlMode = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(107, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.controlMode = header.Data.readUInt32LE(0);
|
||||
if (result.controlMode < 3) { result.controlModeStr = ["NONE_RPAT", "CLIENT", "ADMIN", "REMOTE_ASSISTANCE"][result.controlMode]; }
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getMACAddresses = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(37, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
opt.unshift({ DedicatedMAC: header.Data.slice(0, 6).toString('hex:'), HostMAC: header.Data.slice(6, 12).toString('hex:') });
|
||||
} else { opt.unshift({ DedicatedMAC: null, HostMAC: null }); }
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getDnsSuffix = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(54, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var resultLen = header.Data.readUInt16LE(0);
|
||||
if (resultLen > 0) { opt.unshift(header.Data.slice(2, 2 + resultLen).toString()); } else { opt.unshift(null); }
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getHashHandles = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x2C, null, function (header, fn, opt) {
|
||||
var result = [];
|
||||
if (header.Status == 0) {
|
||||
var resultLen = header.Data.readUInt32LE(0);
|
||||
for (var i = 0; i < resultLen; ++i) {
|
||||
result.push(header.Data.readUInt32LE(4 + (4 * i)));
|
||||
}
|
||||
}
|
||||
opt.unshift(result);
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getCertHashEntry = function (handle, callback) {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
|
||||
var data = new Buffer(4);
|
||||
data.writeUInt32LE(handle, 0);
|
||||
|
||||
this.sendCommand(0x2D, data, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.isDefault = header.Data.readUInt32LE(0);
|
||||
result.isActive = header.Data.readUInt32LE(4);
|
||||
result.hashAlgorithm = header.Data.readUInt8(72);
|
||||
if (result.hashAlgorithm < 4) {
|
||||
result.hashAlgorithmStr = ["MD5", "SHA1", "SHA256", "SHA512"][result.hashAlgorithm];
|
||||
result.hashAlgorithmSize = [16, 20, 32, 64][result.hashAlgorithm];
|
||||
result.certificateHash = header.Data.slice(8, 8 + result.hashAlgorithmSize).toString('hex');
|
||||
}
|
||||
result.name = header.Data.slice(73 + 2, 73 + 2 + header.Data.readUInt16LE(73)).toString();
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getCertHashEntries = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
|
||||
this.getHashHandles(function (handles, fn, opt) {
|
||||
var entries = [];
|
||||
this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
|
||||
}, callback, optional);
|
||||
};
|
||||
this._getHashEntrySink = function (result, fn, opt, entries, handles) {
|
||||
entries.push(result);
|
||||
if (handles.length > 0) {
|
||||
this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
|
||||
} else {
|
||||
opt.unshift(entries);
|
||||
fn.apply(this, opt);
|
||||
}
|
||||
}
|
||||
this.getLocalSystemAccount = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt) {
|
||||
if (header.Data.length == 68) { opt.unshift({ user: header.Data.slice(0, 34).toString(), pass: header.Data.slice(34, 67).toString(), raw: header.Data }); } else { opt.unshift(null); }
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
this.unprovision = function (mode, callback) {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
var data = new Buffer(4);
|
||||
data.writeUInt32LE(mode, 0);
|
||||
this.sendCommand(16, data, function (header, fn, opt) {
|
||||
opt.unshift(header.Status);
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
this.startConfiguration = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x29, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.stopConfiguration = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x5E, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.openUserInitiatedConnection = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x44, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.closeUserInitiatedConnection = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x45, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.getRemoteAccessConnectionStatus = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x46, data, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var hostname = v.slice(14, header.Data.readUInt16LE(12) + 14).toString()
|
||||
opt.unshift({ status: header.Status, networkStatus: header.Data.readUInt32LE(0), remoteAccessStatus: header.Data.readUInt32LE(4), remoteAccessTrigger: header.Data.readUInt32LE(8), mpsHostname: hostname, raw: header.Data });
|
||||
} else {
|
||||
opt.unshift({ status: header.Status });
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
this.getProtocolVersion = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { opt.push(arguments[i]); }
|
||||
|
||||
heci.doIoctl(heci.IOCTL.HECI_VERSION, Buffer.alloc(5), Buffer.alloc(5), function (status, buffer, self, fn, opt) {
|
||||
if (status == 0) {
|
||||
var result = buffer.readUInt8(0).toString() + '.' + buffer.readUInt8(1).toString() + '.' + buffer.readUInt8(2).toString() + '.' + buffer.readUInt16BE(3).toString();
|
||||
opt.unshift(result);
|
||||
fn.apply(self, opt);
|
||||
}
|
||||
else {
|
||||
opt.unshift(null);
|
||||
fn.apply(self, opt);
|
||||
}
|
||||
}, this, callback, optional);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = amt_heci;
|
|
@ -0,0 +1,272 @@
|
|||
var MemoryStream = require('MemoryStream');
|
||||
var WindowsWireless = new Buffer([
|
||||
0x0A, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x5F, 0x53, 0x63, 0x61, 0x6E, 0x28, 0x29, 0x0A, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x77, 0x6C, 0x61, 0x6E,
|
||||
0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x20, 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x50, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x2E, 0x57, 0x6C, 0x61, 0x6E, 0x45,
|
||||
0x6E, 0x75, 0x6D, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x77, 0x6C,
|
||||
0x61, 0x6E, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x29, 0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x63, 0x6F, 0x75, 0x6E, 0x74, 0x20, 0x3D, 0x20,
|
||||
0x77, 0x6C, 0x61, 0x6E, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x29, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x30, 0x2C, 0x20,
|
||||
0x34, 0x29, 0x2E, 0x56, 0x61, 0x6C, 0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x69, 0x6E, 0x66, 0x6F, 0x20, 0x3D, 0x20, 0x77, 0x6C, 0x61, 0x6E, 0x49, 0x6E, 0x74, 0x65,
|
||||
0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x29, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x38, 0x2C, 0x20, 0x35, 0x33, 0x32, 0x29, 0x3B, 0x0A, 0x20, 0x20,
|
||||
0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x69, 0x6E, 0x61, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x69, 0x6E, 0x66, 0x6F, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x31, 0x36, 0x2C, 0x20, 0x35, 0x31, 0x32,
|
||||
0x29, 0x2E, 0x41, 0x6E, 0x73, 0x69, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x69, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3B, 0x0A, 0x20,
|
||||
0x20, 0x20, 0x20, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x28, 0x69, 0x6E, 0x66, 0x6F, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x35, 0x32, 0x38, 0x2C, 0x20, 0x34, 0x29, 0x2E, 0x56, 0x61,
|
||||
0x6C, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x30, 0x3A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3D, 0x20, 0x22, 0x4E, 0x4F, 0x54, 0x20, 0x52, 0x45, 0x41, 0x44, 0x59, 0x22, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6B, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x31, 0x3A, 0x0A, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3D, 0x20, 0x22, 0x43, 0x4F, 0x4E, 0x4E, 0x45, 0x43, 0x54, 0x45, 0x44, 0x22, 0x3B, 0x0A,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6B, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20,
|
||||
0x32, 0x3A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3D, 0x20, 0x22, 0x41, 0x44, 0x2D, 0x48, 0x4F, 0x43, 0x22,
|
||||
0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6B, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73,
|
||||
0x65, 0x20, 0x33, 0x3A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3D, 0x20, 0x22, 0x44, 0x49, 0x53, 0x43, 0x4F,
|
||||
0x4E, 0x4E, 0x45, 0x43, 0x54, 0x49, 0x4E, 0x47, 0x22, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6B, 0x3B, 0x0A, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x34, 0x3A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 0x74, 0x61, 0x74, 0x65,
|
||||
0x20, 0x3D, 0x20, 0x22, 0x44, 0x49, 0x53, 0x43, 0x4F, 0x4E, 0x4E, 0x45, 0x43, 0x54, 0x45, 0x44, 0x22, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62,
|
||||
0x72, 0x65, 0x61, 0x6B, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x35, 0x3A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x69, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3D, 0x20, 0x22, 0x41, 0x53, 0x53, 0x4F, 0x43, 0x49, 0x41, 0x54, 0x49, 0x4E, 0x47, 0x22, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6B, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x36, 0x3A, 0x0A, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3D, 0x20, 0x22, 0x44, 0x49, 0x53, 0x43, 0x4F, 0x56, 0x45, 0x52, 0x49, 0x4E, 0x47, 0x22, 0x3B,
|
||||
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6B, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65,
|
||||
0x20, 0x37, 0x3A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3D, 0x20, 0x22, 0x41, 0x55, 0x54, 0x48, 0x45, 0x4E,
|
||||
0x54, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4E, 0x47, 0x22, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6B, 0x3B, 0x0A, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x3A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 0x74, 0x61, 0x74,
|
||||
0x65, 0x20, 0x3D, 0x20, 0x22, 0x55, 0x4E, 0x4B, 0x4E, 0x4F, 0x57, 0x4E, 0x22, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6B,
|
||||
0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x69, 0x67, 0x75, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x69, 0x6E, 0x66, 0x6F, 0x2E, 0x44, 0x65,
|
||||
0x72, 0x65, 0x66, 0x28, 0x30, 0x2C, 0x20, 0x31, 0x36, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x2E,
|
||||
0x57, 0x6C, 0x61, 0x6E, 0x53, 0x63, 0x61, 0x6E, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x2C, 0x20, 0x69, 0x67, 0x75, 0x69, 0x64, 0x2C, 0x20, 0x30, 0x2C, 0x20,
|
||||
0x30, 0x2C, 0x20, 0x30, 0x29, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E,
|
||||
0x20, 0x28, 0x74, 0x72, 0x75, 0x65, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6C, 0x73, 0x65, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x0A, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x28, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0A, 0x7D, 0x0A, 0x0A, 0x66,
|
||||
0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x28, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x2C, 0x20, 0x5F, 0x62, 0x73, 0x73, 0x69,
|
||||
0x64, 0x2C, 0x20, 0x5F, 0x72, 0x73, 0x73, 0x69, 0x2C, 0x20, 0x5F, 0x6C, 0x71, 0x29, 0x0A, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x73, 0x73, 0x69, 0x64, 0x20, 0x3D,
|
||||
0x20, 0x5F, 0x73, 0x73, 0x69, 0x64, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x62, 0x73, 0x73, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x5F, 0x62, 0x73, 0x73, 0x69, 0x64, 0x3B,
|
||||
0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x72, 0x73, 0x73, 0x69, 0x20, 0x3D, 0x20, 0x5F, 0x72, 0x73, 0x73, 0x69, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73,
|
||||
0x2E, 0x6C, 0x71, 0x20, 0x3D, 0x20, 0x5F, 0x6C, 0x71, 0x3B, 0x0A, 0x7D, 0x0A, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x2E, 0x70, 0x72, 0x6F, 0x74, 0x6F, 0x74, 0x79,
|
||||
0x70, 0x65, 0x2E, 0x74, 0x6F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x20, 0x3D, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x28, 0x29, 0x0A, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x72,
|
||||
0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x73, 0x73, 0x69, 0x64, 0x20, 0x2B, 0x20, 0x22, 0x20, 0x5B, 0x22, 0x20, 0x2B, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x62,
|
||||
0x73, 0x73, 0x69, 0x64, 0x20, 0x2B, 0x20, 0x22, 0x5D, 0x3A, 0x20, 0x22, 0x20, 0x2B, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x6C, 0x71, 0x29, 0x3B, 0x0A, 0x7D, 0x0A, 0x0A, 0x66, 0x75, 0x6E, 0x63,
|
||||
0x74, 0x69, 0x6F, 0x6E, 0x20, 0x4F, 0x6E, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x79, 0x28, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x61, 0x74, 0x61, 0x29, 0x0A,
|
||||
0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x20, 0x3D, 0x20, 0x4E,
|
||||
0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x61, 0x74, 0x61, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x30, 0x2C, 0x20, 0x34, 0x29, 0x2E, 0x56, 0x61, 0x6C, 0x3B,
|
||||
0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x43, 0x6F, 0x64, 0x65, 0x20, 0x3D, 0x20, 0x4E, 0x6F, 0x74, 0x69,
|
||||
0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x61, 0x74, 0x61, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x34, 0x2C, 0x20, 0x34, 0x29, 0x2E, 0x56, 0x61, 0x6C, 0x3B, 0x0A, 0x20, 0x20,
|
||||
0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x47, 0x75, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x61, 0x74,
|
||||
0x61, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x38, 0x2C, 0x20, 0x31, 0x36, 0x29, 0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x28, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x20, 0x26, 0x20, 0x30, 0x58, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x4E,
|
||||
0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x43, 0x6F, 0x64, 0x65, 0x20, 0x3D, 0x3D, 0x20, 0x37, 0x29, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x62, 0x73, 0x73, 0x20, 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x50, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68,
|
||||
0x61, 0x6C, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20,
|
||||
0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x20, 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x50, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x2E, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x2E, 0x47, 0x65, 0x74, 0x42,
|
||||
0x53, 0x53, 0x4C, 0x69, 0x73, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x50, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x2E, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x2C, 0x20, 0x64, 0x61, 0x74, 0x61, 0x47,
|
||||
0x75, 0x69, 0x64, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x33, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x62, 0x73, 0x73, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69,
|
||||
0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x74, 0x6F, 0x74, 0x61, 0x6C, 0x53, 0x69, 0x7A, 0x65, 0x20, 0x3D, 0x20, 0x62, 0x73, 0x73, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28,
|
||||
0x29, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x30, 0x2C, 0x20, 0x34, 0x29, 0x2E, 0x56, 0x61, 0x6C, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76,
|
||||
0x61, 0x72, 0x20, 0x6E, 0x75, 0x6D, 0x49, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x3D, 0x20, 0x62, 0x73, 0x73, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x29, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28,
|
||||
0x34, 0x2C, 0x20, 0x34, 0x29, 0x2E, 0x56, 0x61, 0x6C, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x28, 0x69, 0x20, 0x3D, 0x20,
|
||||
0x30, 0x3B, 0x20, 0x69, 0x20, 0x3C, 0x20, 0x6E, 0x75, 0x6D, 0x49, 0x74, 0x65, 0x6D, 0x73, 0x3B, 0x20, 0x2B, 0x2B, 0x69, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x3D, 0x20, 0x62,
|
||||
0x73, 0x73, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x29, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x38, 0x20, 0x2B, 0x20, 0x28, 0x33, 0x36, 0x30, 0x20, 0x2A, 0x20, 0x69, 0x29, 0x2C, 0x20,
|
||||
0x33, 0x36, 0x30, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x73, 0x73, 0x69, 0x64, 0x20, 0x3D,
|
||||
0x20, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x34, 0x2C, 0x20, 0x33, 0x32, 0x29, 0x2E, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E, 0x74, 0x72, 0x69, 0x6D, 0x28, 0x29,
|
||||
0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x62, 0x73, 0x73, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x69, 0x74,
|
||||
0x65, 0x6D, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x34, 0x30, 0x2C, 0x20, 0x36, 0x29, 0x2E, 0x48, 0x65, 0x78, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x32, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x72, 0x73, 0x73, 0x69, 0x20, 0x3D, 0x20, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x44, 0x65, 0x72, 0x65,
|
||||
0x66, 0x28, 0x35, 0x36, 0x2C, 0x20, 0x34, 0x29, 0x2E, 0x56, 0x61, 0x6C, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61,
|
||||
0x72, 0x20, 0x6C, 0x71, 0x20, 0x3D, 0x20, 0x69, 0x74, 0x65, 0x6D, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x36, 0x30, 0x2C, 0x20, 0x34, 0x29, 0x2E, 0x56, 0x61, 0x6C, 0x3B, 0x0A, 0x0A, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x50, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x2E, 0x65, 0x6D, 0x69, 0x74, 0x28,
|
||||
0x27, 0x53, 0x63, 0x61, 0x6E, 0x27, 0x2C, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x28, 0x73, 0x73, 0x69, 0x64, 0x2C, 0x20, 0x62, 0x73,
|
||||
0x73, 0x69, 0x64, 0x2C, 0x20, 0x72, 0x73, 0x73, 0x69, 0x2C, 0x20, 0x6C, 0x71, 0x29, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0A, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0A, 0x7D, 0x0A, 0x0A, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x57, 0x69, 0x72, 0x65,
|
||||
0x6C, 0x65, 0x73, 0x73, 0x28, 0x29, 0x0A, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x65, 0x6D, 0x69, 0x74, 0x74, 0x65, 0x72, 0x55, 0x74, 0x69, 0x6C, 0x73, 0x20, 0x3D, 0x20,
|
||||
0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x27, 0x65, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x27, 0x29, 0x2E, 0x69, 0x6E, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29,
|
||||
0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x20, 0x3D, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x27, 0x5F,
|
||||
0x47, 0x65, 0x6E, 0x65, 0x72, 0x69, 0x63, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x27, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E, 0x61, 0x74, 0x69, 0x76,
|
||||
0x65, 0x20, 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x72, 0x6F,
|
||||
0x78, 0x79, 0x28, 0x22, 0x77, 0x6C, 0x61, 0x6E, 0x61, 0x70, 0x69, 0x2E, 0x64, 0x6C, 0x6C, 0x22, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E, 0x61, 0x74, 0x69,
|
||||
0x76, 0x65, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x28, 0x22, 0x57, 0x6C, 0x61, 0x6E, 0x4F, 0x70, 0x65, 0x6E, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x22,
|
||||
0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x28,
|
||||
0x22, 0x57, 0x6C, 0x61, 0x6E, 0x47, 0x65, 0x74, 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x42, 0x73, 0x73, 0x4C, 0x69, 0x73, 0x74, 0x22, 0x2C, 0x20, 0x22, 0x47, 0x65, 0x74, 0x42, 0x53, 0x53,
|
||||
0x4C, 0x69, 0x73, 0x74, 0x22, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4D, 0x65,
|
||||
0x74, 0x68, 0x6F, 0x64, 0x28, 0x22, 0x57, 0x6C, 0x61, 0x6E, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x29,
|
||||
0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x28, 0x22,
|
||||
0x57, 0x6C, 0x61, 0x6E, 0x45, 0x6E, 0x75, 0x6D, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x22, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E,
|
||||
0x61, 0x74, 0x69, 0x76, 0x65, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x28, 0x22, 0x57, 0x6C, 0x61, 0x6E, 0x53, 0x63, 0x61, 0x6E, 0x22, 0x29, 0x3B, 0x0A,
|
||||
0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x28, 0x22, 0x57, 0x6C,
|
||||
0x61, 0x6E, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x22, 0x29, 0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6E, 0x65, 0x67,
|
||||
0x6F, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6F, 0x69,
|
||||
0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x68, 0x20, 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C,
|
||||
0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E, 0x61, 0x74, 0x69,
|
||||
0x76, 0x65, 0x2E, 0x57, 0x6C, 0x61, 0x6E, 0x4F, 0x70, 0x65, 0x6E, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x28, 0x32, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x6E, 0x65, 0x67, 0x6F, 0x74, 0x69, 0x61, 0x74,
|
||||
0x65, 0x64, 0x2C, 0x20, 0x68, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x20, 0x3D, 0x20, 0x68, 0x2E, 0x56, 0x61, 0x6C, 0x3B,
|
||||
0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x5F, 0x4E, 0x4F, 0x54, 0x49, 0x46, 0x59, 0x5F, 0x50, 0x52, 0x4F, 0x58, 0x59, 0x5F, 0x4F, 0x42, 0x4A, 0x45, 0x43, 0x54, 0x20,
|
||||
0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6C, 0x6C, 0x62, 0x61, 0x63, 0x6B, 0x50, 0x72, 0x6F,
|
||||
0x78, 0x79, 0x28, 0x4F, 0x6E, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x79, 0x2C, 0x20, 0x32, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x5F, 0x4E, 0x4F, 0x54, 0x49, 0x46,
|
||||
0x59, 0x5F, 0x50, 0x52, 0x4F, 0x58, 0x59, 0x5F, 0x4F, 0x42, 0x4A, 0x45, 0x43, 0x54, 0x2E, 0x50, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x3B, 0x0A, 0x20, 0x20,
|
||||
0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x50, 0x72, 0x65, 0x76, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x20, 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x2E,
|
||||
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x20,
|
||||
0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x2E, 0x57, 0x6C, 0x61, 0x6E, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x2C, 0x20, 0x30, 0x58, 0x30, 0x30, 0x30, 0x30, 0x46, 0x46, 0x46, 0x46, 0x2C, 0x20,
|
||||
0x30, 0x2C, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x5F, 0x4E, 0x4F, 0x54, 0x49, 0x46, 0x59, 0x5F, 0x50, 0x52, 0x4F, 0x58, 0x59, 0x5F, 0x4F, 0x42, 0x4A, 0x45, 0x43, 0x54, 0x2E, 0x43, 0x61, 0x6C,
|
||||
0x6C, 0x62, 0x61, 0x63, 0x6B, 0x2C, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x5F, 0x4E, 0x4F, 0x54, 0x49, 0x46, 0x59, 0x5F, 0x50, 0x52, 0x4F, 0x58, 0x59, 0x5F, 0x4F, 0x42, 0x4A, 0x45, 0x43, 0x54,
|
||||
0x2E, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x50, 0x72, 0x65, 0x76, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x29, 0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6D, 0x69,
|
||||
0x74, 0x74, 0x65, 0x72, 0x55, 0x74, 0x69, 0x6C, 0x73, 0x2E, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x28, 0x27, 0x53, 0x63, 0x61, 0x6E, 0x27, 0x29, 0x3B, 0x0A, 0x20,
|
||||
0x20, 0x20, 0x20, 0x65, 0x6D, 0x69, 0x74, 0x74, 0x65, 0x72, 0x55, 0x74, 0x69, 0x6C, 0x73, 0x2E, 0x61, 0x64, 0x64, 0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x28, 0x27, 0x53, 0x63, 0x61, 0x6E, 0x27,
|
||||
0x2C, 0x20, 0x5F, 0x53, 0x63, 0x61, 0x6E, 0x29, 0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x47, 0x65, 0x74, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64,
|
||||
0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x3D, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x28, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x20, 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61,
|
||||
0x6C, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73,
|
||||
0x2E, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x2E, 0x57, 0x6C, 0x61, 0x6E, 0x45, 0x6E, 0x75, 0x6D, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2E,
|
||||
0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x63, 0x6F, 0x75, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2E,
|
||||
0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x29, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x30, 0x2C, 0x20, 0x34, 0x29, 0x2E, 0x56, 0x61, 0x6C, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x76, 0x61, 0x72, 0x20, 0x69, 0x6E, 0x66, 0x6F, 0x20, 0x3D, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x29, 0x2E, 0x44,
|
||||
0x65, 0x72, 0x65, 0x66, 0x28, 0x38, 0x2C, 0x20, 0x35, 0x33, 0x32, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x69, 0x6E, 0x61, 0x6D, 0x65, 0x20,
|
||||
0x3D, 0x20, 0x69, 0x6E, 0x66, 0x6F, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x31, 0x36, 0x2C, 0x20, 0x35, 0x31, 0x32, 0x29, 0x2E, 0x41, 0x6E, 0x73, 0x69, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67,
|
||||
0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x69, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3D, 0x20, 0x69, 0x6E, 0x66, 0x6F, 0x2E, 0x44, 0x65, 0x72, 0x65,
|
||||
0x66, 0x28, 0x35, 0x32, 0x38, 0x2C, 0x20, 0x34, 0x29, 0x2E, 0x49, 0x6E, 0x74, 0x56, 0x61, 0x6C, 0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x69, 0x6E,
|
||||
0x66, 0x6F, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x35, 0x32, 0x38, 0x2C, 0x20, 0x34, 0x29, 0x2E, 0x49, 0x6E, 0x74, 0x56, 0x61, 0x6C, 0x20, 0x3D, 0x3D, 0x20, 0x31, 0x29, 0x20, 0x2F, 0x2F,
|
||||
0x20, 0x43, 0x4F, 0x4E, 0x4E, 0x45, 0x43, 0x54, 0x45, 0x44, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x53, 0x69, 0x7A, 0x65, 0x20, 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x2E, 0x43, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x70, 0x44,
|
||||
0x61, 0x74, 0x61, 0x20, 0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72,
|
||||
0x28, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x20, 0x3D, 0x20,
|
||||
0x74, 0x68, 0x69, 0x73, 0x2E, 0x4D, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6C, 0x2E, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x28, 0x29, 0x3B, 0x0A, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x69, 0x67, 0x75, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x69, 0x6E, 0x66, 0x6F, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66,
|
||||
0x28, 0x30, 0x2C, 0x20, 0x31, 0x36, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65, 0x74, 0x56, 0x61, 0x6C, 0x20,
|
||||
0x3D, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x2E, 0x57, 0x6C, 0x61, 0x6E, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65,
|
||||
0x28, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x2C, 0x20, 0x69, 0x67, 0x75, 0x69, 0x64, 0x2C, 0x20, 0x37, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x64, 0x61, 0x74, 0x61, 0x53,
|
||||
0x69, 0x7A, 0x65, 0x2C, 0x20, 0x70, 0x44, 0x61, 0x74, 0x61, 0x2C, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x74, 0x56, 0x61, 0x6C, 0x20, 0x3D, 0x3D, 0x20, 0x30, 0x29, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x69, 0x61, 0x74, 0x65,
|
||||
0x64, 0x53, 0x53, 0x49, 0x44, 0x20, 0x3D, 0x20, 0x70, 0x44, 0x61, 0x74, 0x61, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x29, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x35, 0x32, 0x34, 0x2C,
|
||||
0x20, 0x33, 0x32, 0x29, 0x2E, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72,
|
||||
0x20, 0x62, 0x73, 0x73, 0x69, 0x64, 0x20, 0x3D, 0x20, 0x70, 0x44, 0x61, 0x74, 0x61, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x29, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x35, 0x36, 0x30,
|
||||
0x2C, 0x20, 0x36, 0x29, 0x2E, 0x48, 0x65, 0x78, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x76, 0x61, 0x72, 0x20, 0x6C, 0x71, 0x20, 0x3D, 0x20, 0x70, 0x44, 0x61, 0x74, 0x61, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x29, 0x2E, 0x44, 0x65, 0x72, 0x65, 0x66, 0x28, 0x35, 0x37, 0x36,
|
||||
0x2C, 0x20, 0x34, 0x29, 0x2E, 0x49, 0x6E, 0x74, 0x56, 0x61, 0x6C, 0x3B, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
|
||||
0x74, 0x75, 0x72, 0x6E, 0x20, 0x28, 0x6E, 0x65, 0x77, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x28, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64,
|
||||
0x53, 0x53, 0x49, 0x44, 0x2C, 0x20, 0x62, 0x73, 0x73, 0x69, 0x64, 0x2C, 0x20, 0x30, 0x2C, 0x20, 0x6C, 0x71, 0x29, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x7D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x72, 0x6F, 0x77, 0x20, 0x28, 0x22, 0x47, 0x65,
|
||||
0x74, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x73, 0x3A, 0x20, 0x46, 0x41, 0x49, 0x4C, 0x45, 0x44, 0x20, 0x28, 0x6E, 0x6F, 0x74, 0x20,
|
||||
0x61, 0x73, 0x73, 0x6F, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x61, 0x20, 0x6E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x29, 0x22, 0x29, 0x3B, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||
0x7D, 0x3B, 0x0A, 0x0A, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3B, 0x0A, 0x7D, 0x0A, 0x0A, 0x6D, 0x6F, 0x64, 0x75, 0x6C,
|
||||
0x65, 0x2E, 0x65, 0x78, 0x70, 0x6F, 0x72, 0x74, 0x73, 0x20, 0x3D, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x57, 0x69, 0x72, 0x65, 0x6C, 0x65, 0x73, 0x73, 0x28, 0x29, 0x3B, 0x0A]);
|
||||
|
||||
|
||||
|
||||
var WindowsChildScript = new Buffer([
|
||||
0x76, 0x61, 0x72, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x27, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6F, 0x6E, 0x74,
|
||||
0x61, 0x69, 0x6E, 0x65, 0x72, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x76, 0x61, 0x72, 0x20, 0x57, 0x69, 0x72, 0x65, 0x6C, 0x65, 0x73, 0x73, 0x20, 0x3D, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65,
|
||||
0x28, 0x27, 0x57, 0x69, 0x72, 0x65, 0x6C, 0x65, 0x73, 0x73, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x57, 0x69, 0x72, 0x65, 0x6C, 0x65, 0x73, 0x73, 0x2E, 0x6F, 0x6E, 0x28, 0x27, 0x53, 0x63,
|
||||
0x61, 0x6E, 0x27, 0x2C, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x28, 0x61, 0x70, 0x29, 0x20, 0x7B, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6E, 0x74, 0x2E, 0x73, 0x65, 0x6E, 0x64,
|
||||
0x28, 0x61, 0x70, 0x29, 0x3B, 0x20, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x57, 0x69, 0x72, 0x65, 0x6C, 0x65, 0x73, 0x73, 0x2E, 0x53, 0x63, 0x61, 0x6E, 0x28, 0x29, 0x3B, 0x0D, 0x0A]);
|
||||
|
||||
|
||||
function AccessPoint(_ssid, _bssid, _lq)
|
||||
{
|
||||
this.ssid = _ssid;
|
||||
this.bssid = _bssid;
|
||||
this.lq = _lq;
|
||||
}
|
||||
AccessPoint.prototype.toString = function ()
|
||||
{
|
||||
return ("[" + this.bssid + "]: " + this.ssid + " (" + this.lq + ")");
|
||||
//return (this.ssid + " [" + this.bssid + "]: " + this.lq);
|
||||
}
|
||||
|
||||
function WiFiScanner()
|
||||
{
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
emitterUtils.createEvent('accessPoint');
|
||||
|
||||
this.hasWireless = function ()
|
||||
{
|
||||
var retVal = false;
|
||||
var interfaces = require('os').networkInterfaces();
|
||||
for (var name in interfaces)
|
||||
{
|
||||
if (interfaces[name][0].type == 'wireless') { retVal = true; break; }
|
||||
}
|
||||
return (retVal);
|
||||
};
|
||||
|
||||
this.Scan = function ()
|
||||
{
|
||||
if (process.platform == 'win32')
|
||||
{
|
||||
this.master = require('ScriptContainer').Create(15, ContainerPermissions.DEFAULT);
|
||||
this.master.parent = this;
|
||||
this.master.on('data', function (j) { this.parent.emit('accessPoint', new AccessPoint(j.ssid, j.bssid, j.lq)); });
|
||||
|
||||
this.master.addModule('Wireless', WindowsWireless.toString());
|
||||
this.master.ExecuteString(WindowsChildScript.toString());
|
||||
}
|
||||
else if (process.platform == 'linux')
|
||||
{
|
||||
// Need to get the wireless interface name
|
||||
var interfaces = require('os').networkInterfaces();
|
||||
var wlan = null;
|
||||
for (var i in interfaces)
|
||||
{
|
||||
if (interfaces[i][0].type == 'wireless')
|
||||
{
|
||||
wlan = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (wlan != null)
|
||||
{
|
||||
this.child = require('child_process').execFile('/sbin/iwlist', ['iwlist', wlan, 'scan']);
|
||||
this.child.parent = this;
|
||||
this.child.ms = new MemoryStream();
|
||||
this.child.ms.parent = this.child;
|
||||
this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); });
|
||||
this.child.on('exit', function () { this.ms.end(); });
|
||||
this.child.ms.on('end', function ()
|
||||
{
|
||||
var str = this.buffer.toString();
|
||||
tokens = str.split(' - Address: ');
|
||||
for (var block in tokens)
|
||||
{
|
||||
if (block == 0) continue;
|
||||
var ln = tokens[block].split('\n');
|
||||
var _bssid = ln[0];
|
||||
var _lq;
|
||||
var _ssid;
|
||||
|
||||
for (var lnblock in ln)
|
||||
{
|
||||
lnblock = ln[lnblock].trim();
|
||||
lnblock = lnblock.trim();
|
||||
if (lnblock.startsWith('ESSID:'))
|
||||
{
|
||||
_ssid = lnblock.slice(7, lnblock.length - 1);
|
||||
if (_ssid == '<hidden>') { _ssid = ''; }
|
||||
}
|
||||
if (lnblock.startsWith('Signal level='))
|
||||
{
|
||||
_lq = lnblock.slice(13,lnblock.length-4);
|
||||
}
|
||||
else if (lnblock.startsWith('Quality='))
|
||||
{
|
||||
_lq = lnblock.slice(8, 10);
|
||||
var scale = lnblock.slice(11, 13);
|
||||
}
|
||||
}
|
||||
this.parent.parent.emit('accessPoint', new AccessPoint(_ssid, _bssid, _lq));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WiFiScanner;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
|
|||
if (obj.args.tlsoffload) {
|
||||
obj.server = net.createServer(onConnection);
|
||||
} else {
|
||||
obj.server = tls.createServer({ key: certificates.mps.key, cert: certificates.mps.cert, requestCert: true }, onConnection);
|
||||
obj.server = tls.createServer({ key: certificates.mps.key, cert: certificates.mps.cert, requestCert: true, rejectUnauthorized: false }, onConnection);
|
||||
}
|
||||
|
||||
obj.server.listen(args.mpsport, function () { console.log('MeshCentral Intel(R) AMT server running on ' + certificates.CommonName + ':' + args.mpsport + '.'); }).on('error', function (err) { console.error('ERROR: MeshCentral Intel(R) AMT server port ' + args.mpsport + ' is not available.'); if (args.exactports) { process.exit(); } });
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.1.3-j",
|
||||
"version": "0.1.3-r",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
|
|
@ -3358,7 +3358,12 @@
|
|||
p13filetree = data;
|
||||
p13updateFiles(checkedNames);
|
||||
} else {
|
||||
if ((data.path.replace(/\//g, "\\") == p13targetpath.replace(/\//g, "\\")) || ((data.path == '\\') && (p13targetpath == ''))) {
|
||||
// Make both paths use the same seperator not start with /
|
||||
var x1 = data.path.replace(/\//g, "\\");
|
||||
var x2 = p13targetpath.replace(/\//g, "\\");
|
||||
while ((x1.length > 0) && (x1[0] == '\\')) { x1 = x1.substring(1); }
|
||||
while ((x2.length > 0) && (x2[0] == '\\')) { x2 = x2.substring(1); }
|
||||
if ((x1 == x2) || ((data.path == '\\') && (p13targetpath == ''))) {
|
||||
// This is a different folder
|
||||
p13filetree = data;
|
||||
p13updateFiles();
|
||||
|
|
44
webserver.js
44
webserver.js
|
@ -1404,6 +1404,10 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||
obj.handleMeshAgentRequest = function (req, res) {
|
||||
var domain = checkUserIpAddress(req, res);
|
||||
if (domain == null) return;
|
||||
|
||||
// If required, check if this user has rights to do this
|
||||
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true) && (req.session.userid == null)) { res.sendStatus(401); return; }
|
||||
|
||||
if (req.query.id != null) {
|
||||
// Send a specific mesh agent back
|
||||
var argentInfo = obj.parent.meshAgentBinaries[req.query.id];
|
||||
|
@ -1418,10 +1422,12 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||
if (meshes.length != 1) { res.sendStatus(401); return; }
|
||||
var mesh = meshes[0];
|
||||
|
||||
// Check if this user has rights to do this
|
||||
//var user = obj.users[req.session.userid];
|
||||
//if ((user == null) || (mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { res.sendStatus(401); return; }
|
||||
//if (domain.id != mesh.domain) { res.sendStatus(401); return; }
|
||||
// If required, check if this user has rights to do this
|
||||
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true)) {
|
||||
var user = obj.users[req.session.userid];
|
||||
if ((user == null) || (mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { res.sendStatus(401); return; }
|
||||
if (domain.id != mesh.domain) { res.sendStatus(401); return; }
|
||||
}
|
||||
|
||||
var meshidhex = new Buffer(req.query.meshid.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
|
||||
var serveridhex = new Buffer(obj.agentCertificateHashBase64.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
|
||||
|
@ -1449,19 +1455,6 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=meshcmd' + ((req.query.meshcmd <= 4) ? '.exe' : '') });
|
||||
res.statusCode = 200;
|
||||
obj.parent.exeHandler.streamExeWithJavaScript({ platform: argentInfo.platform, sourceFileName: argentInfo.path, destinationStream: res, js: new Buffer(obj.parent.defaultMeshCmd, 'utf8'), peinfo: argentInfo.pe });
|
||||
|
||||
/*
|
||||
// Load the agent
|
||||
obj.fs.readFile(argentInfo.path, function (err, agentexe) {
|
||||
if (err != null) { res.sendStatus(404); return; }
|
||||
// Send out merged meshcmd
|
||||
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=meshcmd' + ((req.query.meshcmd <= 4) ? '.exe' : '') });
|
||||
var meshcmdbuf = new Buffer(obj.parent.defaultMeshCmd, 'utf8'), tail = new Buffer(8);
|
||||
tail.writeInt32BE(meshcmdbuf.length, 0);
|
||||
tail.writeInt32BE(agentexe.length + meshcmdbuf.length + 8, 4);
|
||||
res.send(Buffer.concat([agentexe, meshcmdbuf, tail]));
|
||||
});
|
||||
*/
|
||||
} else if (req.query.meshaction != null) {
|
||||
var domain = checkUserIpAddress(req, res);
|
||||
if (domain == null) { res.sendStatus(404); return; }
|
||||
|
@ -1531,16 +1524,21 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||
var domain = checkUserIpAddress(req, res);
|
||||
if (domain == null) return;
|
||||
//if ((domain.id !== '') || (!req.session) || (req.session == null) || (!req.session.userid)) { res.sendStatus(401); return; }
|
||||
|
||||
|
||||
// If required, check if this user has rights to do this
|
||||
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true) && (req.session.userid == null)) { res.sendStatus(401); return; }
|
||||
|
||||
// Query the meshid
|
||||
obj.db.Get('mesh/' + domain.id + '/' + req.query.id, function (err, meshes) {
|
||||
if (meshes.length != 1) { res.sendStatus(401); return; }
|
||||
var mesh = meshes[0];
|
||||
|
||||
// Check if this user has rights to do this
|
||||
//var user = obj.users[req.session.userid];
|
||||
//if ((user == null) || (mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { res.sendStatus(401); return; }
|
||||
//if (domain.id != mesh.domain) { res.sendStatus(401); return; }
|
||||
|
||||
// If needed, check if this user has rights to do this
|
||||
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true)) {
|
||||
var user = obj.users[req.session.userid];
|
||||
if ((user == null) || (mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { res.sendStatus(401); return; }
|
||||
if (domain.id != mesh.domain) { res.sendStatus(401); return; }
|
||||
}
|
||||
|
||||
var meshidhex = new Buffer(req.query.id.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
|
||||
var serveridhex = new Buffer(obj.agentCertificateHashBase64.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
|
||||
|
|
Loading…
Reference in New Issue