2019-03-05 02:48:45 -05:00
/ *
2021-01-09 17:31:09 -05:00
Copyright 2018 - 2021 Intel Corporation
2019-03-05 02:48:45 -05:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
/ * *
* @ fileoverview Intel ( r ) AMT Management
* @ author Ylian Saint - Hilaire
* @ version v0 . 1.0
* /
/ * *
* Construct a AmtStackCreateService object , this ia the main Intel AMT communication stack .
* @ constructor
* /
function AmtManager ( agent , db , isdebug ) {
2019-11-28 15:27:44 -05:00
var sendConsole = function ( msg ) { agent . SendCommand ( { 'action' : 'msg' , 'type' : 'console' , 'value' : msg } ) ; }
2019-03-11 00:40:25 -04:00
var debug = function ( msg ) { if ( isdebug ) { sendConsole ( 'amt-manager: ' + msg + '<br />' ) ; } }
2019-03-05 02:48:45 -05:00
var amtMei = null , amtMeiState = 0 ;
var amtLms = null , amtLmsState = 0 ;
var amtGetVersionResult = null ;
var obj = this ;
2019-06-14 19:33:53 -04:00
var mestate ;
2019-06-19 20:16:50 -04:00
var trustedHashes = null ; ;
2020-08-11 21:38:38 -04:00
require ( 'events' ) . EventEmitter . call ( obj , true )
. createEvent ( 'stateChange_LMS' )
. createEvent ( 'portBinding_LMS' ) ;
obj . _lmsstate = 0 ;
obj . _mapping = [ ] ;
2020-10-28 02:55:00 -04:00
obj . on ( 'newListener' , function ( name , callback ) {
if ( name == 'portBinding_LMS' ) { callback . call ( this , this . _mapping ) ; }
2020-08-11 21:38:38 -04:00
} ) ;
Object . defineProperty ( obj , 'lmsstate' ,
{
2020-10-28 02:55:00 -04:00
get : function ( ) { return ( this . _lmsstate ) ; } ,
set : function ( value ) { if ( this . _lmsstate != value ) { this . _lmsstate = value ; this . emit ( 'stateChange_LMS' , value ) ; } }
2020-08-11 21:38:38 -04:00
} ) ;
2019-03-05 02:48:45 -05:00
obj . state = 0 ;
obj . onStateChange = null ;
obj . setDebug = function ( x ) { isdebug = x ; }
// Try to load up the MEI module
var rebindToMeiRetrys = 0 ;
obj . reset = function ( ) {
++ rebindToMeiRetrys ;
amtMei = null , amtMeiState = 0 , amtLms = null , amtLmsState = 0 , obj . state = 0 , obj . lmsstate = 0 ;
//debug('Binding to MEI');
try {
var amtMeiLib = require ( 'amt-mei' ) ;
amtMei = new amtMeiLib ( ) ;
2019-06-20 19:56:19 -04:00
amtMei . on ( 'error' , function ( e ) { debug ( 'MEI error' ) ; amtMei = null ; amtMeiState = - 1 ; obj . state = - 1 ; if ( obj . onStateChange != null ) { obj . onStateChange ( amtMeiState ) ; } } ) ;
2019-03-05 02:48:45 -05:00
amtMei . getVersion ( function ( result ) {
if ( result == null ) {
2020-10-28 02:55:00 -04:00
obj . state = amtMeiState = - 1 ;
2019-03-05 02:48:45 -05:00
if ( obj . onStateChange != null ) { obj . onStateChange ( amtMeiState ) ; }
if ( rebindToMeiRetrys < 10 ) { setTimeout ( obj . reset , 10000 ) ; }
} else {
amtGetVersionResult = result ;
2020-10-28 02:55:00 -04:00
obj . state = amtMeiState = 2 ;
2019-03-05 02:48:45 -05:00
rebindToMeiRetrys = 0 ;
if ( obj . onStateChange != null ) { obj . onStateChange ( amtMeiState ) ; }
//debug('MEI binded');
obj . lmsreset ( ) ;
}
} ) ;
2019-11-28 15:27:44 -05:00
} catch ( ex ) { debug ( "MEI exception: " + ex ) ; amtMei = null ; amtMeiState = - 1 ; obj . state = - 1 ; }
2019-03-05 02:48:45 -05:00
}
2020-10-28 02:55:00 -04:00
// Get Intel MEI State in a flexible way
// Flags: 1 = Versions, 2 = OsAdmin, 4 = Hashes, 8 = Network
2020-11-02 03:44:07 -05:00
var getMeiStateCache = { } ; // Some MEI calls will only be made once and cached here.
2020-10-28 02:55:00 -04:00
obj . getMeiState = function ( flags , func ) {
2019-03-05 02:48:45 -05:00
if ( ( amtMei == null ) || ( amtMeiState < 2 ) ) { if ( func != null ) { func ( null ) ; } return ; }
try {
2021-03-05 17:58:00 -05:00
var amtMeiTmpState = { 'core-ver' : 1 , OsHostname : require ( 'os' ) . hostname ( ) , Flags : 0 } ; // Flags: 1=EHBC, 2=CCM, 4=ACM
2020-11-02 03:44:07 -05:00
if ( getMeiStateCache . MeiVersion != null ) { amtMeiTmpState . MeiVersion = getMeiStateCache . MeiVersion ; } else { amtMei . getProtocolVersion ( function ( result ) { if ( result != null ) { getMeiStateCache . MeiVersion = amtMeiTmpState . MeiVersion = result ; } } ) ; }
if ( ( flags & 1 ) != 0 ) {
if ( getMeiStateCache . Versions != null ) {
amtMeiTmpState . Versions = getMeiStateCache . Versions ;
} else {
amtMei . getVersion ( function ( result ) { if ( result ) { getMeiStateCache . Versions = amtMeiTmpState . Versions = { } ; for ( var version in result . Versions ) { amtMeiTmpState . Versions [ result . Versions [ version ] . Description ] = result . Versions [ version ] . Version ; } } } ) ;
}
}
2019-03-05 02:48:45 -05:00
amtMei . getProvisioningMode ( function ( result ) { if ( result ) { amtMeiTmpState . ProvisioningMode = result . mode ; } } ) ;
2020-11-24 22:56:59 -05:00
amtMei . getProvisioningState ( function ( result ) { if ( result ) { amtMeiTmpState . ProvisioningState = result . state ; if ( result . state != 2 ) { amtMei . stopConfiguration ( function ( ) { } ) ; } } } ) ; // 0: "Not Activated (Pre)", 1: "Not Activated (In)", 2: "Activated". Make sure to stop remote configuration if needed.
2019-03-05 02:48:45 -05:00
amtMei . getEHBCState ( function ( result ) { if ( ( result != null ) && ( result . EHBC == true ) ) { amtMeiTmpState . Flags += 1 ; } } ) ;
2019-03-10 14:47:03 -04:00
amtMei . getControlMode ( function ( result ) { if ( result != null ) { if ( result . controlMode == 1 ) { amtMeiTmpState . Flags += 2 ; } if ( result . controlMode == 2 ) { amtMeiTmpState . Flags += 4 ; } } } ) ; // Flag 2 = CCM, 4 = ACM
2019-03-05 02:48:45 -05:00
//amtMei.getMACAddresses(function (result) { if (result) { amtMeiTmpState.mac = result; } });
2020-10-28 02:55:00 -04:00
if ( ( flags & 8 ) != 0 ) {
amtMei . getLanInterfaceSettings ( 0 , function ( result ) {
if ( result ) {
amtMeiTmpState . net0 = result ;
var fqdn = null , interfaces = require ( 'os' ) . networkInterfaces ( ) ; // Look for the DNS suffix for the Intel AMT Ethernet interface
for ( var i in interfaces ) { for ( var j in interfaces [ i ] ) { if ( ( interfaces [ i ] [ j ] . mac == result . mac ) && ( interfaces [ i ] [ j ] . fqdn != null ) && ( interfaces [ i ] [ j ] . fqdn != '' ) ) { amtMeiTmpState . OsDnsSuffix = interfaces [ i ] [ j ] . fqdn ; } } }
}
} ) ;
amtMei . getLanInterfaceSettings ( 1 , function ( result ) { if ( result ) { amtMeiTmpState . net1 = result ; } } ) ;
}
2020-11-02 03:44:07 -05:00
if ( getMeiStateCache . UUID != null ) { amtMeiTmpState . UUID = getMeiStateCache . UUID ; } else { amtMei . getUuid ( function ( result ) { if ( ( result != null ) && ( result . uuid != null ) ) { getMeiStateCache . UUID = amtMeiTmpState . UUID = result . uuid ; } } ) ; }
2020-10-28 02:55:00 -04:00
if ( ( flags & 2 ) != 0 ) { amtMei . getLocalSystemAccount ( function ( x ) { if ( ( x != null ) && x . user && x . pass ) { amtMeiTmpState . OsAdmin = { user : x . user , pass : x . pass } ; } } ) ; }
amtMei . getDnsSuffix ( function ( result ) { if ( result != null ) { amtMeiTmpState . DnsSuffix = result ; } if ( ( flags & 4 ) == 0 ) { if ( func != null ) { func ( amtMeiTmpState ) ; } } } ) ;
if ( ( flags & 4 ) != 0 ) {
amtMei . getHashHandles ( function ( handles ) {
if ( ( handles != null ) && ( handles . length > 0 ) ) { amtMeiTmpState . Hashes = [ ] ; } else { func ( amtMeiTmpState ) ; }
var exitOnCount = handles . length ;
for ( var i = 0 ; i < handles . length ; ++ i ) { this . getCertHashEntry ( handles [ i ] , function ( hashresult ) { amtMeiTmpState . Hashes . push ( hashresult ) ; if ( -- exitOnCount == 0 ) { if ( func != null ) { func ( amtMeiTmpState ) ; } } } ) ; }
} ) ;
}
2019-03-05 02:48:45 -05:00
} catch ( e ) { if ( func != null ) { func ( null ) ; } return ; }
}
// Called on MicroLMS Intel AMT user notification
2020-10-28 02:55:00 -04:00
var handleAmtNotification = function ( notifyMsg ) {
2019-03-05 02:48:45 -05:00
if ( ( notifyMsg == null ) || ( notifyMsg . Body == null ) || ( notifyMsg . Body . MessageID == null ) || ( notifyMsg . Body . MessageArguments == null ) ) return null ;
var amtMessage = notifyMsg . Body . MessageID , amtMessageArg = notifyMsg . Body . MessageArguments [ 0 ] , notify = null ;
switch ( amtMessage ) {
2019-11-28 15:27:44 -05:00
case 'iAMT0050' : { if ( amtMessageArg == '48' ) { notify = "Intel® AMT Serial-over-LAN connected" ; } else if ( amtMessageArg == '49' ) { notify = "Intel® AMT Serial-over-LAN disconnected" ; } break ; } // SOL
case 'iAMT0052' : { if ( amtMessageArg == '1' ) { notify = "Intel® AMT KVM connected" ; } else if ( amtMessageArg == '2' ) { notify = "Intel® AMT KVM disconnected" ; } break ; } // KVM
2019-03-05 02:48:45 -05:00
default : { break ; }
}
// Sent to the entire group, no sessionid or userid specified.
2019-11-28 15:27:44 -05:00
if ( notify != null ) { agent . SendCommand ( { 'action' : 'msg' , 'type' : 'notify' , 'value' : notify , 'tag' : 'general' , 'amtMessage' : amtMessage } ) ; }
2019-03-05 02:48:45 -05:00
}
// Launch LMS
obj . lmsreset = function ( ) {
//debug('Binding to LMS');
obj . lmsstate = 0 ;
try {
var lme _heci = require ( 'amt-lme' ) ;
2020-10-28 02:55:00 -04:00
obj . lmsstate = amtLmsState = 1 ;
2019-03-05 02:48:45 -05:00
amtLms = new lme _heci ( ) ;
2020-10-28 02:55:00 -04:00
amtLms . on ( 'error' , function ( e ) { amtLmsState = 0 ; obj . lmsstate = 0 ; amtLms = null ; debug ( "LMS error: " + e ) ; } ) ;
amtLms . on ( 'connect' , function ( ) { amtLmsState = 2 ; obj . lmsstate = 2 ; debug ( "LMS connected" ) ; } ) ;
amtLms . on ( 'bind' , function ( map ) { obj . _mapping = map ; obj . emit ( 'portBinding_LMS' , map ) ; } ) ;
amtLms . on ( 'notify' , function ( data , options , code ) { handleAmtNotification ( data ) ; } ) ;
2020-11-02 03:44:07 -05:00
} catch ( ex ) {
require ( 'MeshAgent' ) . SendCommand ( { action : 'msg' , type : 'console' , value : "ex: " + ex } ) ;
amtLmsState = - 1 ; obj . lmsstate = - 1 ; amtLms = null ;
}
2019-03-05 02:48:45 -05:00
}
2021-03-04 02:49:53 -05:00
// Start host based ACM activation with TLS
obj . startConfigurationHBased = function startConfigurationHBased ( certHash , hostVpn , dnsSuffixList , func ) {
if ( ( amtMei == null ) || ( amtMeiState < 2 ) ) { if ( func != null ) { func ( { status : - 100 } ) ; } return ; }
amtMei . startConfigurationHBased ( certHash , hostVpn , dnsSuffixList , func ) ;
}
2019-03-05 02:48:45 -05:00
}
module . exports = AmtManager ;