| 1 | /** |
| 2 | * @description Intel(r) AMT WSMAN Stack |
| 3 | * @author Ylian Saint-Hilaire |
| 4 | * @version v0.2.0 |
| 5 | */ |
| 6 | |
| 7 | // Construct a MeshServer object |
| 8 | var WsmanStackCreateService = function (host, port, user, pass, tls, extra) { |
| 9 | var obj = {}; |
| 10 | //obj.onDebugMessage = null; // Set to a function if you want to get debug messages. |
| 11 | obj.NextMessageId = 1; // Next message number, used to label WSMAN calls. |
| 12 | obj.Address = '/wsman'; |
| 13 | obj.comm = CreateWsmanComm(host, port, user, pass, tls, extra); |
| 14 | |
| 15 | obj.PerformAjax = function (postdata, callback, tag, pri, namespaces) { |
| 16 | if (namespaces == undefined) namespaces = ''; |
| 17 | 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) { |
| 18 | if (status != 200) { callback(obj, null, { Header: { HttpError: status } }, status, tag); return; } |
| 19 | var wsresponse = obj.ParseWsman(data); |
| 20 | if (!wsresponse || wsresponse == null) { callback(obj, null, { Header: { HttpError: status } }, 601, tag); } else { callback(obj, wsresponse.Header["ResourceURI"], wsresponse, 200, tag); } |
| 21 | }, tag, pri); |
| 22 | } |
| 23 | |
| 24 | // Private method |
| 25 | //obj.Debug = function (msg) { /*console.log(msg);*/ } |
| 26 | |
| 27 | // Cancel all pending queries with given status |
| 28 | obj.CancelAllQueries = function (s) { obj.comm.CancelAllQueries(s); } |
| 29 | |
| 30 | // Get the last element of a URI string |
| 31 | obj.GetNameFromUrl = function (resuri) { |
| 32 | var x = resuri.lastIndexOf("/"); |
| 33 | return (x == -1)?resuri:resuri.substring(x + 1); |
| 34 | } |
| 35 | |
| 36 | // Perform a WSMAN Subscribe operation |
| 37 | obj.ExecSubscribe = function (resuri, delivery, url, callback, tag, pri, selectors, opaque, user, pass) { |
| 38 | var digest = "", digest2 = ""; |
| 39 | if (user != undefined && pass != undefined) { digest = '<t:IssuedTokens><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 = '<Auth Profile="http://schemas.xmlsoap.org/ws/2004/08/eventing/DeliveryModes/secprofile/http/digest"/>'; } |
| 40 | if (opaque != undefined && opaque != null) { opaque = '<a:ReferenceParameters>' + opaque + '</a:ReferenceParameters>'; } else { opaque = ""; } |
| 41 | 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.dmtf.org/wbem/wsman/1/wsman/' + delivery + '"><e:NotifyTo><a:Address>' + url + '</a:Address></e:NotifyTo>' + digest2 + '</e:Delivery><e:Expires>PT0.000000S</e:Expires></e:Subscribe>'; |
| 42 | obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" 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" xmlns:m="http://x.com"'); |
| 43 | } |
| 44 | |
| 45 | // Perform a WSMAN UnSubscribe operation |
| 46 | obj.ExecUnSubscribe = function (resuri, callback, tag, pri, selectors) { |
| 47 | 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/>'; |
| 48 | obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"'); |
| 49 | } |
| 50 | |
| 51 | // Perform a WSMAN PUT operation |
| 52 | obj.ExecPut = function (resuri, putobj, callback, tag, pri, selectors) { |
| 53 | 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); |
| 54 | obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri); |
| 55 | } |
| 56 | |
| 57 | // Perform a WSMAN CREATE operation |
| 58 | obj.ExecCreate = function (resuri, putobj, callback, tag, pri, selectors) { |
| 59 | var objname = obj.GetNameFromUrl(resuri); |
| 60 | 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 + "\">"; |
| 61 | for (var n in putobj) { data += "<g:" + n + ">" + putobj[n] + "</g:" + n + ">" } |
| 62 | obj.PerformAjax(data + "</g:" + objname + "></Body></Envelope>", callback, tag, pri); |
| 63 | } |
| 64 | |
| 65 | // Perform a WSMAN CREATE operation |
| 66 | obj.ExecCreateXml = function (resuri, argsxml, callback, tag, pri) { |
| 67 | var objname = obj.GetNameFromUrl(resuri), selector = ""; |
| 68 | obj.PerformAjax("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>PT60.000S</w:OperationTimeout></Header><Body><r:" + objname + " xmlns:r=\"" + resuri + "\">" + argsxml + "</r:" + objname + "></Body></Envelope>", callback, tag, pri); |
| 69 | } |
| 70 | |
| 71 | // Perform a WSMAN DELETE operation |
| 72 | obj.ExecDelete = function (resuri, putobj, callback, tag, pri) { |
| 73 | 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>"; |
| 74 | obj.PerformAjax(data, callback, tag, pri); |
| 75 | } |
| 76 | |
| 77 | // Perform a WSMAN GET operation |
| 78 | obj.ExecGet = function (resuri, callback, tag, pri) { |
| 79 | 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); |
| 80 | } |
| 81 | |
| 82 | // Perform a WSMAN method call operation |
| 83 | obj.ExecMethod = function (resuri, method, args, callback, tag, pri, selectors) { |
| 84 | var argsxml = ""; |
| 85 | 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 + ">"; } } } |
| 86 | obj.ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors); |
| 87 | } |
| 88 | |
| 89 | // Perform a WSMAN method call operation. The arguments are already formatted in XML. |
| 90 | obj.ExecMethodXml = function (resuri, method, argsxml, callback, tag, pri, selectors) { |
| 91 | 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); |
| 92 | } |
| 93 | |
| 94 | // Perform a WSMAN ENUM operation |
| 95 | obj.ExecEnum = function (resuri, callback, tag, pri) { |
| 96 | 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); |
| 97 | } |
| 98 | |
| 99 | // Perform a WSMAN PULL operation |
| 100 | obj.ExecPull = function (resuri, enumctx, callback, tag, pri) { |
| 101 | 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); |
| 102 | } |
| 103 | |
| 104 | // Private method |
| 105 | obj.ParseWsman = function (xml) { |
| 106 | try { |
| 107 | if (!xml.childNodes) xml = _turnToXml(xml); |
| 108 | var r = { Header:{} }, header = xml.getElementsByTagName("Header")[0], t; |
| 109 | if (!header) header = xml.getElementsByTagName("a:Header")[0]; |
| 110 | if (!header) return null; |
| 111 | for (var i = 0; i < header.childNodes.length; i++) { |
| 112 | var child = header.childNodes[i]; |
| 113 | r.Header[child.localName] = child.textContent; |
| 114 | } |
| 115 | var body = xml.getElementsByTagName("Body")[0]; |
| 116 | if (!body) body = xml.getElementsByTagName("a:Body")[0]; |
| 117 | if (!body) return null; |
| 118 | if (body.childNodes.length > 0) { |
| 119 | t = body.childNodes[0].localName; |
| 120 | var x = t.indexOf('_OUTPUT'); |
| 121 | if ((x != -1) && (x == (t.length - 7))) { t = t.substring(0, t.length - 7); } |
| 122 | r.Header['Method'] = t; |
| 123 | r.Body = _ParseWsmanRec(body.childNodes[0]); |
| 124 | } |
| 125 | return r; |
| 126 | } catch (e) { |
| 127 | console.log("Unable to parse XML: " + xml); |
| 128 | return null; |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | // Private method |
| 133 | function _ParseWsmanRec(node) { |
| 134 | var data, r = {}; |
| 135 | for (var i = 0; i < node.childNodes.length; i++) { |
| 136 | var child = node.childNodes[i]; |
| 137 | if (child.childElementCount == 0) { data = child.textContent; } else { data = _ParseWsmanRec(child); } |
| 138 | if (data == 'true') data = true; // Convert 'true' into true |
| 139 | if (data == 'false') data = false; // Convert 'false' into false |
| 140 | |
| 141 | var childObj = data; |
| 142 | if (child.attributes.length > 0) { |
| 143 | childObj = {'Value': data }; |
| 144 | for(var j = 0; j < child.attributes.length; j++) { |
| 145 | childObj['@' + child.attributes[j].name] = child.attributes[j].value; |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | if (r[child.localName] instanceof Array) { r[child.localName].push(childObj); } |
| 150 | else if (r[child.localName] == undefined) { r[child.localName] = childObj; } |
| 151 | else { r[child.localName] = [r[child.localName], childObj]; } |
| 152 | } |
| 153 | return r; |
| 154 | } |
| 155 | |
| 156 | function _PutObjToBodyXml(resuri, putObj) { |
| 157 | if(!resuri || putObj === undefined || putObj === null) return ''; |
| 158 | var objname = obj.GetNameFromUrl(resuri); |
| 159 | var result = '<r:' + objname + ' xmlns:r="' + resuri + '">'; |
| 160 | |
| 161 | for (var prop in putObj) { |
| 162 | if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue; |
| 163 | if (putObj[prop] === undefined || putObj[prop] === null || typeof putObj[prop] === 'function') continue; |
| 164 | if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) { |
| 165 | result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>'; |
| 166 | var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector']; |
| 167 | if (Array.isArray(selectorArray)) { |
| 168 | for (var i=0; i< selectorArray.length; i++) { |
| 169 | result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>'; |
| 170 | } |
| 171 | } |
| 172 | else { |
| 173 | result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>'; |
| 174 | } |
| 175 | result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>'; |
| 176 | } |
| 177 | else { |
| 178 | if (Array.isArray(putObj[prop])) { |
| 179 | for (var i = 0; i < putObj[prop].length; i++) { |
| 180 | result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>'; |
| 181 | } |
| 182 | } else { |
| 183 | result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>'; |
| 184 | } |
| 185 | } |
| 186 | } |
| 187 | |
| 188 | result += '</r:' + objname + '>'; |
| 189 | return result; |
| 190 | } |
| 191 | |
| 192 | /* |
| 193 | convert |
| 194 | { @Name: 'InstanceID', @AttrName: 'Attribute Value'} |
| 195 | into |
| 196 | ' Name="InstanceID" AttrName="Attribute Value" ' |
| 197 | */ |
| 198 | function _ObjectToXmlAttributes(objWithAttributes) { |
| 199 | if(!objWithAttributes) return ''; |
| 200 | var result = ' '; |
| 201 | for (var propName in objWithAttributes) { |
| 202 | if (!objWithAttributes.hasOwnProperty(propName) || propName.indexOf('@') !== 0) continue; |
| 203 | result += propName.substring(1) + '="' + objWithAttributes[propName] + '" '; |
| 204 | } |
| 205 | return result; |
| 206 | } |
| 207 | |
| 208 | function _PutObjToSelectorsXml(selectorSet) { |
| 209 | if (!selectorSet) return ''; |
| 210 | if (typeof selectorSet == 'string') return selectorSet; |
| 211 | if (selectorSet['InstanceID']) return "<w:SelectorSet><w:Selector Name=\"InstanceID\">" + selectorSet['InstanceID'] + "</w:Selector></w:SelectorSet>"; |
| 212 | var result = '<w:SelectorSet>'; |
| 213 | for(var propName in selectorSet) { |
| 214 | if (!selectorSet.hasOwnProperty(propName)) continue; |
| 215 | result += '<w:Selector Name="' + propName + '">'; |
| 216 | if (selectorSet[propName]['ReferenceParameters']) { |
| 217 | result += '<a:EndpointReference>'; |
| 218 | result += '<a:Address>' + selectorSet[propName]['Address'] + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + selectorSet[propName]['ReferenceParameters']['ResourceURI'] + '</w:ResourceURI><w:SelectorSet>'; |
| 219 | var selectorArray = selectorSet[propName]['ReferenceParameters']['SelectorSet']['Selector']; |
| 220 | if (Array.isArray(selectorArray)) { |
| 221 | for (var i = 0; i < selectorArray.length; i++) { |
| 222 | result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>'; |
| 223 | } |
| 224 | } |
| 225 | else { |
| 226 | result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>'; |
| 227 | } |
| 228 | result += '</w:SelectorSet></a:ReferenceParameters></a:EndpointReference>'; |
| 229 | } else { |
| 230 | result += selectorSet[propName]; |
| 231 | } |
| 232 | result += '</w:Selector>'; |
| 233 | } |
| 234 | result += '</w:SelectorSet>'; |
| 235 | return result; |
| 236 | } |
| 237 | |
| 238 | function _turnToXml(text) { |
| 239 | if (window.DOMParser) { |
| 240 | return new DOMParser().parseFromString(text, "text/xml"); |
| 241 | } |
| 242 | else // Internet Explorer |
| 243 | { |
| 244 | var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); |
| 245 | xmlDoc.async = false; |
| 246 | xmlDoc.loadXML(text); |
| 247 | return xmlDoc; |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | return obj; |
| 252 | } |