From fd6e0f99128e10a7582a8bff5f6707436c9b2c8d Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Wed, 14 Oct 2020 12:01:26 -0700 Subject: [PATCH] Added TLS support within CIRA, WSMAN stack improvements. --- amt/amt-ider-module.js | 29 +++- amt/amt-ider.js | 24 +++- amt/amt-redir-mesh.js | 29 +++- amt/amt-wsman-comm.js | 301 ++++++----------------------------------- amt/amt-wsman.js | 20 +-- amt/amt-xml.js | 17 ++- amt/amt.js | 17 ++- mpsserver.js | 34 +++-- 8 files changed, 171 insertions(+), 300 deletions(-) diff --git a/amt/amt-ider-module.js b/amt/amt-ider-module.js index 231b8bf3..2bfa5be6 100644 --- a/amt/amt-ider-module.js +++ b/amt/amt-ider-module.js @@ -1,9 +1,30 @@ -/** -* @description IDER Handling Module -* @author Ylian Saint-Hilaire -* @version v0.0.2 +/* +Copyright 2020 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 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 module.exports.CreateAmtRemoteIder = function (webserver, meshcentral) { const fs = require('fs'); diff --git a/amt/amt-ider.js b/amt/amt-ider.js index 9cfa8944..d7fb21b6 100644 --- a/amt/amt-ider.js +++ b/amt/amt-ider.js @@ -1,9 +1,21 @@ -/** -* @description MeshCentral Server IDER handler -* @author Ylian Saint-Hilaire & Bryan Roe -* @copyright Intel Corporation 2018-2020 -* @license Apache-2.0 -* @version v0.0.1 +/* +Copyright 2020 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +@description MeshCentral Server IDER handler +@author Ylian Saint-Hilaire +@version v0.3.0 */ /*jslint node: true */ diff --git a/amt/amt-redir-mesh.js b/amt/amt-redir-mesh.js index fdd2151f..883b5a84 100644 --- a/amt/amt-redir-mesh.js +++ b/amt/amt-redir-mesh.js @@ -1,9 +1,30 @@ -/** -* @description Intel AMT Redirection Transport Module - using Node -* @author Ylian Saint-Hilaire -* @version v0.0.1f +/* +Copyright 2020 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 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 module.exports.CreateAmtRedirect = function (module, domain, user, webserver, meshcentral) { var obj = {}; diff --git a/amt/amt-wsman-comm.js b/amt/amt-wsman-comm.js index 4342df4f..d9810cdd 100644 --- a/amt/amt-wsman-comm.js +++ b/amt/amt-wsman-comm.js @@ -1,10 +1,31 @@ -/** m -* @description Intel(r) AMT WSMAN communication using Node.js TLS -* @author Ylian Saint-Hilaire/Joko Sastriawan -* @version v0.2.0b +/* +Copyright 2020 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 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) { //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 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 (!postdata) postdata = ""; - //obj.Debug("SEND: " + postdata); // DEBUG + if (!postdata) postdata = ''; + //obj.Debug('SEND: ' + postdata); // DEBUG obj.ActiveAjaxCount++; 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 obj.sendRequest = function (postdata, url, action) { - url = url ? url : "/wsman"; - action = action ? action : "POST"; - var h = action + " " + url + " HTTP/1.1\r\n"; + url = url ? url : '/wsman'; + action = action ? action : 'POST'; + var h = action + ' ' + url + ' HTTP/1.1\r\n'; if (obj.challengeParams != null) { - obj.digestRealm = obj.challengeParams["realm"]; + obj.digestRealm = obj.challengeParams['realm']; if (obj.digestRealmMatch && (obj.digestRealm != obj.digestRealmMatch)) { obj.FailAllError = 997; // Cause all new responses to be silent. 997 = Digest Realm check error obj.CancelAllQueries(997); @@ -143,13 +164,13 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon obj.kerberosDone = 1; } } 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)); - 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'; + 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 += '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 obj.xxSend(h); - //console.log("SEND: " + h); // Display send packet + //console.log('SEND: ' + h); // Display send packet } // NODE.js specific private method @@ -331,7 +352,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon // NODE.js specific private method obj.xxOnSocketData = function (data) { - //console.log("RECV:"+data); + //console.log('RECV: ' + data); obj.xtlsDataReceived = true; if (typeof data === 'object') { // 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) { //console.log('ACC(' + obj.socketAccumulator + '): ' + obj.socketAccumulator); 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; //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); } } } obj.socketAccumulator = obj.socketAccumulator.substring(headersize + 4); obj.socketParseState = 1; @@ -363,12 +384,12 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon } if (obj.socketParseState == 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 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 - csize = parseInt(obj.socketXHeader["content-length"]); + csize = parseInt(obj.socketXHeader['content-length']); if (obj.socketAccumulator.length < csize) return; var data = obj.socketAccumulator.substring(0, csize); obj.socketAccumulator = obj.socketAccumulator.substring(csize); @@ -376,7 +397,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon csize = 0; } else { // 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. // Chunk length if found, lets see if we can get the data. 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); } } - /* - * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message - * 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. - */ + // MD5 digest hash + function hex_md5(str) { return obj.crypto.createHash('md5').update(str).digest('hex'); } - /* - * 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; } diff --git a/amt/amt-wsman.js b/amt/amt-wsman.js index 8efd2a2b..e99c661e 100644 --- a/amt/amt-wsman.js +++ b/amt/amt-wsman.js @@ -1,5 +1,5 @@ /* -Copyright 2018 Intel Corporation +Copyright 2020 Intel Corporation Licensed under the Apache License, Version 2.0 (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. See the License for the specific language governing permissions and limitations under the License. + +@description Intel AMT WSMAN Stack +@author Ylian Saint-Hilaire +@version v0.3.0 */ -/** -* @description Intel(r) AMT WSMAN Stack -* @author Ylian Saint-Hilaire/Joko Sastriawan -* @version v0.2.0 -*/ +/*jslint node: true */ +/*jshint node: true */ +/*jshint strict:false */ +/*jshint -W097 */ +/*jshint esversion: 6 */ +"use strict"; -// Construct a MeshServer object -//function WsmanStackCreateService(comm, host, port, user, pass, tls, extra, parent, mode) +// Construct a WSMAN stack object function WsmanStackCreateService(comm) { var obj = {_ObjectID: 'WSMAN'}; diff --git a/amt/amt-xml.js b/amt/amt-xml.js index eaba2df8..3225d4c7 100644 --- a/amt/amt-xml.js +++ b/amt/amt-xml.js @@ -1,5 +1,5 @@ /* -Copyright 2018 Intel Corporation +Copyright 2020 Intel Corporation Licensed under the Apache License, Version 2.0 (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. See the License for the specific language governing permissions and limitations under the License. + +@description Intel AMT XML parsing module +@author Ylian Saint-Hilaire +@version v0.3.0 */ -/** -* @description Parse XML -* @author Ylian Saint-Hilaire -* @version v0.2.0 -*/ +/*jslint node: true */ +/*jshint node: true */ +/*jshint strict:false */ +/*jshint -W097 */ +/*jshint esversion: 6 */ +"use strict"; // Parse XML and return JSON module.exports.ParseWsman = function (xml) { diff --git a/amt/amt.js b/amt/amt.js index 24956db0..b855f3dd 100644 --- a/amt/amt.js +++ b/amt/amt.js @@ -1,5 +1,5 @@ /* -Copyright 2018 Intel Corporation +Copyright 2020 Intel Corporation Licensed under the Apache License, Version 2.0 (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. See the License for the specific language governing permissions and limitations under the License. + +@description Intel AMT Communication Stack +@author Ylian Saint-Hilaire +@version v0.3.0 */ -/** -* @fileoverview Intel(r) AMT Communication StackXX -* @author Ylian Saint-Hilaire -* @version v0.2.0b -*/ +/*jslint node: true */ +/*jshint node: true */ +/*jshint strict:false */ +/*jshint -W097 */ +/*jshint esversion: 6 */ +"use strict"; /** * Construct a AmtStackCreateService object, this is the main Intel AMT communication stack. diff --git a/mpsserver.js b/mpsserver.js index a456bda4..ebf055e4 100644 --- a/mpsserver.js +++ b/mpsserver.js @@ -775,8 +775,8 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { if (cirachannel.onSendOk) { cirachannel.onSendOk(cirachannel); } } else { // Send a part of the pending buffer - SendChannelData(cirachannel.socket, cirachannel.amtchannelid, cirachannel.sendBuffer.substring(0, cirachannel.sendcredits)); - cirachannel.sendBuffer = cirachannel.sendBuffer.substring(cirachannel.sendcredits); + SendChannelData(cirachannel.socket, cirachannel.amtchannelid, cirachannel.sendBuffer.slice(0, cirachannel.sendcredits)); + cirachannel.sendBuffer = cirachannel.sendBuffer.slice(cirachannel.sendcredits); cirachannel.sendcredits = 0; } } @@ -837,8 +837,8 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { if (cirachannel.onSendOk) { cirachannel.onSendOk(cirachannel); } } else { // Send a part of the pending buffer - SendChannelData(cirachannel.socket, cirachannel.amtchannelid, cirachannel.sendBuffer.substring(0, cirachannel.sendcredits)); - cirachannel.sendBuffer = cirachannel.sendBuffer.substring(cirachannel.sendcredits); + SendChannelData(cirachannel.socket, cirachannel.amtchannelid, cirachannel.sendBuffer.slice(0, cirachannel.sendcredits)); + cirachannel.sendBuffer = cirachannel.sendBuffer.slice(cirachannel.sendcredits); 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)); } + // Send a buffer to a given channel function SendChannelData(socket, channelid, data) { - parent.debug('mpscmddata', '<-- CHANNEL_DATA', channelid, data.length, Buffer.from(data, 'binary').toString('hex')); - Write(socket, String.fromCharCode(APFProtocol.CHANNEL_DATA) + common.IntToStr(channelid) + common.IntToStr(data.length) + ((typeof data == 'string') ? data : data.toString('binary'))); + parent.debug('mpscmddata', '<-- CHANNEL_DATA', channelid, data.length); + 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) { @@ -986,6 +992,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { Write(socket, String.fromCharCode(APFProtocol.USERAUTH_SUCCESS)); } + // Send a string or buffer function Write(socket, data) { try { if (args.mpsdebug) { @@ -999,6 +1006,14 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { } 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. // if oob is set to true, don't allow an LMS connection. 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 cirachannel.write = function (data) { 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) { // 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; } // Compute how much data we can send @@ -1046,8 +1062,8 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { return true; } // Send a part of the message - cirachannel.sendBuffer = data.toString('binary').substring(cirachannel.sendcredits); - SendChannelData(cirachannel.socket, cirachannel.amtchannelid, data.toString('binary').substring(0, cirachannel.sendcredits)); + cirachannel.sendBuffer = data.slice(cirachannel.sendcredits); + SendChannelData(cirachannel.socket, cirachannel.amtchannelid, data.slice(0, cirachannel.sendcredits)); cirachannel.sendcredits = 0; return false; };