mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-11-09 13:39:42 -05:00
Mesh agents can now connect and skip server cert check to boost speed
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
37
meshagent.js
37
meshagent.js
@@ -185,6 +185,10 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
|
|
||||||
// Use our server private key to sign the ServerHash + AgentNonce + ServerNonce
|
// Use our server private key to sign the ServerHash + AgentNonce + ServerNonce
|
||||||
obj.agentnonce = msg.substring(50);
|
obj.agentnonce = msg.substring(50);
|
||||||
|
|
||||||
|
// Check if we got the agent auth confirmation
|
||||||
|
if ((obj.receivedCommands & 8) == 0) {
|
||||||
|
// If we did not get an indication that the agent already validated this server, send the server signature.
|
||||||
if (obj.useSwarmCert == true) {
|
if (obj.useSwarmCert == true) {
|
||||||
// Perform the hash signature using older swarm server certificate
|
// Perform the hash signature using older swarm server certificate
|
||||||
obj.parent.parent.certificateOperations.acceleratorPerformSignature(1, msg.substring(2) + obj.nonce, obj, function (obj2, signature) {
|
obj.parent.parent.certificateOperations.acceleratorPerformSignature(1, msg.substring(2) + obj.nonce, obj, function (obj2, signature) {
|
||||||
@@ -198,6 +202,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
obj2.send(obj2.common.ShortToStr(2) + obj.common.ShortToStr(obj2.parent.agentCertificateAsn1.length) + obj2.parent.agentCertificateAsn1 + signature); // Command 2, certificate + signature
|
obj2.send(obj2.common.ShortToStr(2) + obj.common.ShortToStr(obj2.parent.agentCertificateAsn1.length) + obj2.parent.agentCertificateAsn1 + signature); // Command 2, certificate + signature
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check the agent signature if we can
|
// Check the agent signature if we can
|
||||||
if (obj.unauthsign != null) {
|
if (obj.unauthsign != null) {
|
||||||
@@ -242,6 +247,10 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
obj.agentInfo.computerName = msg.substring(72, 72 + computerNameLen);
|
obj.agentInfo.computerName = msg.substring(72, 72 + computerNameLen);
|
||||||
obj.dbMeshKey = 'mesh/' + obj.domain.id + '/' + obj.meshid;
|
obj.dbMeshKey = 'mesh/' + obj.domain.id + '/' + obj.meshid;
|
||||||
completeAgentConnection();
|
completeAgentConnection();
|
||||||
|
} else if (cmd == 4) {
|
||||||
|
if ((msg.length < 2) || ((obj.receivedCommands & 8) != 0)) return;
|
||||||
|
obj.receivedCommands += 8; // Agent can't send the same command twice on the same connection ever. Block DOS attack path.
|
||||||
|
// Agent already authenticated the server, wants to skip the server signature - which is great for server performance.
|
||||||
} else if (cmd == 5) {
|
} else if (cmd == 5) {
|
||||||
// ServerID. Agent is telling us what serverid it expects. Useful if we have many server certificates.
|
// ServerID. Agent is telling us what serverid it expects. Useful if we have many server certificates.
|
||||||
if ((msg.substring(2, 34) == obj.parent.swarmCertificateHash256) || (msg.substring(2, 50) == obj.parent.swarmCertificateHash384)) { obj.useSwarmCert = true; }
|
if ((msg.substring(2, 34) == obj.parent.swarmCertificateHash256) || (msg.substring(2, 50) == obj.parent.swarmCertificateHash384)) { obj.useSwarmCert = true; }
|
||||||
@@ -263,13 +272,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
|
|
||||||
// Once we get all the information about an agent, run this to hook everything up to the server
|
// Once we get all the information about an agent, run this to hook everything up to the server
|
||||||
function completeAgentConnection() {
|
function completeAgentConnection() {
|
||||||
if (obj.authenticated = !1 || obj.meshid == null || obj.pendingCompleteAgentConnection) return;
|
if ((obj.authenticated != 1) || (obj.meshid == null) || obj.pendingCompleteAgentConnection) return;
|
||||||
obj.pendingCompleteAgentConnection = true;
|
obj.pendingCompleteAgentConnection = true;
|
||||||
|
|
||||||
// Check that the mesh exists
|
// Check that the mesh exists
|
||||||
obj.db.Get(obj.dbMeshKey, function (err, meshes) {
|
var mesh = obj.parent.meshes[obj.dbMeshKey];
|
||||||
if (meshes.length == 0) { console.log('Agent connected with invalid domain/mesh, holding connection (' + obj.remoteaddr + ', ' + obj.dbMeshKey + ').'); return; } // If we disconnect, the agnet will just reconnect. We need to log this or tell agent to connect in a few hours.
|
if (mesh == null) { console.log('Agent connected with invalid domain/mesh, holding connection (' + obj.remoteaddr + ', ' + obj.dbMeshKey + ').'); return; } // If we disconnect, the agnet will just reconnect. We need to log this or tell agent to connect in a few hours.
|
||||||
var mesh = meshes[0];
|
|
||||||
if (mesh.mtype != 2) { console.log('Agent connected with invalid mesh type, holding connection (' + obj.remoteaddr + ').'); return; } // If we disconnect, the agnet will just reconnect. We need to log this or tell agent to connect in a few hours.
|
if (mesh.mtype != 2) { console.log('Agent connected with invalid mesh type, holding connection (' + obj.remoteaddr + ').'); return; } // If we disconnect, the agnet will just reconnect. We need to log this or tell agent to connect in a few hours.
|
||||||
|
|
||||||
// Check that the node exists
|
// Check that the node exists
|
||||||
@@ -385,7 +393,6 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the web certificate hash for the speficied domain
|
// Get the web certificate hash for the speficied domain
|
||||||
@@ -566,9 +573,9 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
if (command.caps == null || command.caps == null) { command.caps = 0; } else { if (typeof command.caps != 'number') command.caps = 0; }
|
if (command.caps == null || command.caps == null) { command.caps = 0; } else { if (typeof command.caps != 'number') command.caps = 0; }
|
||||||
|
|
||||||
// Check that the mesh exists
|
// Check that the mesh exists
|
||||||
obj.db.Get(obj.dbMeshKey, function (err, meshes) {
|
var mesh = obj.parent.meshes[obj.dbMeshKey];
|
||||||
if (meshes.length != 1) return;
|
if (mesh == null) return;
|
||||||
var mesh = meshes[0];
|
|
||||||
// Get the node and change it if needed
|
// Get the node and change it if needed
|
||||||
obj.db.Get(obj.dbNodeKey, function (err, nodes) {
|
obj.db.Get(obj.dbNodeKey, function (err, nodes) {
|
||||||
if (nodes.length != 1) return;
|
if (nodes.length != 1) return;
|
||||||
@@ -607,20 +614,19 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the current core information string and event it
|
// Change the current core information string and event it
|
||||||
function ChangeAgentLocationInfo(command) {
|
function ChangeAgentLocationInfo(command) {
|
||||||
if ((command == null) || (command == null)) return; // Safety, should never happen.
|
if ((command == null) || (command == null)) { return; } // Safety, should never happen.
|
||||||
|
|
||||||
// Check that the mesh exists
|
// Check that the mesh exists
|
||||||
obj.db.Get(obj.dbMeshKey, function (err, meshes) {
|
var mesh = obj.parent.meshes[obj.dbMeshKey];
|
||||||
if (meshes.length != 1) return;
|
if (mesh == null) return;
|
||||||
var mesh = meshes[0];
|
|
||||||
// Get the node and change it if needed
|
// Get the node and change it if needed
|
||||||
obj.db.Get(obj.dbNodeKey, function (err, nodes) {
|
obj.db.Get(obj.dbNodeKey, function (err, nodes) {
|
||||||
if (nodes.length != 1) return;
|
if (nodes.length != 1) { return; }
|
||||||
var device = nodes[0];
|
var device = nodes[0];
|
||||||
if (device.agent) {
|
if (device.agent) {
|
||||||
var changes = [], change = 0;
|
var changes = [], change = 0;
|
||||||
@@ -637,13 +643,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
var event = { etype: 'node', action: 'changenode', nodeid: obj.dbNodeKey, domain: domain.id, msg: 'Changed device ' + device.name + ' from mesh ' + mesh.name + ': ' + changes.join(', ') };
|
var event = { etype: 'node', action: 'changenode', nodeid: obj.dbNodeKey, domain: domain.id, msg: 'Changed device ' + device.name + ' from mesh ' + mesh.name + ': ' + changes.join(', ') };
|
||||||
if (obj.agentInfo.capabilities & 0x20) { event.nolog = 1; } // If this is a temporary device, don't log changes
|
if (obj.agentInfo.capabilities & 0x20) { event.nolog = 1; } // If this is a temporary device, don't log changes
|
||||||
var device2 = obj.common.Clone(device);
|
var device2 = obj.common.Clone(device);
|
||||||
if (device2.intelamt && device2.intelamt.pass) delete device2.intelamt.pass; // Remove the Intel AMT password before eventing this.
|
if (device2.intelamt && device2.intelamt.pass) { delete device2.intelamt.pass; } // Remove the Intel AMT password before eventing this.
|
||||||
event.node = device;
|
event.node = device;
|
||||||
obj.parent.parent.DispatchEvent(['*', device.meshid], obj, event);
|
obj.parent.parent.DispatchEvent(['*', device.meshid], obj, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the mesh agent tab in the database
|
// Update the mesh agent tab in the database
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "meshcentral",
|
"name": "meshcentral",
|
||||||
"version": "0.1.9-j",
|
"version": "0.1.9-k",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Remote Management",
|
"Remote Management",
|
||||||
"Intel AMT",
|
"Intel AMT",
|
||||||
|
|||||||
16
webserver.js
16
webserver.js
@@ -1468,10 +1468,9 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
res.sendFile(argentInfo.path);
|
res.sendFile(argentInfo.path);
|
||||||
} else {
|
} else {
|
||||||
// We are going to embed the .msh file into the Windows executable (signed or not).
|
// We are going to embed the .msh file into the Windows executable (signed or not).
|
||||||
// First, query the meshid to build the .msh file
|
// First, fetch the mesh object to build the .msh file
|
||||||
obj.db.Get('mesh/' + domain.id + '/' + req.query.meshid, function (err, meshes) {
|
var mesh = obj.meshes['mesh/' + domain.id + '/' + req.query.meshid];
|
||||||
if (meshes.length != 1) { res.sendStatus(401); return; }
|
if (mesh == null) { res.sendStatus(401); return; }
|
||||||
var mesh = meshes[0];
|
|
||||||
|
|
||||||
// If required, check if this user has rights to do this
|
// If required, check if this user has rights to do this
|
||||||
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true)) {
|
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true)) {
|
||||||
@@ -1493,7 +1492,6 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
if (req.query.tag != null) { meshsettings += "Tag=" + req.query.tag + "\r\n"; }
|
if (req.query.tag != null) { meshsettings += "Tag=" + req.query.tag + "\r\n"; }
|
||||||
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=' + argentInfo.rname });
|
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=' + argentInfo.rname });
|
||||||
obj.parent.exeHandler.streamExeWithMeshPolicy({ platform: 'win32', sourceFileName: obj.parent.meshAgentBinaries[req.query.id].path, destinationStream: res, msh: meshsettings, peinfo: obj.parent.meshAgentBinaries[req.query.id].pe });
|
obj.parent.exeHandler.streamExeWithMeshPolicy({ platform: 'win32', sourceFileName: obj.parent.meshAgentBinaries[req.query.id].path, destinationStream: res, msh: meshsettings, peinfo: obj.parent.meshAgentBinaries[req.query.id].pe });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else if (req.query.script != null) {
|
} else if (req.query.script != null) {
|
||||||
// Send a specific mesh install script back
|
// Send a specific mesh install script back
|
||||||
@@ -1602,10 +1600,9 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
// If required, check if this user has rights to do this
|
// If required, check if this user has rights to do this
|
||||||
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true) && (req.session.userid == null)) { res.sendStatus(401); return; }
|
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true) && (req.session.userid == null)) { res.sendStatus(401); return; }
|
||||||
|
|
||||||
// Query the meshid
|
// Fetch the mesh object
|
||||||
obj.db.Get('mesh/' + domain.id + '/' + req.query.id, function (err, meshes) {
|
var mesh = obj.meshes['mesh/' + domain.id + '/' + req.query.id];
|
||||||
if (meshes.length != 1) { res.sendStatus(401); return; }
|
if (mesh == null) { res.sendStatus(401); return; }
|
||||||
var mesh = meshes[0];
|
|
||||||
|
|
||||||
// If needed, check if this user has rights to do this
|
// If needed, check if this user has rights to do this
|
||||||
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true)) {
|
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true)) {
|
||||||
@@ -1627,7 +1624,6 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
|
|
||||||
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=meshagent.msh' });
|
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=meshagent.msh' });
|
||||||
res.send(meshsettings);
|
res.send(meshsettings);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add HTTP security headers to all responses
|
// Add HTTP security headers to all responses
|
||||||
|
|||||||
Reference in New Issue
Block a user