Fixed ghost connected devices.

Ylian Saint-Hilaire committed Apr 10, 2019 at 10:41 UTC a30340c1bed8eed4f96e8b0cc30f515de3cf1055
3 files changed +79 -39
meshagent.js
+71 -38
@@ -46,41 +46,38 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
46 if (arg == 2) { try { ws._socket._parent.end(); if (obj.nodeid != null) { parent.parent.debug(1, 'Hard disconnect ' + obj.nodeid + ' (' + obj.remoteaddrport + ')'); } } catch (e) { console.log(e); } } // Hard close, close the TCP socket
47 // If arg == 3, don't communicate with this agent anymore, but don't disconnect (Duplicate agent).
48
49 - // If this is a recovery agent, don't bother with all this clean up.
50 - if ((obj.agentInfo.capabilities & 0x40) == 0) {
51 - // Remove this agent from the webserver list
52 - if (parent.wsagents[obj.dbNodeKey] == obj) {
53 - delete parent.wsagents[obj.dbNodeKey];
54 - parent.parent.ClearConnectivityState(obj.dbMeshKey, obj.dbNodeKey, 1);
55 - }
49 + // Remove this agent from the webserver list
50 + if (parent.wsagents[obj.dbNodeKey] == obj) {
51 + delete parent.wsagents[obj.dbNodeKey];
52 + parent.parent.ClearConnectivityState(obj.dbMeshKey, obj.dbNodeKey, 1);
53 + }
54
57 - // Get the current mesh
58 - const mesh = parent.meshes[obj.dbMeshKey];
59 -
60 - // If this is a temporary or recovery agent, or all devices in this group are temporary, remove the agent (0x20 = Temporary, 0x40 = Recovery)
61 - if (((obj.agentInfo) && (obj.agentInfo.capabilities) && (obj.agentInfo.capabilities & 0x20)) || ((mesh) && (mesh.flags) && (mesh.flags & 1))) {
62 - // Delete this node including network interface information and events
63 - db.Remove(obj.dbNodeKey); // Remove node with that id
64 - db.Remove('if' + obj.dbNodeKey); // Remove interface information
65 - db.Remove('nt' + obj.dbNodeKey); // Remove notes
66 - db.Remove('lc' + obj.dbNodeKey); // Remove last connect time
67 - db.RemoveSMBIOS(obj.dbNodeKey); // Remove SMBios data
68 - db.RemoveAllNodeEvents(obj.dbNodeKey); // Remove all events for this node
69 - db.removeAllPowerEventsForNode(obj.dbNodeKey); // Remove all power events for this node
70 -
71 - // Event node deletion
72 - parent.parent.DispatchEvent(['*', obj.dbMeshKey], obj, { etype: 'node', action: 'removenode', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 });
73 -
74 - // Disconnect all connections if needed
75 - const state = parent.parent.GetConnectivityState(obj.dbNodeKey);
76 - if ((state != null) && (state.connectivity != null)) {
77 - if ((state.connectivity & 1) != 0) { parent.wsagents[obj.dbNodeKey].close(); } // Disconnect mesh agent
78 - if ((state.connectivity & 2) != 0) { parent.parent.mpsserver.close(parent.parent.mpsserver.ciraConnections[obj.dbNodeKey]); } // Disconnect CIRA connection
79 - }
80 - } else {
81 - // Update the last connect time
82 - if (obj.authenticated == 2) { db.Set({ _id: 'lc' + obj.dbNodeKey, type: 'lastconnect', domain: domain.id, time: obj.connectTime, addr: obj.remoteaddrport }); }
55 + // Get the current mesh
56 + const mesh = parent.meshes[obj.dbMeshKey];
57 +
58 + // If this is a temporary or recovery agent, or all devices in this group are temporary, remove the agent (0x20 = Temporary, 0x40 = Recovery)
59 + if (((obj.agentInfo) && (obj.agentInfo.capabilities) && ((obj.agentInfo.capabilities & 0x20) || (obj.agentInfo.capabilities & 0x40))) || ((mesh) && (mesh.flags) && (mesh.flags & 1))) {
60 + // Delete this node including network interface information and events
61 + db.Remove(obj.dbNodeKey); // Remove node with that id
62 + db.Remove('if' + obj.dbNodeKey); // Remove interface information
63 + db.Remove('nt' + obj.dbNodeKey); // Remove notes
64 + db.Remove('lc' + obj.dbNodeKey); // Remove last connect time
65 + db.RemoveSMBIOS(obj.dbNodeKey); // Remove SMBios data
66 + db.RemoveAllNodeEvents(obj.dbNodeKey); // Remove all events for this node
67 + db.removeAllPowerEventsForNode(obj.dbNodeKey); // Remove all power events for this node
68 +
69 + // Event node deletion
70 + parent.parent.DispatchEvent(['*', obj.dbMeshKey], obj, { etype: 'node', action: 'removenode', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 });
71 +
72 + // Disconnect all connections if needed
73 + const state = parent.parent.GetConnectivityState(obj.dbNodeKey);
74 + if ((state != null) && (state.connectivity != null)) {
75 + if ((state.connectivity & 1) != 0) { parent.wsagents[obj.dbNodeKey].close(); } // Disconnect mesh agent
76 + if ((state.connectivity & 2) != 0) { parent.parent.mpsserver.close(parent.parent.mpsserver.ciraConnections[obj.dbNodeKey]); } // Disconnect CIRA connection
77 }
78 + } else {
79 + // Update the last connect time
80 + if (obj.authenticated == 2) { db.Set({ _id: 'lc' + obj.dbNodeKey, type: 'lastconnect', domain: domain.id, time: obj.connectTime, addr: obj.remoteaddrport }); }
81 }
82
83 // If we where updating the agent, clean that up.
@@ -525,9 +522,15 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
522 if ((obj.authenticated != 1) || (obj.meshid == null) || obj.pendingCompleteAgentConnection || (obj.agentInfo == null)) { return; }
523 obj.pendingCompleteAgentConnection = true;
524
525 + // If this is a recovery agent
526 if (obj.agentInfo.capabilities & 0x40) {
529 - // This is a recovery agent
530 - obj.send(common.ShortToStr(11) + common.ShortToStr(0)); // Command 11, ask for mesh core hash.
527 + // Inform mesh agent that it's authenticated.
528 + delete obj.pendingCompleteAgentConnection;
529 + obj.authenticated = 2;
530 + obj.send(common.ShortToStr(4));
531 +
532 + // Ask for mesh core hash.
533 + obj.send(common.ShortToStr(11) + common.ShortToStr(0));
534 return;
535 }
536
@@ -656,6 +659,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
659 if (mesh.flags && (mesh.flags & 2) && (device.name != obj.agentInfo.computerName)) { device.name = obj.agentInfo.computerName; change = 1; } // We want the server name to be sync'ed to the hostname
660
661 if (change == 1) {
662 + // Do some clean up if needed, these values should not be in the database.
663 + if (device.conn != null) { delete device.conn; }
664 + if (device.pwr != null) { delete device.pwr; }
665 + if (device.agct != null) { delete device.agct; }
666 + if (device.cict != null) { delete device.cict; }
667 +
668 + // Save the updated device in the database
669 db.Set(device);
670
671 // If this is a temporary device, don't log changes
@@ -781,6 +791,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
791 return; // Probably not worth doing anything else. Hold this agent.
792 }
793
794 + // Check if this is a recovery agent
795 + if (obj.agentInfo.capabilities & 0x40) {
796 + recoveryAgentCoreIsStable(mesh);
797 + return;
798 + }
799 +
800 // Fetch the the real agent nodeid
801 db.Get('ra' + obj.dbNodeKey, function (err, nodes) {
802 if (nodes.length == 1) {
@@ -789,9 +805,6 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
805 }
806 });
807
792 - // Check if this is a recovery agent
793 - if (obj.agentInfo.capabilities & 0x40) { recoveryAgentCoreIsStable(mesh); return; }
794 -
808 // Send Intel AMT policy
809 if (obj.agentExeInfo && (obj.agentExeInfo.amt == true) && (mesh.amt != null)) { // Only send Intel AMT policy to agents what could have AMT.
810 try { obj.send(JSON.stringify({ action: 'amtPolicy', amtPolicy: completeIntelAmtPolicy(common.Clone(mesh.amt)) })); } catch (ex) { }
@@ -1182,6 +1195,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1195
1196 // If there are changes, event the new device
1197 if (change == 1) {
1198 + // Do some clean up if needed, these values should not be in the database.
1199 + if (device.conn != null) { delete device.conn; }
1200 + if (device.pwr != null) { delete device.pwr; }
1201 + if (device.agct != null) { delete device.agct; }
1202 + if (device.cict != null) { delete device.cict; }
1203 +
1204 // Save to the database
1205 db.Set(device);
1206
@@ -1220,6 +1239,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1239
1240 // If there are changes, save and event
1241 if (change == 1) {
1242 + // Do some clean up if needed, these values should not be in the database.
1243 + if (device.conn != null) { delete device.conn; }
1244 + if (device.pwr != null) { delete device.pwr; }
1245 + if (device.agct != null) { delete device.agct; }
1246 + if (device.cict != null) { delete device.cict; }
1247 +
1248 + // Save the device
1249 db.Set(device);
1250
1251 // Event the node change
@@ -1244,6 +1270,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1270 const device = nodes[0];
1271 if (device.agent) {
1272 if (device.agent.tag != tag) {
1273 + // Do some clean up if needed, these values should not be in the database.
1274 + if (device.conn != null) { delete device.conn; }
1275 + if (device.pwr != null) { delete device.pwr; }
1276 + if (device.agct != null) { delete device.agct; }
1277 + if (device.cict != null) { delete device.cict; }
1278 +
1279 + // Set the new tag
1280 device.agent.tag = tag;
1281 db.Set(device);
1282
meshuser.js
+7
@@ -327,6 +327,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
327 db.GetAllTypeNoTypeFieldMeshFiltered(links, domain.id, 'node', command.id, function (err, docs) {
328 var r = {};
329 for (i in docs) {
330 + // Remove any connectivity and power state information, that should not be in the database anyway.
331 + // TODO: Find why these are sometimes saves in the db.
332 + if (docs[i].conn != null) { delete docs[i].conn; }
333 + if (docs[i].pwr != null) { delete docs[i].pwr; }
334 + if (docs[i].agct != null) { delete docs[i].agct; }
335 + if (docs[i].cict != null) { delete docs[i].cict; }
336 +
337 // Add the connection state
338 var state = parent.parent.GetConnectivityState(docs[i]._id);
339 if (state) {
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.3.2-b",
3 + "version": "0.3.2-c",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",