diff --git a/agents/meshcore.js b/agents/meshcore.js index 28396a0b..0db93b5a 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -1075,15 +1075,15 @@ function createMeshCore(agent) { } case 'amtconfig': { // Perform Intel AMT activation and/or configuration - if ((apftunnel != null) || (amt == null)) break; + if ((apftunnel != null) || (amt == null) || (typeof data.user != 'string') || (typeof data.pass != 'string')) break; getMeiState(15, function (state) { if ((apftunnel != null) || (amt == null)) return; if ((state == null) || (state.ProvisioningState == null)) return; if ((state.UUID == null) || (state.UUID.length != 36)) return; // Bad UUID var apfarg = { - mpsurl: mesh.ServerUrl.replace('agent.ashx', 'apf.ashx'), - mpsuser: Buffer.from(mesh.ServerInfo.MeshID, 'hex').toString('base64').substring(0, 16), // TODO: User a server provided encrypted cookie for CIRA-LMS login - mpspass: Buffer.from(mesh.ServerInfo.MeshID, 'hex').toString('base64').substring(0, 16), + mpsurl: mesh.ServerUrl.replace('/agent.ashx', '/apf.ashx'), + mpsuser: data.user, // Agent user name + mpspass: data.pass, // Encrypted login cookie mpskeepalive: 60000, clientname: state.OsHostname, clientaddress: '127.0.0.1', diff --git a/meshagent.js b/meshagent.js index 21de2607..4c951a9b 100644 --- a/meshagent.js +++ b/meshagent.js @@ -897,11 +897,15 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { } } - // Indicate to the agent that we want to reconfigure Intel AMT + // Indicate to the agent that we want to check Intel AMT configuration + // This may trigger a CIRA-LMS tunnel from the agent so the server can inspect the device. obj.sendUpdatedIntelAmtPolicy = function (policy) { if (obj.agentExeInfo && (obj.agentExeInfo.amt == true)) { // Only send Intel AMT policy to agents what could have AMT. if (policy == null) { var mesh = parent.meshes[obj.dbMeshKey]; if (mesh == null) return; policy = mesh.amt; } - if ((policy != null) && (policy.type != 0)) { try { obj.send(JSON.stringify({ action: 'amtconfig' })); } catch (ex) { } } + if ((policy != null) && (policy.type != 0)) { + const cookie = parent.parent.encodeCookie({ a: 'apf', n: obj.dbNodeKey, m: obj.dbMeshKey }, parent.parent.loginCookieEncryptionKey); + try { obj.send(JSON.stringify({ action: 'amtconfig', user: '**MeshAgentApfTunnel**', pass: cookie })); } catch (ex) { } + } } } @@ -954,9 +958,8 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { }); // Indicate that we want to check the Intel AMT configuration - if (obj.agentExeInfo && (obj.agentExeInfo.amt == true) && (mesh.amt != null) && (mesh.amt.type != 0)) { // Only send yo agents what could have AMT and if the policy is not empty. - try { obj.send(JSON.stringify({ action: 'amtconfig' })); } catch (ex) { } - } + // This may trigger a CIRA-LMS tunnel to the server for further processing + obj.sendUpdatedIntelAmtPolicy(); // Fetch system information db.GetHash('si' + obj.dbNodeKey, function (err, results) { diff --git a/mpsserver.js b/mpsserver.js index dd596dce..9da02ed3 100644 --- a/mpsserver.js +++ b/mpsserver.js @@ -544,14 +544,31 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { //console.log('MPS:USERAUTH_REQUEST user=' + username + ', service=' + serviceName + ', method=' + methodName + ', password=' + password); parent.debug('mpscmd', '--> USERAUTH_REQUEST user=' + username + ', service=' + serviceName + ', method=' + methodName + ', password=' + password); - // Check the CIRA password - if ((args.mpspass != null) && (password != args.mpspass)) { incorrectPasswordCount++; parent.debug('mps', 'Incorrect password', username, password); SendUserAuthFail(socket); return -1; } + // If the login uses a cookie, check this now + if ((username == '**MeshAgentApfTunnel**') && (password != null)) { + const cookie = parent.decodeCookie(password, parent.loginCookieEncryptionKey); + if ((cookie == null) || (cookie.a !== 'apf')) { incorrectPasswordCount++; parent.debug('mps', 'Incorrect password', username, password); SendUserAuthFail(socket); return -1; } + if (obj.parent.webserver.meshes[cookie.m] == null) { meshNotFoundCount++; parent.debug('mps', 'Device group not found', username, password); SendUserAuthFail(socket); return -1; } - // Check the CIRA username, which should be the start of the MeshID. - if (usernameLen != 16) { badUserNameLengthCount++; parent.debug('mps', 'Username length not 16', username, password); SendUserAuthFail(socket); return -1; } - var meshIdStart = '/' + username, mesh = null; - if (obj.parent.webserver.meshes) { for (var i in obj.parent.webserver.meshes) { if (obj.parent.webserver.meshes[i]._id.replace(/\@/g, 'X').replace(/\$/g, 'X').indexOf(meshIdStart) > 0) { mesh = obj.parent.webserver.meshes[i]; break; } } } - if (mesh == null) { meshNotFoundCount++; parent.debug('mps', 'Device group not found', username, password); SendUserAuthFail(socket); return -1; } + // Setup the connection + socket.tag.nodeid = cookie.n; + socket.tag.meshid = cookie.m; + socket.tag.connectTime = Date.now(); + + // Add the connection to the MPS connection list + addCiraConnection(socket); + SendUserAuthSuccess(socket); // Notify the auth success on the CIRA connection + return 18 + usernameLen + serviceNameLen + methodNameLen + passwordLen; + } else { + // Check the CIRA password + if ((args.mpspass != null) && (password != args.mpspass)) { incorrectPasswordCount++; parent.debug('mps', 'Incorrect password', username, password); SendUserAuthFail(socket); return -1; } + + // Check the CIRA username, which should be the start of the MeshID. + if (usernameLen != 16) { badUserNameLengthCount++; parent.debug('mps', 'Username length not 16', username, password); SendUserAuthFail(socket); return -1; } + var meshIdStart = '/' + username, mesh = null; + if (obj.parent.webserver.meshes) { for (var i in obj.parent.webserver.meshes) { if (obj.parent.webserver.meshes[i]._id.replace(/\@/g, 'X').replace(/\$/g, 'X').indexOf(meshIdStart) > 0) { mesh = obj.parent.webserver.meshes[i]; break; } } } + if (mesh == null) { meshNotFoundCount++; parent.debug('mps', 'Device group not found', username, password); SendUserAuthFail(socket); return -1; } + } // If this is a agent-less mesh, use the device guid 3 times as ID. if (mesh.mtype == 1) {