Fixed ghost connected devices.

This commit is contained in:
Ylian Saint-Hilaire 2019-04-10 10:41:10 -07:00
parent 4bb307c635
commit d9d056359e
3 changed files with 80 additions and 40 deletions

View File

@ -46,41 +46,38 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
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 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
// If arg == 3, don't communicate with this agent anymore, but don't disconnect (Duplicate agent). // If arg == 3, don't communicate with this agent anymore, but don't disconnect (Duplicate agent).
// If this is a recovery agent, don't bother with all this clean up. // Remove this agent from the webserver list
if ((obj.agentInfo.capabilities & 0x40) == 0) { if (parent.wsagents[obj.dbNodeKey] == obj) {
// Remove this agent from the webserver list delete parent.wsagents[obj.dbNodeKey];
if (parent.wsagents[obj.dbNodeKey] == obj) { parent.parent.ClearConnectivityState(obj.dbMeshKey, obj.dbNodeKey, 1);
delete parent.wsagents[obj.dbNodeKey]; }
parent.parent.ClearConnectivityState(obj.dbMeshKey, obj.dbNodeKey, 1);
} // Get the current mesh
const mesh = parent.meshes[obj.dbMeshKey];
// Get the current mesh
const mesh = parent.meshes[obj.dbMeshKey]; // If this is a temporary or recovery agent, or all devices in this group are temporary, remove the agent (0x20 = Temporary, 0x40 = Recovery)
if (((obj.agentInfo) && (obj.agentInfo.capabilities) && ((obj.agentInfo.capabilities & 0x20) || (obj.agentInfo.capabilities & 0x40))) || ((mesh) && (mesh.flags) && (mesh.flags & 1))) {
// If this is a temporary or recovery agent, or all devices in this group are temporary, remove the agent (0x20 = Temporary, 0x40 = Recovery) // Delete this node including network interface information and events
if (((obj.agentInfo) && (obj.agentInfo.capabilities) && (obj.agentInfo.capabilities & 0x20)) || ((mesh) && (mesh.flags) && (mesh.flags & 1))) { db.Remove(obj.dbNodeKey); // Remove node with that id
// Delete this node including network interface information and events db.Remove('if' + obj.dbNodeKey); // Remove interface information
db.Remove(obj.dbNodeKey); // Remove node with that id db.Remove('nt' + obj.dbNodeKey); // Remove notes
db.Remove('if' + obj.dbNodeKey); // Remove interface information db.Remove('lc' + obj.dbNodeKey); // Remove last connect time
db.Remove('nt' + obj.dbNodeKey); // Remove notes db.RemoveSMBIOS(obj.dbNodeKey); // Remove SMBios data
db.Remove('lc' + obj.dbNodeKey); // Remove last connect time db.RemoveAllNodeEvents(obj.dbNodeKey); // Remove all events for this node
db.RemoveSMBIOS(obj.dbNodeKey); // Remove SMBios data db.removeAllPowerEventsForNode(obj.dbNodeKey); // Remove all power events for this node
db.RemoveAllNodeEvents(obj.dbNodeKey); // Remove all events for this node
db.removeAllPowerEventsForNode(obj.dbNodeKey); // Remove all power events for this node // Event node deletion
parent.parent.DispatchEvent(['*', obj.dbMeshKey], obj, { etype: 'node', action: 'removenode', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 });
// Event node deletion
parent.parent.DispatchEvent(['*', obj.dbMeshKey], obj, { etype: 'node', action: 'removenode', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 }); // Disconnect all connections if needed
const state = parent.parent.GetConnectivityState(obj.dbNodeKey);
// Disconnect all connections if needed if ((state != null) && (state.connectivity != null)) {
const state = parent.parent.GetConnectivityState(obj.dbNodeKey); if ((state.connectivity & 1) != 0) { parent.wsagents[obj.dbNodeKey].close(); } // Disconnect mesh agent
if ((state != null) && (state.connectivity != null)) { if ((state.connectivity & 2) != 0) { parent.parent.mpsserver.close(parent.parent.mpsserver.ciraConnections[obj.dbNodeKey]); } // Disconnect CIRA connection
if ((state.connectivity & 1) != 0) { parent.wsagents[obj.dbNodeKey].close(); } // Disconnect mesh agent
if ((state.connectivity & 2) != 0) { parent.parent.mpsserver.close(parent.parent.mpsserver.ciraConnections[obj.dbNodeKey]); } // Disconnect CIRA connection
}
} else {
// Update the last connect time
if (obj.authenticated == 2) { db.Set({ _id: 'lc' + obj.dbNodeKey, type: 'lastconnect', domain: domain.id, time: obj.connectTime, addr: obj.remoteaddrport }); }
} }
} else {
// Update the last connect time
if (obj.authenticated == 2) { db.Set({ _id: 'lc' + obj.dbNodeKey, type: 'lastconnect', domain: domain.id, time: obj.connectTime, addr: obj.remoteaddrport }); }
} }
// If we where updating the agent, clean that up. // If we where updating the agent, clean that up.
@ -525,9 +522,15 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
if ((obj.authenticated != 1) || (obj.meshid == null) || obj.pendingCompleteAgentConnection || (obj.agentInfo == null)) { return; } if ((obj.authenticated != 1) || (obj.meshid == null) || obj.pendingCompleteAgentConnection || (obj.agentInfo == null)) { return; }
obj.pendingCompleteAgentConnection = true; obj.pendingCompleteAgentConnection = true;
// If this is a recovery agent
if (obj.agentInfo.capabilities & 0x40) { if (obj.agentInfo.capabilities & 0x40) {
// This is a recovery agent // Inform mesh agent that it's authenticated.
obj.send(common.ShortToStr(11) + common.ShortToStr(0)); // Command 11, ask for mesh core hash. delete obj.pendingCompleteAgentConnection;
obj.authenticated = 2;
obj.send(common.ShortToStr(4));
// Ask for mesh core hash.
obj.send(common.ShortToStr(11) + common.ShortToStr(0));
return; return;
} }
@ -656,6 +659,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
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 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
if (change == 1) { if (change == 1) {
// Do some clean up if needed, these values should not be in the database.
if (device.conn != null) { delete device.conn; }
if (device.pwr != null) { delete device.pwr; }
if (device.agct != null) { delete device.agct; }
if (device.cict != null) { delete device.cict; }
// Save the updated device in the database
db.Set(device); db.Set(device);
// If this is a temporary device, don't log changes // If this is a temporary device, don't log changes
@ -781,6 +791,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
return; // Probably not worth doing anything else. Hold this agent. return; // Probably not worth doing anything else. Hold this agent.
} }
// Check if this is a recovery agent
if (obj.agentInfo.capabilities & 0x40) {
recoveryAgentCoreIsStable(mesh);
return;
}
// Fetch the the real agent nodeid // Fetch the the real agent nodeid
db.Get('ra' + obj.dbNodeKey, function (err, nodes) { db.Get('ra' + obj.dbNodeKey, function (err, nodes) {
if (nodes.length == 1) { if (nodes.length == 1) {
@ -789,9 +805,6 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
} }
}); });
// Check if this is a recovery agent
if (obj.agentInfo.capabilities & 0x40) { recoveryAgentCoreIsStable(mesh); return; }
// Send Intel AMT policy // Send Intel AMT policy
if (obj.agentExeInfo && (obj.agentExeInfo.amt == true) && (mesh.amt != null)) { // Only send Intel AMT policy to agents what could have AMT. if (obj.agentExeInfo && (obj.agentExeInfo.amt == true) && (mesh.amt != null)) { // Only send Intel AMT policy to agents what could have AMT.
try { obj.send(JSON.stringify({ action: 'amtPolicy', amtPolicy: completeIntelAmtPolicy(common.Clone(mesh.amt)) })); } catch (ex) { } 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) {
// If there are changes, event the new device // If there are changes, event the new device
if (change == 1) { if (change == 1) {
// Do some clean up if needed, these values should not be in the database.
if (device.conn != null) { delete device.conn; }
if (device.pwr != null) { delete device.pwr; }
if (device.agct != null) { delete device.agct; }
if (device.cict != null) { delete device.cict; }
// Save to the database // Save to the database
db.Set(device); db.Set(device);
@ -1220,6 +1239,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
// If there are changes, save and event // If there are changes, save and event
if (change == 1) { if (change == 1) {
// Do some clean up if needed, these values should not be in the database.
if (device.conn != null) { delete device.conn; }
if (device.pwr != null) { delete device.pwr; }
if (device.agct != null) { delete device.agct; }
if (device.cict != null) { delete device.cict; }
// Save the device
db.Set(device); db.Set(device);
// Event the node change // Event the node change
@ -1244,6 +1270,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
const device = nodes[0]; const device = nodes[0];
if (device.agent) { if (device.agent) {
if (device.agent.tag != tag) { if (device.agent.tag != tag) {
// Do some clean up if needed, these values should not be in the database.
if (device.conn != null) { delete device.conn; }
if (device.pwr != null) { delete device.pwr; }
if (device.agct != null) { delete device.agct; }
if (device.cict != null) { delete device.cict; }
// Set the new tag
device.agent.tag = tag; device.agent.tag = tag;
db.Set(device); db.Set(device);

View File

@ -327,6 +327,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
db.GetAllTypeNoTypeFieldMeshFiltered(links, domain.id, 'node', command.id, function (err, docs) { db.GetAllTypeNoTypeFieldMeshFiltered(links, domain.id, 'node', command.id, function (err, docs) {
var r = {}; var r = {};
for (i in docs) { for (i in docs) {
// Remove any connectivity and power state information, that should not be in the database anyway.
// TODO: Find why these are sometimes saves in the db.
if (docs[i].conn != null) { delete docs[i].conn; }
if (docs[i].pwr != null) { delete docs[i].pwr; }
if (docs[i].agct != null) { delete docs[i].agct; }
if (docs[i].cict != null) { delete docs[i].cict; }
// Add the connection state // Add the connection state
var state = parent.parent.GetConnectivityState(docs[i]._id); var state = parent.parent.GetConnectivityState(docs[i]._id);
if (state) { if (state) {

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.3.2-b", "version": "0.3.2-c",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",