From d4c55680e27a38e135763062c74691e3614546de Mon Sep 17 00:00:00 2001 From: jsastriawan Date: Thu, 19 Sep 2019 12:25:13 -0700 Subject: [PATCH 1/2] Add AMT stack and disable _socket debug on apfserver.js --- amt/amt-wsman-comm.js | 659 ++++++++++++++++++++++++++ amt/amt-wsman.js | 213 +++++++++ amt/amt-xml.js | 189 ++++++++ amt/amt.js | 1020 +++++++++++++++++++++++++++++++++++++++++ apfserver.js | 2 +- 5 files changed, 2082 insertions(+), 1 deletion(-) create mode 100644 amt/amt-wsman-comm.js create mode 100644 amt/amt-wsman.js create mode 100644 amt/amt-xml.js create mode 100644 amt/amt.js diff --git a/amt/amt-wsman-comm.js b/amt/amt-wsman-comm.js new file mode 100644 index 00000000..49d32b89 --- /dev/null +++ b/amt/amt-wsman-comm.js @@ -0,0 +1,659 @@ +/** +* @description Intel(r) AMT WSMAN communication using Node.js TLS +* @author Ylian Saint-Hilaire +* @version v0.2.0b +*/ + +// Construct a MeshServer object +var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, parent, mode) { + //console.log('CreateWsmanComm', host, port, user, pass, tls, tlsoptions); + + 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.challengeParams = null; + obj.noncecounter = 1; + obj.authcounter = 0; + + obj.Address = '/wsman'; + obj.challengeParams = null; + obj.noncecounter = 1; + obj.authcounter = 0; + obj.cnonce = Math.random().toString(36).substring(7); // Generate a random client nonce + + obj.net = require('net'); + obj.tls = require('tls'); + obj.crypto = require('crypto'); + obj.constants = require('constants'); + obj.socket = null; + obj.socketState = 0; + obj.kerberosDone = 0; + obj.amtVersion = null; + + obj.host = host; + obj.port = port; + obj.user = user; + obj.pass = pass; + obj.xtls = tls; + obj.xtlsoptions = tlsoptions; + obj.parent = parent; + obj.mode = mode;//0: webrelay; 1: direct, 2: CIRA, 3: APF relay + obj.xtlsFingerprint; + obj.xtlsCertificate = null; + obj.xtlsCheck = 0; // 0 = No TLS, 1 = CA Checked, 2 = Pinned, 3 = Untrusted + obj.xtlsSkipHostCheck = 0; + obj.xtlsMethod = 0; + obj.xtlsDataReceived = false; + obj.digestRealmMatch = null; + obj.digestRealm = null; + + // Private method + obj.Debug = function (msg) { console.log(msg); } + + // 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) { obj.gotNextMessagesError({ status: obj.FailAllError }, 'error', null, [postdata, callback, tag, url, action]); return; } + if (!postdata) postdata = ""; + //obj.Debug("SEND: " + postdata); // DEBUG + + obj.ActiveAjaxCount++; + return obj.PerformAjaxExNodeJS(postdata, callback, tag, url, action); + } + + // NODE.js specific private method + obj.pendingAjaxCall = []; + + // NODE.js specific private method + obj.PerformAjaxExNodeJS = function (postdata, callback, tag, url, action) { obj.PerformAjaxExNodeJS2(postdata, callback, tag, url, action, 5); } + + // NODE.js specific private method + obj.PerformAjaxExNodeJS2 = function (postdata, callback, tag, url, action, retry) { + if (retry <= 0 || obj.FailAllError != 0) { + // Too many retry, fail here. + obj.ActiveAjaxCount--; + if (obj.FailAllError != 999) obj.gotNextMessages(null, 'error', { status: ((obj.FailAllError == 0) ? 408 : obj.FailAllError) }, [postdata, callback, tag, url, action]); // 408 is timeout error + obj.PerformNextAjax(); + return; + } + obj.pendingAjaxCall.push([postdata, callback, tag, url, action, retry]); + if (obj.socketState == 0) { obj.xxConnectHttpSocket(); } + else if (obj.socketState == 2) { obj.sendRequest(postdata, url, action); } + } + + // 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"; + if (obj.challengeParams != null) { + 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); + return; + } + } + if ((obj.user == '*') && (kerberos != null)) { + // Kerberos Auth + if (obj.kerberosDone == 0) { + var ticketName = 'HTTP' + ((obj.tls == 1) ? 'S' : '') + '/' + ((obj.pass == '') ? (obj.host + ':' + obj.port) : obj.pass); + // Ask for the new Kerberos ticket + //console.log('kerberos.getTicket', ticketName); + var ticketReturn = kerberos.getTicket(ticketName); + if (ticketReturn.returnCode == 0 || ticketReturn.returnCode == 0x90312) { + h += 'Authorization: Negotiate ' + ticketReturn.ticket + '\r\n'; + if (process.platform.indexOf('win') >= 0) { + // Clear kerberos tickets on both 32 and 64bit Windows platforms + try { require('child_process').exec('%windir%\\system32\\klist purge', function (error, stdout, stderr) { if (error) { require('child_process').exec('%windir%\\sysnative\\klist purge', function (error, stdout, stderr) { if (error) { console.error('Unable to purge kerberos tickets'); } }); } }); } catch (e) { console.log(e); } + } + } else { + console.log('Unexpected Kerberos error code: ' + ticketReturn.returnCode); + } + 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'; + } + 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 + } + + // NODE.js specific private method + obj.parseDigest = function (header) { + var t = header.substring(7).split(','); + for (i in t) t[i] = t[i].trim(); + return t.reduce(function (obj, s) { var parts = s.split('='); obj[parts[0]] = parts[1].replace(new RegExp('\"', 'g'), ''); return obj; }, {}) + } + + // NODE.js specific private method + obj.renderDigest = function (params) { + var paramsnames = []; + for (i in params) { paramsnames.push(i); } + return 'Digest ' + paramsnames.reduce(function (s1, ii) { return s1 + ',' + ii + '="' + params[ii] + '"' }, '').substring(1); + } + + // NODE.js specific private method + obj.xxConnectHttpSocket = function () { + //obj.Debug("xxConnectHttpSocket"); + obj.socketParseState = 0; + obj.socketAccumulator = ''; + obj.socketHeader = null; + obj.socketData = ''; + obj.socketState = 1; + obj.kerberosDone = 0; + + if (obj.mode==0 && obj.xtlsoptions && obj.xtlsoptions.meshServerConnect) { //Webrelay + // Use the websocket wrapper to connect to MeshServer server + obj.socket = CreateWebSocketWrapper(obj.xtlsoptions.host, obj.xtlsoptions.port, '/webrelay.ashx?user=' + encodeURIComponent(obj.xtlsoptions.username) + '&pass=' + encodeURIComponent(obj.xtlsoptions.password) + '&host=' + encodeURIComponent(obj.host) + '&p=1&tls1only=' + obj.xtlsMethod, obj.xtlsoptions.xtlsFingerprint); + obj.socket.setEncoding('binary'); + obj.socket.setTimeout(6000); // Set socket idle timeout + obj.socket.ondata = obj.xxOnSocketData; + obj.socket.onclose = function () { if (obj.xtlsDataReceived == false) { obj.xtlsMethod = 1 - obj.xtlsMethod; } obj.xxOnSocketClosed(); } + obj.socket.ontimeout = function () { if (obj.xtlsDataReceived == false) { obj.xtlsMethod = 1 - obj.xtlsMethod; } obj.xxOnSocketClosed(); } + obj.socket.connect(obj.xxOnSocketConnected); + obj.socket.setNoDelay(true); // Disable nagle. We will encode each WSMAN request as a single send block and want to send it at once. This may help Intel AMT handle pipelining? + } else if (obj.mode==1 ) { //Direct + if (obj.xtls != 1) { + // Connect without TLS + obj.socket = new obj.net.Socket(); + obj.socket.setEncoding('binary'); + obj.socket.setTimeout(6000); // Set socket idle timeout + obj.socket.on('data', obj.xxOnSocketData); + obj.socket.on('close', obj.xxOnSocketClosed); + obj.socket.on('timeout', obj.xxOnSocketClosed); + obj.socket.connect(obj.port, obj.host, obj.xxOnSocketConnected); + } else { + // Connect with TLS + var options = { secureProtocol: ((obj.xtlsMethod == 0) ? 'SSLv23_method' : 'TLSv1_method'), ciphers: 'RSA+AES:!aNULL:!MD5:!DSS', secureOptions: obj.constants.SSL_OP_NO_SSLv2 | obj.constants.SSL_OP_NO_SSLv3 | obj.constants.SSL_OP_NO_COMPRESSION | obj.constants.SSL_OP_CIPHER_SERVER_PREFERENCE, rejectUnauthorized: false }; + if (obj.xtlsoptions) { + if (obj.xtlsoptions.ca) options.ca = obj.xtlsoptions.ca; + if (obj.xtlsoptions.cert) options.cert = obj.xtlsoptions.cert; + if (obj.xtlsoptions.key) options.key = obj.xtlsoptions.key; + obj.xtlsoptions = options; + } + obj.socket = obj.tls.connect(obj.port, obj.host, obj.xtlsoptions, obj.xxOnSocketConnected); + obj.socket.setEncoding('binary'); + obj.socket.setTimeout(6000); // Set socket idle timeout + obj.socket.on('data', obj.xxOnSocketData); + obj.socket.on('close', obj.xxOnSocketClosed); + obj.socket.on('timeout', obj.xxOnSocketClosed); + obj.socket.on('error', function (e) { if (e.message && e.message.indexOf('sslv3 alert bad record mac') >= 0) { obj.xtlsMethod = 1 - obj.xtlsMethod; } }); + } + obj.socket.setNoDelay(true); // Disable nagle. We will encode each WSMAN request as a single send block and want to send it at once. This may help Intel AMT handle pipelining? + } else if (obj.mode==2 || obj.mode==3) { // CIRA and APF + if (obj.mode==2) { // CIRA + var ciraconn = obj.parent.mpsserver.ciraConnections[obj.host]; + obj.socket = obj.parent.mpsserver.SetupCiraChannel(ciraconn, obj.port); + } else { //APF + var apfconn = obj.parent.apfserver.apfConnections[obj.host]; + obj.socket = obj.parent.apfserver.SetupCiraChannel(apfconn, obj.port); + } + obj.socket.onData = function (ccon, data) { + _OnSocketData(data); + } + + obj.socket.onStateChange = function (ccon, state) { + if (state == 0) { + try { + obj.socketParseState = 0; + obj.socketAccumulator = ''; + obj.socketHeader = null; + obj.socketData = ''; + obj.socketState = 0; + _OnSocketClosed(); + } catch (e) { } + } else if (state == 2) { + // channel open success + _OnSocketConnected(); + } + } + } + } + + // Get the certificate of Intel AMT + obj.getPeerCertificate = function () { if (obj.xtls == 1) { return obj.socket.getPeerCertificate(); } return null; } + obj.getPeerCertificateFingerprint = function () { if (obj.xtls == 1) { return obj.socket.getPeerCertificate().fingerprint.split(':').join('').toLowerCase(); } return null; } + + // NODE.js specific private method + obj.xxOnSocketConnected = function () { + if (obj.socket == null) return; + // check TLS certificate for webrelay and direct only + if (obj.mode < 2 && obj.xtls == 1) { + obj.xtlsCertificate = obj.socket.getPeerCertificate(); + + // ###BEGIN###{Certificates} + // Setup the forge certificate check + var camatch = 0; + if (obj.xtlsoptions.ca) { + var forgeCert = forge.pki.certificateFromAsn1(forge.asn1.fromDer(atob(obj.xtlsCertificate.raw.toString('base64')))); + var caStore = forge.pki.createCaStore(obj.xtlsoptions.ca); + // Got thru all certificates in the store and look for a match. + for (var i in caStore.certs) { + if (camatch == 0) { + var c = caStore.certs[i], verified = false; + try { verified = c.verify(forgeCert); } catch (e) { } + if (verified == true) { camatch = c; } + } + } + // We found a match, check that the CommonName matches the hostname + if ((obj.xtlsSkipHostCheck == 0) && (camatch != 0)) { + amtcertname = forgeCert.subject.getField('CN').value; + if (amtcertname.toLowerCase() != obj.host.toLowerCase()) { camatch = 0; } + } + } + if ((camatch == 0) && (obj.xtlsFingerprint != 0) && (obj.xtlsCertificate.fingerprint.split(':').join('').toLowerCase() != obj.xtlsFingerprint)) { + obj.FailAllError = 998; // Cause all new responses to be silent. 998 = TLS Certificate check error + obj.CancelAllQueries(998); + return; + } + if ((obj.xtlsFingerprint == 0) && (camatch == 0)) { obj.xtlsCheck = 3; } else { obj.xtlsCheck = (camatch == 0) ? 2 : 1; } + // ###END###{Certificates} + // ###BEGIN###{!Certificates} + if ((obj.xtlsFingerprint != 0) && (obj.xtlsCertificate.fingerprint.split(':').join('').toLowerCase() != obj.xtlsFingerprint)) { + obj.FailAllError = 998; // Cause all new responses to be silent. 998 = TLS Certificate check error + obj.CancelAllQueries(998); + return; + } + obj.xtlsCheck = 2; + // ###END###{!Certificates} + } else { obj.xtlsCheck = 0; } + obj.socketState = 2; + obj.socketParseState = 0; + for (i in obj.pendingAjaxCall) { obj.sendRequest(obj.pendingAjaxCall[i][0], obj.pendingAjaxCall[i][3], obj.pendingAjaxCall[i][4]); } + } + + // NODE.js specific private method + obj.xxOnSocketData = function (data) { + obj.xtlsDataReceived = true; + if (urlvars && urlvars['wsmantrace']) { console.log("WSMAN-RECV(" + data.length + "): " + data); } + if (typeof data === 'object') { + // This is an ArrayBuffer, convert it to a string array (used in IE) + var binary = "", bytes = new Uint8Array(data), length = bytes.byteLength; + for (var i = 0; i < length; i++) { binary += String.fromCharCode(bytes[i]); } + data = binary; + } + else if (typeof data !== 'string') return; + + obj.socketAccumulator += data; + while (true) { + //console.log('ACC(' + obj.socketAccumulator + '): ' + obj.socketAccumulator); + if (obj.socketParseState == 0) { + var headersize = obj.socketAccumulator.indexOf("\r\n\r\n"); + if (headersize < 0) return; + //obj.Debug(obj.socketAccumulator.substring(0, headersize)); // Display received HTTP header + 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; + obj.socketData = ''; + obj.socketXHeader = { Directive: obj.socketHeader[0].split(' ') }; + for (i in obj.socketHeader) { + if (i != 0) { + var x2 = obj.socketHeader[i].indexOf(':'); + obj.socketXHeader[obj.socketHeader[i].substring(0, x2).toLowerCase()] = obj.socketHeader[i].substring(x2 + 2); + } + } + } + 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'))) { + // The body ends with a close, in this case, we will only process the header + csize = 0; + } else if (obj.socketXHeader["content-length"] != undefined) { + // The body length is specified by the 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); + obj.socketData = data; + csize = 0; + } else { + // The body is chunked + 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); + if (obj.socketAccumulator.length < clen + 2 + csize + 2) return; + // We got a chunk with all of the data, handle the chunck now. + var data = obj.socketAccumulator.substring(clen + 2, clen + 2 + csize); + obj.socketAccumulator = obj.socketAccumulator.substring(clen + 2 + csize + 2); + obj.socketData += data; + } + if (csize == 0) { + //obj.Debug("xxOnSocketData DONE: (" + obj.socketData.length + "): " + obj.socketData); + obj.xxProcessHttpResponse(obj.socketXHeader, obj.socketData); + obj.socketParseState = 0; + obj.socketHeader = null; + } + } + } + } + + // NODE.js specific private method + obj.xxProcessHttpResponse = function (header, data) { + //obj.Debug("xxProcessHttpResponse: " + header.Directive[1]); + + var s = parseInt(header.Directive[1]); + if (isNaN(s)) s = 500; + if (s == 401 && ++(obj.authcounter) < 3) { + obj.challengeParams = obj.parseDigest(header['www-authenticate']); // Set the digest parameters, after this, the socket will close and we will auto-retry + obj.socket.end(); + } else { + var r = obj.pendingAjaxCall.shift(); + if (r == null || r.length < 1) { console.log("pendingAjaxCall error, " + r); return; } + //if (s != 200) { obj.Debug("Error, status=" + s + "\r\n\r\nreq=" + r[0] + "\r\n\r\nresp=" + data); } // Debug: Display the request & response if something did not work. + obj.authcounter = 0; + obj.ActiveAjaxCount--; + obj.gotNextMessages(data, 'success', { status: s }, r); + obj.PerformNextAjax(); + } + } + + // NODE.js specific private method + obj.xxOnSocketClosed = function (data) { + //obj.Debug("xxOnSocketClosed"); + obj.socketState = 0; + if (obj.socket != null) { obj.socket.destroy(); obj.socket = null; } + if (obj.pendingAjaxCall.length > 0) { + var r = obj.pendingAjaxCall.shift(); + var retry = r[5]; + setTimeout(function () { obj.PerformAjaxExNodeJS2(r[0], r[1], r[2], r[3], r[4], --retry) }, 500); // Wait half a second and try again + } + } + + // NODE.js specific private method + obj.xxSend = function (x) { + if (obj.socketState == 2) { + if (urlvars && urlvars['wsmantrace']) { console.log("WSMAN-SEND(" + x.length + "): " + x); } + obj.socket.write(new Buffer(x, "binary")); + } + } + + // Cancel all pending queries with given status + obj.CancelAllQueries = function (s) { + obj.FailAllError = s; + while (obj.PendingAjax.length > 0) { var x = obj.PendingAjax.shift(); x[1](null, s, x[2]); } + if (obj.socket != null) { obj.socket.end(); obj.socket = null; obj.socketState = 0; } + } + + // Private method + obj.gotNextMessages = function (data, status, request, callArgs) { + if (obj.FailAllError == 999) return; + if (obj.FailAllError != 0) { try { callArgs[1](null, obj.FailAllError, callArgs[2]); } catch (ex) { console.error(ex); } return; } + if (request.status != 200) { try { callArgs[1](null, request.status, callArgs[2]); } catch (ex) { console.error(ex); } return; } + try { callArgs[1](data, 200, callArgs[2]); } catch (ex) { console.error(ex); } + } + + // Private method + obj.gotNextMessagesError = function (request, status, errorThrown, callArgs) { + if (obj.FailAllError == 999) return; + if (obj.FailAllError != 0) { try { callArgs[1](null, obj.FailAllError, callArgs[2]); } catch (ex) { console.error(ex); } return; } + 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. + */ + + /* + * 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; +} + +module.exports = CreateWsmanComm; \ No newline at end of file diff --git a/amt/amt-wsman.js b/amt/amt-wsman.js new file mode 100644 index 00000000..88f71bde --- /dev/null +++ b/amt/amt-wsman.js @@ -0,0 +1,213 @@ +/* +Copyright 2018 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @description Intel(r) AMT WSMAN Stack +* @author Ylian Saint-Hilaire +* @version v0.2.0 +*/ + +// Construct a MeshServer object +function WsmanStackCreateService(CreateWsmanComm, host, port, user, pass, tls, extra) +{ + var obj = {_ObjectID: 'WSMAN'}; + //obj.onDebugMessage = null; // Set to a function if you want to get debug messages. + obj.NextMessageId = 1; // Next message number, used to label WSMAN calls. + obj.Address = '/wsman'; + obj.xmlParser = require('./amt-xml.js'); + + if (arguments.length == 1 && typeof (arguments[0] == 'object')) + { + var CreateWsmanComm = arguments[0].transport; + if (CreateWsmanComm) { obj.comm = new CreateWsmanComm(arguments[0]); } + } + else + { + var CreateWsmanComm = arguments[0]; + if (CreateWsmanComm) { + obj.comm = new CreateWsmanComm(host, port, user, pass, tls, extra); + } + } + + obj.PerformAjax = function PerformAjax(postdata, callback, tag, pri, namespaces) { + if (namespaces == null) namespaces = ''; + obj.comm.PerformAjax('
' + postdata, function (data, status, tag) { + if (status != 200) { callback(obj, null, { Header: { HttpError: status } }, status, tag); return; } + var wsresponse = obj.xmlParser.ParseWsman(data); + if (!wsresponse || wsresponse == null) { callback(obj, null, { Header: { HttpError: status } }, 601, tag); } else { callback(obj, wsresponse.Header["ResourceURI"], wsresponse, 200, tag); } + }, tag, pri); + } + + // Private method + //obj.Debug = function (msg) { /*console.log(msg);*/ } + + // Cancel all pending queries with given status + obj.CancelAllQueries = function CancelAllQueries(s) { obj.comm.CancelAllQueries(s); } + + // Get the last element of a URI string + obj.GetNameFromUrl = function (resuri) { + var x = resuri.lastIndexOf("/"); + return (x == -1)?resuri:resuri.substring(x + 1); + } + + // Perform a WSMAN Subscribe operation + obj.ExecSubscribe = function ExecSubscribe(resuri, delivery, url, callback, tag, pri, selectors, opaque, user, pass) { + var digest = "", digest2 = "", opaque = ""; + if (user != null && pass != null) { digest = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken' + user + '' + pass + ''; digest2 = ''; } + if (opaque != null) { opaque = '' + opaque + ''; } + 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" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous" + _PutObjToSelectorsXml(selectors) + digest + '
' + url + '' + opaque + '' + digest2 + ''; + obj.PerformAjax(data + "
", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:m="http://x.com"'); + } + + // Perform a WSMAN UnSubscribe operation + obj.ExecUnSubscribe = function ExecUnSubscribe(resuri, callback, tag, pri, selectors) { + var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous" + _PutObjToSelectorsXml(selectors) + ''; + obj.PerformAjax(data + "", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"'); + } + + // Perform a WSMAN PUT operation + obj.ExecPut = function ExecPut(resuri, putobj, callback, tag, pri, selectors) { + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Put" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60.000S" + _PutObjToSelectorsXml(selectors) + '' + _PutObjToBodyXml(resuri, putobj); + obj.PerformAjax(data + "", callback, tag, pri); + } + + // Perform a WSMAN CREATE operation + obj.ExecCreate = function ExecCreate(resuri, putobj, callback, tag, pri, selectors) { + var objname = obj.GetNameFromUrl(resuri); + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Create" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S" + _PutObjToSelectorsXml(selectors) + ""; + for (var n in putobj) { data += "" + putobj[n] + "" } + obj.PerformAjax(data + "", callback, tag, pri); + } + + // Perform a WSMAN DELETE operation + obj.ExecDelete = function ExecDelete(resuri, putobj, callback, tag, pri) { + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S" + _PutObjToSelectorsXml(putobj) + ""; + obj.PerformAjax(data, callback, tag, pri); + } + + // Perform a WSMAN GET operation + obj.ExecGet = function ExecGet(resuri, callback, tag, pri) { + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S", callback, tag, pri); + } + + // Perform a WSMAN method call operation + obj.ExecMethod = function ExecMethod(resuri, method, args, callback, tag, pri, selectors) { + var argsxml = ""; + for (var i in args) { if (args[i] != null) { if (Array.isArray(args[i])) { for (var x in args[i]) { argsxml += "" + args[i][x] + ""; } } else { argsxml += "" + args[i] + ""; } } } + obj.ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors); + } + + // Perform a WSMAN method call operation. The arguments are already formatted in XML. + obj.ExecMethodXml = function ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors) { + obj.PerformAjax(resuri + "/" + method + "" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S" + _PutObjToSelectorsXml(selectors) + "" + argsxml + "", callback, tag, pri); + } + + // Perform a WSMAN ENUM operation + obj.ExecEnum = function ExecEnum(resuri, callback, tag, pri) { + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S", callback, tag, pri); + } + + // Perform a WSMAN PULL operation + obj.ExecPull = function ExecPull(resuri, enumctx, callback, tag, pri) { + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S" + enumctx + "99999999", callback, tag, pri); + } + + function _PutObjToBodyXml(resuri, putObj) { + if (!resuri || putObj == null) return ''; + var objname = obj.GetNameFromUrl(resuri); + var result = ''; + + 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 += '' + putObj[prop].Address + '' + putObj[prop]['ReferenceParameters']["ResourceURI"] + ''; + var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector']; + if (Array.isArray(selectorArray)) { + for (var i=0; i< selectorArray.length; i++) { + result += '' + selectorArray[i]['Value'] + ''; + } + } + else { + result += '' + selectorArray['Value'] + ''; + } + result += ''; + } + else { + if (Array.isArray(putObj[prop])) { + for (var i = 0; i < putObj[prop].length; i++) { + result += '' + putObj[prop][i].toString() + ''; + } + } else { + result += '' + putObj[prop].toString() + ''; + } + } + } + + result += ''; + 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 "" + selectorSet['InstanceID'] + ""; + var result = ''; + for(var propName in selectorSet) { + if (!selectorSet.hasOwnProperty(propName)) continue; + result += ''; + if (selectorSet[propName]['ReferenceParameters']) { + result += ''; + result += '' + selectorSet[propName]['Address'] + '' + selectorSet[propName]['ReferenceParameters']['ResourceURI'] + ''; + var selectorArray = selectorSet[propName]['ReferenceParameters']['SelectorSet']['Selector']; + if (Array.isArray(selectorArray)) { + for (var i = 0; i < selectorArray.length; i++) { + result += '' + selectorArray[i]['Value'] + ''; + } + } else { + result += '' + selectorArray['Value'] + ''; + } + result += ''; + } else { + result += selectorSet[propName]; + } + result += ''; + } + result += ''; + return result; + } + + return obj; +} + +module.exports = WsmanStackCreateService; \ No newline at end of file diff --git a/amt/amt-xml.js b/amt/amt-xml.js new file mode 100644 index 00000000..5e4a20c5 --- /dev/null +++ b/amt/amt-xml.js @@ -0,0 +1,189 @@ +/* +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 Parse XML +* @author Ylian Saint-Hilaire +* @version v0.2.0 +*/ + +// Parse XML and return JSON +module.exports.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 = ''; + + 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 += '' + putObj[prop].Address + '' + putObj[prop]['ReferenceParameters']["ResourceURI"] + ''; + var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector']; + if (Array.isArray(selectorArray)) { + for (var i = 0; i < selectorArray.length; i++) { + result += '' + selectorArray[i]['Value'] + ''; + } + } + else { + result += '' + selectorArray['Value'] + ''; + } + result += ''; + } + else { + if (Array.isArray(putObj[prop])) { + for (var i = 0; i < putObj[prop].length; i++) { + result += '' + putObj[prop][i].toString() + ''; + } + } else { + result += '' + putObj[prop].toString() + ''; + } + } + } + + result += ''; + return result; +} + +// This is a drop-in replacement to _turnToXml() that works without xml parser dependency. +try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : null); } }); } catch (ex) { } +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; +} \ No newline at end of file diff --git a/amt/amt.js b/amt/amt.js new file mode 100644 index 00000000..c5164b04 --- /dev/null +++ b/amt/amt.js @@ -0,0 +1,1020 @@ +/* +Copyright 2018 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @fileoverview Intel(r) AMT Communication StackXX +* @author Ylian Saint-Hilaire +* @version v0.2.0b +*/ + +/** + * Construct a AmtStackCreateService object, this is the main Intel AMT communication stack. + * @constructor + */ +function AmtStackCreateService(wsmanStack) { + var obj = new Object(); + obj._ObjectID = 'AMT' + obj.wsman = wsmanStack; + obj.pfx = ["http://intel.com/wbem/wscim/1/amt-schema/1/", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/", "http://intel.com/wbem/wscim/1/ips-schema/1/"]; + obj.PendingEnums = []; + obj.PendingBatchOperations = 0; + obj.ActiveEnumsCount = 0; + obj.MaxActiveEnumsCount = 1; // Maximum number of enumerations that can be done at the same time. + obj.onProcessChanged = null; + var _MaxProcess = 0; + var _LastProcess = 0; + + // Return the number of pending actions + obj.GetPendingActions = function () { return (obj.PendingEnums.length * 2) + (obj.ActiveEnumsCount) + obj.wsman.comm.PendingAjax.length + obj.wsman.comm.ActiveAjaxCount + obj.PendingBatchOperations; } + + // Private Method, Update the current processing status, this gives the application an idea of what progress is being done by the WSMAN stack + function _up() { + var x = obj.GetPendingActions(); + if (_MaxProcess < x) _MaxProcess = x; + if (obj.onProcessChanged != null && _LastProcess != x) { + //console.log("Process Old=" + _LastProcess + ", New=" + x + ", PEnums=" + obj.PendingEnums.length + ", AEnums=" + obj.ActiveEnumsCount + ", PAjax=" + obj.wsman.comm.PendingAjax.length + ", AAjax=" + obj.wsman.comm.ActiveAjaxCount + ", PBatch=" + obj.PendingBatchOperations); + _LastProcess = x; + obj.onProcessChanged(x, _MaxProcess); + } + if (x == 0) _MaxProcess = 0; + } + + // Perform a WSMAN "SUBSCRIBE" operation. + obj.Subscribe = function Subscribe(name, delivery, url, callback, tag, pri, selectors, opaque, user, pass) { obj.wsman.ExecSubscribe(obj.CompleteName(name), delivery, url, function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri, selectors, opaque, user, pass); _up(); } + + // Perform a WSMAN "UNSUBSCRIBE" operation. + obj.UnSubscribe = function UnSubscribe(name, callback, tag, pri, selectors) { obj.wsman.ExecUnSubscribe(obj.CompleteName(name), function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri, selectors); _up(); } + + // Perform a WSMAN "GET" operation. + obj.Get = function Get(name, callback, tag, pri) { obj.wsman.ExecGet(obj.CompleteName(name), function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri); _up(); } + + // Perform a WSMAN "PUT" operation. + obj.Put = function Put(name, putobj, callback, tag, pri, selectors) { obj.wsman.ExecPut(obj.CompleteName(name), putobj, function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri, selectors); _up(); } + + // Perform a WSMAN "CREATE" operation. + obj.Create = function Create(name, putobj, callback, tag, pri) { obj.wsman.ExecCreate(obj.CompleteName(name), putobj, function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri); _up(); } + + // Perform a WSMAN "DELETE" operation. + obj.Delete = function Delete(name, putobj, callback, tag, pri) { obj.wsman.ExecDelete(obj.CompleteName(name), putobj, function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri); _up(); } + + // Perform a WSMAN method call operation. + obj.Exec = function Exec(name, method, args, callback, tag, pri, selectors) { obj.wsman.ExecMethod(obj.CompleteName(name), method, args, function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, obj.CompleteExecResponse(response), xstatus, tag); }, 0, pri, selectors); _up(); } + + // Perform a WSMAN method call operation. + obj.ExecWithXml = function ExecWithXml(name, method, args, callback, tag, pri, selectors) { obj.wsman.ExecMethodXml(obj.CompleteName(name), method, execArgumentsToXml(args), function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, obj.CompleteExecResponse(response), xstatus, tag); }, 0, pri, selectors); _up(); } + + // Perform a WSMAN "ENUMERATE" operation. + obj.Enum = function Enum(name, callback, tag, pri) { + if (obj.ActiveEnumsCount < obj.MaxActiveEnumsCount) { + obj.ActiveEnumsCount++; obj.wsman.ExecEnum(obj.CompleteName(name), function (ws, resuri, response, xstatus, tag0) { _up(); _EnumStartSink(name, response, callback, resuri, xstatus, tag0); }, tag, pri); + } else { + obj.PendingEnums.push([name, callback, tag, pri]); + } + _up(); + } + + // Private method + function _EnumStartSink(name, response, callback, resuri, status, tag, pri) { + if (status != 200) { callback.call(obj, obj, name, null, status, tag); _EnumDoNext(1); return; } + if (response == null || response.Header["Method"] != "EnumerateResponse" || !response.Body["EnumerationContext"]) { callback.call(obj, obj, name, null, 603, tag); _EnumDoNext(1); return; } + var enumctx = response.Body["EnumerationContext"]; + obj.wsman.ExecPull(resuri, enumctx, function (ws, resuri, response, xstatus) { _EnumContinueSink(name, response, callback, resuri, [], xstatus, tag, pri); }); + } + + // Private method + function _EnumContinueSink(name, response, callback, resuri, items, status, tag, pri) { + if (status != 200) { callback.call(obj, obj, name, null, status, tag); _EnumDoNext(1); return; } + if (response == null || response.Header["Method"] != "PullResponse") { callback.call(obj, obj, name, null, 604, tag); _EnumDoNext(1); return; } + for (var i in response.Body["Items"]) { + if (response.Body["Items"][i] instanceof Array) { + for (var j in response.Body["Items"][i]) { items.push(response.Body["Items"][i][j]); } + } else { + items.push(response.Body["Items"][i]); + } + } + if (response.Body["EnumerationContext"]) { + var enumctx = response.Body["EnumerationContext"]; + obj.wsman.ExecPull(resuri, enumctx, function (ws, resuri, response, xstatus) { _EnumContinueSink(name, response, callback, resuri, items, xstatus, tag, 1); }); + } else { + _EnumDoNext(1); + callback.call(obj, obj, name, items, status, tag); + _up(); + } + } + + // Private method + function _EnumDoNext(dec) { + obj.ActiveEnumsCount -= dec; + if (obj.ActiveEnumsCount >= obj.MaxActiveEnumsCount || obj.PendingEnums.length == 0) return; + var x = obj.PendingEnums.shift(); + obj.Enum(x[0], x[1], x[2]); + _EnumDoNext(0); + } + + // Perform a batch of WSMAN "ENUM" operations. + obj.BatchEnum = function (batchname, names, callback, tag, continueOnError, pri) { + obj.PendingBatchOperations += (names.length * 2); + _BatchNextEnum(batchname, Clone(names), callback, tag, {}, continueOnError, pri); _up(); + } + + function Clone(v) { return JSON.parse(JSON.stringify(v)); } + + // Request each enum in the batch, stopping if something does not return status 200 + function _BatchNextEnum(batchname, names, callback, tag, results, continueOnError, pri) { + obj.PendingBatchOperations -= 2; + var n = names.shift(), f = obj.Enum; + if (n[0] == '*') { f = obj.Get; n = n.substring(1); } // If the name starts with a star, do a GET instead of an ENUM. This will reduce round trips. + //console.log((f == obj.Get?'Get ':'Enum ') + n); + // Perform a GET/ENUM action + f(n, function (stack, name, responses, status, tag0) { + tag0[2][name] = { response: (responses==null?null:responses.Body), responses: responses, status: status }; + if (tag0[1].length == 0 || status == 401 || (continueOnError != true && status != 200 && status != 400)) { obj.PendingBatchOperations -= (names.length * 2); _up(); callback.call(obj, obj, batchname, tag0[2], status, tag); } + else { _up(); _BatchNextEnum(batchname, names, callback, tag, tag0[2], pri); } + }, [batchname, names, results], pri); + _up(); + } + + // Perform a batch of WSMAN "GET" operations. + obj.BatchGet = function (batchname, names, callback, tag, pri) { + _FetchNext({ name: batchname, names: names, callback: callback, current: 0, responses: {}, tag: tag, pri: pri }); _up(); + } + + // Private method + function _FetchNext(batch) { + if (batch.names.length <= batch.current) { + batch.callback.call(obj, obj, batch.name, batch.responses, 200, batch.tag); + } else { + obj.wsman.ExecGet(obj.CompleteName(batch.names[batch.current]), function (ws, resuri, response, xstatus) { _Fetched(batch, response, xstatus); }, batch.pri); + batch.current++; + } + _up(); + } + + // Private method + function _Fetched(batch, response, status) { + if (response == null || status != 200) { + batch.callback.call(obj, obj, batch.name, null, status, batch.tag); + } else { + batch.responses[response.Header["Method"]] = response; + _FetchNext(batch); + } + } + + // Private method + obj.CompleteName = function(name) { + if (name.indexOf("AMT_") == 0) return obj.pfx[0] + name; + if (name.indexOf("CIM_") == 0) return obj.pfx[1] + name; + if (name.indexOf("IPS_") == 0) return obj.pfx[2] + name; + } + + obj.CompleteExecResponse = function (resp) { + if (resp && resp != null && resp.Body && (resp.Body["ReturnValue"] != undefined)) { resp.Body.ReturnValueStr = obj.AmtStatusToStr(resp.Body["ReturnValue"]); } + return resp; + } + + obj.RequestPowerStateChange = function (PowerState, callback_func) { + obj.CIM_PowerManagementService_RequestPowerStateChange(PowerState, "
http://schemas.xmlsoap.org/ws/2004/08/addressing
http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystemCIM_ComputerSystemManagedSystem", null, null, callback_func); + } + + obj.SetBootConfigRole = function (Role, callback_func) { + obj.CIM_BootService_SetBootConfigRole("
http://schemas.xmlsoap.org/ws/2004/08/addressing
http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_BootConfigSettingIntel(r) AMT: Boot Configuration 0", Role, callback_func); + } + + // Cancel all pending queries with given status + obj.CancelAllQueries = function (s) { + obj.wsman.CancelAllQueries(s); + } + + // Auto generated methods + obj.AMT_AgentPresenceWatchdog_RegisterAgent = function (callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "RegisterAgent", {}, callback_func, tag, pri, selectors); } + obj.AMT_AgentPresenceWatchdog_AssertPresence = function (SequenceNumber, callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func, tag, pri, selectors); } + obj.AMT_AgentPresenceWatchdog_AssertShutdown = function (SequenceNumber, callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func, tag, pri, selectors); } + //obj.AMT_AgentPresenceWatchdog_RegisterAgent = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdog", "RegisterAgent", {}, callback_func); } + //obj.AMT_AgentPresenceWatchdog_AssertPresence = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func); } + //obj.AMT_AgentPresenceWatchdog_AssertShutdown = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func); } + obj.AMT_AgentPresenceWatchdog_AddAction = function (OldState, NewState, EventOnTransition, ActionSd, ActionEac, callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "AddAction", { "OldState": OldState, "NewState": NewState, "EventOnTransition": EventOnTransition, "ActionSd": ActionSd, "ActionEac": ActionEac }, callback_func, tag, pri, selectors); } + obj.AMT_AgentPresenceWatchdog_DeleteAllActions = function (callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "DeleteAllActions", {}, callback_func, tag, pri, selectors); } + obj.AMT_AgentPresenceWatchdogAction_GetActionEac = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdogAction", "GetActionEac", {}, callback_func); } + obj.AMT_AgentPresenceWatchdogVA_RegisterAgent = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "RegisterAgent", {}, callback_func); } + obj.AMT_AgentPresenceWatchdogVA_AssertPresence = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func); } + obj.AMT_AgentPresenceWatchdogVA_AssertShutdown = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func); } + obj.AMT_AgentPresenceWatchdogVA_AddAction = function (OldState, NewState, EventOnTransition, ActionSd, ActionEac, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AddAction", { "OldState": OldState, "NewState": NewState, "EventOnTransition": EventOnTransition, "ActionSd": ActionSd, "ActionEac": ActionEac }, callback_func); } + obj.AMT_AgentPresenceWatchdogVA_DeleteAllActions = function (_method_dummy, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "DeleteAllActions", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_AlarmClockService_AddAlarm = function AlarmClockService_AddAlarm(alarmInstance, callback_func) + { + var id = alarmInstance.InstanceID; + var nm = alarmInstance.ElementName; + var start = alarmInstance.StartTime.Datetime; + var interval = alarmInstance.Interval ? alarmInstance.Interval.Datetime : undefined; + var doc = alarmInstance.DeleteOnCompletion; + var tpl = "" + id + "" + nm + "" + start + "" + ((interval!=undefined)?("" + interval + ""):"") + "" + doc + "" + obj.wsman.ExecMethodXml(obj.CompleteName("AMT_AlarmClockService"), "AddAlarm", tpl, callback_func); + }; + obj.AMT_AuditLog_ClearLog = function (callback_func) { obj.Exec("AMT_AuditLog", "ClearLog", {}, callback_func); } + obj.AMT_AuditLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_AuditLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.AMT_AuditLog_ReadRecords = function (StartIndex, callback_func, tag) { obj.Exec("AMT_AuditLog", "ReadRecords", { "StartIndex": StartIndex }, callback_func, tag); } + obj.AMT_AuditLog_SetAuditLock = function (LockTimeoutInSeconds, Flag, Handle, callback_func) { obj.Exec("AMT_AuditLog", "SetAuditLock", { "LockTimeoutInSeconds": LockTimeoutInSeconds, "Flag": Flag, "Handle": Handle }, callback_func); } + obj.AMT_AuditLog_ExportAuditLogSignature = function (SigningMechanism, callback_func) { obj.Exec("AMT_AuditLog", "ExportAuditLogSignature", { "SigningMechanism": SigningMechanism }, callback_func); } + obj.AMT_AuditLog_SetSigningKeyMaterial = function (SigningMechanismType, SigningKey, LengthOfCertificates, Certificates, callback_func) { obj.Exec("AMT_AuditLog", "SetSigningKeyMaterial", { "SigningMechanismType": SigningMechanismType, "SigningKey": SigningKey, "LengthOfCertificates": LengthOfCertificates, "Certificates": Certificates }, callback_func); } + obj.AMT_AuditPolicyRule_SetAuditPolicy = function (Enable, AuditedAppID, EventID, PolicyType, callback_func) { obj.Exec("AMT_AuditPolicyRule", "SetAuditPolicy", { "Enable": Enable, "AuditedAppID": AuditedAppID, "EventID": EventID, "PolicyType": PolicyType }, callback_func); } + obj.AMT_AuditPolicyRule_SetAuditPolicyBulk = function (Enable, AuditedAppID, EventID, PolicyType, callback_func) { obj.Exec("AMT_AuditPolicyRule", "SetAuditPolicyBulk", { "Enable": Enable, "AuditedAppID": AuditedAppID, "EventID": EventID, "PolicyType": PolicyType }, callback_func); } + obj.AMT_AuthorizationService_AddUserAclEntryEx = function (DigestUsername, DigestPassword, KerberosUserSid, AccessPermission, Realms, callback_func) { obj.Exec("AMT_AuthorizationService", "AddUserAclEntryEx", { "DigestUsername": DigestUsername, "DigestPassword": DigestPassword, "KerberosUserSid": KerberosUserSid, "AccessPermission": AccessPermission, "Realms": Realms }, callback_func); } + obj.AMT_AuthorizationService_EnumerateUserAclEntries = function (StartIndex, callback_func) { obj.Exec("AMT_AuthorizationService", "EnumerateUserAclEntries", { "StartIndex": StartIndex }, callback_func); } + obj.AMT_AuthorizationService_GetUserAclEntryEx = function (Handle, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "GetUserAclEntryEx", { "Handle": Handle }, callback_func, tag); } + obj.AMT_AuthorizationService_UpdateUserAclEntryEx = function (Handle, DigestUsername, DigestPassword, KerberosUserSid, AccessPermission, Realms, callback_func) { obj.Exec("AMT_AuthorizationService", "UpdateUserAclEntryEx", { "Handle": Handle, "DigestUsername": DigestUsername, "DigestPassword": DigestPassword, "KerberosUserSid": KerberosUserSid, "AccessPermission": AccessPermission, "Realms": Realms }, callback_func); } + obj.AMT_AuthorizationService_RemoveUserAclEntry = function (Handle, callback_func) { obj.Exec("AMT_AuthorizationService", "RemoveUserAclEntry", { "Handle": Handle }, callback_func); } + obj.AMT_AuthorizationService_SetAdminAclEntryEx = function (Username, DigestPassword, callback_func) { obj.Exec("AMT_AuthorizationService", "SetAdminAclEntryEx", { "Username": Username, "DigestPassword": DigestPassword }, callback_func); } + obj.AMT_AuthorizationService_GetAdminAclEntry = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminAclEntry", {}, callback_func); } + obj.AMT_AuthorizationService_GetAdminAclEntryStatus = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminAclEntryStatus", {}, callback_func); } + obj.AMT_AuthorizationService_GetAdminNetAclEntryStatus = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminNetAclEntryStatus", {}, callback_func); } + obj.AMT_AuthorizationService_SetAclEnabledState = function (Handle, Enabled, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "SetAclEnabledState", { "Handle": Handle, "Enabled": Enabled }, callback_func, tag); } + obj.AMT_AuthorizationService_GetAclEnabledState = function (Handle, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "GetAclEnabledState", { "Handle": Handle }, callback_func, tag); } + obj.AMT_EndpointAccessControlService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.AMT_EndpointAccessControlService_GetPosture = function (PostureType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetPosture", { "PostureType": PostureType }, callback_func); } + obj.AMT_EndpointAccessControlService_GetPostureHash = function (PostureType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetPostureHash", { "PostureType": PostureType }, callback_func); } + obj.AMT_EndpointAccessControlService_UpdatePostureState = function (UpdateType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "UpdatePostureState", { "UpdateType": UpdateType }, callback_func); } + obj.AMT_EndpointAccessControlService_GetEacOptions = function (callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetEacOptions", {}, callback_func); } + obj.AMT_EndpointAccessControlService_SetEacOptions = function (EacVendors, PostureHashAlgorithm, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "SetEacOptions", { "EacVendors": EacVendors, "PostureHashAlgorithm": PostureHashAlgorithm }, callback_func); } + obj.AMT_EnvironmentDetectionSettingData_SetSystemDefensePolicy = function (Policy, callback_func) { obj.Exec("AMT_EnvironmentDetectionSettingData", "SetSystemDefensePolicy", { "Policy": Policy }, callback_func); } + obj.AMT_EnvironmentDetectionSettingData_EnableVpnRouting = function (Enable, callback_func) { obj.Exec("AMT_EnvironmentDetectionSettingData", "EnableVpnRouting", { "Enable": Enable }, callback_func); } + obj.AMT_EthernetPortSettings_SetLinkPreference = function (LinkPreference, Timeout, callback_func) { obj.Exec("AMT_EthernetPortSettings", "SetLinkPreference", { "LinkPreference": LinkPreference, "Timeout": Timeout }, callback_func); } + obj.AMT_HeuristicPacketFilterStatistics_ResetSelectedStats = function (SelectedStatistics, callback_func) { obj.Exec("AMT_HeuristicPacketFilterStatistics", "ResetSelectedStats", { "SelectedStatistics": SelectedStatistics }, callback_func); } + obj.AMT_KerberosSettingData_GetCredentialCacheState = function (callback_func) { obj.Exec("AMT_KerberosSettingData", "GetCredentialCacheState", {}, callback_func); } + obj.AMT_KerberosSettingData_SetCredentialCacheState = function (Enable, callback_func) { obj.Exec("AMT_KerberosSettingData", "SetCredentialCacheState", { "Enable": Enable }, callback_func); } + obj.AMT_MessageLog_CancelIteration = function (IterationIdentifier, callback_func) { obj.Exec("AMT_MessageLog", "CancelIteration", { "IterationIdentifier": IterationIdentifier }, callback_func); } + obj.AMT_MessageLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_MessageLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.AMT_MessageLog_ClearLog = function (callback_func) { obj.Exec("AMT_MessageLog", "ClearLog", { }, callback_func); } + obj.AMT_MessageLog_GetRecords = function (IterationIdentifier, MaxReadRecords, callback_func, tag) { obj.Exec("AMT_MessageLog", "GetRecords", { "IterationIdentifier": IterationIdentifier, "MaxReadRecords": MaxReadRecords }, callback_func, tag); } + obj.AMT_MessageLog_GetRecord = function (IterationIdentifier, PositionToNext, callback_func) { obj.Exec("AMT_MessageLog", "GetRecord", { "IterationIdentifier": IterationIdentifier, "PositionToNext": PositionToNext }, callback_func); } + obj.AMT_MessageLog_PositionAtRecord = function (IterationIdentifier, MoveAbsolute, RecordNumber, callback_func) { obj.Exec("AMT_MessageLog", "PositionAtRecord", { "IterationIdentifier": IterationIdentifier, "MoveAbsolute": MoveAbsolute, "RecordNumber": RecordNumber }, callback_func); } + obj.AMT_MessageLog_PositionToFirstRecord = function (callback_func, tag) { + obj.Exec("AMT_MessageLog", "PositionToFirstRecord", {}, callback_func, tag); } + obj.AMT_MessageLog_FreezeLog = function (Freeze, callback_func) { obj.Exec("AMT_MessageLog", "FreezeLog", { "Freeze": Freeze }, callback_func); } + obj.AMT_PublicKeyManagementService_AddCRL = function (Url, SerialNumbers, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddCRL", { "Url": Url, "SerialNumbers": SerialNumbers }, callback_func); } + obj.AMT_PublicKeyManagementService_ResetCRLList = function (_method_dummy, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "ResetCRLList", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_PublicKeyManagementService_AddCertificate = function (CertificateBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddCertificate", { "CertificateBlob": CertificateBlob }, callback_func); } + obj.AMT_PublicKeyManagementService_AddTrustedRootCertificate = function (CertificateBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddTrustedRootCertificate", { "CertificateBlob": CertificateBlob }, callback_func); } + obj.AMT_PublicKeyManagementService_AddKey = function (KeyBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddKey", { "KeyBlob": KeyBlob }, callback_func); } + obj.AMT_PublicKeyManagementService_GeneratePKCS10Request = function (KeyPair, DNName, Usage, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GeneratePKCS10Request", { "KeyPair": KeyPair, "DNName": DNName, "Usage": Usage }, callback_func); } + obj.AMT_PublicKeyManagementService_GeneratePKCS10RequestEx = function (KeyPair, SigningAlgorithm, NullSignedCertificateRequest, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GeneratePKCS10RequestEx", { "KeyPair": KeyPair, "SigningAlgorithm": SigningAlgorithm, "NullSignedCertificateRequest": NullSignedCertificateRequest }, callback_func); } + obj.AMT_PublicKeyManagementService_GenerateKeyPair = function (KeyAlgorithm, KeyLength, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GenerateKeyPair", { "KeyAlgorithm": KeyAlgorithm, "KeyLength": KeyLength }, callback_func); } + obj.AMT_RedirectionService_RequestStateChange = function (RequestedState, callback_func) { obj.Exec("AMT_RedirectionService", "RequestStateChange", { "RequestedState": RequestedState }, callback_func); } + obj.AMT_RedirectionService_TerminateSession = function (SessionType, callback_func) { obj.Exec("AMT_RedirectionService", "TerminateSession", { "SessionType": SessionType }, callback_func); } + obj.AMT_RemoteAccessService_AddMpServer = function (AccessInfo, InfoFormat, Port, AuthMethod, Certificate, Username, Password, CN, callback_func) { obj.Exec("AMT_RemoteAccessService", "AddMpServer", { "AccessInfo": AccessInfo, "InfoFormat": InfoFormat, "Port": Port, "AuthMethod": AuthMethod, "Certificate": Certificate, "Username": Username, "Password": Password, "CN": CN }, callback_func); } + obj.AMT_RemoteAccessService_AddRemoteAccessPolicyRule = function (Trigger, TunnelLifeTime, ExtendedData, MpServer, callback_func) { obj.Exec("AMT_RemoteAccessService", "AddRemoteAccessPolicyRule", { "Trigger": Trigger, "TunnelLifeTime": TunnelLifeTime, "ExtendedData": ExtendedData, "MpServer": MpServer }, callback_func); } + obj.AMT_RemoteAccessService_CloseRemoteAccessConnection = function (_method_dummy, callback_func) { obj.Exec("AMT_RemoteAccessService", "CloseRemoteAccessConnection", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_SetupAndConfigurationService_CommitChanges = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "CommitChanges", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_SetupAndConfigurationService_Unprovision = function (ProvisioningMode, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "Unprovision", { "ProvisioningMode": ProvisioningMode }, callback_func); } + obj.AMT_SetupAndConfigurationService_PartialUnprovision = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "PartialUnprovision", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_SetupAndConfigurationService_ResetFlashWearOutProtection = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "ResetFlashWearOutProtection", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_SetupAndConfigurationService_ExtendProvisioningPeriod = function (Duration, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "ExtendProvisioningPeriod", { "Duration": Duration }, callback_func); } + obj.AMT_SetupAndConfigurationService_SetMEBxPassword = function (Password, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "SetMEBxPassword", { "Password": Password }, callback_func); } + obj.AMT_SetupAndConfigurationService_SetTLSPSK = function (PID, PPS, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "SetTLSPSK", { "PID": PID, "PPS": PPS }, callback_func); } + obj.AMT_SetupAndConfigurationService_GetProvisioningAuditRecord = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetProvisioningAuditRecord", {}, callback_func); } + obj.AMT_SetupAndConfigurationService_GetUuid = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetUuid", {}, callback_func); } + obj.AMT_SetupAndConfigurationService_GetUnprovisionBlockingComponents = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetUnprovisionBlockingComponents", {}, callback_func); } + obj.AMT_SetupAndConfigurationService_GetProvisioningAuditRecordV2 = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetProvisioningAuditRecordV2", {}, callback_func); } + obj.AMT_SystemDefensePolicy_GetTimeout = function (callback_func) { obj.Exec("AMT_SystemDefensePolicy", "GetTimeout", {}, callback_func); } + obj.AMT_SystemDefensePolicy_SetTimeout = function (Timeout, callback_func) { obj.Exec("AMT_SystemDefensePolicy", "SetTimeout", { "Timeout": Timeout }, callback_func); } + obj.AMT_SystemDefensePolicy_UpdateStatistics = function (NetworkInterface, ResetOnRead, callback_func, tag, pri, selectors) { obj.Exec("AMT_SystemDefensePolicy", "UpdateStatistics", { "NetworkInterface": NetworkInterface, "ResetOnRead": ResetOnRead }, callback_func, tag, pri, selectors); } + obj.AMT_SystemPowerScheme_SetPowerScheme = function (callback_func, schemeInstanceId, tag) { obj.Exec("AMT_SystemPowerScheme", "SetPowerScheme", {}, callback_func, tag, 0, { "InstanceID": schemeInstanceId }); } + obj.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch = function (callback_func, tag) { obj.Exec("AMT_TimeSynchronizationService", "GetLowAccuracyTimeSynch", {}, callback_func, tag); } + obj.AMT_TimeSynchronizationService_SetHighAccuracyTimeSynch = function (Ta0, Tm1, Tm2, callback_func, tag) { obj.Exec("AMT_TimeSynchronizationService", "SetHighAccuracyTimeSynch", { "Ta0": Ta0, "Tm1": Tm1, "Tm2": Tm2 }, callback_func, tag); } + obj.AMT_UserInitiatedConnectionService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_UserInitiatedConnectionService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.AMT_WebUIService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func, tag) { obj.Exec("AMT_WebUIService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func, tag); } + obj.AMT_WiFiPortConfigurationService_AddWiFiSettings = function (WiFiEndpoint, WiFiEndpointSettingsInput, IEEE8021xSettingsInput, ClientCredential, CACredential, callback_func) { obj.ExecWithXml("AMT_WiFiPortConfigurationService", "AddWiFiSettings", { "WiFiEndpoint": WiFiEndpoint, "WiFiEndpointSettingsInput": WiFiEndpointSettingsInput, "IEEE8021xSettingsInput": IEEE8021xSettingsInput, "ClientCredential": ClientCredential, "CACredential": CACredential }, callback_func); } + obj.AMT_WiFiPortConfigurationService_UpdateWiFiSettings = function (WiFiEndpointSettings, WiFiEndpointSettingsInput, IEEE8021xSettingsInput, ClientCredential, CACredential, callback_func) { obj.ExecWithXml("AMT_WiFiPortConfigurationService", "UpdateWiFiSettings", { "WiFiEndpointSettings": WiFiEndpointSettings, "WiFiEndpointSettingsInput": WiFiEndpointSettingsInput, "IEEE8021xSettingsInput": IEEE8021xSettingsInput, "ClientCredential": ClientCredential, "CACredential": CACredential }, callback_func); } + obj.AMT_WiFiPortConfigurationService_DeleteAllITProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllITProfiles", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_WiFiPortConfigurationService_DeleteAllUserProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllUserProfiles", { "_method_dummy": _method_dummy }, callback_func); } + obj.CIM_Account_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Account", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_AccountManagementService_CreateAccount = function (System, AccountTemplate, callback_func) { obj.Exec("CIM_AccountManagementService", "CreateAccount", { "System": System, "AccountTemplate": AccountTemplate }, callback_func); } + obj.CIM_BootConfigSetting_ChangeBootOrder = function (Source, callback_func) { obj.Exec("CIM_BootConfigSetting", "ChangeBootOrder", { "Source": Source }, callback_func); } + obj.CIM_BootService_SetBootConfigRole = function (BootConfigSetting, Role, callback_func) { obj.Exec("CIM_BootService", "SetBootConfigRole", { "BootConfigSetting": BootConfigSetting, "Role": Role }, callback_func, 0, 1); } + obj.CIM_Card_ConnectorPower = function (Connector, PoweredOn, callback_func) { obj.Exec("CIM_Card", "ConnectorPower", { "Connector": Connector, "PoweredOn": PoweredOn }, callback_func); } + obj.CIM_Card_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_Card", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); } + obj.CIM_Chassis_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_Chassis", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); } + obj.CIM_Fan_SetSpeed = function (DesiredSpeed, callback_func) { obj.Exec("CIM_Fan", "SetSpeed", { "DesiredSpeed": DesiredSpeed }, callback_func); } + obj.CIM_KVMRedirectionSAP_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_KVMRedirectionSAP", "RequestStateChange", { "RequestedState": RequestedState/*, "TimeoutPeriod": TimeoutPeriod */}, callback_func); } + obj.CIM_MediaAccessDevice_LockMedia = function (Lock, callback_func) { obj.Exec("CIM_MediaAccessDevice", "LockMedia", { "Lock": Lock }, callback_func); } + obj.CIM_MediaAccessDevice_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_MediaAccessDevice", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_MediaAccessDevice_Reset = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "Reset", {}, callback_func); } + obj.CIM_MediaAccessDevice_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_MediaAccessDevice", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_MediaAccessDevice_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_MediaAccessDevice", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_MediaAccessDevice_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_MediaAccessDevice", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_MediaAccessDevice_SaveProperties = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "SaveProperties", {}, callback_func); } + obj.CIM_MediaAccessDevice_RestoreProperties = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "RestoreProperties", {}, callback_func); } + obj.CIM_MediaAccessDevice_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_MediaAccessDevice", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_PhysicalFrame_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_PhysicalFrame", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); } + obj.CIM_PhysicalPackage_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_PhysicalPackage", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); } + obj.CIM_PowerManagementService_RequestPowerStateChange = function (PowerState, ManagedElement, Time, TimeoutPeriod, callback_func) { obj.Exec("CIM_PowerManagementService", "RequestPowerStateChange", { "PowerState": PowerState, "ManagedElement": ManagedElement, "Time": Time, "TimeoutPeriod": TimeoutPeriod }, callback_func, 0, 1); } + obj.CIM_PowerSupply_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_PowerSupply", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_PowerSupply_Reset = function (callback_func) { obj.Exec("CIM_PowerSupply", "Reset", {}, callback_func); } + obj.CIM_PowerSupply_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_PowerSupply", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_PowerSupply_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_PowerSupply", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_PowerSupply_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_PowerSupply", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_PowerSupply_SaveProperties = function (callback_func) { obj.Exec("CIM_PowerSupply", "SaveProperties", {}, callback_func); } + obj.CIM_PowerSupply_RestoreProperties = function (callback_func) { obj.Exec("CIM_PowerSupply", "RestoreProperties", {}, callback_func); } + obj.CIM_PowerSupply_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_PowerSupply", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_Processor_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Processor", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_Processor_Reset = function (callback_func) { obj.Exec("CIM_Processor", "Reset", {}, callback_func); } + obj.CIM_Processor_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Processor", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_Processor_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Processor", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_Processor_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Processor", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_Processor_SaveProperties = function (callback_func) { obj.Exec("CIM_Processor", "SaveProperties", {}, callback_func); } + obj.CIM_Processor_RestoreProperties = function (callback_func) { obj.Exec("CIM_Processor", "RestoreProperties", {}, callback_func); } + obj.CIM_Processor_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Processor", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_RecordLog_ClearLog = function (callback_func) { obj.Exec("CIM_RecordLog", "ClearLog", {}, callback_func); } + obj.CIM_RecordLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_RecordLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_RedirectionService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_RedirectionService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_Sensor_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Sensor", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_Sensor_Reset = function (callback_func) { obj.Exec("CIM_Sensor", "Reset", {}, callback_func); } + obj.CIM_Sensor_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Sensor", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_Sensor_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Sensor", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_Sensor_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Sensor", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_Sensor_SaveProperties = function (callback_func) { obj.Exec("CIM_Sensor", "SaveProperties", {}, callback_func); } + obj.CIM_Sensor_RestoreProperties = function (callback_func) { obj.Exec("CIM_Sensor", "RestoreProperties", {}, callback_func); } + obj.CIM_Sensor_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Sensor", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_StatisticalData_ResetSelectedStats = function (SelectedStatistics, callback_func) { obj.Exec("CIM_StatisticalData", "ResetSelectedStats", { "SelectedStatistics": SelectedStatistics }, callback_func); } + obj.CIM_Watchdog_KeepAlive = function (callback_func) { obj.Exec("CIM_Watchdog", "KeepAlive", {}, callback_func); } + obj.CIM_Watchdog_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Watchdog", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_Watchdog_Reset = function (callback_func) { obj.Exec("CIM_Watchdog", "Reset", {}, callback_func); } + obj.CIM_Watchdog_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Watchdog", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_Watchdog_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Watchdog", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_Watchdog_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Watchdog", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_Watchdog_SaveProperties = function (callback_func) { obj.Exec("CIM_Watchdog", "SaveProperties", {}, callback_func); } + obj.CIM_Watchdog_RestoreProperties = function (callback_func) { obj.Exec("CIM_Watchdog", "RestoreProperties", {}, callback_func); } + obj.CIM_Watchdog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Watchdog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_WiFiPort_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_WiFiPort", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_WiFiPort_Reset = function (callback_func) { obj.Exec("CIM_WiFiPort", "Reset", {}, callback_func); } + obj.CIM_WiFiPort_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_WiFiPort", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_WiFiPort_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_WiFiPort", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_WiFiPort_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_WiFiPort", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_WiFiPort_SaveProperties = function (callback_func) { obj.Exec("CIM_WiFiPort", "SaveProperties", {}, callback_func); } + obj.CIM_WiFiPort_RestoreProperties = function (callback_func) { obj.Exec("CIM_WiFiPort", "RestoreProperties", {}, callback_func); } + obj.CIM_WiFiPort_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_WiFiPort", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.IPS_HostBasedSetupService_Setup = function (NetAdminPassEncryptionType, NetworkAdminPassword, McNonce, Certificate, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "Setup", { "NetAdminPassEncryptionType": NetAdminPassEncryptionType, "NetworkAdminPassword": NetworkAdminPassword, "McNonce": McNonce, "Certificate": Certificate, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); } + obj.IPS_HostBasedSetupService_AddNextCertInChain = function (NextCertificate, IsLeafCertificate, IsRootCertificate, callback_func) { obj.Exec("IPS_HostBasedSetupService", "AddNextCertInChain", { "NextCertificate": NextCertificate, "IsLeafCertificate": IsLeafCertificate, "IsRootCertificate": IsRootCertificate }, callback_func); } + obj.IPS_HostBasedSetupService_AdminSetup = function (NetAdminPassEncryptionType, NetworkAdminPassword, McNonce, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "AdminSetup", { "NetAdminPassEncryptionType": NetAdminPassEncryptionType, "NetworkAdminPassword": NetworkAdminPassword, "McNonce": McNonce, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); } + obj.IPS_HostBasedSetupService_UpgradeClientToAdmin = function (McNonce, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "UpgradeClientToAdmin", { "McNonce": McNonce, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); } + obj.IPS_HostBasedSetupService_DisableClientControlMode = function (_method_dummy, callback_func) { obj.Exec("IPS_HostBasedSetupService", "DisableClientControlMode", { "_method_dummy": _method_dummy }, callback_func); } + obj.IPS_KVMRedirectionSettingData_TerminateSession = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "TerminateSession", {}, callback_func); } + obj.IPS_KVMRedirectionSettingData_DataChannelRead = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelRead", {}, callback_func); } + obj.IPS_KVMRedirectionSettingData_DataChannelWrite = function (Data, callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelWrite", { "DataMessage": Data }, callback_func); } + obj.IPS_OptInService_StartOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "StartOptIn", {}, callback_func); } + obj.IPS_OptInService_CancelOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "CancelOptIn", {}, callback_func); } + obj.IPS_OptInService_SendOptInCode = function (OptInCode, callback_func) { obj.Exec("IPS_OptInService", "SendOptInCode", { "OptInCode": OptInCode }, callback_func); } + obj.IPS_OptInService_StartService = function (callback_func) { obj.Exec("IPS_OptInService", "StartService", {}, callback_func); } + obj.IPS_OptInService_StopService = function (callback_func) { obj.Exec("IPS_OptInService", "StopService", {}, callback_func); } + obj.IPS_OptInService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_OptInService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.IPS_ProvisioningRecordLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_ProvisioningRecordLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.IPS_ProvisioningRecordLog_ClearLog = function (_method_dummy, callback_func) { obj.Exec("IPS_ProvisioningRecordLog", "ClearLog", { "_method_dummy": _method_dummy }, callback_func); } + obj.IPS_SecIOService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_SecIOService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + + obj.AmtStatusToStr = function (code) { if (obj.AmtStatusCodes[code]) return obj.AmtStatusCodes[code]; else return "UNKNOWN_ERROR" } + obj.AmtStatusCodes = { + 0x0000: "SUCCESS", + 0x0001: "INTERNAL_ERROR", + 0x0002: "NOT_READY", + 0x0003: "INVALID_PT_MODE", + 0x0004: "INVALID_MESSAGE_LENGTH", + 0x0005: "TABLE_FINGERPRINT_NOT_AVAILABLE", + 0x0006: "INTEGRITY_CHECK_FAILED", + 0x0007: "UNSUPPORTED_ISVS_VERSION", + 0x0008: "APPLICATION_NOT_REGISTERED", + 0x0009: "INVALID_REGISTRATION_DATA", + 0x000A: "APPLICATION_DOES_NOT_EXIST", + 0x000B: "NOT_ENOUGH_STORAGE", + 0x000C: "INVALID_NAME", + 0x000D: "BLOCK_DOES_NOT_EXIST", + 0x000E: "INVALID_BYTE_OFFSET", + 0x000F: "INVALID_BYTE_COUNT", + 0x0010: "NOT_PERMITTED", + 0x0011: "NOT_OWNER", + 0x0012: "BLOCK_LOCKED_BY_OTHER", + 0x0013: "BLOCK_NOT_LOCKED", + 0x0014: "INVALID_GROUP_PERMISSIONS", + 0x0015: "GROUP_DOES_NOT_EXIST", + 0x0016: "INVALID_MEMBER_COUNT", + 0x0017: "MAX_LIMIT_REACHED", + 0x0018: "INVALID_AUTH_TYPE", + 0x0019: "AUTHENTICATION_FAILED", + 0x001A: "INVALID_DHCP_MODE", + 0x001B: "INVALID_IP_ADDRESS", + 0x001C: "INVALID_DOMAIN_NAME", + 0x001D: "UNSUPPORTED_VERSION", + 0x001E: "REQUEST_UNEXPECTED", + 0x001F: "INVALID_TABLE_TYPE", + 0x0020: "INVALID_PROVISIONING_STATE", + 0x0021: "UNSUPPORTED_OBJECT", + 0x0022: "INVALID_TIME", + 0x0023: "INVALID_INDEX", + 0x0024: "INVALID_PARAMETER", + 0x0025: "INVALID_NETMASK", + 0x0026: "FLASH_WRITE_LIMIT_EXCEEDED", + 0x0027: "INVALID_IMAGE_LENGTH", + 0x0028: "INVALID_IMAGE_SIGNATURE", + 0x0029: "PROPOSE_ANOTHER_VERSION", + 0x002A: "INVALID_PID_FORMAT", + 0x002B: "INVALID_PPS_FORMAT", + 0x002C: "BIST_COMMAND_BLOCKED", + 0x002D: "CONNECTION_FAILED", + 0x002E: "CONNECTION_TOO_MANY", + 0x002F: "RNG_GENERATION_IN_PROGRESS", + 0x0030: "RNG_NOT_READY", + 0x0031: "CERTIFICATE_NOT_READY", + 0x0400: "DISABLED_BY_POLICY", + 0x0800: "NETWORK_IF_ERROR_BASE", + 0x0801: "UNSUPPORTED_OEM_NUMBER", + 0x0802: "UNSUPPORTED_BOOT_OPTION", + 0x0803: "INVALID_COMMAND", + 0x0804: "INVALID_SPECIAL_COMMAND", + 0x0805: "INVALID_HANDLE", + 0x0806: "INVALID_PASSWORD", + 0x0807: "INVALID_REALM", + 0x0808: "STORAGE_ACL_ENTRY_IN_USE", + 0x0809: "DATA_MISSING", + 0x080A: "DUPLICATE", + 0x080B: "EVENTLOG_FROZEN", + 0x080C: "PKI_MISSING_KEYS", + 0x080D: "PKI_GENERATING_KEYS", + 0x080E: "INVALID_KEY", + 0x080F: "INVALID_CERT", + 0x0810: "CERT_KEY_NOT_MATCH", + 0x0811: "MAX_KERB_DOMAIN_REACHED", + 0x0812: "UNSUPPORTED", + 0x0813: "INVALID_PRIORITY", + 0x0814: "NOT_FOUND", + 0x0815: "INVALID_CREDENTIALS", + 0x0816: "INVALID_PASSPHRASE", + 0x0818: "NO_ASSOCIATION", + 0x081B: "AUDIT_FAIL", + 0x081C: "BLOCKING_COMPONENT", + 0x0821: "USER_CONSENT_REQUIRED", + 0x1000: "APP_INTERNAL_ERROR", + 0x1001: "NOT_INITIALIZED", + 0x1002: "LIB_VERSION_UNSUPPORTED", + 0x1003: "INVALID_PARAM", + 0x1004: "RESOURCES", + 0x1005: "HARDWARE_ACCESS_ERROR", + 0x1006: "REQUESTOR_NOT_REGISTERED", + 0x1007: "NETWORK_ERROR", + 0x1008: "PARAM_BUFFER_TOO_SHORT", + 0x1009: "COM_NOT_INITIALIZED_IN_THREAD", + 0x100A: "URL_REQUIRED" + } + + // + // Methods used for getting the event log + // + + obj.GetMessageLog = function (func, tag) { + obj.AMT_MessageLog_PositionToFirstRecord(_GetMessageLog0, [func, tag, []]); + } + function _GetMessageLog0(stack, name, responses, status, tag) { + if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; } + obj.AMT_MessageLog_GetRecords(responses.Body["IterationIdentifier"], 390, _GetMessageLog1, tag); + } + function _GetMessageLog1(stack, name, responses, status, tag) { + if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; } + var i, j, x, e, AmtMessages = tag[2], t = new Date(), TimeStamp, ra = responses.Body["RecordArray"]; + if (typeof ra === 'string') { responses.Body["RecordArray"] = [responses.Body["RecordArray"]]; } + + for (i in ra) { + e = Buffer.from(ra[i], 'base64'); + if (e != null) { + TimeStamp = ReadIntX(e, 0); + if ((TimeStamp > 0) && (TimeStamp < 0xFFFFFFFF)) { + x = { 'DeviceAddress': e[4], 'EventSensorType': e[5], 'EventType': e[6], 'EventOffset': e[7], 'EventSourceType': e[8], 'EventSeverity': e[9], 'SensorNumber': e[10], 'Entity': e[11], 'EntityInstance': e[12], 'EventData': [], 'Time': new Date((TimeStamp + (t.getTimezoneOffset() * 60)) * 1000) }; + for (j = 13; j < 21; j++) { x['EventData'].push(e[j]); } + x['EntityStr'] = _SystemEntityTypes[x['Entity']]; + x['Desc'] = _GetEventDetailStr(x['EventSensorType'], x['EventOffset'], x['EventData'], x['Entity']); + if (!x['EntityStr']) x['EntityStr'] = "Unknown"; + AmtMessages.push(x); + } + } + } + + if (responses.Body["NoMoreRecords"] != true) { + obj.AMT_MessageLog_GetRecords(responses.Body["IterationIdentifier"], 390, _GetMessageLog1, [tag[0], AmtMessages, tag[2]]); } + else { tag[0](obj, AmtMessages, tag[2], status); } + } + + var _EventTrapSourceTypes = "Platform firmware (e.g. BIOS)|SMI handler|ISV system management software|Alert ASIC|IPMI|BIOS vendor|System board set vendor|System integrator|Third party add-in|OSV|NIC|System management card".split('|'); + var _SystemFirmwareError = "Unspecified.|No system memory is physically installed in the system.|No usable system memory, all installed memory has experienced an unrecoverable failure.|Unrecoverable hard-disk/ATAPI/IDE device failure.|Unrecoverable system-board failure.|Unrecoverable diskette subsystem failure.|Unrecoverable hard-disk controller failure.|Unrecoverable PS/2 or USB keyboard failure.|Removable boot media not found.|Unrecoverable video controller failure.|No video device detected.|Firmware (BIOS) ROM corruption detected.|CPU voltage mismatch (processors that share same supply have mismatched voltage requirements)|CPU speed matching failure".split('|'); + var _SystemFirmwareProgress = "Unspecified.|Memory initialization.|Starting hard-disk initialization and test|Secondary processor(s) initialization|User authentication|User-initiated system setup|USB resource configuration|PCI resource configuration|Option ROM initialization|Video initialization|Cache initialization|SM Bus initialization|Keyboard controller initialization|Embedded controller/management controller initialization|Docking station attachment|Enabling docking station|Docking station ejection|Disabling docking station|Calling operating system wake-up vector|Starting operating system boot process|Baseboard or motherboard initialization|reserved|Floppy initialization|Keyboard test|Pointing device test|Primary processor initialization".split('|'); + var _SystemEntityTypes = "Unspecified|Other|Unknown|Processor|Disk|Peripheral|System management module|System board|Memory module|Processor module|Power supply|Add in card|Front panel board|Back panel board|Power system board|Drive backplane|System internal expansion board|Other system board|Processor board|Power unit|Power module|Power management board|Chassis back panel board|System chassis|Sub chassis|Other chassis board|Disk drive bay|Peripheral bay|Device bay|Fan cooling|Cooling unit|Cable interconnect|Memory device|System management software|BIOS|Intel(r) ME|System bus|Group|Intel(r) ME|External environment|Battery|Processing blade|Connectivity switch|Processor/memory module|I/O module|Processor I/O module|Management controller firmware|IPMI channel|PCI bus|PCI express bus|SCSI bus|SATA/SAS bus|Processor front side bus".split('|'); + obj.RealmNames = "||Redirection|PT Administration|Hardware Asset|Remote Control|Storage|Event Manager|Storage Admin|Agent Presence Local|Agent Presence Remote|Circuit Breaker|Network Time|General Information|Firmware Update|EIT|LocalUN|Endpoint Access Control|Endpoint Access Control Admin|Event Log Reader|Audit Log|ACL Realm|||Local System".split('|'); + obj.WatchdogCurrentStates = { 1: 'Not Started', 2: 'Stopped', 4: 'Running', 8: 'Expired', 16: 'Suspended' }; + + function _GetEventDetailStr(eventSensorType, eventOffset, eventDataField, entity) { + + if (eventSensorType == 15) + { + if (eventDataField[0] == 235) return "Invalid Data"; + if (eventOffset == 0) return _SystemFirmwareError[eventDataField[1]]; + return _SystemFirmwareProgress[eventDataField[1]]; + } + + if (eventSensorType == 18 && eventDataField[0] == 170) // System watchdog event + { + return "Agent watchdog " + char2hex(eventDataField[4]) + char2hex(eventDataField[3]) + char2hex(eventDataField[2]) + char2hex(eventDataField[1]) + "-" + char2hex(eventDataField[6]) + char2hex(eventDataField[5]) + "-... changed to " + obj.WatchdogCurrentStates[eventDataField[7]]; + } + + //if (eventSensorType == 5 && eventOffset == 0) // System chassis + //{ + // return "Case intrusion"; + //} + + //if (eventSensorType == 192 && eventOffset == 0 && eventDataField[0] == 170 && eventDataField[1] == 48) + //{ + // if (eventDataField[2] == 0) return "A remote Serial Over LAN session was established."; + // if (eventDataField[2] == 1) return "Remote Serial Over LAN session finished. User control was restored."; + // if (eventDataField[2] == 2) return "A remote IDE-Redirection session was established."; + // if (eventDataField[2] == 3) return "Remote IDE-Redirection session finished. User control was restored."; + //} + + //if (eventSensorType == 36) + //{ + // long handle = ((long)(eventDataField[1]) << 24) + ((long)(eventDataField[2]) << 16) + ((long)(eventDataField[3]) << 8) + (long)(eventDataField[4]); + // string nic = string.Format("#{0}", eventDataField[0]); + // if (eventDataField[0] == 0xAA) nic = "wired"; // TODO: Add wireless ***** + // //if (eventDataField[0] == 0xAA) nic = "wireless"; + + // if (handle == 4294967293) { return string.Format("All received packet filter was matched on {0} interface.", nic); } + // if (handle == 4294967292) { return string.Format("All outbound packet filter was matched on {0} interface.", nic); } + // if (handle == 4294967290) { return string.Format("Spoofed packet filter was matched on {0} interface.", nic); } + // return string.Format("Filter {0} was matched on {1} interface.", handle, nic); + //} + + //if (eventSensorType == 192) + //{ + // if (eventDataField[2] == 0) return "Security policy invoked. Some or all network traffic (TX) was stopped."; + // if (eventDataField[2] == 2) return "Security policy invoked. Some or all network traffic (RX) was stopped."; + // return "Security policy invoked."; + //} + + //if (eventSensorType == 193) + //{ + // if (eventDataField[0] == 0xAA && eventDataField[1] == 0x30 && eventDataField[2] == 0x00 && eventDataField[3] == 0x00) { return "User request for remote connection."; } + // if (eventDataField[0] == 0xAA && eventDataField[1] == 0x20 && eventDataField[2] == 0x03 && eventDataField[3] == 0x01) { return "EAC error: attempt to get posture while NAC in Intel(r) AMT is disabled."; // eventDataField = 0xAA20030100000000 } + // if (eventDataField[0] == 0xAA && eventDataField[1] == 0x20 && eventDataField[2] == 0x04 && eventDataField[3] == 0x00) { return "Certificate revoked. "; } + //} + + if (eventSensorType == 6) return "Authentication failed " + (eventDataField[1] + (eventDataField[2] << 8)) + " times. The system may be under attack."; + if (eventSensorType == 30) return "No bootable media"; + if (eventSensorType == 32) return "Operating system lockup or power interrupt"; + if (eventSensorType == 35) return "System boot failure"; + if (eventSensorType == 37) return "System firmware started (at least one CPU is properly executing)."; + return "Unknown Sensor Type #" + eventSensorType; + } + +// ###BEGIN###{AuditLog} + + // Useful link: https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Fsecurityadminevents.htm + + var _AmtAuditStringTable = + { + 16: 'Security Admin', + 17: 'RCO', + 18: 'Redirection Manager', + 19: 'Firmware Update Manager', + 20: 'Security Audit Log', + 21: 'Network Time', + 22: 'Network Administration', + 23: 'Storage Administration', + 24: 'Event Manager', + 25: 'Circuit Breaker Manager', + 26: 'Agent Presence Manager', + 27: 'Wireless Configuration', + 28: 'EAC', + 29: 'KVM', + 30: 'User Opt-In Events', + 32: 'Screen Blanking', + 33: 'Watchdog Events', + 1600: 'Provisioning Started', + 1601: 'Provisioning Completed', + 1602: 'ACL Entry Added', + 1603: 'ACL Entry Modified', + 1604: 'ACL Entry Removed', + 1605: 'ACL Access with Invalid Credentials', + 1606: 'ACL Entry State', + 1607: 'TLS State Changed', + 1608: 'TLS Server Certificate Set', + 1609: 'TLS Server Certificate Remove', + 1610: 'TLS Trusted Root Certificate Added', + 1611: 'TLS Trusted Root Certificate Removed', + 1612: 'TLS Preshared Key Set', + 1613: 'Kerberos Settings Modified', + 1614: 'Kerberos Master Key Modified', + 1615: 'Flash Wear out Counters Reset', + 1616: 'Power Package Modified', + 1617: 'Set Realm Authentication Mode', + 1618: 'Upgrade Client to Admin Control Mode', + 1619: 'Unprovisioning Started', + 1700: 'Performed Power Up', + 1701: 'Performed Power Down', + 1702: 'Performed Power Cycle', + 1703: 'Performed Reset', + 1704: 'Set Boot Options', + 1800: 'IDER Session Opened', + 1801: 'IDER Session Closed', + 1802: 'IDER Enabled', + 1803: 'IDER Disabled', + 1804: 'SoL Session Opened', + 1805: 'SoL Session Closed', + 1806: 'SoL Enabled', + 1807: 'SoL Disabled', + 1808: 'KVM Session Started', + 1809: 'KVM Session Ended', + 1810: 'KVM Enabled', + 1811: 'KVM Disabled', + 1812: 'VNC Password Failed 3 Times', + 1900: 'Firmware Updated', + 1901: 'Firmware Update Failed', + 2000: 'Security Audit Log Cleared', + 2001: 'Security Audit Policy Modified', + 2002: 'Security Audit Log Disabled', + 2003: 'Security Audit Log Enabled', + 2004: 'Security Audit Log Exported', + 2005: 'Security Audit Log Recovered', + 2100: 'Intel(R) ME Time Set', + 2200: 'TCPIP Parameters Set', + 2201: 'Host Name Set', + 2202: 'Domain Name Set', + 2203: 'VLAN Parameters Set', + 2204: 'Link Policy Set', + 2205: 'IPv6 Parameters Set', + 2300: 'Global Storage Attributes Set', + 2301: 'Storage EACL Modified', + 2302: 'Storage FPACL Modified', + 2303: 'Storage Write Operation', + 2400: 'Alert Subscribed', + 2401: 'Alert Unsubscribed', + 2402: 'Event Log Cleared', + 2403: 'Event Log Frozen', + 2500: 'CB Filter Added', + 2501: 'CB Filter Removed', + 2502: 'CB Policy Added', + 2503: 'CB Policy Removed', + 2504: 'CB Default Policy Set', + 2505: 'CB Heuristics Option Set', + 2506: 'CB Heuristics State Cleared', + 2600: 'Agent Watchdog Added', + 2601: 'Agent Watchdog Removed', + 2602: 'Agent Watchdog Action Set', + 2700: 'Wireless Profile Added', + 2701: 'Wireless Profile Removed', + 2702: 'Wireless Profile Updated', + 2800: 'EAC Posture Signer SET', + 2801: 'EAC Enabled', + 2802: 'EAC Disabled', + 2803: 'EAC Posture State', + 2804: 'EAC Set Options', + 2900: 'KVM Opt-in Enabled', + 2901: 'KVM Opt-in Disabled', + 2902: 'KVM Password Changed', + 2903: 'KVM Consent Succeeded', + 2904: 'KVM Consent Failed', + 3000: 'Opt-In Policy Change', + 3001: 'Send Consent Code Event', + 3002: 'Start Opt-In Blocked Event' + } + + // Return human readable extended audit log data + // TODO: Just put some of them here, but many more still need to be added, helpful link here: + // https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Fsecurityadminevents.htm + obj.GetAuditLogExtendedDataStr = function (id, data) { + if ((id == 1602 || id == 1604) && data[0] == 0) { return data.splice(2, 2 + data[1]).toString(); } // ACL Entry Added/Removed (Digest) + if (id == 1603) { if (data[1] == 0) { return data.splice(3).toString(); } return null; } // ACL Entry Modified + if (id == 1605) { return ["Invalid ME access", "Invalid MEBx access"][data[0]]; } // ACL Access with Invalid Credentials + if (id == 1606) { var r = ["Disabled", "Enabled"][data[0]]; if (data[1] == 0) { r += ", " + data[3]; } return r; } // ACL Entry State + if (id == 1607) { return "Remote " + ["NoAuth", "ServerAuth", "MutualAuth"][data[0]] + ", Local " + ["NoAuth", "ServerAuth", "MutualAuth"][data[1]]; } // TLS State Changed + if (id == 1617) { return obj.RealmNames[ReadInt(data, 0)] + ", " + ["NoAuth", "Auth", "Disabled"][data[4]]; } // Set Realm Authentication Mode + if (id == 1619) { return ["BIOS", "MEBx", "Local MEI", "Local WSMAN", "Remote WSAMN"][data[0]]; } // Intel AMT Unprovisioning Started + if (id == 1900) { return "From " + ReadShort(data, 0) + "." + ReadShort(data, 2) + "." + ReadShort(data, 4) + "." + ReadShort(data, 6) + " to " + ReadShort(data, 8) + "." + ReadShort(data, 10) + "." + ReadShort(data, 12) + "." + ReadShort(data, 14); } // Firmware Updated + if (id == 2100) { var t4 = new Date(); t4.setTime(ReadInt(data, 0) * 1000 + (new Date().getTimezoneOffset() * 60000)); return t4.toLocaleString(); } // Intel AMT Time Set + if (id == 3000) { return "From " + ["None", "KVM", "All"][data[0]] + " to " + ["None", "KVM", "All"][data[1]]; } // Opt-In Policy Change + if (id == 3001) { return ["Success", "Failed 3 times"][data[0]]; } // Send Consent Code Event + return null; + } + + obj.GetAuditLog = function (func) { + obj.AMT_AuditLog_ReadRecords(1, _GetAuditLog0, [func, []]); + } + + function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; } + function ReadShort(v, p) { return (v[p] << 8) + v[p + 1]; } + function ReadInt(v, p) { return (v[p] * 0x1000000) + (v[p + 1] << 16) + (v[p + 2] << 8) + v[p + 3]; } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32. + function ReadIntX(v, p) { return (v[p + 3] * 0x1000000) + (v[p + 2] << 16) + (v[p + 1] << 8) + v[p]; } + function btoa(x) { return Buffer.from(x).toString('base64'); } + function atob(x) { var z = null; try { z = Buffer.from(x, 'base64').toString(); } catch (e) { console.log(e); } return z; } + + function _GetAuditLog0(stack, name, responses, status, tag) { + if (status != 200) { tag[0](obj, [], status); return; } + var ptr, i, e, es, x, r = tag[1], t = new Date(), TimeStamp; + + if (responses.Body['RecordsReturned'] > 0) { + responses.Body['EventRecords'] = MakeToArray(responses.Body['EventRecords']); + + for (i in responses.Body['EventRecords']) { + e = null; + try { + es = atob(responses.Body['EventRecords'][i]); + e = new Buffer(es); + } catch (ex) { + console.log(ex + " " + responses.Body['EventRecords'][i]) + } + + x = { 'AuditAppID': ReadShort(e, 0), 'EventID': ReadShort(e, 2), 'InitiatorType': e[4] }; + x['AuditApp'] = _AmtAuditStringTable[x['AuditAppID']]; + x['Event'] = _AmtAuditStringTable[(x['AuditAppID'] * 100) + x['EventID']]; + if (!x['Event']) x['Event'] = '#' + x['EventID']; + + // Read and process the initiator + if (x['InitiatorType'] == 0) { + // HTTP digest + var userlen = e[5]; + x['Initiator'] = e.slice(6, 6 + userlen).toString(); + ptr = 6 + userlen; + } + if (x['InitiatorType'] == 1) { + // Kerberos + x['KerberosUserInDomain'] = ReadInt(e, 5); + var userlen = e[9]; + x['Initiator'] = GetSidString(e.slice(10, 10 + userlen)); + ptr = 10 + userlen; + } + if (x['InitiatorType'] == 2) { + // Local + x['Initiator'] = 'Local'; + ptr = 5; + } + if (x['InitiatorType'] == 3) { + // KVM Default Port + x['Initiator'] = 'KVM Default Port'; + ptr = 5; + } + + // Read timestamp + TimeStamp = ReadInt(e, ptr); + x['Time'] = new Date((TimeStamp + (t.getTimezoneOffset() * 60)) * 1000); + ptr += 4; + + // Read network access + x['MCLocationType'] = e[ptr++]; + var netlen = e[ptr++]; + + x['NetAddress'] = e.slice(ptr, ptr + netlen).toString(); + + // Read extended data + ptr += netlen; + var exlen = e[ptr++]; + x['Ex'] = e.slice(ptr, ptr + exlen); + x['ExStr'] = obj.GetAuditLogExtendedDataStr((x['AuditAppID'] * 100) + x['EventID'], x['Ex']); + r.push(x); + } + } + if (responses.Body['TotalRecordCount'] > r.length) { + obj.AMT_AuditLog_ReadRecords(r.length + 1, _GetAuditLog0, [tag[0], r]); + } else { + tag[0](obj, r, status); + } + } + + // ###END###{AuditLog} + + /* + // ###BEGIN###{Certificates} + + // Forge MD5 + function hex_md5(str) { return forge.md.md5.create().update(str).digest().toHex(); } + + // ###END###{Certificates} + + // ###BEGIN###{!Certificates} + + // TinyMD5 from https://github.com/jbt/js-crypto + + // Perform MD5 setup + var md5_k = []; + for (var i = 0; i < 64;) { md5_k[i] = 0 | (Math.abs(Math.sin(++i)) * 4294967296); } + + // Perform MD5 on raw string and return hex + function hex_md5(str) { + var b, c, d, j, + x = [], + str2 = unescape(encodeURI(str)), + a = str2.length, + h = [b = 1732584193, c = -271733879, ~b, ~c], + i = 0; + + for (; i <= a;) x[i >> 2] |= (str2.charCodeAt(i) || 128) << 8 * (i++ % 4); + + x[str = (a + 8 >> 6) * 16 + 14] = a * 8; + i = 0; + + for (; i < str; i += 16) { + a = h; j = 0; + for (; j < 64;) { + a = [ + d = a[3], + ((b = a[1] | 0) + + ((d = ( + (a[0] + + [ + b & (c = a[2]) | ~b & d, + d & b | ~d & c, + b ^ c ^ d, + c ^ (b | ~d) + ][a = j >> 4] + ) + + (md5_k[j] + + (x[[ + j, + 5 * j + 1, + 3 * j + 5, + 7 * j + ][a] % 16 + i] | 0) + ) + )) << (a = [ + 7, 12, 17, 22, + 5, 9, 14, 20, + 4, 11, 16, 23, + 6, 10, 15, 21 + ][4 * a + j++ % 4]) | d >>> 32 - a) + ), + b, + c + ]; + } + for (j = 4; j;) h[--j] = h[j] + a[j]; + } + + str = ''; + for (; j < 32;) str += ((h[j >> 3] >> ((1 ^ j++ & 7) * 4)) & 15).toString(16); + return str; + } + + // ###END###{!Certificates} + + // Perform MD5 on raw string and return raw string result + function rstr_md5(str) { return hex2rstr(hex_md5(str)); } + */ + /* + Convert arguments into selector set and body XML. Used by AMT_WiFiPortConfigurationService_UpdateWiFiSettings. + args = { + "WiFiEndpoint": { + __parameterType: 'reference', + __resourceUri: 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpoint', + Name: 'WiFi Endpoint 0' + }, + "WiFiEndpointSettingsInput": + { + __parameterType: 'instance', + __namespace: 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpointSettings', + ElementName: document.querySelector('#editProfile-profileName').value, + InstanceID: 'Intel(r) AMT:WiFi Endpoint Settings ' + document.querySelector('#editProfile-profileName').value, + AuthenticationMethod: document.querySelector('#editProfile-networkAuthentication').value, + //BSSType: 3, // Intel(r) AMT supports only infrastructure networks + EncryptionMethod: document.querySelector('#editProfile-encryption').value, + SSID: document.querySelector('#editProfile-networkName').value, + Priority: 100, + PSKPassPhrase: document.querySelector('#editProfile-passPhrase').value + }, + "IEEE8021xSettingsInput": null, + "ClientCredential": null, + "CACredential": null + }, + */ + function execArgumentsToXml(args) { + if (args === undefined || args === null) return null; + + var result = ''; + for (var argName in args) { + var arg = args[argName]; + if (!arg) continue; + if (arg['__parameterType'] === 'reference') result += referenceToXml(argName, arg); + else result += instanceToXml(argName, arg); + //if(arg['__isInstance']) result += instanceToXml(argName, arg); + } + return result; + } + + /** + * Convert JavaScript object into XML + + + Wireless-Profile-Admin + Intel(r) AMT:WiFi Endpoint Settings Wireless-Profile-Admin + 6 + 4 + 100 + P@ssw0rd + + */ + function instanceToXml(instanceName, inInstance) { + if (inInstance === undefined || inInstance === null) return null; + + var hasNamespace = !!inInstance['__namespace']; + var startTag = hasNamespace ? ''; + for (var prop in inInstance) { + if (!inInstance.hasOwnProperty(prop) || prop.indexOf('__') === 0) continue; + + if (typeof inInstance[prop] === 'function' || Array.isArray(inInstance[prop])) continue; + + if (typeof inInstance[prop] === 'object') { + //result += startTag + prop +'>' + instanceToXml('prop', inInstance[prop]) + endTag + prop +'>'; + console.error('only convert one level down...'); + } + else { + result += startTag + prop + '>' + inInstance[prop].toString() + endTag + prop + '>'; + } + } + result += ''; + return result; + } + + + /** + * Convert a selector set into XML. Expect no nesting. + * { + * selectorName : selectorValue, + * selectorName : selectorValue, + * ... ... + * } + + + http://192.168.1.103:16992/wsman + + http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpoint + + WiFi Endpoint 0 + + + + + */ + function referenceToXml(referenceName, inReference) { + if (inReference === undefined || inReference === null) return null; + + var result = '/wsman' + inReference['__resourceUri'] + ''; + for (var selectorName in inReference) { + if (!inReference.hasOwnProperty(selectorName) || selectorName.indexOf('__') === 0) continue; + + if (typeof inReference[selectorName] === 'function' || + typeof inReference[selectorName] === 'object' || + Array.isArray(inReference[selectorName])) + continue; + + result += '' + inReference[selectorName].toString() + ''; + } + + result += ''; + return result; + } + + // Convert a byte array of SID into string + function GetSidString(sid) { + var r = "S-" + sid.charCodeAt(0) + "-" + sid.charCodeAt(7); + for (var i = 2; i < (sid.length / 4) ; i++) r += "-" + ReadIntX(sid, i * 4); + return r; + } + + // Convert a SID readable string into bytes + function GetSidByteArray(sidString) { + if (!sidString || sidString == null) return null; + var sidParts = sidString.split('-'); + + // Make sure the SID has at least 4 parts and starts with 'S' + if (sidParts.length < 4 || (sidParts[0] != 's' && sidParts[0] != 'S')) return null; + + // Check that each part of the SID is really an integer + for (var i = 1; i < sidParts.length; i++) { var y = parseInt(sidParts[i]); if (y != sidParts[i]) return null; sidParts[i] = y; } + + // Version (8 bit) + Id count (8 bit) + 48 bit in big endian -- DO NOT use bitwise right shift operator. JavaScript converts the number into a 32 bit integer before shifting. In real world, it's highly likely this part is always 0. + var r = String.fromCharCode(sidParts[1]) + String.fromCharCode(sidParts.length - 3) + ShortToStr(Math.floor(sidParts[2] / Math.pow(2, 32))) + IntToStr((sidParts[2]) & 0xFFFF); + + // the rest are in 32 bit in little endian + for (var i = 3; i < sidParts.length; i++) r += IntToStrX(sidParts[i]); + return r; + } + + return obj; +} +module.exports = AmtStackCreateService; \ No newline at end of file diff --git a/apfserver.js b/apfserver.js index 72ea9041..ed69ca18 100644 --- a/apfserver.js +++ b/apfserver.js @@ -140,7 +140,7 @@ module.exports.CreateApfServer = function (parent, db, args) { parent.debug('apf',"WS Extensions:"+socket.extensions); parent.debug('apf',"WS Binary type:"+socket.binaryType); - socket._socket.on('data', function(chunk) { console.log(chunk.toString('hex'))}); + //socket._socket.on('data', function(chunk) { console.log(chunk.toString('hex'))}); // Setup the APF keep alive timer // Websocket does not have timout From 9c09a3ebc01c75820a382c29cf05b5d7a12f2b93 Mon Sep 17 00:00:00 2001 From: jsastriawan Date: Fri, 20 Sep 2019 17:21:58 -0700 Subject: [PATCH 2/2] A working serverside AMT API via 3 different modes, namely mode 1 (AMT Direct), mode 2 (CIRA) and mode 3 (APF bridge) --- agents/modules_meshcore/apfclient.js | 12 ++-- agents/modules_meshcore_min/apfclient.min.js | 2 +- amt/amt-wsman-comm.js | 39 +++++------- amt/amt-wsman.js | 6 +- meshuser.js | 66 ++++++++++++++++++++ mpsserver.js | 4 +- 6 files changed, 94 insertions(+), 35 deletions(-) diff --git a/agents/modules_meshcore/apfclient.js b/agents/modules_meshcore/apfclient.js index 3f26c01a..4dcb900c 100644 --- a/agents/modules_meshcore/apfclient.js +++ b/agents/modules_meshcore/apfclient.js @@ -332,7 +332,7 @@ function CreateAPFClient(parent, args) { if (pfwd_ports.indexOf(p_res.target_port) >= 0) { // connect socket to that port obj.downlinks[p_res.sender_chan] = obj.net.createConnection({ host: obj.args.clientaddress, port: p_res.target_port }, function () { - obj.downlinks[p_res.sender_chan].setEncoding('binary');//assume everything is binary, not interpreting + //obj.downlinks[p_res.sender_chan].setEncoding('binary');//assume everything is binary, not interpreting SendChannelOpenConfirm(socket.ws, p_res); }); @@ -348,8 +348,10 @@ function CreateAPFClient(parent, args) { obj.downlinks[p_res.sender_chan].on('end', function () { if (obj.downlinks[p_res.sender_chan]) { try { + Debug("Socket ends."); SendChannelClose(socket.ws, p_res.sender_chan); - delete obj.downlinks[p_res.sender_chan]; + // add some delay before removing... otherwise race condition + setTimeout(function () { delete obj.downlinks[p_res.sender_chan];},100); } catch (e) { Debug("Downlink connection exception: " + e); } @@ -449,14 +451,14 @@ function CreateAPFClient(parent, args) { function SendChannelData(socket, chan, len, data) { var buf = String.fromCharCode(APFProtocol.CHANNEL_DATA) + IntToStr(chan) + IntToStr(len) + data; - socket.write(Buffer.from(buf, 'binary')); + socket.write(buf); Debug("APF: Send ChannelData: " + rstr2hex(buf)); } function SendChannelClose(socket, chan) { var buf = String.fromCharCode(APFProtocol.CHANNEL_CLOSE) + IntToStr(chan); - socket.write(Buffer.from(buf, 'binary')); - Debug("APF: Send ChannelClose: " + rstr2hex(buf)); + socket.write(buf); + Debug("APF: Send ChannelClose "); } obj.connect = function () { diff --git a/agents/modules_meshcore_min/apfclient.min.js b/agents/modules_meshcore_min/apfclient.min.js index 5e4eca9e..f917dcba 100644 --- a/agents/modules_meshcore_min/apfclient.min.js +++ b/agents/modules_meshcore_min/apfclient.min.js @@ -1 +1 @@ -function CreateAPFClient(q,e){var o={};o.parent=q;o.args=e;o.http=require("http");o.net=require("net");o.forwardClient=null;o.downlinks={};o.pfwd_idx=0;o.timer=null;function u(K,J){return(K.charCodeAt(J)*16777216)+(K.charCodeAt(J+1)<<16)+(K.charCodeAt(J+2)<<8)+K.charCodeAt(J+3)}function n(J){return String.fromCharCode((J>>24)&255,(J>>16)&255,(J>>8)&255,J&255)}function m(J){var L="",K=(""+J).match(/../g),M;while(M=K.shift()){L+=String.fromCharCode("0x"+M)}return L}function h(J){return(J+256).toString(16).substr(-2).toUpperCase()}function w(K){var L="",J;for(J=0;J0){o.forwardClient.tag.accumulator=o.forwardClient.tag.accumulator.slice(O)}if(o.cirastate==i.FAILED){k("APF: in a failed state, destroying socket.");o.forwardClient.ws.end()}}while(O>0)}catch(N){k(N)}});o.forwardClient.ws.on("error",function(M){k("APF: Connection error, ending connecting.");if(o.timer!=null){clearInterval(o.timer);o.timer=null}});o.state=i.INITIAL;F(o.forwardClient.ws,o.args.clientuuid);G(o.forwardClient.ws,"auth@amt.intel.com")};function l(J){return J.substring(6,8)+J.substring(4,6)+J.substring(2,4)+J.substring(0,2)+"-"+J.substring(10,12)+J.substring(8,10)+"-"+J.substring(14,16)+J.substring(12,14)+"-"+J.substring(16,20)+"-"+J.substring(20)}function I(K){K=K.replace(/-/g,"");var J=K.substring(6,8)+K.substring(4,6)+K.substring(2,4)+K.substring(0,2);J+=K.substring(10,12)+K.substring(8,10)+K.substring(14,16)+K.substring(12,14)+K.substring(16,20)+K.substring(20);return J}function f(K){var L="";for(var J=0;J=i.AUTH_SERVICE_REQUEST_SENT){H(U.ws,o.args.mpsuser,o.args.mpspass)}}else{if(S=="pfwd@amt.intel.com"){if(o.cirastate>=i.PFWD_SERVICE_REQUEST_SENT){C(U.ws,o.args.clientname,s[o.pfwd_idx++])}}}return 5+T;case d.REQUEST_SUCCESS:if(O>=5){var Q=u(M,1);k("APF: Request to port forward "+Q+" successful.");if(o.pfwd_idx=0){o.downlinks[P.sender_chan]=o.net.createConnection({host:o.args.clientaddress,port:P.target_port},function(){o.downlinks[P.sender_chan].setEncoding("binary");z(U.ws,P)});o.downlinks[P.sender_chan].on("data",function(V){y(U.ws,P.sender_chan,V.length,V)});o.downlinks[P.sender_chan].on("error",function(V){k("Downlink connection error: "+V)});o.downlinks[P.sender_chan].on("end",function(){if(o.downlinks[P.sender_chan]){try{x(U.ws,P.sender_chan);delete o.downlinks[P.sender_chan]}catch(V){k("Downlink connection exception: "+V)}}})}else{A(U.ws,P)}return P.len;case d.CHANNEL_OPEN_CONFIRMATION:k("APF: CHANNEL_OPEN_CONFIRMATION");return 17;case d.CHANNEL_CLOSE:var R=u(M,1);k("APF: CHANNEL_CLOSE: "+R);x(U.ws,R);try{o.downlinks[R].end();delete o.downlinks[R]}catch(N){}return 5;case d.CHANNEL_DATA:k("APF: CHANNEL_DATA: "+JSON.stringify(w(M)));var R=u(M,1);var K=u(M,5);var J=M.substring(9,9+K);if(o.downlinks[R]){try{o.downlinks[R].write(J,"binary",function(){k("Write completed.");B(U.ws,R,K)})}catch(N){k("Cannot forward data to downlink socket.")}}return 9+K;case d.CHANNEL_WINDOW_ADJUST:k("APF: CHANNEL_WINDOW_ADJUST ");return 9;default:k("CMD: "+L+" is not implemented.");o.cirastate=i.FAILED;return 0}}function r(L){var N={len:0,cmd:d.CHANNEL_OPEN,chan_type:"",sender_chan:0,window_size:0,target_address:"",target_port:0,origin_address:"",origin_port:0,};var K=u(L,1);N.chan_type=L.substring(5,5+K);N.sender_chan=u(L,5+K);N.window_size=u(L,9+K);var J=u(L,17+K);N.target_address=L.substring(21+K,21+K+J);N.target_port=u(L,21+K+J);var M=u(L,25+K+J);N.origin_address=L.substring(29+K+J,29+K+J+M);N.origin_port=u(L,29+K+J+M);N.len=33+K+J+M;return N}function A(L,J){var K=String.fromCharCode(d.CHANNEL_OPEN_FAILURE)+n(J.sender_chan)+n(2)+n(0)+n(0);L.write(K);k("APF: Send ChannelOpenFailure")}function z(L,J){var K=String.fromCharCode(d.CHANNEL_OPEN_CONFIRMATION)+n(J.sender_chan)+n(J.sender_chan)+n(J.window_size)+n(4294967295);L.write(K);k("APF: Send ChannelOpenConfirmation")}function B(M,J,L){var K=String.fromCharCode(d.CHANNEL_WINDOW_ADJUST)+n(J)+n(L);M.write(K);k("APF: Send ChannelWindowAdjust: "+w(K))}function y(N,K,M,L){var J=String.fromCharCode(d.CHANNEL_DATA)+n(K)+n(M)+L;N.write(Buffer.from(J,"binary"));k("APF: Send ChannelData: "+w(J))}function x(L,K){var J=String.fromCharCode(d.CHANNEL_CLOSE)+n(K);L.write(Buffer.from(J,"binary"));k("APF: Send ChannelClose: "+w(J))}o.connect=function(){if(o.forwardClient!=null){try{o.forwardClient.ws.end()}catch(J){k(J)}}o.cirastate=i.INITIAL;o.pfwd_idx=0;var K=o.http.parseUri(o.args.mpsurl);K.rejectUnauthorized=0;o.forwardClient=o.http.request(K);o.forwardClient.upgrade=o.onSecureConnect;o.forwardClient.end()};o.disconnect=function(){try{o.forwardClient.ws.end()}catch(J){k(J)}};return o}module.exports=CreateAPFClient; \ No newline at end of file +function CreateAPFClient(q,e){var o={};o.parent=q;o.args=e;o.http=require("http");o.net=require("net");o.forwardClient=null;o.downlinks={};o.pfwd_idx=0;o.timer=null;function u(K,J){return(K.charCodeAt(J)*16777216)+(K.charCodeAt(J+1)<<16)+(K.charCodeAt(J+2)<<8)+K.charCodeAt(J+3)}function n(J){return String.fromCharCode((J>>24)&255,(J>>16)&255,(J>>8)&255,J&255)}function m(J){var L="",K=(""+J).match(/../g),M;while(M=K.shift()){L+=String.fromCharCode("0x"+M)}return L}function h(J){return(J+256).toString(16).substr(-2).toUpperCase()}function w(K){var L="",J;for(J=0;J0){o.forwardClient.tag.accumulator=o.forwardClient.tag.accumulator.slice(O)}if(o.cirastate==i.FAILED){k("APF: in a failed state, destroying socket.");o.forwardClient.ws.end()}}while(O>0)}catch(N){k(N)}});o.forwardClient.ws.on("error",function(M){k("APF: Connection error, ending connecting.");if(o.timer!=null){clearInterval(o.timer);o.timer=null}});o.state=i.INITIAL;F(o.forwardClient.ws,o.args.clientuuid);G(o.forwardClient.ws,"auth@amt.intel.com")};function l(J){return J.substring(6,8)+J.substring(4,6)+J.substring(2,4)+J.substring(0,2)+"-"+J.substring(10,12)+J.substring(8,10)+"-"+J.substring(14,16)+J.substring(12,14)+"-"+J.substring(16,20)+"-"+J.substring(20)}function I(K){K=K.replace(/-/g,"");var J=K.substring(6,8)+K.substring(4,6)+K.substring(2,4)+K.substring(0,2);J+=K.substring(10,12)+K.substring(8,10)+K.substring(14,16)+K.substring(12,14)+K.substring(16,20)+K.substring(20);return J}function f(K){var L="";for(var J=0;J=i.AUTH_SERVICE_REQUEST_SENT){H(U.ws,o.args.mpsuser,o.args.mpspass)}}else{if(S=="pfwd@amt.intel.com"){if(o.cirastate>=i.PFWD_SERVICE_REQUEST_SENT){C(U.ws,o.args.clientname,s[o.pfwd_idx++])}}}return 5+T;case d.REQUEST_SUCCESS:if(O>=5){var Q=u(M,1);k("APF: Request to port forward "+Q+" successful.");if(o.pfwd_idx=0){o.downlinks[P.sender_chan]=o.net.createConnection({host:o.args.clientaddress,port:P.target_port},function(){z(U.ws,P)});o.downlinks[P.sender_chan].on("data",function(V){y(U.ws,P.sender_chan,V.length,V)});o.downlinks[P.sender_chan].on("error",function(V){k("Downlink connection error: "+V)});o.downlinks[P.sender_chan].on("end",function(){if(o.downlinks[P.sender_chan]){try{k("Socket ends.");x(U.ws,P.sender_chan);setTimeout(function(){delete o.downlinks[P.sender_chan]},100)}catch(V){k("Downlink connection exception: "+V)}}})}else{A(U.ws,P)}return P.len;case d.CHANNEL_OPEN_CONFIRMATION:k("APF: CHANNEL_OPEN_CONFIRMATION");return 17;case d.CHANNEL_CLOSE:var R=u(M,1);k("APF: CHANNEL_CLOSE: "+R);x(U.ws,R);try{o.downlinks[R].end();delete o.downlinks[R]}catch(N){}return 5;case d.CHANNEL_DATA:k("APF: CHANNEL_DATA: "+JSON.stringify(w(M)));var R=u(M,1);var K=u(M,5);var J=M.substring(9,9+K);if(o.downlinks[R]){try{o.downlinks[R].write(J,"binary",function(){k("Write completed.");B(U.ws,R,K)})}catch(N){k("Cannot forward data to downlink socket.")}}return 9+K;case d.CHANNEL_WINDOW_ADJUST:k("APF: CHANNEL_WINDOW_ADJUST ");return 9;default:k("CMD: "+L+" is not implemented.");o.cirastate=i.FAILED;return 0}}function r(L){var N={len:0,cmd:d.CHANNEL_OPEN,chan_type:"",sender_chan:0,window_size:0,target_address:"",target_port:0,origin_address:"",origin_port:0,};var K=u(L,1);N.chan_type=L.substring(5,5+K);N.sender_chan=u(L,5+K);N.window_size=u(L,9+K);var J=u(L,17+K);N.target_address=L.substring(21+K,21+K+J);N.target_port=u(L,21+K+J);var M=u(L,25+K+J);N.origin_address=L.substring(29+K+J,29+K+J+M);N.origin_port=u(L,29+K+J+M);N.len=33+K+J+M;return N}function A(L,J){var K=String.fromCharCode(d.CHANNEL_OPEN_FAILURE)+n(J.sender_chan)+n(2)+n(0)+n(0);L.write(K);k("APF: Send ChannelOpenFailure")}function z(L,J){var K=String.fromCharCode(d.CHANNEL_OPEN_CONFIRMATION)+n(J.sender_chan)+n(J.sender_chan)+n(J.window_size)+n(4294967295);L.write(K);k("APF: Send ChannelOpenConfirmation")}function B(M,J,L){var K=String.fromCharCode(d.CHANNEL_WINDOW_ADJUST)+n(J)+n(L);M.write(K);k("APF: Send ChannelWindowAdjust: "+w(K))}function y(N,K,M,L){var J=String.fromCharCode(d.CHANNEL_DATA)+n(K)+n(M)+L;N.write(J);k("APF: Send ChannelData: "+w(J))}function x(L,K){var J=String.fromCharCode(d.CHANNEL_CLOSE)+n(K);L.write(J);k("APF: Send ChannelClose ")}o.connect=function(){if(o.forwardClient!=null){try{o.forwardClient.ws.end()}catch(J){k(J)}}o.cirastate=i.INITIAL;o.pfwd_idx=0;var K=o.http.parseUri(o.args.mpsurl);K.rejectUnauthorized=0;o.forwardClient=o.http.request(K);o.forwardClient.upgrade=o.onSecureConnect;o.forwardClient.end()};o.disconnect=function(){try{o.forwardClient.ws.end()}catch(J){k(J)}};return o}module.exports=CreateAPFClient; \ No newline at end of file diff --git a/amt/amt-wsman-comm.js b/amt/amt-wsman-comm.js index 49d32b89..9c804e5f 100644 --- a/amt/amt-wsman-comm.js +++ b/amt/amt-wsman-comm.js @@ -1,6 +1,6 @@ /** * @description Intel(r) AMT WSMAN communication using Node.js TLS -* @author Ylian Saint-Hilaire +* @author Ylian Saint-Hilaire/Joko Sastriawan * @version v0.2.0b */ @@ -39,7 +39,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, parent, obj.xtls = tls; obj.xtlsoptions = tlsoptions; obj.parent = parent; - obj.mode = mode;//0: webrelay; 1: direct, 2: CIRA, 3: APF relay + obj.mode = mode;//1: direct, 2: CIRA, 3: APF relay obj.xtlsFingerprint; obj.xtlsCertificate = null; obj.xtlsCheck = 0; // 0 = No TLS, 1 = CA Checked, 2 = Pinned, 3 = Untrusted @@ -167,17 +167,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, parent, obj.socketState = 1; obj.kerberosDone = 0; - if (obj.mode==0 && obj.xtlsoptions && obj.xtlsoptions.meshServerConnect) { //Webrelay - // Use the websocket wrapper to connect to MeshServer server - obj.socket = CreateWebSocketWrapper(obj.xtlsoptions.host, obj.xtlsoptions.port, '/webrelay.ashx?user=' + encodeURIComponent(obj.xtlsoptions.username) + '&pass=' + encodeURIComponent(obj.xtlsoptions.password) + '&host=' + encodeURIComponent(obj.host) + '&p=1&tls1only=' + obj.xtlsMethod, obj.xtlsoptions.xtlsFingerprint); - obj.socket.setEncoding('binary'); - obj.socket.setTimeout(6000); // Set socket idle timeout - obj.socket.ondata = obj.xxOnSocketData; - obj.socket.onclose = function () { if (obj.xtlsDataReceived == false) { obj.xtlsMethod = 1 - obj.xtlsMethod; } obj.xxOnSocketClosed(); } - obj.socket.ontimeout = function () { if (obj.xtlsDataReceived == false) { obj.xtlsMethod = 1 - obj.xtlsMethod; } obj.xxOnSocketClosed(); } - obj.socket.connect(obj.xxOnSocketConnected); - obj.socket.setNoDelay(true); // Disable nagle. We will encode each WSMAN request as a single send block and want to send it at once. This may help Intel AMT handle pipelining? - } else if (obj.mode==1 ) { //Direct + if (obj.mode==1 ) { //Direct if (obj.xtls != 1) { // Connect without TLS obj.socket = new obj.net.Socket(); @@ -214,7 +204,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, parent, obj.socket = obj.parent.apfserver.SetupCiraChannel(apfconn, obj.port); } obj.socket.onData = function (ccon, data) { - _OnSocketData(data); + obj.xxOnSocketData(data); } obj.socket.onStateChange = function (ccon, state) { @@ -225,11 +215,11 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, parent, obj.socketHeader = null; obj.socketData = ''; obj.socketState = 0; - _OnSocketClosed(); + obj.xxOnSocketClosed(); } catch (e) { } } else if (state == 2) { // channel open success - _OnSocketConnected(); + obj.xxOnSocketConnected(); } } } @@ -289,8 +279,8 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, parent, // NODE.js specific private method obj.xxOnSocketData = function (data) { - obj.xtlsDataReceived = true; - if (urlvars && urlvars['wsmantrace']) { console.log("WSMAN-RECV(" + data.length + "): " + 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) var binary = "", bytes = new Uint8Array(data), length = bytes.byteLength; @@ -305,7 +295,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, parent, if (obj.socketParseState == 0) { var headersize = obj.socketAccumulator.indexOf("\r\n\r\n"); if (headersize < 0) return; - //obj.Debug(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"); 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); @@ -361,8 +351,10 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, parent, var s = parseInt(header.Directive[1]); if (isNaN(s)) s = 500; if (s == 401 && ++(obj.authcounter) < 3) { - obj.challengeParams = obj.parseDigest(header['www-authenticate']); // Set the digest parameters, after this, the socket will close and we will auto-retry - obj.socket.end(); + obj.challengeParams = obj.parseDigest(header['www-authenticate']); // Set the digest parameters, after this, the socket will close and we will auto-retry + if (obj.mode==1) { + obj.socket.end(); + } } else { var r = obj.pendingAjaxCall.shift(); if (r == null || r.length < 1) { console.log("pendingAjaxCall error, " + r); return; } @@ -378,7 +370,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, parent, obj.xxOnSocketClosed = function (data) { //obj.Debug("xxOnSocketClosed"); obj.socketState = 0; - if (obj.socket != null) { obj.socket.destroy(); obj.socket = null; } + if (obj.mode ==1 && obj.socket != null) { obj.socket.destroy(); obj.socket = null; } if (obj.pendingAjaxCall.length > 0) { var r = obj.pendingAjaxCall.shift(); var retry = r[5]; @@ -389,8 +381,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, parent, // NODE.js specific private method obj.xxSend = function (x) { if (obj.socketState == 2) { - if (urlvars && urlvars['wsmantrace']) { console.log("WSMAN-SEND(" + x.length + "): " + x); } - obj.socket.write(new Buffer(x, "binary")); + obj.socket.write(Buffer.from(x, "binary")); } } diff --git a/amt/amt-wsman.js b/amt/amt-wsman.js index 88f71bde..4dc38aa5 100644 --- a/amt/amt-wsman.js +++ b/amt/amt-wsman.js @@ -16,12 +16,12 @@ limitations under the License. /** * @description Intel(r) AMT WSMAN Stack -* @author Ylian Saint-Hilaire +* @author Ylian Saint-Hilaire/Joko Sastriawan * @version v0.2.0 */ // Construct a MeshServer object -function WsmanStackCreateService(CreateWsmanComm, host, port, user, pass, tls, extra) +function WsmanStackCreateService(CreateWsmanComm, host, port, user, pass, tls, extra, parent, mode) { var obj = {_ObjectID: 'WSMAN'}; //obj.onDebugMessage = null; // Set to a function if you want to get debug messages. @@ -38,7 +38,7 @@ function WsmanStackCreateService(CreateWsmanComm, host, port, user, pass, tls, e { var CreateWsmanComm = arguments[0]; if (CreateWsmanComm) { - obj.comm = new CreateWsmanComm(host, port, user, pass, tls, extra); + obj.comm = new CreateWsmanComm(host, port, user, pass, tls, extra, parent, mode); } } diff --git a/meshuser.js b/meshuser.js index 52a1ad68..629b316d 100644 --- a/meshuser.js +++ b/meshuser.js @@ -48,6 +48,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use obj.user = user; obj.domain = domain; + // Server side amt stack + var WsmanComm = require('./amt/amt-wsman-comm.js'); + var Wsman = require('./amt/amt-wsman.js'); + var Amt = require('./amt/amt.js'); + // Send a message to the user //obj.send = function (data) { try { if (typeof data == 'string') { ws.send(Buffer.from(data, 'binary')); } else { ws.send(data); } } catch (e) { } } @@ -2784,6 +2789,39 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } break; } + case 'amt': { + if (common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid + if (common.validateInt(command.mode, 0, 3) == false) break; // Check connection mode + // validate if communication mode is possible + if (command.mode == null || command.mode==0) { + break;//unsupported + } else if (command.mode == 1) { + var state = parent.parent.GetConnectivityState(command.nodeid); + if ( (state == null) || (state.connectivity & 4)==0 ) break; + } else if (command.mode == 2) { + if (parent.parent.mpsserver.ciraConnections[command.nodeid] == null) break; + } else if (command.mode == 3) { + if (parent.parent.apfserver.apfConnections[command.nodeid] == null) break; + } + var nodeid = command.nodeid; + if ((nodeid.split('/').length == 3) && (nodeid.split('/')[1] == domain.id)) { // Validate the domain, operation only valid for current domain + // Get the device + db.Get(nodeid, function (err, nodes) { + if ((nodes == null) || (nodes.length != 1)) return; + var node = nodes[0]; + + // Get the mesh for this device + mesh = parent.meshes[node.meshid]; + if (mesh) { + // Check if this user has rights to do this + if (mesh.links[user._id] != null && ((mesh.links[user._id].rights & 8) != 0)) { // "Remote Control permission" + handleAmtCommand(command, node); + } + } + }); + } + break; + } default: { // Unknown user action console.log('Unknown action from user ' + user.name + ': ' + command.action + '.'); @@ -2912,5 +2950,33 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use function getRandomPassword() { return Buffer.from(parent.crypto.randomBytes(9), 'binary').toString('base64').split('/').join('@'); } + function handleAmtCommand(cmd, node) { + if (cmd==null) return; + var host = cmd.nodeid; + if (cmd.mode==1) { + host = node.host; + } + var tlsoptions = null; + var wsman = new Wsman(WsmanComm, host, node.intelamt.tls? 16993: 16992, node.intelamt.user, node.intelamt.pass, + node.intelamt.tls,tlsoptions, parent.parent, cmd.mode); + var amt = new Amt(wsman); + switch (cmd.command) { + case "Get-GeneralSettings": { + amt.Get("AMT_GeneralSettings", function(obj, name, response, status) { + if (status==200) { + var resp = { action: 'amt', nodeid: cmd.nodeid, command: 'Get-GeneralSettings', value: response.Body} + ws.send(JSON.stringify(resp)); + } else { + ws.send(JSON.stringify({"error": error})); + } + }); + break; + } + default: { + // do nothing + } + } + } + return obj; }; \ No newline at end of file diff --git a/mpsserver.js b/mpsserver.js index 8be3c95c..764fd28e 100644 --- a/mpsserver.js +++ b/mpsserver.js @@ -791,8 +791,8 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { return true; } // Send a part of the message - cirachannel.sendBuffer = data.substring(cirachannel.sendcredits); - SendChannelData(cirachannel.socket, cirachannel.amtchannelid, data.substring(0, cirachannel.sendcredits)); + cirachannel.sendBuffer = data.toString('binary').substring(cirachannel.sendcredits); + SendChannelData(cirachannel.socket, cirachannel.amtchannelid, data.toString('binary').substring(0, cirachannel.sendcredits)); cirachannel.sendcredits = 0; return false; };