1. Updated AgentMessage infrastructure 2. Updated to be compatible with older agents, displaying agentmessage advising to update, if important components are missing
1. Updated AgentMessage infrastructure 2. Updated to be compatible with older agents, displaying agentmessage advising to update, if important components are missing
Bryan Roe committed
Jun 8, 2021 at 00:11 UTC
73f426bc24c29f4258c441a1df5891c3d2d1df8c
1 file changed
+117
-38
agents/meshcore.js
+117
-38
@@ -46,9 +46,11 @@ var MESHRIGHT_CHATNOTIFY = 16384;
46
var MESHRIGHT_UNINSTALL = 32768;
47
var MESHRIGHT_NODESKTOP = 65536;
48
49
-if (require('MeshAgent').ARCHID == null) {
49
+if (require('MeshAgent').ARCHID == null)
50
+{
51
var id = null;
51
- switch (process.platform) {
52
+ switch (process.platform)
53
+ {
54
case 'win32':
55
id = require('_GenericMarshal').PointerSize == 4 ? 3 : 4;
56
break;
@@ -56,21 +58,22 @@ if (require('MeshAgent').ARCHID == null) {
58
id = require('_GenericMarshal').PointerSize == 4 ? 31 : 30;
59
break;
60
case 'darwin':
59
- try {
61
+ try
62
+ {
63
id = require('os').arch() == 'x64' ? 16 : 29;
64
}
62
- catch (xx) {
65
+ catch (xx)
66
+ {
67
id = 16;
68
}
69
break;
70
}
71
if (id != null) { Object.defineProperty(require('MeshAgent'), 'ARCHID', { value: id }); }
72
}
69
-
73
var obj = {};
74
var agentFileHttpRequests = {}; // Currently active agent HTTPS GET requests from the server.
75
var agentFileHttpPendingRequests = []; // Pending HTTPS GET requests from the server.
73
-var debugConsole = (_MSH().debugConsole == 1);
76
+var debugConsole = (global._MSH && (_MSH().debugConsole == 1));
77
78
if (process.platform == 'win32' && require('user-sessions').isRoot()) {
79
// Check the Agent Uninstall MetaData for correctness, as the installer may have written an incorrect value
@@ -277,8 +280,16 @@ obj.DAIPC.on('connection', function (c) {
280
});
281
282
// Send current sessions to registered apps
280
-function broadcastSessionsToRegisteredApps(x) {
283
+function broadcastSessionsToRegisteredApps(x)
284
+{
285
+ var p = {}, i;
286
+ for (i = 0; i < sendAgentMessage.messages.length; ++i)
287
+ {
288
+ p[i] = sendAgentMessage.messages[i];
289
+ }
290
+ tunnelUserCount.msg = p;
291
broadcastToRegisteredApps({ cmd: 'sessions', sessions: tunnelUserCount });
292
+ tunnelUserCount.msg = {};
293
}
294
295
// Send this object to all registered local applications
@@ -838,7 +849,8 @@ function handleServerCommand(data) {
849
850
// Perform manual server TLS certificate checking based on the certificate hash given by the server.
851
woptions.rejectUnauthorized = 0;
841
- woptions.checkServerIdentity = function checkServerIdentity(certs) {
852
+ woptions.checkServerIdentity = function checkServerIdentity(certs)
853
+ {
854
/*
855
try { sendConsoleText("certs[0].digest: " + certs[0].digest); } catch (ex) { sendConsoleText(ex); }
856
try { sendConsoleText("certs[0].fingerprint: " + certs[0].fingerprint); } catch (ex) { sendConsoleText(ex); }
@@ -847,8 +859,15 @@ function handleServerCommand(data) {
859
*/
860
861
// If the tunnel certificate matches the control channel certificate, accept the connection
850
- try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.digest == certs[0].digest) return; } catch (ex) { }
851
- try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.fingerprint == certs[0].fingerprint) return; } catch (ex) { }
862
+ var noErrors = true;
863
+ try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.digest == certs[0].digest) return; } catch (ex) { noErrors = false; }
864
+ try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.fingerprint == certs[0].fingerprint) return; } catch (ex) { noErrors = false; }
865
+ if (certs[0].digest == null || noErrors == true)
866
+ {
867
+ sendAgentMessage("This agent is using insecure tunnels, consider updating.", 3, 119, true);
868
+ return;
869
+ }
870
+
871
// Check that the certificate is the one expected by the server, fail if not.
872
if ((checkServerIdentity.servertlshash != null) && (checkServerIdentity.servertlshash.toLowerCase() != certs[0].digest.split(':').join('').toLowerCase())) { throw new Error('BadCert') }
873
}
@@ -2942,31 +2961,32 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
2961
break;
2962
}
2963
case 'agentmsg': {
2945
- if (args['_'].length == 0) {
2964
+ if (args['_'].length == 0)
2965
+ {
2966
response = "Proper usage:\r\n agentmsg add \"[message]\" [iconIndex]\r\n agentmsg remove [index]\r\n agentmsg list"; // Display usage
2947
- } else {
2948
- if ((args['_'][0] == 'add') && (args['_'].length > 1)) {
2949
- var msgIndex = 1, iconIndex = 0;
2950
- while (tunnelUserCount.msg[msgIndex] != null) { msgIndex++; }
2967
+ } else
2968
+ {
2969
+ if ((args['_'][0] == 'add') && (args['_'].length > 1))
2970
+ {
2971
+ var msgID, iconIndex = 0;
2972
if (args['_'].length >= 3) { try { iconIndex = parseInt(args['_'][2]); } catch (e) { } }
2973
if (typeof iconIndex != 'number') { iconIndex = 0; }
2953
- tunnelUserCount.msg[msgIndex] = { msg: args['_'][1], icon: iconIndex };
2954
- response = 'Agent message ' + msgIndex + ' added.';
2955
- } else if ((args['_'][0] == 'remove') && (args['_'].length > 1)) {
2956
- var msgIndex = 0;
2957
- try { msgIndex = parseInt(args['_'][1]); } catch (x) { }
2958
- if (tunnelUserCount.msg[msgIndex] == null) { response = "Message not found."; } else { delete tunnelUserCount.msg[msgIndex]; response = "Message removed."; }
2959
- } else if (args['_'][0] == 'list') {
2960
- response = JSON.stringify(tunnelUserCount.msg, null, 2);
2974
+ msgID = sendAgentMessage(args['_'][1], iconIndex);
2975
+ response = 'Agent message: ' + msgID + ' added.';
2976
+ } else if ((args['_'][0] == 'remove') && (args['_'].length > 1))
2977
+ {
2978
+ var r = removeAgentMessage(args['_'][1]);
2979
+ response = 'Message ' + (r ? 'removed' : 'NOT FOUND');
2980
+ } else if (args['_'][0] == 'list')
2981
+ {
2982
+ response = JSON.stringify(sendAgentMessage(), null, 2);
2983
}
2962
- try { mesh.SendCommand({ action: 'sessions', type: 'msg', value: tunnelUserCount.msg }); } catch (x) { }
2984
broadcastSessionsToRegisteredApps();
2985
}
2986
break;
2987
}
2988
case 'clearagentmsg': {
2968
- tunnelUserCount.msg = {};
2969
- try { mesh.SendCommand({ action: 'sessions', type: 'msg', value: tunnelUserCount.msg }); } catch (x) { }
2989
+ removeAgentMessage();
2990
broadcastSessionsToRegisteredApps();
2991
break;
2992
}
@@ -3985,14 +4005,58 @@ function sendConsoleText(text, sessionid) {
4005
if (sessionid != 'pipe') { require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: text, sessionid: sessionid }); }
4006
}
4007
4008
+function removeAgentMessage(msgid)
4009
+{
4010
+ var ret = false;
4011
+ if (msgid == null)
4012
+ {
4013
+ // Delete all messages
4014
+ sendAgentMessage.messages = [];
4015
+ ret = true;
4016
+ }
4017
+ else
4018
+ {
4019
+ var i = sendAgentMessage.messages.findIndex(function (v) { return (v.id == msgid); });
4020
+ if (i >= 0)
4021
+ {
4022
+ sendAgentMessage.messages.splice(i, 1);
4023
+ ret = true;
4024
+ }
4025
+ }
4026
+ if (ret) { sendAgentMessage(); }
4027
+ return (ret);
4028
+}
4029
+
4030
// Send a mesh agent message to server, placing a bubble/badge on the agent device
3989
-function sendAgentMessage(msg, icon) {
3990
- if (sendAgentMessage.messages == null) {
3991
- sendAgentMessage.messages = {};
3992
- sendAgentMessage.nextid = 1;
4031
+function sendAgentMessage(msg, icon, serverid, first)
4032
+{
4033
+ if (sendAgentMessage.messages == null)
4034
+ {
4035
+ sendAgentMessage.messages = [];
4036
+ }
4037
+
4038
+ if (arguments.length > 0)
4039
+ {
4040
+ if (first == null || (serverid && first && sendAgentMessage.messages.findIndex(function (v) { return (v.msgid == serverid); }) < 0))
4041
+ {
4042
+ sendAgentMessage.messages.push({ msg: msg, icon: icon, msgid: serverid });
4043
+ sendAgentMessage.messages.peek().id = sendAgentMessage.messages.peek()._hashCode();
4044
+ }
4045
+ }
4046
+
4047
+ var p = {}, i;
4048
+ for (i = 0; i < sendAgentMessage.messages.length; ++i)
4049
+ {
4050
+ p[i] = sendAgentMessage.messages[i];
4051
+ }
4052
+ try
4053
+ {
4054
+ require('MeshAgent').SendCommand({ action: 'sessions', type: 'msg', value: p });
4055
+ }
4056
+ catch(ex)
4057
+ {
4058
}
3994
- sendAgentMessage.messages[sendAgentMessage.nextid++] = { msg: msg, icon: icon };
3995
- require('MeshAgent').SendCommand({ action: 'sessions', type: 'msg', value: sendAgentMessage.messages });
4059
+ return (arguments.length > 0 ? sendAgentMessage.messages.peek().id : sendAgentMessage.messages);
4060
}
4061
function getOpenDescriptors() {
4062
switch (process.platform) {
@@ -4390,14 +4454,27 @@ function agentUpdate_Start(updateurl, updateoptions) {
4454
//process.exit = function (code) { console.log("Exit with code: " + code.toString()); }
4455
4456
// Called when the server connection state changes
4393
-function handleServerConnection(state) {
4457
+function handleServerConnection(state)
4458
+{
4459
meshServerConnectionState = state;
4395
- if (meshServerConnectionState == 0) {
4460
+ if (meshServerConnectionState == 0)
4461
+ {
4462
// Server disconnected
4463
if (selfInfoUpdateTimer != null) { clearInterval(selfInfoUpdateTimer); selfInfoUpdateTimer = null; }
4464
lastSelfInfo = null;
4399
- } else {
4465
+ } else
4466
+ {
4467
// Server connected, send mesh core information
4468
+ if (require('MeshAgent').ServerInfo == null || require('MeshAgent').ServerInfo.ControlChannelCertificate == null)
4469
+ {
4470
+ // Outdated Agent, will have insecure tunnels
4471
+ sendAgentMessage("This agent has an outdated certificate validation mechanism, consider updating.", 3, 118);
4472
+ }
4473
+ else if (global._MSH == null)
4474
+ {
4475
+ sendAgentMessage("This agent is outdated, consider updating.", 3, 120);
4476
+ }
4477
+
4478
var oldNodeId = db.Get('OldNodeId');
4479
if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); }
4480
@@ -4407,14 +4484,16 @@ function handleServerConnection(state) {
4484
// Update the server on with basic info, logged in users and more advanced stuff, like Intel ME and Network Settings
4485
meInfoStr = null;
4486
sendPeriodicServerUpdate(null, true);
4410
- if (selfInfoUpdateTimer == null) {
4487
+ if (selfInfoUpdateTimer == null)
4488
+ {
4489
selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); // 20 minutes
4490
selfInfoUpdateTimer.metadata = 'meshcore (InfoUpdate Timer)';
4491
}
4492
4493
// Send any state messages
4416
- if (Object.keys(tunnelUserCount.msg).length > 0) {
4417
- try { mesh.SendCommand({ action: 'sessions', type: 'msg', value: tunnelUserCount.msg }); } catch (e) { }
4494
+ if (Object.keys(tunnelUserCount.msg).length > 0)
4495
+ {
4496
+ sendAgentMessage();
4497
broadcastSessionsToRegisteredApps();
4498
}
4499