Improved APF control command.

Ylian Saint-Hilaire committed Oct 12, 2020 at 09:29 UTC d3461b8d70fb3928669193657d0ffd460f6ad3e0
3 files changed +53 -24
agents/meshcore.js
+14 -11
@@ -3538,8 +3538,12 @@ function createMeshCore(agent) {
3538 case 'apf': {
3539 if (meshCoreObj.intelamt !== null) {
3540 if (args['_'].length == 1) {
3541 - if (args['_'][0] == 'on') {
3542 - response = "Starting APF tunnel";
3541 + var connType = -1, connTypeStr = args['_'][0].toLowerCase();
3542 + if (connTypeStr == 'lms') { connType = 2; }
3543 + if (connTypeStr == 'relay') { connType = 1; }
3544 + if (connTypeStr == 'cira') { connType = 0; }
3545 + if (connTypeStr == 'off') { connType = -2; }
3546 + if (connType >= 0) { // Connect
3547 var apfarg = {
3548 mpsurl: mesh.ServerUrl.replace('agent.ashx', 'apf.ashx'),
3549 mpsuser: Buffer.from(mesh.ServerInfo.MeshID, 'hex').toString('base64').substring(0, 16),
@@ -3548,7 +3552,7 @@ function createMeshCore(agent) {
3552 clientname: require('os').hostname(),
3553 clientaddress: '127.0.0.1',
3554 clientuuid: meshCoreObj.intelamt.uuid,
3551 - conntype: 2 // 0 = CIRA, 1 = Relay, 2 = LMS. The correct value is 2 since we are performing an LMS relay, other values for testing.
3555 + conntype: connType // 0 = CIRA, 1 = Relay, 2 = LMS. The correct value is 2 since we are performing an LMS relay, other values for testing.
3556 };
3557 if ((apfarg.clientuuid == null) || (apfarg.clientuuid.length != 36)) {
3558 response = "Unable to get Intel AMT UUID: " + apfarg.clientuuid;
@@ -3557,25 +3561,24 @@ function createMeshCore(agent) {
3561 apftunnel = require('apfclient')(tobj, apfarg);
3562 try {
3563 apftunnel.connect();
3560 - response += "...success";
3564 + response = "Started APF tunnel";
3565 } catch (e) {
3562 - response += JSON.stringify(e);
3566 + response = JSON.stringify(e);
3567 }
3568 }
3565 - } else if (args['_'][0] == 'off') {
3566 - response = "Stopping APF tunnel";
3569 + } else if (connType == -2) { // Disconnect
3570 try {
3571 apftunnel.disconnect();
3569 - response += "..success";
3572 + response = "Stopped APF tunnel";
3573 } catch (e) {
3571 - response += JSON.stringify(e);
3574 + response = JSON.stringify(e);
3575 }
3576 apftunnel = null;
3577 } else {
3575 - response = "Invalid command.\r\nCmd syntax: apf on|off";
3578 + response = "Invalid command.\r\nUse: apf lms|relay|cira|off";
3579 }
3580 } else {
3578 - response = "APF tunnel is " + (apftunnel == null ? "off" : "on");
3581 + response = "APF tunnel is " + (apftunnel == null ? "off" : "on") + "\r\nUse: apf lms|relay|cira|off";
3582 }
3583 } else {
3584 response = "APF tunnel requires Intel AMT";
agents/modules_meshcore/apfclient.js
+25 -8
@@ -1,9 +1,25 @@
1 +/*
2 +Copyright 2018-2020 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 /**
2 -* @description APF/CIRA Client for duktape
3 -* @author Joko Sastriawan
18 +* @description APF/CIRA Client for Duktape
19 +* @author Joko Sastriawan & Ylian Saint-Hilaire
20 * @copyright Intel Corporation 2019
21 * @license Apache-2.0
6 -* @version v0.0.1
22 +* @version v0.0.2
23 */
24
25 function CreateAPFClient(parent, args) {
@@ -84,7 +100,7 @@ function CreateAPFClient(parent, args) {
100 KEEPALIVE_REPLY: 209,
101 KEEPALIVE_OPTIONS_REQUEST: 210,
102 KEEPALIVE_OPTIONS_REPLY: 211,
87 - MESH_CONNECTION_TYPE: 250 // This is a Mesh specific command that instructs the server of the connection type: 1 = Relay, 2 = LMS.
103 + JSON_CONTROL: 250 // This is a Mesh specific command that sends JSON to and from the MPS server.
104 }
105
106 var APFDisconnectCode = {
@@ -163,14 +179,15 @@ function CreateAPFClient(parent, args) {
179 });
180
181 obj.state = CIRASTATE.INITIAL;
166 - if (typeof obj.args.conntype == 'number') { SendConnectionType(obj.forwardClient.ws, obj.args.conntype); }
182 + if ((typeof obj.args.conntype == 'number') && (obj.args.conntype != 0)) { SendJsonControl(obj.forwardClient.ws, { action: 'connType', value: obj.args.conntype } ); }
183 SendProtocolVersion(obj.forwardClient.ws, obj.args.clientuuid);
184 SendServiceRequest(obj.forwardClient.ws, 'auth@amt.intel.com');
185 }
186
171 - function SendConnectionType(socket, type) {
172 - socket.write(String.fromCharCode(APFProtocol.MESH_CONNECTION_TYPE) + IntToStr(type));
173 - Debug("APF: Send connection type " + type);
187 + function SendJsonControl(socket, o) {
188 + var data = JSON.stringify(o)
189 + socket.write(String.fromCharCode(APFProtocol.JSON_CONTROL) + IntToStr(data.length) + data);
190 + Debug("APF: Send JSON control: " + data);
191 }
192
193 function SendProtocolVersion(socket, uuid) {
mpsserver.js
+14 -5
@@ -80,7 +80,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
80 KEEPALIVE_REPLY: 209,
81 KEEPALIVE_OPTIONS_REQUEST: 210,
82 KEEPALIVE_OPTIONS_REPLY: 211,
83 - MESH_CONNECTION_TYPE: 250 // This is a Mesh specific command that instructs the server of the connection type: 1 = Relay, 2 = LMS.
83 + JSON_CONTROL: 250 // This is a Mesh specific command that sends JSON to and from the MPS server.
84 };
85
86 /*
@@ -870,13 +870,22 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
870 removeCiraConnection(socket);
871 return 7;
872 }
873 - case APFProtocol.MESH_CONNECTION_TYPE: // This is a Mesh specific command to indicate the connect type.
873 + case APFProtocol.JSON_CONTROL: // This is a Mesh specific command that sends JSON to and from the MPS server.
874 {
875 if (len < 5) return 0;
876 - if ((socket.tag.connType == 0) && (socket.tag.SystemId == null)) { // Once set, the connection type can't be changed.
877 - socket.tag.connType = common.ReadInt(data, 1); // 0 = CIRA, 1 = Relay, 2 = LMS
876 + var jsondatalen = common.ReadInt(data, 1);
877 + if (len < (5 + jsondatalen)) return 0;
878 + var jsondata = null, jsondatastr = data.substring(5, 5 + jsondatalen);
879 + try { jsondata = JSON.parse(jsondatastr); } catch (ex) { }
880 + if ((jsondata == null) || (typeof jsondata.action != 'string')) return;
881 + switch (jsondata.action) {
882 + case 'connType':
883 + if ((socket.tag.connType != 0) || (socket.tag.SystemId != null)) return; // Once set, the connection type can't be changed.
884 + if (typeof jsondata.value != 'number') return;
885 + socket.tag.connType = jsondata.value; // 0 = CIRA, 1 = Relay, 2 = LMS
886 + break;
887 }
879 - return 5;
888 + return 5 + jsondatalen;
889 }
890 default:
891 {