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