Added TLS support within CIRA, WSMAN stack improvements.

This commit is contained in:
Ylian Saint-Hilaire 2020-10-14 12:01:26 -07:00
parent 759a7bbaf5
commit fd6e0f9912
8 changed files with 171 additions and 300 deletions

View File

@ -1,9 +1,30 @@
/** /*
* @description IDER Handling Module Copyright 2020 Intel Corporation
* @author Ylian Saint-Hilaire
* @version v0.0.2 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 AMT IDER module
@author Ylian Saint-Hilaire
@version v0.3.0
*/ */
/*jslint node: true */
/*jshint node: true */
/*jshint strict:false */
/*jshint -W097 */
/*jshint esversion: 6 */
"use strict";
// Construct a Intel AMT IDER object // Construct a Intel AMT IDER object
module.exports.CreateAmtRemoteIder = function (webserver, meshcentral) { module.exports.CreateAmtRemoteIder = function (webserver, meshcentral) {
const fs = require('fs'); const fs = require('fs');

View File

@ -1,9 +1,21 @@
/** /*
* @description MeshCentral Server IDER handler Copyright 2020 Intel Corporation
* @author Ylian Saint-Hilaire & Bryan Roe
* @copyright Intel Corporation 2018-2020 Licensed under the Apache License, Version 2.0 (the "License");
* @license Apache-2.0 you may not use this file except in compliance with the License.
* @version v0.0.1 You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@description MeshCentral Server IDER handler
@author Ylian Saint-Hilaire
@version v0.3.0
*/ */
/*jslint node: true */ /*jslint node: true */

View File

@ -1,9 +1,30 @@
/** /*
* @description Intel AMT Redirection Transport Module - using Node Copyright 2020 Intel Corporation
* @author Ylian Saint-Hilaire
* @version v0.0.1f 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 AMT redirection stack
@author Ylian Saint-Hilaire
@version v0.3.0
*/ */
/*jslint node: true */
/*jshint node: true */
/*jshint strict:false */
/*jshint -W097 */
/*jshint esversion: 6 */
"use strict";
// Construct a MeshServer object // Construct a MeshServer object
module.exports.CreateAmtRedirect = function (module, domain, user, webserver, meshcentral) { module.exports.CreateAmtRedirect = function (module, domain, user, webserver, meshcentral) {
var obj = {}; var obj = {};

View File

@ -1,10 +1,31 @@
/** m /*
* @description Intel(r) AMT WSMAN communication using Node.js TLS Copyright 2020 Intel Corporation
* @author Ylian Saint-Hilaire/Joko Sastriawan
* @version v0.2.0b 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 AMT WSMAN communication module for NodeJS
@author Ylian Saint-Hilaire
@version v0.3.0
*/ */
// Construct a MeshServer object /*jslint node: true */
/*jshint node: true */
/*jshint strict:false */
/*jshint -W097 */
/*jshint esversion: 6 */
"use strict";
// Construct a WSMAN stack communication object
var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraConnection) { var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraConnection) {
//console.log('CreateWsmanComm', host, port, user, pass, tls, tlsoptions); //console.log('CreateWsmanComm', host, port, user, pass, tls, tlsoptions);
@ -84,8 +105,8 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
// Private method // Private method
obj.PerformAjaxEx = function (postdata, callback, tag, url, action) { obj.PerformAjaxEx = function (postdata, callback, tag, url, action) {
if (obj.FailAllError != 0) { obj.gotNextMessagesError({ status: obj.FailAllError }, 'error', null, [postdata, callback, tag, url, action]); return; } if (obj.FailAllError != 0) { obj.gotNextMessagesError({ status: obj.FailAllError }, 'error', null, [postdata, callback, tag, url, action]); return; }
if (!postdata) postdata = ""; if (!postdata) postdata = '';
//obj.Debug("SEND: " + postdata); // DEBUG //obj.Debug('SEND: ' + postdata); // DEBUG
obj.ActiveAjaxCount++; obj.ActiveAjaxCount++;
return obj.PerformAjaxExNodeJS(postdata, callback, tag, url, action); return obj.PerformAjaxExNodeJS(postdata, callback, tag, url, action);
@ -113,11 +134,11 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
// NODE.js specific private method // NODE.js specific private method
obj.sendRequest = function (postdata, url, action) { obj.sendRequest = function (postdata, url, action) {
url = url ? url : "/wsman"; url = url ? url : '/wsman';
action = action ? action : "POST"; action = action ? action : 'POST';
var h = action + " " + url + " HTTP/1.1\r\n"; var h = action + ' ' + url + ' HTTP/1.1\r\n';
if (obj.challengeParams != null) { if (obj.challengeParams != null) {
obj.digestRealm = obj.challengeParams["realm"]; obj.digestRealm = obj.challengeParams['realm'];
if (obj.digestRealmMatch && (obj.digestRealm != obj.digestRealmMatch)) { if (obj.digestRealmMatch && (obj.digestRealm != obj.digestRealmMatch)) {
obj.FailAllError = 997; // Cause all new responses to be silent. 997 = Digest Realm check error obj.FailAllError = 997; // Cause all new responses to be silent. 997 = Digest Realm check error
obj.CancelAllQueries(997); obj.CancelAllQueries(997);
@ -143,13 +164,13 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
obj.kerberosDone = 1; obj.kerberosDone = 1;
} }
} else if (obj.challengeParams != null) { } else if (obj.challengeParams != null) {
var response = hex_md5(hex_md5(obj.user + ':' + obj.challengeParams["realm"] + ':' + obj.pass) + ':' + obj.challengeParams["nonce"] + ':' + obj.noncecounter + ':' + obj.cnonce + ':' + obj.challengeParams["qop"] + ':' + hex_md5(action + ':' + url)); var response = hex_md5(hex_md5(obj.user + ':' + obj.challengeParams['realm'] + ':' + obj.pass) + ':' + obj.challengeParams['nonce'] + ':' + obj.noncecounter + ':' + obj.cnonce + ':' + obj.challengeParams['qop'] + ':' + hex_md5(action + ':' + url));
h += 'Authorization: ' + obj.renderDigest({ "username": obj.user, "realm": obj.challengeParams["realm"], "nonce": obj.challengeParams["nonce"], "uri": url, "qop": obj.challengeParams["qop"], "response": response, "nc": obj.noncecounter++, "cnonce": obj.cnonce }) + '\r\n'; h += 'Authorization: ' + obj.renderDigest({ 'username': obj.user, 'realm': obj.challengeParams['realm'], 'nonce': obj.challengeParams['nonce'], 'uri': url, 'qop': obj.challengeParams['qop'], 'response': response, 'nc': obj.noncecounter++, 'cnonce': obj.cnonce }) + '\r\n';
} }
h += 'Host: ' + obj.host + ':' + obj.port + '\r\nContent-Length: ' + postdata.length + '\r\n\r\n' + postdata; // Use Content-Length h += 'Host: ' + obj.host + ':' + obj.port + '\r\nContent-Length: ' + postdata.length + '\r\n\r\n' + postdata; // Use Content-Length
//h += 'Host: ' + obj.host + ':' + obj.port + '\r\nTransfer-Encoding: chunked\r\n\r\n' + postdata.length.toString(16).toUpperCase() + '\r\n' + postdata + '\r\n0\r\n\r\n'; // Use Chunked-Encoding //h += 'Host: ' + obj.host + ':' + obj.port + '\r\nTransfer-Encoding: chunked\r\n\r\n' + postdata.length.toString(16).toUpperCase() + '\r\n' + postdata + '\r\n0\r\n\r\n'; // Use Chunked-Encoding
obj.xxSend(h); obj.xxSend(h);
//console.log("SEND: " + h); // Display send packet //console.log('SEND: ' + h); // Display send packet
} }
// NODE.js specific private method // NODE.js specific private method
@ -331,7 +352,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
// NODE.js specific private method // NODE.js specific private method
obj.xxOnSocketData = function (data) { obj.xxOnSocketData = function (data) {
//console.log("RECV:"+data); //console.log('RECV: ' + data);
obj.xtlsDataReceived = true; obj.xtlsDataReceived = true;
if (typeof data === 'object') { if (typeof data === 'object') {
// This is an ArrayBuffer, convert it to a string array (used in IE) // This is an ArrayBuffer, convert it to a string array (used in IE)
@ -345,10 +366,10 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
while (true) { while (true) {
//console.log('ACC(' + obj.socketAccumulator + '): ' + obj.socketAccumulator); //console.log('ACC(' + obj.socketAccumulator + '): ' + obj.socketAccumulator);
if (obj.socketParseState == 0) { if (obj.socketParseState == 0) {
var headersize = obj.socketAccumulator.indexOf("\r\n\r\n"); var headersize = obj.socketAccumulator.indexOf('\r\n\r\n');
if (headersize < 0) return; if (headersize < 0) return;
//obj.Debug("Header: "+obj.socketAccumulator.substring(0, headersize)); // Display received HTTP header //obj.Debug("Header: "+obj.socketAccumulator.substring(0, headersize)); // Display received HTTP header
obj.socketHeader = obj.socketAccumulator.substring(0, headersize).split("\r\n"); obj.socketHeader = obj.socketAccumulator.substring(0, headersize).split('\r\n');
if (obj.amtVersion == null) { for (var i in obj.socketHeader) { if (obj.socketHeader[i].indexOf('Server: Intel(R) Active Management Technology ') == 0) { obj.amtVersion = obj.socketHeader[i].substring(46); } } } if (obj.amtVersion == null) { for (var i in obj.socketHeader) { if (obj.socketHeader[i].indexOf('Server: Intel(R) Active Management Technology ') == 0) { obj.amtVersion = obj.socketHeader[i].substring(46); } } }
obj.socketAccumulator = obj.socketAccumulator.substring(headersize + 4); obj.socketAccumulator = obj.socketAccumulator.substring(headersize + 4);
obj.socketParseState = 1; obj.socketParseState = 1;
@ -363,12 +384,12 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
} }
if (obj.socketParseState == 1) { if (obj.socketParseState == 1) {
var csize = -1; var csize = -1;
if ((obj.socketXHeader["connection"] != undefined) && (obj.socketXHeader["connection"].toLowerCase() == 'close') && ((obj.socketXHeader["transfer-encoding"] == undefined) || (obj.socketXHeader["transfer-encoding"].toLowerCase() != 'chunked'))) { if ((obj.socketXHeader['connection'] != undefined) && (obj.socketXHeader['connection'].toLowerCase() == 'close') && ((obj.socketXHeader["transfer-encoding"] == undefined) || (obj.socketXHeader["transfer-encoding"].toLowerCase() != 'chunked'))) {
// The body ends with a close, in this case, we will only process the header // The body ends with a close, in this case, we will only process the header
csize = 0; csize = 0;
} else if (obj.socketXHeader["content-length"] != undefined) { } else if (obj.socketXHeader['content-length'] != undefined) {
// The body length is specified by the content-length // The body length is specified by the content-length
csize = parseInt(obj.socketXHeader["content-length"]); csize = parseInt(obj.socketXHeader['content-length']);
if (obj.socketAccumulator.length < csize) return; if (obj.socketAccumulator.length < csize) return;
var data = obj.socketAccumulator.substring(0, csize); var data = obj.socketAccumulator.substring(0, csize);
obj.socketAccumulator = obj.socketAccumulator.substring(csize); obj.socketAccumulator = obj.socketAccumulator.substring(csize);
@ -376,7 +397,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
csize = 0; csize = 0;
} else { } else {
// The body is chunked // The body is chunked
var clen = obj.socketAccumulator.indexOf("\r\n"); var clen = obj.socketAccumulator.indexOf('\r\n');
if (clen < 0) return; // Chunk length not found, exit now and get more data. if (clen < 0) return; // Chunk length not found, exit now and get more data.
// Chunk length if found, lets see if we can get the data. // Chunk length if found, lets see if we can get the data.
csize = parseInt(obj.socketAccumulator.substring(0, clen), 16); csize = parseInt(obj.socketAccumulator.substring(0, clen), 16);
@ -479,243 +500,9 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
try { callArgs[1](obj, null, { Header: { HttpError: request.status } }, request.status, callArgs[2]); } catch (ex) { console.error(ex); } try { callArgs[1](obj, null, { Header: { HttpError: request.status } }, request.status, callArgs[2]); } catch (ex) { console.error(ex); }
} }
/* // MD5 digest hash
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message function hex_md5(str) { return obj.crypto.createHash('md5').update(str).digest('hex'); }
* Digest Algorithm, as defined in RFC 1321.
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
/*
* Configurable variables. You may need to tweak these to be compatible with
* the server-side, but the defaults work in most cases.
*/
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function hex_md5(s) { return binl2hex(core_md5(str2binl(s), s.length * chrsz)); }
function b64_md5(s) { return binl2b64(core_md5(str2binl(s), s.length * chrsz)); }
function str_md5(s) { return binl2str(core_md5(str2binl(s), s.length * chrsz)); }
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
/*
* Perform a simple self-test to see if the VM is working
*/
function md5_vm_test() {
return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}
/*
* Calculate the MD5 of an array of little-endian words, and a bit length
*/
function core_md5(x, len) {
/* append padding */
x[len >> 5] |= 0x80 << ((len) % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
for (var i = 0; i < x.length; i += 16) {
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
}
return Array(a, b, c, d);
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
function md5_cmn(q, a, b, x, s, t) {
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
}
function md5_ff(a, b, c, d, x, s, t) {
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t) {
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t) {
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t) {
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}
/*
* Calculate the HMAC-MD5, of a key and some data
*/
function core_hmac_md5(key, data) {
var bkey = str2binl(key);
if (bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
var ipad = Array(16), opad = Array(16);
for (var i = 0; i < 16; i++) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
return core_md5(opad.concat(hash), 512 + 128);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function bit_rol(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
}
/*
* Convert a string to an array of little-endian words
* If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
*/
function str2binl(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz)
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32);
return bin;
}
/*
* Convert an array of little-endian words to a string
*/
function binl2str(bin) {
var str = "";
var mask = (1 << chrsz) - 1;
for (var i = 0; i < bin.length * 32; i += chrsz)
str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask);
return str;
}
/*
* Convert an array of little-endian words to a hex string.
*/
function binl2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +
hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
}
return str;
}
/*
* Convert an array of little-endian words to a base-64 string
*/
function binl2b64(binarray) {
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var str = "";
for (var i = 0; i < binarray.length * 4; i += 3) {
var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16)
| (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8)
| ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF);
for (var j = 0; j < 4; j++) {
if (i * 8 + j * 6 > binarray.length * 32) str += b64pad;
else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
}
}
return str;
}
return obj; return obj;
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2018 Intel Corporation Copyright 2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -12,16 +12,20 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
@description Intel AMT WSMAN Stack
@author Ylian Saint-Hilaire
@version v0.3.0
*/ */
/** /*jslint node: true */
* @description Intel(r) AMT WSMAN Stack /*jshint node: true */
* @author Ylian Saint-Hilaire/Joko Sastriawan /*jshint strict:false */
* @version v0.2.0 /*jshint -W097 */
*/ /*jshint esversion: 6 */
"use strict";
// Construct a MeshServer object // Construct a WSMAN stack object
//function WsmanStackCreateService(comm, host, port, user, pass, tls, extra, parent, mode)
function WsmanStackCreateService(comm) function WsmanStackCreateService(comm)
{ {
var obj = {_ObjectID: 'WSMAN'}; var obj = {_ObjectID: 'WSMAN'};

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2018 Intel Corporation Copyright 2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -12,13 +12,18 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
@description Intel AMT XML parsing module
@author Ylian Saint-Hilaire
@version v0.3.0
*/ */
/** /*jslint node: true */
* @description Parse XML /*jshint node: true */
* @author Ylian Saint-Hilaire /*jshint strict:false */
* @version v0.2.0 /*jshint -W097 */
*/ /*jshint esversion: 6 */
"use strict";
// Parse XML and return JSON // Parse XML and return JSON
module.exports.ParseWsman = function (xml) { module.exports.ParseWsman = function (xml) {

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2018 Intel Corporation Copyright 2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -12,13 +12,18 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
@description Intel AMT Communication Stack
@author Ylian Saint-Hilaire
@version v0.3.0
*/ */
/** /*jslint node: true */
* @fileoverview Intel(r) AMT Communication StackXX /*jshint node: true */
* @author Ylian Saint-Hilaire /*jshint strict:false */
* @version v0.2.0b /*jshint -W097 */
*/ /*jshint esversion: 6 */
"use strict";
/** /**
* Construct a AmtStackCreateService object, this is the main Intel AMT communication stack. * Construct a AmtStackCreateService object, this is the main Intel AMT communication stack.

View File

@ -775,8 +775,8 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
if (cirachannel.onSendOk) { cirachannel.onSendOk(cirachannel); } if (cirachannel.onSendOk) { cirachannel.onSendOk(cirachannel); }
} else { } else {
// Send a part of the pending buffer // Send a part of the pending buffer
SendChannelData(cirachannel.socket, cirachannel.amtchannelid, cirachannel.sendBuffer.substring(0, cirachannel.sendcredits)); SendChannelData(cirachannel.socket, cirachannel.amtchannelid, cirachannel.sendBuffer.slice(0, cirachannel.sendcredits));
cirachannel.sendBuffer = cirachannel.sendBuffer.substring(cirachannel.sendcredits); cirachannel.sendBuffer = cirachannel.sendBuffer.slice(cirachannel.sendcredits);
cirachannel.sendcredits = 0; cirachannel.sendcredits = 0;
} }
} }
@ -837,8 +837,8 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
if (cirachannel.onSendOk) { cirachannel.onSendOk(cirachannel); } if (cirachannel.onSendOk) { cirachannel.onSendOk(cirachannel); }
} else { } else {
// Send a part of the pending buffer // Send a part of the pending buffer
SendChannelData(cirachannel.socket, cirachannel.amtchannelid, cirachannel.sendBuffer.substring(0, cirachannel.sendcredits)); SendChannelData(cirachannel.socket, cirachannel.amtchannelid, cirachannel.sendBuffer.slice(0, cirachannel.sendcredits));
cirachannel.sendBuffer = cirachannel.sendBuffer.substring(cirachannel.sendcredits); cirachannel.sendBuffer = cirachannel.sendBuffer.slice(cirachannel.sendcredits);
cirachannel.sendcredits = 0; cirachannel.sendcredits = 0;
} }
} }
@ -959,9 +959,15 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
Write(socket, String.fromCharCode(APFProtocol.CHANNEL_CLOSE) + common.IntToStr(channelid)); Write(socket, String.fromCharCode(APFProtocol.CHANNEL_CLOSE) + common.IntToStr(channelid));
} }
// Send a buffer to a given channel
function SendChannelData(socket, channelid, data) { function SendChannelData(socket, channelid, data) {
parent.debug('mpscmddata', '<-- CHANNEL_DATA', channelid, data.length, Buffer.from(data, 'binary').toString('hex')); parent.debug('mpscmddata', '<-- CHANNEL_DATA', channelid, data.length);
Write(socket, String.fromCharCode(APFProtocol.CHANNEL_DATA) + common.IntToStr(channelid) + common.IntToStr(data.length) + ((typeof data == 'string') ? data : data.toString('binary'))); const buf = Buffer.alloc(9 + data.length);
buf[0] = APFProtocol.CHANNEL_DATA; // CHANNEL_DATA
buf.writeInt32BE(channelid, 1); // ChannelID
buf.writeInt32BE(data.length, 5); // Data Length
data.copy(buf, 9, 0);
WriteBuffer(socket, buf);
} }
function SendChannelWindowAdjust(socket, channelid, bytestoadd) { function SendChannelWindowAdjust(socket, channelid, bytestoadd) {
@ -986,6 +992,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
Write(socket, String.fromCharCode(APFProtocol.USERAUTH_SUCCESS)); Write(socket, String.fromCharCode(APFProtocol.USERAUTH_SUCCESS));
} }
// Send a string or buffer
function Write(socket, data) { function Write(socket, data) {
try { try {
if (args.mpsdebug) { if (args.mpsdebug) {
@ -999,6 +1006,14 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
} catch (ex) { } } catch (ex) { }
} }
// Send a buffer
function WriteBuffer(socket, data) {
try {
if (args.mpsdebug) { console.log('MPS <-- (' + buf.length + '):' + data.toString('hex')); } // Print out sent bytes
if (socket.websocket == 1) { socket.send(data); } else { socket.write(data); }
} catch (ex) { }
}
// Returns a CIRA/Relay/LMS connection to a nodeid, use the best possible connection, CIRA first, Relay second, LMS third. // Returns a CIRA/Relay/LMS connection to a nodeid, use the best possible connection, CIRA first, Relay second, LMS third.
// if oob is set to true, don't allow an LMS connection. // if oob is set to true, don't allow an LMS connection.
obj.GetConnectionToNode = function (nodeid, targetport, oob) { obj.GetConnectionToNode = function (nodeid, targetport, oob) {
@ -1033,9 +1048,10 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
// This function writes data to this CIRA channel // This function writes data to this CIRA channel
cirachannel.write = function (data) { cirachannel.write = function (data) {
if (cirachannel.state == 0) return false; if (cirachannel.state == 0) return false;
if (typeof data == 'string') { data = Buffer.from(data, 'binary'); } // Make sure we always handle buffers when sending data.
if (cirachannel.state == 1 || cirachannel.sendcredits == 0 || cirachannel.sendBuffer != null) { if (cirachannel.state == 1 || cirachannel.sendcredits == 0 || cirachannel.sendBuffer != null) {
// Channel is connected, but we are out of credits. Add the data to the outbound buffer. // Channel is connected, but we are out of credits. Add the data to the outbound buffer.
if (cirachannel.sendBuffer == null) { cirachannel.sendBuffer = data; } else { cirachannel.sendBuffer += data; } if (cirachannel.sendBuffer == null) { cirachannel.sendBuffer = data; } else { cirachannel.sendBuffer = Buffer.concat([ cirachannel.sendBuffer, data ]); }
return true; return true;
} }
// Compute how much data we can send // Compute how much data we can send
@ -1046,8 +1062,8 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
return true; return true;
} }
// Send a part of the message // Send a part of the message
cirachannel.sendBuffer = data.toString('binary').substring(cirachannel.sendcredits); cirachannel.sendBuffer = data.slice(cirachannel.sendcredits);
SendChannelData(cirachannel.socket, cirachannel.amtchannelid, data.toString('binary').substring(0, cirachannel.sendcredits)); SendChannelData(cirachannel.socket, cirachannel.amtchannelid, data.slice(0, cirachannel.sendcredits));
cirachannel.sendcredits = 0; cirachannel.sendcredits = 0;
return false; return false;
}; };