mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-03-09 15:40:18 +00:00
MeshAgents on Windows are now signed.
This commit is contained in:
parent
618dfbe42e
commit
80545a7e57
54 changed files with 135 additions and 8640 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,456 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Script Compiler / Decompiler / Runner
|
||||
* @author Ylian Saint-Hilaire
|
||||
* @version v0.1.0e
|
||||
*/
|
||||
|
||||
// Core functions
|
||||
script_functionTable1 = ['nop', 'jump', 'set', 'print', 'dialog', 'getitem', 'substr', 'indexof', 'split', 'join', 'length', 'jsonparse', 'jsonstr', 'add', 'substract', 'parseint', 'wsbatchenum', 'wsput', 'wscreate', 'wsdelete', 'wsexec', 'scriptspeed', 'wssubscribe', 'wsunsubscribe', 'readchar', 'signwithdummyca'];
|
||||
|
||||
// functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
script_functionTable2 = ['encodeuri', 'decodeuri', 'passwordcheck', 'atob', 'btoa', 'hex2str', 'str2hex', 'random', 'md5', 'maketoarray', 'readshort', 'readshortx', 'readint', 'readsint', 'readintx', 'shorttostr', 'shorttostrx', 'inttostr', 'inttostrx'];
|
||||
|
||||
// functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
script_functionTableX2 = [encodeURI, decodeURI, passwordcheck, window.atob.bind(window), window.btoa.bind(window), hex2rstr, rstr2hex, random, rstr_md5, MakeToArray, ReadShort, ReadShortX, ReadInt, ReadSInt, ReadIntX, ShortToStr, ShortToStrX, IntToStr, IntToStrX];
|
||||
|
||||
// Optional functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
script_functionTable3 = ['pullsystemstatus', 'pulleventlog', 'pullauditlog', 'pullcertificates', 'pullwatchdog', 'pullsystemdefense', 'pullhardware', 'pulluserinfo', 'pullremoteaccess', 'highlightblock', 'disconnect', 'getsidstring', 'getsidbytearray', 'pulleventsubscriptions'];
|
||||
|
||||
// Optional functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
script_functionTableX3 = [
|
||||
PullSystemStatus
|
||||
,
|
||||
// ###BEGIN###{EventLog}
|
||||
PullEventLog
|
||||
// ###END###{EventLog}
|
||||
,
|
||||
// ###BEGIN###{AuditLog}
|
||||
PullAuditLog
|
||||
// ###END###{AuditLog}
|
||||
,
|
||||
// ###BEGIN###{Certificates}
|
||||
PullCertificates
|
||||
// ###END###{Certificates}
|
||||
,
|
||||
// ###BEGIN###{AgentPresence}
|
||||
PullWatchdog
|
||||
// ###END###{AgentPresence}
|
||||
,
|
||||
// ###BEGIN###{SystemDefense}
|
||||
PullSystemDefense
|
||||
// ###END###{SystemDefense}
|
||||
,
|
||||
// ###BEGIN###{HardwareInfo}
|
||||
PullHardware
|
||||
// ###END###{HardwareInfo}
|
||||
,
|
||||
PullUserInfo
|
||||
,
|
||||
// ###BEGIN###{RemoteAccess}
|
||||
PullRemoteAccess
|
||||
// ###END###{RemoteAccess}
|
||||
,
|
||||
// ###BEGIN###{Scripting-Editor}
|
||||
script_HighlightBlock
|
||||
// ###END###{Scripting-Editor}
|
||||
,
|
||||
// ###BEGIN###{ComputerSelector}
|
||||
disconnect
|
||||
// ###END###{ComputerSelector}
|
||||
,
|
||||
function (runner, x) { return GetSidString(x); }
|
||||
,
|
||||
function (runner, x) { return GetSidByteArray(x); }
|
||||
,
|
||||
// ###BEGIN###{EventSubscriptions}
|
||||
PullEventSubscriptions
|
||||
// ###END###{EventSubscriptions}
|
||||
];
|
||||
|
||||
// Setup the script state
|
||||
function script_setup(binary, startvars) {
|
||||
var obj = { startvars:startvars };
|
||||
if (binary.length < 6) { console.error('Invalid script length'); return null; } // Script must have at least 6 byte header
|
||||
if (ReadInt(binary, 0) != 0x247D2945) { console.error('Invalid binary script'); return null; } // Check the script magic header
|
||||
if (ReadShort(binary, 4) > 1) { console.error('Unsupported script version'); return null; } // Check the script version
|
||||
obj.script = binary.substring(6);
|
||||
// obj.onStep;
|
||||
// obj.onConsole;
|
||||
|
||||
// Reset the script to the start
|
||||
obj.reset = function (stepspeed) {
|
||||
obj.stop();
|
||||
obj.ip = 0;
|
||||
obj.variables = startvars;
|
||||
obj.state = 1;
|
||||
}
|
||||
|
||||
// Start the script
|
||||
obj.start = function (stepspeed) {
|
||||
obj.stop();
|
||||
obj.stepspeed = stepspeed;
|
||||
if (stepspeed > 0) { obj.timer = setInterval(function () { obj.step() }, stepspeed); }
|
||||
}
|
||||
|
||||
// Stop the script
|
||||
obj.stop = function () {
|
||||
if (obj.timer != null) { clearInterval(obj.timer); }
|
||||
obj.timer = null;
|
||||
obj.stepspeed = 0;
|
||||
}
|
||||
|
||||
// function used to load and store variable values
|
||||
obj.getVar = function (name) { if (name == undefined) return undefined; return obj.getVarEx(name.split('.'), obj.variables); }
|
||||
obj.getVarEx = function (name, val) { try { if (name == undefined) return undefined; if (name.length == 0) return val; return obj.getVarEx(name.slice(1), val[name[0]]); } catch (e) { return null; } }
|
||||
obj.setVar = function (name, val) { obj.setVarEx(name.split('.'), obj.variables, val); }
|
||||
obj.setVarEx = function (name, vars, val) { if (name.length == 1) { vars[name[0]] = val; } else { obj.setVarEx(name.slice(1), vars[name[0]], val); } }
|
||||
|
||||
// Run the script one step forward
|
||||
obj.step = function () {
|
||||
if (obj.state != 1) return;
|
||||
if (obj.ip < obj.script.length) {
|
||||
var cmdid = ReadShort(obj.script, obj.ip);
|
||||
var cmdlen = ReadShort(obj.script, obj.ip + 2);
|
||||
var argcount = ReadShort(obj.script, obj.ip + 4);
|
||||
var argptr = obj.ip + 6;
|
||||
var args = [];
|
||||
|
||||
// Clear all temp variables (This is optional)
|
||||
for (var i in obj.variables) { if (i.startsWith('__')) { delete obj.variables[i]; } }
|
||||
|
||||
// Loop on each argument, moving forward by the argument length each time
|
||||
for (var i = 0; i < argcount; i++) {
|
||||
var arglen = ReadShort(obj.script, argptr);
|
||||
var argval = obj.script.substring(argptr + 2, argptr + 2 + arglen);
|
||||
var argtyp = argval.charCodeAt(0);
|
||||
argval = argval.substring(1);
|
||||
if (argtyp < 2) {
|
||||
// Get the value and replace all {var} with variable values
|
||||
while (argval.split("{").length > 1) { var t = argval.split("{").pop().split("}").shift(); argval = argval.replace('{' + t + '}', obj.getVar(t)); }
|
||||
if (argtyp == 1) { obj.variables['__' + i] = decodeURI(argval); argval = '__' + i; } // If argtyp is 1, this is a literal. Store in temp variable.
|
||||
args.push(argval);
|
||||
}
|
||||
if (argtyp == 2 || argtyp == 3) {
|
||||
obj.variables['__' + i] = ReadSInt(argval, 0);
|
||||
args.push('__' + i);
|
||||
}
|
||||
argptr += (2 + arglen);
|
||||
}
|
||||
|
||||
// Move instruction pointer forward by command size
|
||||
obj.ip += cmdlen;
|
||||
|
||||
// Get all variable values
|
||||
var argsval = [];
|
||||
for (var i = 0; i < 10; i++) { argsval.push(obj.getVar(args[i])); }
|
||||
var storeInArg0;
|
||||
|
||||
try {
|
||||
if (cmdid < 10000) {
|
||||
// Lets run the actual command
|
||||
switch (cmdid) {
|
||||
case 0: // nop
|
||||
break;
|
||||
case 1: // jump(label) or jump(label, a, compare, b)
|
||||
if (argsval[2]) {
|
||||
if (
|
||||
(argsval[2] == '<' && argsval[1] < argsval[3]) ||
|
||||
(argsval[2] == '<=' && argsval[1] <= argsval[3]) ||
|
||||
(argsval[2] == '!=' && argsval[1] != argsval[3]) ||
|
||||
(argsval[2] == '=' && argsval[1] == argsval[3]) ||
|
||||
(argsval[2] == '>=' && argsval[1] >= argsval[3]) ||
|
||||
(argsval[2] == '>' && argsval[1] > argsval[3])
|
||||
) { obj.ip = argsval[0]; }
|
||||
} else {
|
||||
obj.ip = argsval[0]; // Set the instruction pointer to the new location in the script
|
||||
}
|
||||
break;
|
||||
case 2: // set(variable, value)
|
||||
if (args[1] == undefined) delete obj.variables[args[0]]; else obj.setVar(args[0], argsval[1]);
|
||||
break;
|
||||
case 3: // print(message)
|
||||
if (obj.onConsole) { obj.onConsole(obj.toString(argsval[0]), obj); } else { console.log(obj.toString(argsval[0])); }
|
||||
// Q(obj.consoleid).value += () + '\n'); Q(obj.console).scrollTop = Q(obj.console).scrollHeight;
|
||||
break;
|
||||
case 4: // dialog(title, content, buttons)
|
||||
obj.state = 2;
|
||||
obj.dialog = true;
|
||||
setDialogMode(11, argsval[0], argsval[2], obj.xxStepDialogOk, argsval[1], obj);
|
||||
break;
|
||||
case 5: // getitem(a, b, c)
|
||||
for (var i in argsval[1]) { if (argsval[1][i][argsval[2]] == argsval[3]) { storeInArg0 = i; } };
|
||||
break;
|
||||
case 6: // substr(variable_dest, variable_src, index, len)
|
||||
storeInArg0 = argsval[1].substr(argsval[2], argsval[3]);
|
||||
break;
|
||||
case 7: // indexOf(variable_dest, variable_src, index, len)
|
||||
storeInArg0 = argsval[1].indexOf(argsval[2]);
|
||||
break;
|
||||
case 8: // split(variable_dest, variable_src, separator)
|
||||
storeInArg0 = argsval[1].split(argsval[2]);
|
||||
break;
|
||||
case 9: // join(variable_dest, variable_src, separator)
|
||||
storeInArg0 = argsval[1].join(argsval[2]);
|
||||
break;
|
||||
case 10: // length(variable_dest, variable_src)
|
||||
storeInArg0 = argsval[1].length;
|
||||
break;
|
||||
case 11: // jsonparse(variable_dest, json)
|
||||
storeInArg0 = JSON.parse(argsval[1]);
|
||||
break;
|
||||
case 12: // jsonstr(variable_dest, variable_src)
|
||||
storeInArg0 = JSON.stringify(argsval[1]);
|
||||
break;
|
||||
case 13: // add(variable_dest, variable_src, value)
|
||||
storeInArg0 = (argsval[1] + argsval[2]);
|
||||
break;
|
||||
case 14: // substract(variable_dest, variable_src, value)
|
||||
storeInArg0 = (argsval[1] - argsval[2]);
|
||||
break;
|
||||
case 15: // parseInt(variable_dest, variable_src)
|
||||
storeInArg0 = parseInt(argsval[1]);
|
||||
break;
|
||||
case 16: // wsbatchenum(name, objectList)
|
||||
obj.state = 2;
|
||||
obj.amtstack.BatchEnum(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
|
||||
break;
|
||||
case 17: // wsput(name, args)
|
||||
obj.state = 2;
|
||||
obj.amtstack.Put(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
|
||||
break;
|
||||
case 18: // wscreate(name, args)
|
||||
obj.state = 2;
|
||||
obj.amtstack.Create(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
|
||||
break;
|
||||
case 19: // wsdelete(name, args)
|
||||
obj.state = 2;
|
||||
obj.amtstack.Delete(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
|
||||
break;
|
||||
case 20: // wsexec(name, method, args, selectors)
|
||||
obj.state = 2;
|
||||
obj.amtstack.Exec(argsval[0], argsval[1], argsval[2], obj.xxWsmanReturn, obj, 0, argsval[3]);
|
||||
break;
|
||||
case 21: // Script Speed
|
||||
obj.stepspeed = argsval[0];
|
||||
if (obj.timer != null) { clearInterval(obj.timer); obj.timer = setInterval(function () { obj.step() }, obj.stepspeed); }
|
||||
break;
|
||||
case 22: // wssubscribe(name, delivery, url, selectors, opaque, user, pass)
|
||||
obj.state = 2;
|
||||
obj.amtstack.Subscribe(argsval[0], argsval[1], argsval[2], obj.xxWsmanReturn, obj, 0, argsval[3], argsval[4], argsval[5], argsval[6]);
|
||||
break;
|
||||
case 23: // wsunsubscribe(name, selectors)
|
||||
obj.state = 2;
|
||||
obj.amtstack.UnSubscribe(argsval[0], obj.xxWsmanReturn, obj, 0, argsval[1]);
|
||||
break;
|
||||
case 24: // readchar(str, pos)
|
||||
console.log(argsval[1], argsval[2], argsval[1].charCodeAt(argsval[2]));
|
||||
storeInArg0 = argsval[1].charCodeAt(argsval[2]);
|
||||
break;
|
||||
case 25: // signWithDummyCa
|
||||
// ###BEGIN###{Certificates}
|
||||
obj.state = 2;
|
||||
// DERKey, xxCaPrivateKey, certattributes, issuerattributes
|
||||
amtcert_signWithCaKey(argsval[0], null, argsval[1], { 'CN': 'Untrusted Root Certificate' }, obj.xxSignWithDummyCaReturn);
|
||||
// ###END###{Certificates}
|
||||
break;
|
||||
default: {
|
||||
obj.state = 9;
|
||||
console.error("Script Error, unknown command: " + cmdid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cmdid < 20000) {
|
||||
// functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
storeInArg0 = script_functionTableX2[cmdid - 10000](argsval[1], argsval[2], argsval[3], argsval[4], argsval[5], argsval[6]);
|
||||
} else {
|
||||
// Optional functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
if (script_functionTableX3 && script_functionTableX3[cmdid - 20000]) {
|
||||
storeInArg0 = script_functionTableX3[cmdid - 20000](obj, argsval[1], argsval[2], argsval[3], argsval[4], argsval[5], argsval[6]); // Note that optional calls start with "obj" as first argument.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (storeInArg0 != undefined) obj.setVar(args[0], storeInArg0);
|
||||
} catch (e) {
|
||||
if (typeof e == 'object') { e = e.message; }
|
||||
obj.setVar('_exception', e);
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.state == 1 && obj.ip >= obj.script.length) { obj.state = 0; obj.stop(); }
|
||||
if (obj.onStep) obj.onStep(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
obj.xxStepDialogOk = function (button) {
|
||||
obj.variables['DialogSelect'] = button;
|
||||
obj.state = 1;
|
||||
obj.dialog = false;
|
||||
if (obj.onStep) obj.onStep(obj);
|
||||
}
|
||||
|
||||
// ###BEGIN###{**ClosureAdvancedMode}
|
||||
obj.xxWsmanReturnFix = function (x) {
|
||||
if (!x || x == null) return;
|
||||
if (x.Header) { x['Header'] = x.Header; delete x.Header; }
|
||||
if (x.Body) { x['Body'] = x.Body; delete x.Body; }
|
||||
if (x.Responses) { x['Responses'] = x.Responses; delete x.Responses; }
|
||||
if (x.Response) { x['Response'] = x.Response; delete x.Response; }
|
||||
if (x.ReturnValueStr) { x['ReturnValueStr'] = x.ReturnValueStr; delete x.ReturnValueStr; }
|
||||
}
|
||||
// ###END###{**ClosureAdvancedMode}
|
||||
|
||||
obj.xxWsmanReturn = function (stack, name, responses, status) {
|
||||
// ###BEGIN###{**ClosureAdvancedMode}
|
||||
// This is required when Google Closure is used
|
||||
if (responses) {
|
||||
obj.xxWsmanReturnFix(responses);
|
||||
for (var i in responses) {
|
||||
obj.xxWsmanReturnFix(responses[i]);
|
||||
for (var j in responses[i]) { obj.xxWsmanReturnFix(responses[i][j]); }
|
||||
}
|
||||
}
|
||||
// ###END###{**ClosureAdvancedMode}
|
||||
obj.setVar(name, responses);
|
||||
obj.setVar('wsman_result', status);
|
||||
obj.setVar('wsman_result_str', ((httpErrorTable[status]) ? (httpErrorTable[status]) : ('Error #' + status)));
|
||||
obj.state = 1;
|
||||
if (obj.onStep) obj.onStep(obj);
|
||||
}
|
||||
|
||||
// ###BEGIN###{Certificates}
|
||||
obj.xxSignWithDummyCaReturn = function (cert) {
|
||||
obj.setVar('signed_cert', btoa(_arrayBufferToString(cert)));
|
||||
obj.state = 1;
|
||||
if (obj.onStep) obj.onStep(obj);
|
||||
}
|
||||
// ###END###{Certificates}
|
||||
|
||||
obj.toString = function (x) { if (typeof x == 'object') return JSON.stringify(x); return x; }
|
||||
|
||||
obj.reset();
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Argument types: 0 = Variable, 1 = String, 2 = Integer, 3 = Label
|
||||
function script_compile(script, onmsg) {
|
||||
var r = '', scriptlines = script.split('\n'), labels = {}, labelswap = [], swaps = [];
|
||||
// Go thru each script line and encode it
|
||||
for (var i in scriptlines) {
|
||||
var scriptline = scriptlines[i];
|
||||
if (scriptline.startsWith('##SWAP ')) { var x = scriptline.split(' '); if (x.length == 3) { swaps[x[1]] = x[2]; } } // Add a swap instance
|
||||
if (scriptline[0] == '#' || scriptline.length == 0) continue; // Skip comments & blank lines
|
||||
for (var x in swaps) { scriptline = scriptline.split(x).join(swaps[x]); } // Apply all swaps
|
||||
var keywords = scriptline.match(/"[^"]*"|[^\s"]+/g);
|
||||
if (keywords.length == 0) continue; // Skip blank lines
|
||||
if (scriptline[0] == ':') { labels[keywords[0].toUpperCase()] = r.length; continue; } // Mark a label position
|
||||
var funcIndex = script_functionTable1.indexOf(keywords[0].toLowerCase());
|
||||
if (funcIndex == -1) { funcIndex = script_functionTable2.indexOf(keywords[0].toLowerCase()); if (funcIndex >= 0) funcIndex += 10000; }
|
||||
if (funcIndex == -1) { funcIndex = script_functionTable3.indexOf(keywords[0].toLowerCase()); if (funcIndex >= 0) funcIndex += 20000; } // Optional methods
|
||||
if (funcIndex == -1) { if (onmsg) { onmsg("Unabled to compile, unknown command: " + keywords[0]); } return ''; }
|
||||
// Encode CommandId, CmdSize, ArgCount, Arg1Len, Arg1, Arg2Len, Arg2...
|
||||
var cmd = ShortToStr(keywords.length - 1);
|
||||
for (var j in keywords) {
|
||||
if (j == 0) continue;
|
||||
if (keywords[j][0] == ':') {
|
||||
labelswap.push([keywords[j], r.length + cmd.length + 7]); // Add a label swap
|
||||
cmd += ShortToStr(5) + String.fromCharCode(3) + IntToStr(0xFFFFFFFF); // Put an empty label
|
||||
} else {
|
||||
var argint = parseInt(keywords[j]);
|
||||
if (argint == keywords[j]) {
|
||||
cmd += ShortToStr(5) + String.fromCharCode(2) + IntToStr(argint);
|
||||
} else {
|
||||
if (keywords[j][0] == '"' && keywords[j][keywords[j].length - 1] == '"') {
|
||||
cmd += ShortToStr(keywords[j].length - 1) + String.fromCharCode(1) + keywords[j].substring(1, keywords[j].length - 1);
|
||||
} else {
|
||||
cmd += ShortToStr(keywords[j].length + 1) + String.fromCharCode(0) + keywords[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cmd = ShortToStr(funcIndex) + ShortToStr(cmd.length + 4) + cmd;
|
||||
r += cmd;
|
||||
}
|
||||
// Perform all the needed label swaps
|
||||
for (i in labelswap) {
|
||||
var label = labelswap[i][0].toUpperCase(), position = labelswap[i][1], target = labels[label];
|
||||
if (target == undefined) { if (onmsg) { onmsg("Unabled to compile, unknown label: " + label); } return ''; }
|
||||
r = r.substr(0, position) + IntToStr(target) + r.substr(position + 4);
|
||||
}
|
||||
return IntToStr(0x247D2945) + ShortToStr(1) + r;
|
||||
}
|
||||
|
||||
// Decompile the script, intended for debugging only
|
||||
function script_decompile(binary, onecmd) {
|
||||
var r = '', ptr = 6, labelcount = 0, labels = {};
|
||||
if (onecmd >= 0) {
|
||||
ptr = onecmd; // If we are decompiling just one command, set the ptr to that command.
|
||||
} else {
|
||||
if (binary.length < 6) { return '# Invalid script length'; }
|
||||
var magic = ReadInt(binary, 0);
|
||||
var version = ReadShort(binary, 4);
|
||||
if (magic != 0x247D2945) { return '# Invalid binary script: ' + magic; }
|
||||
if (version != 1) { return '# Invalid script version'; }
|
||||
}
|
||||
// Loop on each command, moving forward by the command length each time.
|
||||
while (ptr < binary.length) {
|
||||
var cmdid = ReadShort(binary, ptr);
|
||||
var cmdlen = ReadShort(binary, ptr + 2);
|
||||
var argcount = ReadShort(binary, ptr + 4);
|
||||
var argptr = ptr + 6;
|
||||
var argstr = '';
|
||||
if (!(onecmd >= 0)) r += ":label" + (ptr - 6) + "\n";
|
||||
// Loop on each argument, moving forward by the argument length each time
|
||||
for (var i = 0; i < argcount; i++) {
|
||||
var arglen = ReadShort(binary, argptr);
|
||||
var argval = binary.substring(argptr + 2, argptr + 2 + arglen);
|
||||
var argtyp = argval.charCodeAt(0);
|
||||
if (argtyp == 0) { argstr += ' ' + argval.substring(1); } // Variable
|
||||
else if (argtyp == 1) { argstr += ' \"' + argval.substring(1) + '\"'; } // String
|
||||
else if (argtyp == 2) { argstr += ' ' + ReadInt(argval, 1); } // Integer
|
||||
else if (argtyp == 3) { // Label
|
||||
var target = ReadInt(argval, 1);
|
||||
var label = labels[target];
|
||||
if (!label) { label = ":label" + target; labels[label] = target; }
|
||||
argstr += ' ' + label;
|
||||
}
|
||||
argptr += (2 + arglen);
|
||||
}
|
||||
// Go in the script function table to decode the function
|
||||
if (cmdid < 10000) {
|
||||
r += script_functionTable1[cmdid] + argstr + "\n";
|
||||
} else {
|
||||
if (cmdid >= 20000) {
|
||||
r += script_functionTable3[cmdid - 20000] + argstr + "\n"; // Optional methods
|
||||
} else {
|
||||
r += script_functionTable2[cmdid - 10000] + argstr + "\n";
|
||||
}
|
||||
}
|
||||
ptr += cmdlen;
|
||||
if (onecmd >= 0) return r; // If we are decompiling just one command, exit now
|
||||
}
|
||||
// Remove all unused labels
|
||||
var scriptlines = r.split('\n');
|
||||
r = '';
|
||||
for (var i in scriptlines) {
|
||||
var line = scriptlines[i];
|
||||
if (line[0] != ':') { r += line + '\n'; } else { if (labels[line]) { r += line + '\n'; } }
|
||||
}
|
||||
return r;
|
||||
}
|
|
@ -1,332 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description Intel(r) AMT WSMAN Stack
|
||||
* @author Ylian Saint-Hilaire
|
||||
* @version v0.2.0
|
||||
*/
|
||||
|
||||
// Construct a MeshServer object
|
||||
function WsmanStackCreateService(CreateWsmanComm, host, port, user, pass, tls, extra) {
|
||||
var obj = {};
|
||||
//obj.onDebugMessage = null; // Set to a function if you want to get debug messages.
|
||||
obj.NextMessageId = 1; // Next message number, used to label WSMAN calls.
|
||||
obj.Address = '/wsman';
|
||||
obj.comm = new CreateWsmanComm(host, port, user, pass, tls, extra);
|
||||
|
||||
obj.PerformAjax = function (postdata, callback, tag, pri, namespaces) {
|
||||
if (namespaces == null) namespaces = '';
|
||||
obj.comm.PerformAjax('<?xml version=\"1.0\" encoding=\"utf-8\"?><Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns=\"http://www.w3.org/2003/05/soap-envelope\" ' + namespaces + '><Header><a:Action>' + postdata, function (data, status, tag) {
|
||||
if (status != 200) { callback(obj, null, { Header: { HttpError: status } }, status, tag); return; }
|
||||
var wsresponse = obj.ParseWsman(data);
|
||||
if (!wsresponse || wsresponse == null) { callback(obj, null, { Header: { HttpError: status } }, 601, tag); } else { callback(obj, wsresponse.Header["ResourceURI"], wsresponse, 200, tag); }
|
||||
}, tag, pri);
|
||||
}
|
||||
|
||||
// Private method
|
||||
//obj.Debug = function (msg) { /*console.log(msg);*/ }
|
||||
|
||||
// Cancel all pending queries with given status
|
||||
obj.CancelAllQueries = function (s) { obj.comm.CancelAllQueries(s); }
|
||||
|
||||
// Get the last element of a URI string
|
||||
obj.GetNameFromUrl = function (resuri) {
|
||||
var x = resuri.lastIndexOf("/");
|
||||
return (x == -1)?resuri:resuri.substring(x + 1);
|
||||
}
|
||||
|
||||
// Perform a WSMAN Subscribe operation
|
||||
obj.ExecSubscribe = function (resuri, delivery, url, callback, tag, pri, selectors, opaque, user, pass) {
|
||||
var digest = "", digest2 = "", opaque = "";
|
||||
if (user != null && pass != null) { digest = '<t:IssuedTokens xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:se="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><t:RequestSecurityTokenResponse><t:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</t:TokenType><t:RequestedSecurityToken><se:UsernameToken><se:Username>' + user + '</se:Username><se:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText">' + pass + '</se:Password></se:UsernameToken></t:RequestedSecurityToken></t:RequestSecurityTokenResponse></t:IssuedTokens>'; digest2 = '<w:Auth Profile="http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/http/digest"/>'; }
|
||||
if (opaque != null) { opaque = '<a:ReferenceParameters><m:arg>' + opaque + '</m:arg></a:ReferenceParameters>'; }
|
||||
if (delivery == 'PushWithAck') { delivery = 'dmtf.org/wbem/wsman/1/wsman/PushWithAck'; } else if (delivery == 'Push') { delivery = 'xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push'; }
|
||||
var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + digest + '</Header><Body><e:Subscribe><e:Delivery Mode="http://schemas.' + delivery + '"><e:NotifyTo><a:Address>' + url + '</a:Address>' + opaque + '</e:NotifyTo>' + digest2 + '</e:Delivery></e:Subscribe>';
|
||||
obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:m="http://x.com"');
|
||||
}
|
||||
|
||||
// Perform a WSMAN UnSubscribe operation
|
||||
obj.ExecUnSubscribe = function (resuri, callback, tag, pri, selectors) {
|
||||
var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + '</Header><Body><e:Unsubscribe/>';
|
||||
obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"');
|
||||
}
|
||||
|
||||
// Perform a WSMAN PUT operation
|
||||
obj.ExecPut = function (resuri, putobj, callback, tag, pri, selectors) {
|
||||
var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Put</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + '</Header><Body>' + _PutObjToBodyXml(resuri, putobj);
|
||||
obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN CREATE operation
|
||||
obj.ExecCreate = function (resuri, putobj, callback, tag, pri, selectors) {
|
||||
var objname = obj.GetNameFromUrl(resuri);
|
||||
var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><g:" + objname + " xmlns:g=\"" + resuri + "\">";
|
||||
for (var n in putobj) { data += "<g:" + n + ">" + putobj[n] + "</g:" + n + ">" }
|
||||
obj.PerformAjax(data + "</g:" + objname + "></Body></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN DELETE operation
|
||||
obj.ExecDelete = function (resuri, putobj, callback, tag, pri) {
|
||||
var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(putobj) + "</Header><Body /></Envelope>";
|
||||
obj.PerformAjax(data, callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN GET operation
|
||||
obj.ExecGet = function (resuri, callback, tag, pri) {
|
||||
obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body /></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN method call operation
|
||||
obj.ExecMethod = function (resuri, method, args, callback, tag, pri, selectors) {
|
||||
var argsxml = "";
|
||||
for (var i in args) { if (args[i] != null) { if (Array.isArray(args[i])) { for (var x in args[i]) { argsxml += "<r:" + i + ">" + args[i][x] + "</r:" + i + ">"; } } else { argsxml += "<r:" + i + ">" + args[i] + "</r:" + i + ">"; } } }
|
||||
obj.ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors);
|
||||
}
|
||||
|
||||
// Perform a WSMAN method call operation. The arguments are already formatted in XML.
|
||||
obj.ExecMethodXml = function (resuri, method, argsxml, callback, tag, pri, selectors) {
|
||||
obj.PerformAjax(resuri + "/" + method + "</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><r:" + method + '_INPUT' + " xmlns:r=\"" + resuri + "\">" + argsxml + "</r:" + method + "_INPUT></Body></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN ENUM operation
|
||||
obj.ExecEnum = function (resuri, callback, tag, pri) {
|
||||
obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Enumerate xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\" /></Body></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
// Perform a WSMAN PULL operation
|
||||
obj.ExecPull = function (resuri, enumctx, callback, tag, pri) {
|
||||
obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\"><EnumerationContext>" + enumctx + "</EnumerationContext><MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters></Pull></Body></Envelope>", callback, tag, pri);
|
||||
}
|
||||
|
||||
// Private method
|
||||
obj.ParseWsman = function (xml) {
|
||||
try {
|
||||
if (!xml.childNodes) xml = _turnToXml(xml);
|
||||
var r = { Header:{} }, header = xml.getElementsByTagName("Header")[0], t;
|
||||
if (!header) header = xml.getElementsByTagName("a:Header")[0];
|
||||
if (!header) return null;
|
||||
for (var i = 0; i < header.childNodes.length; i++) {
|
||||
var child = header.childNodes[i];
|
||||
r.Header[child.localName] = child.textContent;
|
||||
}
|
||||
var body = xml.getElementsByTagName("Body")[0];
|
||||
if (!body) body = xml.getElementsByTagName("a:Body")[0];
|
||||
if (!body) return null;
|
||||
if (body.childNodes.length > 0) {
|
||||
t = body.childNodes[0].localName;
|
||||
if (t.indexOf("_OUTPUT") == t.length - 7) { t = t.substring(0, t.length - 7); }
|
||||
r.Header['Method'] = t;
|
||||
r.Body = _ParseWsmanRec(body.childNodes[0]);
|
||||
}
|
||||
return r;
|
||||
} catch (e) {
|
||||
console.log("Unable to parse XML: " + xml);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Private method
|
||||
function _ParseWsmanRec(node) {
|
||||
var data, r = {};
|
||||
for (var i = 0; i < node.childNodes.length; i++) {
|
||||
var child = node.childNodes[i];
|
||||
if ((child.childElementCount == null) || (child.childElementCount == 0)) { data = child.textContent; } else { data = _ParseWsmanRec(child); }
|
||||
if (data == 'true') data = true; // Convert 'true' into true
|
||||
if (data == 'false') data = false; // Convert 'false' into false
|
||||
if ((parseInt(data) + '') === data) data = parseInt(data); // Convert integers
|
||||
|
||||
var childObj = data;
|
||||
if ((child.attributes != null) && (child.attributes.length > 0)) {
|
||||
childObj = { 'Value': data };
|
||||
for(var j = 0; j < child.attributes.length; j++) {
|
||||
childObj['@' + child.attributes[j].name] = child.attributes[j].value;
|
||||
}
|
||||
}
|
||||
|
||||
if (r[child.localName] instanceof Array) { r[child.localName].push(childObj); }
|
||||
else if (r[child.localName] == null) { r[child.localName] = childObj; }
|
||||
else { r[child.localName] = [r[child.localName], childObj]; }
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
function _PutObjToBodyXml(resuri, putObj) {
|
||||
if (!resuri || putObj == null) return '';
|
||||
var objname = obj.GetNameFromUrl(resuri);
|
||||
var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';
|
||||
|
||||
for (var prop in putObj) {
|
||||
if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue;
|
||||
if (putObj[prop] == null || typeof putObj[prop] === 'function') continue;
|
||||
if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) {
|
||||
result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>';
|
||||
var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector'];
|
||||
if (Array.isArray(selectorArray)) {
|
||||
for (var i=0; i< selectorArray.length; i++) {
|
||||
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
|
||||
}
|
||||
}
|
||||
else {
|
||||
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
|
||||
}
|
||||
result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>';
|
||||
}
|
||||
else {
|
||||
if (Array.isArray(putObj[prop])) {
|
||||
for (var i = 0; i < putObj[prop].length; i++) {
|
||||
result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>';
|
||||
}
|
||||
} else {
|
||||
result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result += '</r:' + objname + '>';
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
convert
|
||||
{ @Name: 'InstanceID', @AttrName: 'Attribute Value'}
|
||||
into
|
||||
' Name="InstanceID" AttrName="Attribute Value" '
|
||||
*/
|
||||
function _ObjectToXmlAttributes(objWithAttributes) {
|
||||
if(!objWithAttributes) return '';
|
||||
var result = ' ';
|
||||
for (var propName in objWithAttributes) {
|
||||
if (!objWithAttributes.hasOwnProperty(propName) || propName.indexOf('@') !== 0) continue;
|
||||
result += propName.substring(1) + '="' + objWithAttributes[propName] + '" ';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function _PutObjToSelectorsXml(selectorSet) {
|
||||
if (!selectorSet) return '';
|
||||
if (typeof selectorSet == 'string') return selectorSet;
|
||||
if (selectorSet['InstanceID']) return "<w:SelectorSet><w:Selector Name=\"InstanceID\">" + selectorSet['InstanceID'] + "</w:Selector></w:SelectorSet>";
|
||||
var result = '<w:SelectorSet>';
|
||||
for(var propName in selectorSet) {
|
||||
if (!selectorSet.hasOwnProperty(propName)) continue;
|
||||
result += '<w:Selector Name="' + propName + '">';
|
||||
if (selectorSet[propName]['ReferenceParameters']) {
|
||||
result += '<a:EndpointReference>';
|
||||
result += '<a:Address>' + selectorSet[propName]['Address'] + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + selectorSet[propName]['ReferenceParameters']['ResourceURI'] + '</w:ResourceURI><w:SelectorSet>';
|
||||
var selectorArray = selectorSet[propName]['ReferenceParameters']['SelectorSet']['Selector'];
|
||||
if (Array.isArray(selectorArray)) {
|
||||
for (var i = 0; i < selectorArray.length; i++) {
|
||||
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
|
||||
}
|
||||
}
|
||||
else {
|
||||
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
|
||||
}
|
||||
result += '</w:SelectorSet></a:ReferenceParameters></a:EndpointReference>';
|
||||
} else {
|
||||
result += selectorSet[propName];
|
||||
}
|
||||
result += '</w:Selector>';
|
||||
}
|
||||
result += '</w:SelectorSet>';
|
||||
return result;
|
||||
}
|
||||
|
||||
// This is a drop-in replacement to _turnToXml() that works without xml parser dependency.
|
||||
Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : null); } });
|
||||
function _treeBuilder() {
|
||||
this.tree = [];
|
||||
this.push = function (element) { this.tree.push(element); };
|
||||
this.pop = function () { var element = this.tree.pop(); if (this.tree.length > 0) { var x = this.tree.peek(); x.childNodes.push(element); x.childElementCount = x.childNodes.length; } return (element); };
|
||||
this.peek = function () { return (this.tree.peek()); }
|
||||
this.addNamespace = function (prefix, namespace) { this.tree.peek().nsTable[prefix] = namespace; if (this.tree.peek().attributes.length > 0) { for (var i = 0; i < this.tree.peek().attributes; ++i) { var a = this.tree.peek().attributes[i]; if (prefix == '*' && a.name == a.localName) { a.namespace = namespace; } else if (prefix != '*' && a.name != a.localName) { var pfx = a.name.split(':')[0]; if (pfx == prefix) { a.namespace = namespace; } } } } }
|
||||
this.getNamespace = function (prefix) { for (var i = this.tree.length - 1; i >= 0; --i) { if (this.tree[i].nsTable[prefix] != null) { return (this.tree[i].nsTable[prefix]); } } return null; }
|
||||
}
|
||||
function _turnToXml(text) { if (text == null) return null; return ({ childNodes: [_turnToXmlRec(text)], getElementsByTagName: _getElementsByTagName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS }); }
|
||||
function _getElementsByTagNameNS(ns, name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name && (node.namespace == ns || ns == '*')) { ret.push(node); } }); return ret; }
|
||||
function _getElementsByTagName(name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name) { ret.push(node); } }); return ret; }
|
||||
function _getChildElementsByTagName(name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name) { ret.push(this.childNodes[node]); } } } return (ret); }
|
||||
function _getChildElementsByTagNameNS(ns, name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name && (ns == '*' || this.childNodes[node].namespace == ns)) { ret.push(this.childNodes[node]); } } } return (ret); }
|
||||
function _xmlTraverseAllRec(nodes, func) { for (var i in nodes) { func(nodes[i]); if (nodes[i].childNodes) { _xmlTraverseAllRec(nodes[i].childNodes, func); } } }
|
||||
function _turnToXmlRec(text) {
|
||||
var elementStack = new _treeBuilder(), lastElement = null, x1 = text.split('<'), ret = [], element = null, currentElementName = null;
|
||||
for (var i in x1) {
|
||||
var x2 = x1[i].split('>'), x3 = x2[0].split(' '), elementName = x3[0];
|
||||
if ((elementName.length > 0) && (elementName[0] != '?')) {
|
||||
if (elementName[0] != '/') {
|
||||
var attributes = [], localName, localname2 = elementName.split(' ')[0].split(':'), localName = (localname2.length > 1) ? localname2[1] : localname2[0];
|
||||
Object.defineProperty(attributes, "get",
|
||||
{
|
||||
value: function () {
|
||||
if (arguments.length == 1) {
|
||||
for (var a in this) { if (this[a].name == arguments[0]) { return (this[a]); } }
|
||||
}
|
||||
else if (arguments.length == 2) {
|
||||
for (var a in this) { if (this[a].name == arguments[1] && (arguments[0] == '*' || this[a].namespace == arguments[0])) { return (this[a]); } }
|
||||
}
|
||||
else {
|
||||
throw ('attributes.get(): Invalid number of parameters');
|
||||
}
|
||||
}
|
||||
});
|
||||
elementStack.push({ name: elementName, localName: localName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS, getChildElementsByTagNameNS: _getChildElementsByTagNameNS, attributes: attributes, childNodes: [], nsTable: {} });
|
||||
// Parse Attributes
|
||||
if (x3.length > 0) {
|
||||
var skip = false;
|
||||
for (var j in x3) {
|
||||
if (x3[j] == '/') {
|
||||
// This is an empty Element
|
||||
elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
|
||||
elementStack.peek().textContent = '';
|
||||
lastElement = elementStack.pop();
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
var k = x3[j].indexOf('=');
|
||||
if (k > 0) {
|
||||
var attrName = x3[j].substring(0, k);
|
||||
var attrValue = x3[j].substring(k + 2, x3[j].length - 1);
|
||||
var attrNS = elementStack.getNamespace('*');
|
||||
|
||||
if (attrName == 'xmlns') {
|
||||
elementStack.addNamespace('*', attrValue);
|
||||
attrNS = attrValue;
|
||||
} else if (attrName.startsWith('xmlns:')) {
|
||||
elementStack.addNamespace(attrName.substring(6), attrValue);
|
||||
} else {
|
||||
var ax = attrName.split(':');
|
||||
if (ax.length == 2) { attrName = ax[1]; attrNS = elementStack.getNamespace(ax[0]); }
|
||||
}
|
||||
var x = { name: attrName, value: attrValue }
|
||||
if (attrNS != null) x.namespace = attrNS;
|
||||
elementStack.peek().attributes.push(x);
|
||||
}
|
||||
}
|
||||
if (skip) { continue; }
|
||||
}
|
||||
elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
|
||||
if (x2[1]) { elementStack.peek().textContent = x2[1]; }
|
||||
} else { lastElement = elementStack.pop(); }
|
||||
}
|
||||
}
|
||||
return lastElement;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
module.exports = WsmanStackCreateService;
|
|
@ -1,121 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description WSMAN communication using duktape http
|
||||
* @author Ylian Saint-Hilaire
|
||||
* @version v0.2.0c
|
||||
*/
|
||||
|
||||
// Construct a WSMAN communication object
|
||||
function CreateWsmanComm(host, port, user, pass, tls, extra) {
|
||||
var obj = {};
|
||||
obj.PendingAjax = []; // List of pending AJAX calls. When one frees up, another will start.
|
||||
obj.ActiveAjaxCount = 0; // Number of currently active AJAX calls
|
||||
obj.MaxActiveAjaxCount = 1; // Maximum number of activate AJAX calls at the same time.
|
||||
obj.FailAllError = 0; // Set this to non-zero to fail all AJAX calls with that error status, 999 causes responses to be silent.
|
||||
obj.host = host;
|
||||
obj.port = port;
|
||||
obj.user = user;
|
||||
obj.pass = pass;
|
||||
obj.tls = tls;
|
||||
obj.digest = null;
|
||||
obj.RequestCount = 0;
|
||||
|
||||
// Private method
|
||||
// pri = priority, if set to 1, the call is high priority and put on top of the stack.
|
||||
obj.PerformAjax = function (postdata, callback, tag, pri, url, action) {
|
||||
if ((obj.ActiveAjaxCount == 0 || ((obj.ActiveAjaxCount < obj.MaxActiveAjaxCount) && (obj.challengeParams != null))) && obj.PendingAjax.length == 0) {
|
||||
// There are no pending AJAX calls, perform the call now.
|
||||
obj.PerformAjaxEx(postdata, callback, tag, url, action);
|
||||
} else {
|
||||
// If this is a high priority call, put this call in front of the array, otherwise put it in the back.
|
||||
if (pri == 1) { obj.PendingAjax.unshift([postdata, callback, tag, url, action]); } else { obj.PendingAjax.push([postdata, callback, tag, url, action]); }
|
||||
}
|
||||
}
|
||||
|
||||
// Private method
|
||||
obj.PerformNextAjax = function () {
|
||||
if (obj.ActiveAjaxCount >= obj.MaxActiveAjaxCount || obj.PendingAjax.length == 0) return;
|
||||
var x = obj.PendingAjax.shift();
|
||||
obj.PerformAjaxEx(x[0], x[1], x[2], x[3], x[4]);
|
||||
obj.PerformNextAjax();
|
||||
}
|
||||
|
||||
// Private method
|
||||
obj.PerformAjaxEx = function (postdata, callback, tag, url, action) {
|
||||
if (obj.FailAllError != 0) { if (obj.FailAllError != 999) { obj.gotNextMessagesError({ status: obj.FailAllError }, 'error', null, [postdata, callback, tag]); } return; }
|
||||
if (!postdata) postdata = "";
|
||||
//console.log("SEND: " + postdata); // DEBUG
|
||||
|
||||
// We are in a DukTape environement
|
||||
if (obj.digest == null) { obj.digest = require('http-digest').create(obj.user, obj.pass); obj.digest.http = require('http'); }
|
||||
var request = { protocol: (obj.tls == 1 ? 'https:' : 'http:'), method: 'POST', host: obj.host, path: '/wsman', port: obj.port, rejectUnauthorized: false, checkServerIdentity: function (cert) { console.log('checkServerIdentity', JSON.stringify(cert)); } };
|
||||
var req = obj.digest.request(request);
|
||||
//console.log('Request ' + (obj.RequestCount++));
|
||||
req.on('error', function (e) { obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); });
|
||||
req.on('response', function (response) {
|
||||
//console.log('Response: ' + response.statusCode);
|
||||
if (response.statusCode != 200) {
|
||||
console.log('ERR:' + JSON.stringify(response));
|
||||
obj.gotNextMessagesError({ status: response.statusCode }, 'error', null, [postdata, callback, tag]);
|
||||
} else {
|
||||
response.acc = '';
|
||||
response.on('data', function (data2) { this.acc += data2; });
|
||||
response.on('end', function () { obj.gotNextMessages(response.acc, 'success', { status: response.statusCode }, [postdata, callback, tag]); });
|
||||
}
|
||||
});
|
||||
|
||||
// Send POST body, this work with binary.
|
||||
req.write(postdata);
|
||||
req.end();
|
||||
obj.ActiveAjaxCount++;
|
||||
return req;
|
||||
}
|
||||
|
||||
// AJAX specific private method
|
||||
obj.pendingAjaxCall = [];
|
||||
|
||||
// Private method
|
||||
obj.gotNextMessages = function (data, status, request, callArgs) {
|
||||
obj.ActiveAjaxCount--;
|
||||
if (obj.FailAllError == 999) return;
|
||||
//console.log("RECV: " + data); // DEBUG
|
||||
if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
|
||||
if (request.status != 200) { callArgs[1](null, request.status, callArgs[2]); return; }
|
||||
callArgs[1](data, 200, callArgs[2]);
|
||||
obj.PerformNextAjax();
|
||||
}
|
||||
|
||||
// Private method
|
||||
obj.gotNextMessagesError = function (request, status, errorThrown, callArgs) {
|
||||
obj.ActiveAjaxCount--;
|
||||
if (obj.FailAllError == 999) return;
|
||||
if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
|
||||
//if (status != 200) { console.log("ERROR, status=" + status + "\r\n\r\nreq=" + callArgs[0]); } // Debug: Display the request & response if something did not work.
|
||||
if (obj.FailAllError != 999) { callArgs[1]({ Header: { HttpError: request.status } }, request.status, callArgs[2]); }
|
||||
obj.PerformNextAjax();
|
||||
}
|
||||
|
||||
// Cancel all pending queries with given status
|
||||
obj.CancelAllQueries = function (s) {
|
||||
while (obj.PendingAjax.length > 0) { var x = obj.PendingAjax.shift(); x[1](null, s, x[2]); }
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
module.exports = CreateWsmanComm;
|
|
@ -356,8 +356,8 @@ function AmtStackCreateService(wsmanStack) {
|
|||
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_KVMRedirectionSettingData_DataChannelRead = function (callback_func, tag) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelRead", {}, callback_func, tag); }
|
||||
obj.IPS_KVMRedirectionSettingData_DataChannelWrite = function (Data, callback_func, tag) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelWrite", { "DataMessage": Data }, callback_func, tag); }
|
||||
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); }
|
||||
|
|
|
@ -1,297 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
var Q = require('queue');
|
||||
|
||||
function amt_heci() {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('connect');
|
||||
|
||||
var heci = require('heci');
|
||||
|
||||
this._amt = heci.create();
|
||||
this._amt.BiosVersionLen = 65;
|
||||
this._amt.UnicodeStringLen = 20;
|
||||
|
||||
this._amt.rq = new Q();
|
||||
this._amt.Parent = this;
|
||||
this._amt.on('error', function (e) { this.Parent.emit('error', e); });
|
||||
this._amt.on('connect', function () {
|
||||
this.Parent.emit('connect');
|
||||
this.on('data', function (chunk) {
|
||||
//console.log("Received: " + chunk.length + " bytes");
|
||||
var header = this.Parent.getCommand(chunk);
|
||||
//console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
|
||||
|
||||
var user = this.rq.deQueue();
|
||||
var params = user.optional;
|
||||
var callback = user.func;
|
||||
|
||||
params.unshift(header);
|
||||
callback.apply(this.Parent, params);
|
||||
});
|
||||
});
|
||||
this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
|
||||
|
||||
this.getCommand = function (chunk) {
|
||||
var command = chunk.length == 0 ? (this._amt.rq.peekQueue().cmd | 0x800000) : chunk.readUInt32LE(4);
|
||||
var ret = { IsResponse: (command & 0x800000) == 0x800000 ? true : false, Command: (command & 0x7FFFFF), Status: chunk.length != 0 ? chunk.readUInt32LE(12) : -1, Data: chunk.length != 0 ? chunk.slice(16) : null };
|
||||
return (ret);
|
||||
};
|
||||
|
||||
this.sendCommand = function () {
|
||||
if (arguments.length < 3 || typeof (arguments[0]) != 'number' || typeof (arguments[1]) != 'object' || typeof (arguments[2]) != 'function') { throw ('invalid parameters'); }
|
||||
var args = [];
|
||||
for (var i = 3; i < arguments.length; ++i) { args.push(arguments[i]); }
|
||||
|
||||
this._amt.rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args });
|
||||
|
||||
var header = Buffer.from('010100000000000000000000', 'hex');
|
||||
header.writeUInt32LE(arguments[0] | 0x04000000, 4);
|
||||
header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8);
|
||||
|
||||
this._amt.write(arguments[1] == null ? header : Buffer.concat([header, arguments[1]]));
|
||||
}
|
||||
|
||||
this.getVersion = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(26, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, this._amt.BiosVersionLen), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4);
|
||||
for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen) ; ++i) {
|
||||
val.Versions[i] = { Description: v.slice(2, v.readUInt16LE(0) + 2).toString(), Version: v.slice(4 + this._amt.UnicodeStringLen, 4 + this._amt.UnicodeStringLen + v.readUInt16LE(2 + this._amt.UnicodeStringLen)).toString() };
|
||||
v = v.slice(4 + (2 * this._amt.UnicodeStringLen));
|
||||
}
|
||||
opt.unshift(val);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
|
||||
this.getProvisioningState = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(17, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.state = header.Data.readUInt32LE(0);
|
||||
if (result.state < 3) { result.stateStr = ["PRE", "IN", "POST"][result.state]; }
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getProvisioningMode = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(8, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.mode = header.Data.readUInt32LE(0);
|
||||
if (result.mode < 4) { result.modeStr = ["NONE", "ENTERPRISE", "SMALL_BUSINESS", "REMOTE_ASSISTANCE"][result.mode]; }
|
||||
result.legacy = header.Data.readUInt32LE(4) == 0 ? false : true;
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getEHBCState = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(132, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
opt.unshift({ EHBC: header.Data.readUInt32LE(0) != 0 });
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getControlMode = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(107, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.controlMode = header.Data.readUInt32LE(0);
|
||||
if (result.controlMode < 3) { result.controlModeStr = ["NONE_RPAT", "CLIENT", "ADMIN", "REMOTE_ASSISTANCE"][result.controlMode]; }
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getMACAddresses = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(37, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
opt.unshift({ DedicatedMAC: header.Data.slice(0, 6).toString('hex:'), HostMAC: header.Data.slice(6, 12).toString('hex:') });
|
||||
} else { opt.unshift({ DedicatedMAC: null, HostMAC: null }); }
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getDnsSuffix = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(54, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var resultLen = header.Data.readUInt16LE(0);
|
||||
if (resultLen > 0) { opt.unshift(header.Data.slice(2, 2 + resultLen).toString()); } else { opt.unshift(null); }
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getHashHandles = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x2C, null, function (header, fn, opt) {
|
||||
var result = [];
|
||||
if (header.Status == 0) {
|
||||
var resultLen = header.Data.readUInt32LE(0);
|
||||
for (var i = 0; i < resultLen; ++i) {
|
||||
result.push(header.Data.readUInt32LE(4 + (4 * i)));
|
||||
}
|
||||
}
|
||||
opt.unshift(result);
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getCertHashEntry = function (handle, callback) {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
|
||||
var data = new Buffer(4);
|
||||
data.writeUInt32LE(handle, 0);
|
||||
|
||||
this.sendCommand(0x2D, data, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.isDefault = header.Data.readUInt32LE(0);
|
||||
result.isActive = header.Data.readUInt32LE(4);
|
||||
result.hashAlgorithm = header.Data.readUInt8(72);
|
||||
if (result.hashAlgorithm < 4) {
|
||||
result.hashAlgorithmStr = ["MD5", "SHA1", "SHA256", "SHA512"][result.hashAlgorithm];
|
||||
result.hashAlgorithmSize = [16, 20, 32, 64][result.hashAlgorithm];
|
||||
result.certificateHash = header.Data.slice(8, 8 + result.hashAlgorithmSize).toString('hex');
|
||||
}
|
||||
result.name = header.Data.slice(73 + 2, 73 + 2 + header.Data.readUInt16LE(73)).toString();
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
this.getCertHashEntries = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
|
||||
this.getHashHandles(function (handles, fn, opt) {
|
||||
var entries = [];
|
||||
this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
|
||||
}, callback, optional);
|
||||
};
|
||||
this._getHashEntrySink = function (result, fn, opt, entries, handles) {
|
||||
entries.push(result);
|
||||
if (handles.length > 0) {
|
||||
this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
|
||||
} else {
|
||||
opt.unshift(entries);
|
||||
fn.apply(this, opt);
|
||||
}
|
||||
}
|
||||
this.getLocalSystemAccount = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt) {
|
||||
if (header.Data.length == 68) { opt.unshift({ user: header.Data.slice(0, 34).toString(), pass: header.Data.slice(34, 67).toString(), raw: header.Data }); } else { opt.unshift(null); }
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
this.unprovision = function (mode, callback) {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
var data = new Buffer(4);
|
||||
data.writeUInt32LE(mode, 0);
|
||||
this.sendCommand(16, data, function (header, fn, opt) {
|
||||
opt.unshift(header.Status);
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
this.startConfiguration = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x29, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.stopConfiguration = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x5E, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.openUserInitiatedConnection = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x44, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.closeUserInitiatedConnection = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x45, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
|
||||
}
|
||||
this.getRemoteAccessConnectionStatus = function () {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x46, data, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var hostname = v.slice(14, header.Data.readUInt16LE(12) + 14).toString()
|
||||
opt.unshift({ status: header.Status, networkStatus: header.Data.readUInt32LE(0), remoteAccessStatus: header.Data.readUInt32LE(4), remoteAccessTrigger: header.Data.readUInt32LE(8), mpsHostname: hostname, raw: header.Data });
|
||||
} else {
|
||||
opt.unshift({ status: header.Status });
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
this.getProtocolVersion = function (callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { opt.push(arguments[i]); }
|
||||
|
||||
heci.doIoctl(heci.IOCTL.HECI_VERSION, Buffer.alloc(5), Buffer.alloc(5), function (status, buffer, self, fn, opt) {
|
||||
if (status == 0) {
|
||||
var result = buffer.readUInt8(0).toString() + '.' + buffer.readUInt8(1).toString() + '.' + buffer.readUInt8(2).toString() + '.' + buffer.readUInt16BE(3).toString();
|
||||
opt.unshift(result);
|
||||
fn.apply(self, opt);
|
||||
}
|
||||
else {
|
||||
opt.unshift(null);
|
||||
fn.apply(self, opt);
|
||||
}
|
||||
}, this, callback, optional);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = amt_heci;
|
|
@ -1,324 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
var MemoryStream = require('MemoryStream');
|
||||
var lme_id = 0;
|
||||
var lme_port_offset = 0; // Debug: Set this to "-100" to bind to 16892 & 16893 and IN_ADDRANY. This is for LMS debugging.
|
||||
|
||||
|
||||
var APF_DISCONNECT = 1;
|
||||
var APF_SERVICE_REQUEST = 5;
|
||||
var APF_SERVICE_ACCEPT = 6;
|
||||
var APF_USERAUTH_REQUEST = 50;
|
||||
var APF_USERAUTH_FAILURE = 51;
|
||||
var APF_USERAUTH_SUCCESS = 52;
|
||||
var APF_GLOBAL_REQUEST = 80;
|
||||
var APF_REQUEST_SUCCESS = 81;
|
||||
var APF_REQUEST_FAILURE = 82;
|
||||
var APF_CHANNEL_OPEN = 90;
|
||||
var APF_CHANNEL_OPEN_CONFIRMATION = 91;
|
||||
var APF_CHANNEL_OPEN_FAILURE = 92;
|
||||
var APF_CHANNEL_WINDOW_ADJUST = 93;
|
||||
var APF_CHANNEL_DATA = 94;
|
||||
var APF_CHANNEL_CLOSE = 97;
|
||||
var APF_PROTOCOLVERSION = 192;
|
||||
|
||||
|
||||
function lme_object() {
|
||||
this.ourId = ++lme_id;
|
||||
this.amtId = -1;
|
||||
this.LME_CHANNEL_STATUS = 'LME_CS_FREE';
|
||||
this.txWindow = 0;
|
||||
this.rxWindow = 0;
|
||||
this.localPort = 0;
|
||||
this.errorCount = 0;
|
||||
}
|
||||
|
||||
function stream_bufferedWrite() {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
this.buffer = [];
|
||||
this._readCheckImmediate = undefined;
|
||||
|
||||
// Writable Events
|
||||
emitterUtils.createEvent('close');
|
||||
emitterUtils.createEvent('drain');
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('finish');
|
||||
emitterUtils.createEvent('pipe');
|
||||
emitterUtils.createEvent('unpipe');
|
||||
|
||||
// Readable Events
|
||||
emitterUtils.createEvent('readable');
|
||||
this.isEmpty = function () {
|
||||
return (this.buffer.length == 0);
|
||||
};
|
||||
this.isWaiting = function () {
|
||||
return (this._readCheckImmediate == undefined);
|
||||
};
|
||||
this.write = function (chunk) {
|
||||
for (var args in arguments) { if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; } }
|
||||
var tmp = Buffer.alloc(chunk.length);
|
||||
chunk.copy(tmp);
|
||||
this.buffer.push({ offset: 0, data: tmp });
|
||||
this.emit('readable');
|
||||
return (this.buffer.length == 0 ? true : false);
|
||||
};
|
||||
this.read = function () {
|
||||
var size = arguments.length == 0 ? undefined : arguments[0];
|
||||
var bytesRead = 0;
|
||||
var list = [];
|
||||
while ((size == undefined || bytesRead < size) && this.buffer.length > 0) {
|
||||
var len = this.buffer[0].data.length - this.buffer[0].offset;
|
||||
var offset = this.buffer[0].offset;
|
||||
|
||||
if (len > (size - bytesRead)) {
|
||||
// Only reading a subset
|
||||
list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead));
|
||||
this.buffer[0].offset += (size - bytesRead);
|
||||
bytesRead += (size - bytesRead);
|
||||
} else {
|
||||
// Reading the entire thing
|
||||
list.push(this.buffer[0].data.slice(offset));
|
||||
bytesRead += len;
|
||||
this.buffer.shift();
|
||||
}
|
||||
}
|
||||
this._readCheckImmediate = setImmediate(function (buffered) {
|
||||
buffered._readCheckImmediate = undefined;
|
||||
if (buffered.buffer.length == 0) {
|
||||
buffered.emit('drain'); // Drained
|
||||
} else {
|
||||
buffered.emit('readable'); // Not drained
|
||||
}
|
||||
}, this);
|
||||
return (Buffer.concat(list));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function lme_heci(options) {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('connect');
|
||||
|
||||
if (options.debug == true) { lme_port_offset = -100; } // LMS debug mode
|
||||
|
||||
var heci = require('heci');
|
||||
this.INITIAL_RXWINDOW_SIZE = 4096;
|
||||
|
||||
this._LME = heci.create();
|
||||
this._LME.LMS = this;
|
||||
this._LME.on('error', function (e) { this.LMS.emit('error', e); });
|
||||
this._LME.on('connect', function () {
|
||||
this.LMS.emit('connect');
|
||||
this.on('data', function (chunk) {
|
||||
// this = HECI
|
||||
var cmd = chunk.readUInt8(0);
|
||||
|
||||
switch (cmd) {
|
||||
default:
|
||||
//console.log('Received ' + chunk.length + ' bytes of data for LMS');
|
||||
//console.log('Command = ' + cmd);
|
||||
break;
|
||||
case APF_SERVICE_REQUEST:
|
||||
var nameLen = chunk.readUInt32BE(1);
|
||||
var name = chunk.slice(5, nameLen + 5);
|
||||
//console.log("Service Request for: " + name);
|
||||
if (name == 'pfwd@amt.intel.com' || name == 'auth@amt.intel.com') {
|
||||
var outBuffer = Buffer.alloc(5 + nameLen);
|
||||
outBuffer.writeUInt8(6, 0);
|
||||
outBuffer.writeUInt32BE(nameLen, 1);
|
||||
outBuffer.write(name.toString(), 5);
|
||||
this.write(outBuffer);
|
||||
//console.log('Answering APF_SERVICE_REQUEST');
|
||||
} else {
|
||||
//console.log('UNKNOWN APF_SERVICE_REQUEST');
|
||||
}
|
||||
break;
|
||||
case APF_GLOBAL_REQUEST:
|
||||
var nameLen = chunk.readUInt32BE(1);
|
||||
var name = chunk.slice(5, nameLen + 5).toString();
|
||||
|
||||
switch (name) {
|
||||
case 'tcpip-forward':
|
||||
var len = chunk.readUInt32BE(nameLen + 6);
|
||||
var port = chunk.readUInt32BE(nameLen + 10 + len);
|
||||
//console.log("[" + chunk.length + "/" + len + "] APF_GLOBAL_REQUEST for: " + name + " on port " + port);
|
||||
if (this[name] == undefined) {
|
||||
this[name] = {};
|
||||
}
|
||||
this[name][port] = require('net').createServer();
|
||||
this[name][port].HECI = this;
|
||||
if (lme_port_offset == 0) {
|
||||
this[name][port].listen({ port: port, host: '127.0.0.1' }); // Normal mode
|
||||
} else {
|
||||
this[name][port].listen({ port: (port + lme_port_offset) }); // Debug mode
|
||||
}
|
||||
this[name][port].on('connection', function (socket) {
|
||||
//console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort);
|
||||
this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort - lme_port_offset);
|
||||
});
|
||||
var outBuffer = Buffer.alloc(5);
|
||||
outBuffer.writeUInt8(81, 0);
|
||||
outBuffer.writeUInt32BE(port, 1);
|
||||
this.write(outBuffer);
|
||||
break;
|
||||
case 'cancel-tcpip-forward':
|
||||
break;
|
||||
case 'udp-send-to@amt.intel.com':
|
||||
break;
|
||||
default:
|
||||
//console.log("Unknown APF_GLOBAL_REQUEST for: " + name);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case APF_CHANNEL_OPEN_CONFIRMATION:
|
||||
var rChannel = chunk.readUInt32BE(1);
|
||||
var sChannel = chunk.readUInt32BE(5);
|
||||
var wSize = chunk.readUInt32BE(9);
|
||||
//console.log('rChannel/' + rChannel + ', sChannel/' + sChannel + ', wSize/' + wSize);
|
||||
if (this.sockets[rChannel] != undefined) {
|
||||
this.sockets[rChannel].lme.amtId = sChannel;
|
||||
this.sockets[rChannel].lme.rxWindow = wSize;
|
||||
this.sockets[rChannel].lme.txWindow = wSize;
|
||||
this.sockets[rChannel].lme.LME_CHANNEL_STATUS = 'LME_CS_CONNECTED';
|
||||
//console.log('LME_CS_CONNECTED');
|
||||
this.sockets[rChannel].bufferedStream = new stream_bufferedWrite();
|
||||
this.sockets[rChannel].bufferedStream.socket = this.sockets[rChannel];
|
||||
this.sockets[rChannel].bufferedStream.on('readable', function () {
|
||||
if (this.socket.lme.txWindow > 0) {
|
||||
var buffer = this.read(this.socket.lme.txWindow);
|
||||
var packet = Buffer.alloc(9 + buffer.length);
|
||||
packet.writeUInt8(APF_CHANNEL_DATA, 0);
|
||||
packet.writeUInt32BE(this.socket.lme.amtId, 1);
|
||||
packet.writeUInt32BE(buffer.length, 5);
|
||||
buffer.copy(packet, 9);
|
||||
this.socket.lme.txWindow -= buffer.length;
|
||||
this.socket.HECI.write(packet);
|
||||
}
|
||||
});
|
||||
this.sockets[rChannel].bufferedStream.on('drain', function () {
|
||||
this.socket.resume();
|
||||
});
|
||||
this.sockets[rChannel].on('data', function (chunk) {
|
||||
if (!this.bufferedStream.write(chunk)) { this.pause(); }
|
||||
});
|
||||
this.sockets[rChannel].on('end', function () {
|
||||
var outBuffer = Buffer.alloc(5);
|
||||
outBuffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
|
||||
outBuffer.writeUInt32BE(this.lme.amtId, 1);
|
||||
this.HECI.write(outBuffer);
|
||||
});
|
||||
this.sockets[rChannel].resume();
|
||||
}
|
||||
|
||||
break;
|
||||
case APF_PROTOCOLVERSION:
|
||||
var major = chunk.readUInt32BE(1);
|
||||
var minor = chunk.readUInt32BE(5);
|
||||
var reason = chunk.readUInt32BE(9);
|
||||
var outBuffer = Buffer.alloc(93);
|
||||
outBuffer.writeUInt8(192, 0);
|
||||
outBuffer.writeUInt32BE(1, 1);
|
||||
outBuffer.writeUInt32BE(0, 5);
|
||||
outBuffer.writeUInt32BE(reason, 9);
|
||||
//console.log('Answering PROTOCOL_VERSION');
|
||||
this.write(outBuffer);
|
||||
break;
|
||||
case APF_CHANNEL_WINDOW_ADJUST:
|
||||
var rChannelId = chunk.readUInt32BE(1);
|
||||
var bytesToAdd = chunk.readUInt32BE(5);
|
||||
if (this.sockets[rChannelId] != undefined) {
|
||||
this.sockets[rChannelId].lme.txWindow += bytesToAdd;
|
||||
if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) {
|
||||
this.sockets[rChannelId].bufferedStream.emit('readable');
|
||||
}
|
||||
} else {
|
||||
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST');
|
||||
}
|
||||
break;
|
||||
case APF_CHANNEL_DATA:
|
||||
var rChannelId = chunk.readUInt32BE(1);
|
||||
var dataLen = chunk.readUInt32BE(5);
|
||||
var data = chunk.slice(9, 9 + dataLen);
|
||||
if (this.sockets[rChannelId] != undefined) {
|
||||
this.sockets[rChannelId].pendingBytes.push(data.length);
|
||||
this.sockets[rChannelId].write(data, function () {
|
||||
var written = this.pendingBytes.shift();
|
||||
var outBuffer = Buffer.alloc(9);
|
||||
outBuffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
|
||||
outBuffer.writeUInt32BE(this.lme.amtId, 1);
|
||||
outBuffer.writeUInt32BE(written, 5);
|
||||
this.HECI.write(outBuffer);
|
||||
});
|
||||
} else {
|
||||
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA');
|
||||
}
|
||||
break;
|
||||
case APF_CHANNEL_CLOSE:
|
||||
var rChannelId = chunk.readUInt32BE(1);
|
||||
if (this.sockets[rChannelId] != undefined) {
|
||||
this.sockets[rChannelId].end();
|
||||
var amtId = this.sockets[rChannelId].lme.amtId;
|
||||
var buffer = Buffer.alloc(5);
|
||||
delete this.sockets[rChannelId];
|
||||
|
||||
buffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
|
||||
buffer.writeUInt32BE(amtId, 1);
|
||||
this.write(buffer);
|
||||
} else {
|
||||
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE');
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.bindDuplexStream = function (duplexStream, remoteFamily, localPort) {
|
||||
var socket = duplexStream;
|
||||
//console.log('New [' + remoteFamily + '] Virtual Connection/' + socket.localPort);
|
||||
socket.pendingBytes = [];
|
||||
socket.HECI = this._LME;
|
||||
socket.LMS = this;
|
||||
socket.lme = new lme_object();
|
||||
socket.lme.Socket = socket;
|
||||
var buffer = new MemoryStream();
|
||||
buffer.writeUInt8(0x5A);
|
||||
buffer.writeUInt32BE(15);
|
||||
buffer.write('forwarded-tcpip');
|
||||
buffer.writeUInt32BE(socket.lme.ourId);
|
||||
buffer.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE);
|
||||
buffer.writeUInt32BE(0xFFFFFFFF);
|
||||
for (var i = 0; i < 2; ++i) {
|
||||
if (remoteFamily == 'IPv6') {
|
||||
buffer.writeUInt32BE(3);
|
||||
buffer.write('::1');
|
||||
} else {
|
||||
buffer.writeUInt32BE(9);
|
||||
buffer.write('127.0.0.1');
|
||||
}
|
||||
buffer.writeUInt32BE(localPort);
|
||||
}
|
||||
this._LME.write(buffer.buffer);
|
||||
if (this._LME.sockets == undefined) { this._LME.sockets = {}; }
|
||||
this._LME.sockets[socket.lme.ourId] = socket;
|
||||
socket.pause();
|
||||
};
|
||||
|
||||
this._LME.connect(heci.GUIDS.LME, { noPipeline: 0 });
|
||||
}
|
||||
|
||||
module.exports = lme_heci;
|
Loading…
Add table
Add a link
Reference in a new issue