diff --git a/agents/meshcore.js b/agents/meshcore.js index 9b8fbb4c..54385f84 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -3538,8 +3538,12 @@ function createMeshCore(agent) { case 'apf': { if (meshCoreObj.intelamt !== null) { if (args['_'].length == 1) { - if (args['_'][0] == 'on') { - response = "Starting APF tunnel"; + var connType = -1, connTypeStr = args['_'][0].toLowerCase(); + if (connTypeStr == 'lms') { connType = 2; } + if (connTypeStr == 'relay') { connType = 1; } + if (connTypeStr == 'cira') { connType = 0; } + if (connTypeStr == 'off') { connType = -2; } + if (connType >= 0) { // Connect var apfarg = { mpsurl: mesh.ServerUrl.replace('agent.ashx', 'apf.ashx'), mpsuser: Buffer.from(mesh.ServerInfo.MeshID, 'hex').toString('base64').substring(0, 16), @@ -3548,7 +3552,7 @@ function createMeshCore(agent) { clientname: require('os').hostname(), clientaddress: '127.0.0.1', clientuuid: meshCoreObj.intelamt.uuid, - conntype: 2 // 0 = CIRA, 1 = Relay, 2 = LMS. The correct value is 2 since we are performing an LMS relay, other values for testing. + conntype: connType // 0 = CIRA, 1 = Relay, 2 = LMS. The correct value is 2 since we are performing an LMS relay, other values for testing. }; if ((apfarg.clientuuid == null) || (apfarg.clientuuid.length != 36)) { response = "Unable to get Intel AMT UUID: " + apfarg.clientuuid; @@ -3557,25 +3561,24 @@ function createMeshCore(agent) { apftunnel = require('apfclient')(tobj, apfarg); try { apftunnel.connect(); - response += "...success"; + response = "Started APF tunnel"; } catch (e) { - response += JSON.stringify(e); + response = JSON.stringify(e); } } - } else if (args['_'][0] == 'off') { - response = "Stopping APF tunnel"; + } else if (connType == -2) { // Disconnect try { apftunnel.disconnect(); - response += "..success"; + response = "Stopped APF tunnel"; } catch (e) { - response += JSON.stringify(e); + response = JSON.stringify(e); } apftunnel = null; } else { - response = "Invalid command.\r\nCmd syntax: apf on|off"; + response = "Invalid command.\r\nUse: apf lms|relay|cira|off"; } } else { - response = "APF tunnel is " + (apftunnel == null ? "off" : "on"); + response = "APF tunnel is " + (apftunnel == null ? "off" : "on") + "\r\nUse: apf lms|relay|cira|off"; } } else { response = "APF tunnel requires Intel AMT"; diff --git a/agents/modules_meshcore/apfclient.js b/agents/modules_meshcore/apfclient.js index de7a1f2f..6ee9a9f2 100644 --- a/agents/modules_meshcore/apfclient.js +++ b/agents/modules_meshcore/apfclient.js @@ -1,9 +1,25 @@ +/* +Copyright 2018-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 APF/CIRA Client for duktape -* @author Joko Sastriawan +* @description APF/CIRA Client for Duktape +* @author Joko Sastriawan & Ylian Saint-Hilaire * @copyright Intel Corporation 2019 * @license Apache-2.0 -* @version v0.0.1 +* @version v0.0.2 */ function CreateAPFClient(parent, args) { @@ -84,7 +100,7 @@ function CreateAPFClient(parent, args) { KEEPALIVE_REPLY: 209, KEEPALIVE_OPTIONS_REQUEST: 210, KEEPALIVE_OPTIONS_REPLY: 211, - MESH_CONNECTION_TYPE: 250 // This is a Mesh specific command that instructs the server of the connection type: 1 = Relay, 2 = LMS. + JSON_CONTROL: 250 // This is a Mesh specific command that sends JSON to and from the MPS server. } var APFDisconnectCode = { @@ -163,14 +179,15 @@ function CreateAPFClient(parent, args) { }); obj.state = CIRASTATE.INITIAL; - if (typeof obj.args.conntype == 'number') { SendConnectionType(obj.forwardClient.ws, obj.args.conntype); } + if ((typeof obj.args.conntype == 'number') && (obj.args.conntype != 0)) { SendJsonControl(obj.forwardClient.ws, { action: 'connType', value: obj.args.conntype } ); } SendProtocolVersion(obj.forwardClient.ws, obj.args.clientuuid); SendServiceRequest(obj.forwardClient.ws, 'auth@amt.intel.com'); } - function SendConnectionType(socket, type) { - socket.write(String.fromCharCode(APFProtocol.MESH_CONNECTION_TYPE) + IntToStr(type)); - Debug("APF: Send connection type " + type); + function SendJsonControl(socket, o) { + var data = JSON.stringify(o) + socket.write(String.fromCharCode(APFProtocol.JSON_CONTROL) + IntToStr(data.length) + data); + Debug("APF: Send JSON control: " + data); } function SendProtocolVersion(socket, uuid) { diff --git a/mpsserver.js b/mpsserver.js index 2660531e..25412c4b 100644 --- a/mpsserver.js +++ b/mpsserver.js @@ -80,7 +80,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { KEEPALIVE_REPLY: 209, KEEPALIVE_OPTIONS_REQUEST: 210, KEEPALIVE_OPTIONS_REPLY: 211, - MESH_CONNECTION_TYPE: 250 // This is a Mesh specific command that instructs the server of the connection type: 1 = Relay, 2 = LMS. + JSON_CONTROL: 250 // This is a Mesh specific command that sends JSON to and from the MPS server. }; /* @@ -870,13 +870,22 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { removeCiraConnection(socket); return 7; } - case APFProtocol.MESH_CONNECTION_TYPE: // This is a Mesh specific command to indicate the connect type. + case APFProtocol.JSON_CONTROL: // This is a Mesh specific command that sends JSON to and from the MPS server. { if (len < 5) return 0; - if ((socket.tag.connType == 0) && (socket.tag.SystemId == null)) { // Once set, the connection type can't be changed. - socket.tag.connType = common.ReadInt(data, 1); // 0 = CIRA, 1 = Relay, 2 = LMS + var jsondatalen = common.ReadInt(data, 1); + if (len < (5 + jsondatalen)) return 0; + var jsondata = null, jsondatastr = data.substring(5, 5 + jsondatalen); + try { jsondata = JSON.parse(jsondatastr); } catch (ex) { } + if ((jsondata == null) || (typeof jsondata.action != 'string')) return; + switch (jsondata.action) { + case 'connType': + if ((socket.tag.connType != 0) || (socket.tag.SystemId != null)) return; // Once set, the connection type can't be changed. + if (typeof jsondata.value != 'number') return; + socket.tag.connType = jsondata.value; // 0 = CIRA, 1 = Relay, 2 = LMS + break; } - return 5; + return 5 + jsondatalen; } default: {