Mesh agents can now connect and skip server cert check to boost speed
This commit is contained in:
parent
d3db0e4ef6
commit
82801f4069
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
|
||||||
|
|
Loading…
Reference in New Issue