mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-24 22:25:52 -05:00
Base64 encoding of meshid/nodeid in the database.
This commit is contained in:
parent
1952d75860
commit
ace4046415
@ -179,7 +179,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
obj.unauth = {};
|
obj.unauth = {};
|
||||||
obj.unauth.nodeCert = null;
|
obj.unauth.nodeCert = null;
|
||||||
try { obj.unauth.nodeCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))); } catch (e) { return; }
|
try { obj.unauth.nodeCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))); } catch (e) { return; }
|
||||||
obj.unauth.nodeid = obj.forge.pki.getPublicKeyFingerprint(obj.unauth.nodeCert.publicKey, { encoding: 'hex', md: obj.forge.md.sha384.create() });
|
obj.unauth.nodeid = new Buffer(obj.forge.pki.getPublicKeyFingerprint(obj.unauth.nodeCert.publicKey, { md: obj.forge.md.sha384.create() }).data, 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||||
|
|
||||||
// Check the agent signature if we can
|
// Check the agent signature if we can
|
||||||
if (obj.agentnonce == null) { obj.unauthsign = msg.substring(4 + certlen); } else { if (processAgentSignature(msg.substring(4 + certlen)) == false) { console.log('Bad Agent Signature'); obj.close(); return; } }
|
if (obj.agentnonce == null) { obj.unauthsign = msg.substring(4 + certlen); } else { if (processAgentSignature(msg.substring(4 + certlen)) == false) { console.log('Bad Agent Signature'); obj.close(); return; } }
|
||||||
@ -196,7 +196,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
obj.agentInfo.agentId = obj.common.ReadInt(msg, 6);
|
obj.agentInfo.agentId = obj.common.ReadInt(msg, 6);
|
||||||
obj.agentInfo.agentVersion = obj.common.ReadInt(msg, 10);
|
obj.agentInfo.agentVersion = obj.common.ReadInt(msg, 10);
|
||||||
obj.agentInfo.platformType = obj.common.ReadInt(msg, 14);
|
obj.agentInfo.platformType = obj.common.ReadInt(msg, 14);
|
||||||
obj.meshid = obj.common.rstr2hex(msg.substring(18, 66)).toUpperCase();
|
obj.meshid = new Buffer(msg.substring(18, 66), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');;
|
||||||
obj.agentInfo.capabilities = obj.common.ReadInt(msg, 66);
|
obj.agentInfo.capabilities = obj.common.ReadInt(msg, 66);
|
||||||
var computerNameLen = obj.common.ReadShort(msg, 70);
|
var computerNameLen = obj.common.ReadShort(msg, 70);
|
||||||
obj.agentInfo.computerName = msg.substring(72, 72 + computerNameLen);
|
obj.agentInfo.computerName = msg.substring(72, 72 + computerNameLen);
|
||||||
@ -339,7 +339,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
if (obj.unauth.nodeCert.publicKey.verify(md.digest().bytes(), msg) == false) { return false; }
|
if (obj.unauth.nodeCert.publicKey.verify(md.digest().bytes(), msg) == false) { return false; }
|
||||||
|
|
||||||
// Connection is a success, clean up
|
// Connection is a success, clean up
|
||||||
obj.nodeid = obj.unauth.nodeid.toUpperCase();
|
obj.nodeid = obj.unauth.nodeid;
|
||||||
obj.dbNodeKey = 'node/' + domain.id + '/' + obj.nodeid;
|
obj.dbNodeKey = 'node/' + domain.id + '/' + obj.nodeid;
|
||||||
delete obj.nonce;
|
delete obj.nonce;
|
||||||
delete obj.agentnonce;
|
delete obj.agentnonce;
|
||||||
|
@ -270,11 +270,11 @@ function CreateMeshCentralServer() {
|
|||||||
while (obj.dbconfig.amtWsEventSecret == null) { process.nextTick(); }
|
while (obj.dbconfig.amtWsEventSecret == null) { process.nextTick(); }
|
||||||
var username = buf.toString('hex');
|
var username = buf.toString('hex');
|
||||||
var nodeid = obj.args.getwspass;
|
var nodeid = obj.args.getwspass;
|
||||||
var pass = require('crypto').createHash('sha384').update(username.toLowerCase() + ":" + nodeid.toUpperCase() + ":" + obj.dbconfig.amtWsEventSecret).digest("base64").substring(0, 12).split("/").join("x").split("\\").join("x");
|
var pass = require('crypto').createHash('sha384').update(username.toLowerCase() + ":" + nodeid + ":" + obj.dbconfig.amtWsEventSecret).digest("base64").substring(0, 12).split("/").join("x").split("\\").join("x");
|
||||||
console.log('--- Intel(r) AMT WSMAN eventing credentials ---');
|
console.log('--- Intel(r) AMT WSMAN eventing credentials ---');
|
||||||
console.log('Username: ' + username);
|
console.log('Username: ' + username);
|
||||||
console.log('Password: ' + pass);
|
console.log('Password: ' + pass);
|
||||||
console.log('Argument: ' + nodeid.toLowerCase());
|
console.log('Argument: ' + nodeid);
|
||||||
process.exit();
|
process.exit();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,15 +4,6 @@
|
|||||||
* @version v0.0.1
|
* @version v0.0.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Construct a MeshRelay object, called upon connection
|
|
||||||
module.exports.CreateMeshRelayKey = function (parent, func) {
|
|
||||||
parent.crypto.randomBytes(48, function (err, buf) {
|
|
||||||
var key = buf.toString('hex').toUpperCase() + ':' + Date.now();
|
|
||||||
key += ':' + parent.crypto.createHmac('SHA384', parent.relayRandom).update(key).digest('hex');
|
|
||||||
func(key);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.CreateMeshRelay = function (parent, ws, req) {
|
module.exports.CreateMeshRelay = function (parent, ws, req) {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.ws = ws;
|
obj.ws = ws;
|
||||||
|
@ -17,7 +17,7 @@ module.exports.CreateMeshScanner = function (parent) {
|
|||||||
var periodicScanTime = (60000 * 20); // Interval between scans, 20 minutes.
|
var periodicScanTime = (60000 * 20); // Interval between scans, 20 minutes.
|
||||||
var membershipIPv4 = '239.255.255.235';
|
var membershipIPv4 = '239.255.255.235';
|
||||||
var membershipIPv6 = 'FF02:0:0:0:0:0:0:FE';
|
var membershipIPv6 = 'FF02:0:0:0:0:0:0:FE';
|
||||||
obj.agentCertificatHashHex = parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(parent.certificates.agent.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'hex' });
|
obj.agentCertificatHashHex = parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(parent.certificates.agent.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'hex' }).toUpperCase();
|
||||||
obj.error = 0;
|
obj.error = 0;
|
||||||
|
|
||||||
// Get a list of IPv4 and IPv6 interface addresses
|
// Get a list of IPv4 and IPv6 interface addresses
|
||||||
@ -119,9 +119,9 @@ module.exports.CreateMeshScanner = function (parent) {
|
|||||||
obj.start = function () {
|
obj.start = function () {
|
||||||
if (obj.server4 != null) return;
|
if (obj.server4 != null) return;
|
||||||
var url = (parent.args.notls ? 'ws' : 'wss') + '://%s:' + parent.args.port + '/agent.ashx';
|
var url = (parent.args.notls ? 'ws' : 'wss') + '://%s:' + parent.args.port + '/agent.ashx';
|
||||||
obj.multicastPacket4 = Buffer.from("MeshCentral2|" + obj.agentCertificatHashHex.toUpperCase() + '|' + url, 'ascii');
|
obj.multicastPacket4 = Buffer.from("MeshCentral2|" + obj.agentCertificatHashHex + '|' + url, 'ascii');
|
||||||
url = (parent.args.notls ? 'ws' : 'wss') + '://[%s]:' + parent.args.port + '/agent.ashx';
|
url = (parent.args.notls ? 'ws' : 'wss') + '://[%s]:' + parent.args.port + '/agent.ashx';
|
||||||
obj.multicastPacket6 = Buffer.from("MeshCentral2|" + obj.agentCertificatHashHex.toUpperCase() + '|' + url, 'ascii');
|
obj.multicastPacket6 = Buffer.from("MeshCentral2|" + obj.agentCertificatHashHex + '|' + url, 'ascii');
|
||||||
setupServers();
|
setupServers();
|
||||||
obj.mainTimer = setInterval(obj.performScan, periodicScanTime);
|
obj.mainTimer = setInterval(obj.performScan, periodicScanTime);
|
||||||
return obj;
|
return obj;
|
||||||
@ -150,7 +150,7 @@ module.exports.CreateMeshScanner = function (parent) {
|
|||||||
// Called when a UDP packet is received from an agent.
|
// Called when a UDP packet is received from an agent.
|
||||||
function onUdpPacket(msg, info, server) {
|
function onUdpPacket(msg, info, server) {
|
||||||
//console.log('Received ' + msg.length + ' bytes from ' + info.address + ':' + info.port + ', on interface: ' + server.xxlocal + '.');
|
//console.log('Received ' + msg.length + ' bytes from ' + info.address + ':' + info.port + ', on interface: ' + server.xxlocal + '.');
|
||||||
if ((msg.length == 64) && (msg.toString('ascii') == obj.agentCertificatHashHex.toUpperCase())) {
|
if ((msg.length == 64) && (msg.toString('ascii') == obj.agentCertificatHashHex)) {
|
||||||
if (server.xxtype == 4) { try { server.send(obj.multicastPacket4, 0, obj.multicastPacket4.length, info.port, info.address); } catch (e) { } }
|
if (server.xxtype == 4) { try { server.send(obj.multicastPacket4, 0, obj.multicastPacket4.length, info.port, info.address); } catch (e) { } }
|
||||||
if (server.xxtype == 6) { try { server.send(obj.multicastPacket6, 0, obj.multicastPacket6.length, info.port, info.address); } catch (e) { } }
|
if (server.xxtype == 6) { try { server.send(obj.multicastPacket6, 0, obj.multicastPacket6.length, info.port, info.address); } catch (e) { } }
|
||||||
}
|
}
|
||||||
|
16
mpsserver.js
16
mpsserver.js
@ -108,11 +108,11 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
|
|||||||
// This is a node where the MeshID is indicated within the CIRA certificate
|
// This is a node where the MeshID is indicated within the CIRA certificate
|
||||||
var domainid = '', meshid;
|
var domainid = '', meshid;
|
||||||
var xx = socket.tag.clientCert.subject.O.split('/');
|
var xx = socket.tag.clientCert.subject.O.split('/');
|
||||||
if (xx.length == 1) { meshid = xx[0].toUpperCase(); } else { domainid = xx[0].toLowerCase(); meshid = xx[1].toUpperCase(); }
|
if (xx.length == 1) { meshid = xx[0]; } else { domainid = xx[0].toLowerCase(); meshid = xx[1]; }
|
||||||
|
|
||||||
socket.tag.domainid = domainid;
|
socket.tag.domainid = domainid;
|
||||||
socket.tag.meshid = 'mesh/' + domainid + '/' + meshid;
|
socket.tag.meshid = 'mesh/' + domainid + '/' + meshid;
|
||||||
socket.tag.nodeid = 'node/' + domainid + '/' + require('crypto').createHash('sha384').update(common.hex2rstr(socket.tag.clientCert.modulus, 'binary')).digest('hex').toUpperCase();
|
socket.tag.nodeid = 'node/' + domainid + '/' + require('crypto').createHash('sha384').update(common.hex2rstr(socket.tag.clientCert.modulus, 'binary')).digest('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||||
socket.tag.name = socket.tag.clientCert.subject.CN;
|
socket.tag.name = socket.tag.clientCert.subject.CN;
|
||||||
socket.tag.connectTime = Date.now();
|
socket.tag.connectTime = Date.now();
|
||||||
socket.tag.host = '';
|
socket.tag.host = '';
|
||||||
@ -216,19 +216,19 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
|
|||||||
// Check the CIRA password
|
// Check the CIRA password
|
||||||
if ((args.mpspass != undefined) && (password != args.mpspass)) { Debug(1, 'MPS:Incorrect password', username, password); SendUserAuthFail(socket); return -1; }
|
if ((args.mpspass != undefined) && (password != args.mpspass)) { Debug(1, 'MPS:Incorrect password', username, password); SendUserAuthFail(socket); return -1; }
|
||||||
|
|
||||||
// Check the CIRA username, which should be the HEX start of the MeshID.
|
// Check the CIRA username, which should be the start of the MeshID.
|
||||||
if (usernameLen != 16) { SendUserAuthFail(socket); return -1; }
|
if (usernameLen != 16) { Debug(1, 'MPS:Username length not 16', username, password); SendUserAuthFail(socket); return -1; }
|
||||||
var meshIdStart = '/' + username;
|
var meshIdStart = '/' + username;
|
||||||
meshIdStart = meshIdStart.toUpperCase();
|
|
||||||
obj.db.GetAllType('mesh', function (err, docs) {
|
obj.db.GetAllType('mesh', function (err, docs) {
|
||||||
var mesh = null;
|
var mesh = null;
|
||||||
for (var i in docs) { if (docs[i]._id.indexOf(meshIdStart) > 0) { mesh = docs[i]; break; } }
|
for (var i in docs) { if (docs[i]._id.indexOf(meshIdStart) > 0) { mesh = docs[i]; break; } }
|
||||||
if (mesh == null) { SendUserAuthFail(socket); return -1; }
|
if (mesh == null) { Debug(1, 'MPS:Mesh not found', username, password);SendUserAuthFail(socket); return -1; }
|
||||||
|
|
||||||
// Intel AMT GUID (socket.tag.SystemId) will be used at NodeID
|
// Intel AMT GUID (socket.tag.SystemId) will be used at NodeID
|
||||||
var systemid = socket.tag.SystemId.split('-').join('').toUpperCase();
|
var systemid = socket.tag.SystemId.split('-').join('');
|
||||||
|
var nodeid = new Buffer(systemid + systemid + systemid, 'hex').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||||
socket.tag.name = '';
|
socket.tag.name = '';
|
||||||
socket.tag.nodeid = 'node/' + mesh.domain + '/' + systemid + systemid + systemid; // Turn 16bit systemid guid into 48bit nodeid
|
socket.tag.nodeid = 'node/' + mesh.domain + '/' + nodeid; // Turn 16bit systemid guid into 48bit nodeid that is base64 encoded
|
||||||
socket.tag.meshid = mesh._id;
|
socket.tag.meshid = mesh._id;
|
||||||
|
|
||||||
obj.db.Get(socket.tag.nodeid, function (err, nodes) {
|
obj.db.Get(socket.tag.nodeid, function (err, nodes) {
|
||||||
|
@ -33,7 +33,7 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
obj.retryBackoff = 0;
|
obj.retryBackoff = 0;
|
||||||
obj.connectHandler = null;
|
obj.connectHandler = null;
|
||||||
obj.webCertificatHash = obj.parent.parent.webserver.webCertificatHash;
|
obj.webCertificatHash = obj.parent.parent.webserver.webCertificatHash;
|
||||||
obj.agentCertificatHashHex = obj.parent.parent.webserver.agentCertificatHashHex;
|
obj.agentCertificatHashBase64 = obj.parent.parent.webserver.agentCertificatHashBase64;
|
||||||
obj.agentCertificatAsn1 = obj.parent.parent.webserver.agentCertificatAsn1;
|
obj.agentCertificatAsn1 = obj.parent.parent.webserver.agentCertificatAsn1;
|
||||||
obj.peerServerId = null;
|
obj.peerServerId = null;
|
||||||
obj.authenticated = 0;
|
obj.authenticated = 0;
|
||||||
@ -108,8 +108,8 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
var certlen = obj.common.ReadShort(msg, 2), serverCert = null;
|
var certlen = obj.common.ReadShort(msg, 2), serverCert = null;
|
||||||
try { serverCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))); } catch (e) { }
|
try { serverCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))); } catch (e) { }
|
||||||
if (serverCert == null) { obj.parent.parent.debug(1, 'OutPeer: Invalid server certificate.'); disconnect(); return; }
|
if (serverCert == null) { obj.parent.parent.debug(1, 'OutPeer: Invalid server certificate.'); disconnect(); return; }
|
||||||
var serverid = obj.forge.pki.getPublicKeyFingerprint(serverCert.publicKey, { encoding: 'hex', md: obj.forge.md.sha384.create() });
|
var serverid = new Buffer(obj.forge.pki.getPublicKeyFingerprint(serverCert.publicKey, { encoding: 'binary', md: obj.forge.md.sha384.create() }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||||
if (serverid !== obj.agentCertificatHashHex) { obj.parent.parent.debug(1, 'OutPeer: Server hash mismatch.'); disconnect(); return; }
|
if (serverid !== obj.agentCertificatHashBase64) { obj.parent.parent.debug(1, 'OutPeer: Server hash mismatch.'); disconnect(); return; }
|
||||||
|
|
||||||
// Server signature, verify it
|
// Server signature, verify it
|
||||||
var md = obj.forge.md.sha384.create();
|
var md = obj.forge.md.sha384.create();
|
||||||
@ -121,20 +121,20 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
// Connection is a success, clean up
|
// Connection is a success, clean up
|
||||||
delete obj.nonce;
|
delete obj.nonce;
|
||||||
delete obj.servernonce;
|
delete obj.servernonce;
|
||||||
obj.serverCertHash = obj.common.rstr2hex(obj.serverCertHash).toLowerCase(); // Change this value to hex
|
obj.serverCertHash = new Buffer(obj.serverCertHash, 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'); // Change this value to base64
|
||||||
obj.connectionState |= 4;
|
obj.connectionState |= 4;
|
||||||
obj.retryBackoff = 0; // Set backoff connection timer back to fast.
|
obj.retryBackoff = 0; // Set backoff connection timer back to fast.
|
||||||
obj.parent.parent.debug(1, 'OutPeer ' + obj.serverid + ': Verified peer connection to ' + obj.url);
|
obj.parent.parent.debug(1, 'OutPeer ' + obj.serverid + ': Verified peer connection to ' + obj.url);
|
||||||
|
|
||||||
// Send information about our server to the peer
|
// Send information about our server to the peer
|
||||||
if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificatHashHex })); }
|
if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificatHashBase64 })); }
|
||||||
//if ((obj.connectionState == 15) && (obj.connectHandler != null)) { obj.connectHandler(1); }
|
//if ((obj.connectionState == 15) && (obj.connectHandler != null)) { obj.connectHandler(1); }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4: {
|
case 4: {
|
||||||
// Server confirmed authentication, we are allowed to send commands to the server
|
// Server confirmed authentication, we are allowed to send commands to the server
|
||||||
obj.connectionState |= 8;
|
obj.connectionState |= 8;
|
||||||
if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificatHashHex })); }
|
if (obj.connectionState == 15) { obj.ws.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificatHashBase64 })); }
|
||||||
//if ((obj.connectionState == 15) && (obj.connectHandler != null)) { obj.connectHandler(1); }
|
//if ((obj.connectionState == 15) && (obj.connectHandler != null)) { obj.connectHandler(1); }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
if ((command.serverid != null) && (command.dbid != null)) {
|
if ((command.serverid != null) && (command.dbid != null)) {
|
||||||
if (command.serverid == obj.parent.serverid) { console.log('ERROR: Same server ID, trying to peer with self. (' + obj.url + ', ' + command.serverid + ').'); return; }
|
if (command.serverid == obj.parent.serverid) { console.log('ERROR: Same server ID, trying to peer with self. (' + obj.url + ', ' + command.serverid + ').'); return; }
|
||||||
if (command.dbid != obj.parent.parent.db.identifier) { console.log('ERROR: Database ID mismatch. Trying to peer to a server with the wrong database. (' + obj.url + ', ' + command.serverid + ').'); return; }
|
if (command.dbid != obj.parent.parent.db.identifier) { console.log('ERROR: Database ID mismatch. Trying to peer to a server with the wrong database. (' + obj.url + ', ' + command.serverid + ').'); return; }
|
||||||
if (obj.serverCertHash != command.serverCertHash) { console.log('ERROR: Outer certificate hash mismatch. (' + obj.url + ', ' + command.serverid + ').'); return; }
|
if (obj.serverCertHash != command.serverCertHash) { console.log('ERROR: Outer certificate hash mismatch (2). (' + obj.url + ', ' + command.serverid + ').'); return; }
|
||||||
obj.peerServerId = command.serverid;
|
obj.peerServerId = command.serverid;
|
||||||
obj.peerServerKey = new Buffer(command.key, 'hex');
|
obj.peerServerKey = new Buffer(command.key, 'hex');
|
||||||
obj.authenticated = 3;
|
obj.authenticated = 3;
|
||||||
@ -213,7 +213,7 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
obj.remoteaddr = obj.ws._socket.remoteAddress;
|
obj.remoteaddr = obj.ws._socket.remoteAddress;
|
||||||
obj.receivedCommands = 0;
|
obj.receivedCommands = 0;
|
||||||
obj.webCertificatHash = obj.parent.parent.webserver.webCertificatHash;
|
obj.webCertificatHash = obj.parent.parent.webserver.webCertificatHash;
|
||||||
obj.agentCertificatHashHex = obj.parent.parent.webserver.agentCertificatHashHex;
|
obj.agentCertificatHashBase64 = obj.parent.parent.webserver.agentCertificatHashBase64;
|
||||||
obj.agentCertificatAsn1 = obj.parent.parent.webserver.agentCertificatAsn1;
|
obj.agentCertificatAsn1 = obj.parent.parent.webserver.agentCertificatAsn1;
|
||||||
obj.infoSent = 0;
|
obj.infoSent = 0;
|
||||||
obj.peerServerId = null;
|
obj.peerServerId = null;
|
||||||
@ -283,10 +283,10 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
obj.unauth = {};
|
obj.unauth = {};
|
||||||
obj.unauth.nodeCert = null;
|
obj.unauth.nodeCert = null;
|
||||||
try { obj.unauth.nodeCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))); } catch (e) { return; }
|
try { obj.unauth.nodeCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))); } catch (e) { return; }
|
||||||
obj.unauth.nodeid = obj.forge.pki.getPublicKeyFingerprint(obj.unauth.nodeCert.publicKey, { encoding: 'hex', md: obj.forge.md.sha384.create() });
|
obj.unauth.nodeid = new Buffer(obj.forge.pki.getPublicKeyFingerprint(obj.unauth.nodeCert.publicKey, { encoding: 'binary', md: obj.forge.md.sha384.create() }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||||
|
|
||||||
// Check the peer server signature if we can
|
// Check the peer server signature if we can
|
||||||
if (obj.peernonce == null) { obj.unauthsign = msg.substring(4 + certlen); } else { if (processPeerSignature(msg.substring(4 + certlen)) == false) { disconnect(); return; } }
|
if (obj.peernonce == null) { obj.unauthsign = msg.substring(4 + certlen); } else { if (processPeerSignature(msg.substring(4 + certlen)) == false) { obj.close(); return; } }
|
||||||
completePeerServerConnection();
|
completePeerServerConnection();
|
||||||
}
|
}
|
||||||
else if (cmd == 3) {
|
else if (cmd == 3) {
|
||||||
@ -313,7 +313,7 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
function completePeerServerConnection() {
|
function completePeerServerConnection() {
|
||||||
if (obj.authenticated != 1) return;
|
if (obj.authenticated != 1) return;
|
||||||
obj.send(obj.common.ShortToStr(4));
|
obj.send(obj.common.ShortToStr(4));
|
||||||
obj.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificatHashHex }));
|
obj.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey.toString('hex'), serverCertHash: obj.parent.parent.webserver.webCertificatHashBase64 }));
|
||||||
obj.authenticated = 2;
|
obj.authenticated = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,10 +324,10 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
md.update(obj.nonce, 'binary');
|
md.update(obj.nonce, 'binary');
|
||||||
md.update(obj.peernonce, 'binary');
|
md.update(obj.peernonce, 'binary');
|
||||||
if (obj.unauth.nodeCert.publicKey.verify(md.digest().bytes(), msg) == false) { return false; }
|
if (obj.unauth.nodeCert.publicKey.verify(md.digest().bytes(), msg) == false) { return false; }
|
||||||
if (obj.unauth.nodeid !== obj.agentCertificatHashHex) { return false; }
|
if (obj.unauth.nodeid !== obj.agentCertificatHashBase64) { return false; }
|
||||||
|
|
||||||
// Connection is a success, clean up
|
// Connection is a success, clean up
|
||||||
obj.nodeid = obj.unauth.nodeid.toUpperCase();
|
obj.nodeid = obj.unauth.nodeid;
|
||||||
delete obj.nonce;
|
delete obj.nonce;
|
||||||
delete obj.peernonce;
|
delete obj.peernonce;
|
||||||
delete obj.unauth;
|
delete obj.unauth;
|
||||||
@ -396,7 +396,7 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
obj.decodeCookie = function (cookie, key) {
|
obj.decodeCookie = function (cookie, key) {
|
||||||
try {
|
try {
|
||||||
if (key == null) { key = obj.serverKey; }
|
if (key == null) { key = obj.serverKey; }
|
||||||
cookie = new Buffer(cookie.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64'); // HEX: This is not an efficient split, but it's very compatible.
|
cookie = new Buffer(cookie.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64');
|
||||||
var decipher = obj.crypto.createDecipheriv('aes-256-gcm', key, cookie.slice(0, 12));
|
var decipher = obj.crypto.createDecipheriv('aes-256-gcm', key, cookie.slice(0, 12));
|
||||||
decipher.setAuthTag(cookie.slice(12, 16));
|
decipher.setAuthTag(cookie.slice(12, 16));
|
||||||
var o = JSON.parse(decipher.update(cookie.slice(28), 'binary', 'utf8') + decipher.final('utf8'));
|
var o = JSON.parse(decipher.update(cookie.slice(28), 'binary', 'utf8') + decipher.final('utf8'));
|
||||||
@ -612,7 +612,7 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
peerTunnel.ws2.on('error', function (error) { peerTunnel.parent.parent.debug(1, 'FTunnel ' + obj.serverid + ': Connection error'); peerTunnel.close(); });
|
peerTunnel.ws2.on('error', function (error) { peerTunnel.parent.parent.debug(1, 'FTunnel ' + obj.serverid + ': Connection error'); peerTunnel.close(); });
|
||||||
|
|
||||||
// If the peer server web socket is closed, clean up.
|
// If the peer server web socket is closed, clean up.
|
||||||
peerTunnel.ws2.on('close', function (req) { peerTunnel.parent.parent.debug(1, 'FTunnel disconnect ' + peerTunnel.nodeid); peerTunnel.close(); });
|
peerTunnel.ws2.on('close', function (req) { peerTunnel.parent.parent.debug(1, 'FTunnel disconnect ' + peerTunnel.serverid); peerTunnel.close(); });
|
||||||
|
|
||||||
// If a message is received from the peer, Peer ---> Browser (TODO: Pipe this?)
|
// If a message is received from the peer, Peer ---> Browser (TODO: Pipe this?)
|
||||||
peerTunnel.ws2.on('message', function (msg) { try { peerTunnel.ws2.pause(); peerTunnel.ws1.send(msg, function () { peerTunnel.ws2.resume(); }); } catch (e) { } });
|
peerTunnel.ws2.on('message', function (msg) { try { peerTunnel.ws2.pause(); peerTunnel.ws1.send(msg, function () { peerTunnel.ws2.resume(); }); } catch (e) { } });
|
||||||
@ -623,10 +623,10 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
|
|
||||||
// Get the peer server's certificate and compute the server public key hash
|
// Get the peer server's certificate and compute the server public key hash
|
||||||
var serverCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(peerTunnel.ws2._socket.getPeerCertificate().raw.toString('binary')));
|
var serverCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(peerTunnel.ws2._socket.getPeerCertificate().raw.toString('binary')));
|
||||||
var serverCertHashHex = obj.forge.pki.getPublicKeyFingerprint(serverCert.publicKey, { encoding: 'hex', md: obj.forge.md.sha384.create() });
|
var serverCertHashHex = new Buffer(obj.forge.pki.getPublicKeyFingerprint(serverCert.publicKey, { encoding: 'binary', md: obj.forge.md.sha384.create() }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||||
|
|
||||||
// Check if the peer certificate is the expected one for this serverid
|
// Check if the peer certificate is the expected one for this serverid
|
||||||
if (obj.peerServers[serverid] == null || obj.peerServers[serverid].serverCertHash != serverCertHashHex) { console.log('ERROR: Outer certificate hash mismatch. (' + peerTunnel.url + ', ' + peerTunnel.serverid + ').'); peerTunnel.close(); return; }
|
if (obj.peerServers[serverid] == null || obj.peerServers[serverid].serverCertHash != serverCertHashHex) { console.log('ERROR: Outer certificate hash mismatch (1). (' + peerTunnel.url + ', ' + peerTunnel.serverid + ').'); peerTunnel.close(); return; }
|
||||||
|
|
||||||
// Connection accepted, resume the web socket to start the data flow
|
// Connection accepted, resume the web socket to start the data flow
|
||||||
peerTunnel.ws1.resume();
|
peerTunnel.ws1.resume();
|
||||||
@ -639,7 +639,7 @@ module.exports.CreateMultiServer = function (parent, args) {
|
|||||||
peerTunnel.ws1.on('error', function (err) { peerTunnel.close(); });
|
peerTunnel.ws1.on('error', function (err) { peerTunnel.close(); });
|
||||||
|
|
||||||
// If the web socket is closed, close the associated TCP connection.
|
// If the web socket is closed, close the associated TCP connection.
|
||||||
peerTunnel.ws1.on('close', function (req) { peerTunnel.parent.parent.debug(1, 'FTunnel disconnect ' + peerTunnel.nodeid); peerTunnel.close(); });
|
peerTunnel.ws1.on('close', function (req) { peerTunnel.parent.parent.debug(1, 'FTunnel disconnect ' + peerTunnel.serverid); peerTunnel.close(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect both sides of the tunnel
|
// Disconnect both sides of the tunnel
|
||||||
|
32
webserver.js
32
webserver.js
@ -70,8 +70,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
|
|
||||||
// Perform hash on web certificate and agent certificate
|
// Perform hash on web certificate and agent certificate
|
||||||
obj.webCertificatHash = parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.web.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'binary' });
|
obj.webCertificatHash = parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.web.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'binary' });
|
||||||
obj.webCertificatHashHex = parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.web.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'hex' });
|
obj.webCertificatHashBase64 = new Buffer(parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.web.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'binary' }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||||
obj.agentCertificatHashHex = parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.agent.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'hex' });
|
obj.agentCertificatHashBase64 = new Buffer(parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.agent.cert).publicKey, { md: parent.certificateOperations.forge.md.sha384.create(), encoding: 'binary' }), 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||||
obj.agentCertificatAsn1 = parent.certificateOperations.forge.asn1.toDer(parent.certificateOperations.forge.pki.certificateToAsn1(parent.certificateOperations.forge.pki.certificateFromPem(parent.certificates.agent.cert))).getBytes();
|
obj.agentCertificatAsn1 = parent.certificateOperations.forge.asn1.toDer(parent.certificateOperations.forge.pki.certificateToAsn1(parent.certificateOperations.forge.pki.certificateFromPem(parent.certificates.agent.cert))).getBytes();
|
||||||
|
|
||||||
// Main lists
|
// Main lists
|
||||||
@ -1294,7 +1294,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
if ((command.meshtype == 1) || (command.meshtype == 2)) {
|
if ((command.meshtype == 1) || (command.meshtype == 2)) {
|
||||||
// Create a type 1 agent-less Intel AMT mesh.
|
// Create a type 1 agent-less Intel AMT mesh.
|
||||||
obj.crypto.randomBytes(48, function (err, buf) {
|
obj.crypto.randomBytes(48, function (err, buf) {
|
||||||
var meshid = 'mesh/' + domain.id + '/' + buf.toString('hex').toUpperCase();
|
var meshid = 'mesh/' + domain.id + '/' + buf.toString('base64').replace(/\+/g, '@').replace(/\//g, '$');;
|
||||||
var links = {}
|
var links = {}
|
||||||
links[user._id] = { name: user.name, rights: 0xFFFFFFFF };
|
links[user._id] = { name: user.name, rights: 0xFFFFFFFF };
|
||||||
var mesh = { type: 'mesh', _id: meshid, name: command.meshname, mtype: command.meshtype, desc: command.desc, domain: domain.id, links: links };
|
var mesh = { type: 'mesh', _id: meshid, name: command.meshname, mtype: command.meshtype, desc: command.desc, domain: domain.id, links: links };
|
||||||
@ -1449,7 +1449,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
// Create a new nodeid
|
// Create a new nodeid
|
||||||
obj.crypto.randomBytes(48, function (err, buf) {
|
obj.crypto.randomBytes(48, function (err, buf) {
|
||||||
// create the new node
|
// create the new node
|
||||||
var nodeid = 'node/' + domain.id + '/' + buf.toString('hex').toUpperCase();
|
var nodeid = 'node/' + domain.id + '/' + buf.toString('base64').replace(/\+/g, '@').replace(/\//g, '$');;
|
||||||
var device = { type: 'node', mtype: 1, _id: nodeid, meshid: command.meshid, name: command.devicename, host: command.hostname, domain: domain.id, intelamt: { user: command.amtusername, pass: command.amtpassword, tls: parseInt(command.amttls) } };
|
var device = { type: 'node', mtype: 1, _id: nodeid, meshid: command.meshid, name: command.devicename, host: command.hostname, domain: domain.id, intelamt: { user: command.amtusername, pass: command.amtpassword, tls: parseInt(command.amttls) } };
|
||||||
obj.db.Set(device);
|
obj.db.Set(device);
|
||||||
|
|
||||||
@ -1789,7 +1789,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
// Completed event read, let get the argument that must contain the nodeid
|
// Completed event read, let get the argument that must contain the nodeid
|
||||||
var i = eventData.indexOf('<m:arg xmlns:m="http://x.com">');
|
var i = eventData.indexOf('<m:arg xmlns:m="http://x.com">');
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
var nodeid = eventData.substring(i + 30, i + 30 + 64).toUpperCase();
|
var nodeid = eventData.substring(i + 30, i + 30 + 64);
|
||||||
if (nodeid.length == 64) {
|
if (nodeid.length == 64) {
|
||||||
var nodekey = 'node/' + domain.id + '/' + nodeid;
|
var nodekey = 'node/' + domain.id + '/' + nodeid;
|
||||||
|
|
||||||
@ -1941,13 +1941,17 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
//if ((user == null) || (mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { res.sendStatus(401); return; }
|
//if ((user == null) || (mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { res.sendStatus(401); return; }
|
||||||
//if (domain.id != mesh.domain) { res.sendStatus(401); return; }
|
//if (domain.id != mesh.domain) { res.sendStatus(401); return; }
|
||||||
|
|
||||||
|
var meshidhex = new Buffer(req.query.id.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
|
||||||
|
var serveridhex = new Buffer(obj.agentCertificatHashBase64.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
|
||||||
|
|
||||||
var xdomain = domain.id;
|
var xdomain = domain.id;
|
||||||
if (xdomain != '') xdomain += "/";
|
if (xdomain != '') xdomain += "/";
|
||||||
var meshsettings = "MeshName=" + mesh.name + "\r\nMeshType=" + mesh.mtype + "\r\nMeshID=0x" + req.query.id.toUpperCase() + "\r\nServerID=" + obj.agentCertificatHashHex.toUpperCase() + "\r\n";
|
var meshsettings = "MeshName=" + mesh.name + "\r\nMeshType=" + mesh.mtype + "\r\nMeshID=0x" + meshidhex + "\r\nServerID=" + serveridhex + "\r\n";
|
||||||
if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + certificates.CommonName + ":" + obj.args.port + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; }
|
if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + certificates.CommonName + ":" + obj.args.port + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; }
|
||||||
|
|
||||||
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);
|
||||||
|
console.log(meshsettings);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2049,22 +2053,6 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
|
|
||||||
obj.app.get(url + 'stop', function (req, res) { res.send('Stopping Server, <a href="' + url + '">click here to login</a>.'); setTimeout(function () { parent.Stop(); }, 500); });
|
obj.app.get(url + 'stop', function (req, res) { res.send('Stopping Server, <a href="' + url + '">click here to login</a>.'); setTimeout(function () { parent.Stop(); }, 500); });
|
||||||
|
|
||||||
/*
|
|
||||||
// DEBUG ONLY: Returns a mesh relay key
|
|
||||||
obj.app.get(url + 'getkey', function (req, res) {
|
|
||||||
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/plain' });
|
|
||||||
require('./meshrelay.js').CreateMeshRelayKey(obj, function (x) { res.send(x); });
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Test
|
|
||||||
obj.app.get(url + 'test.json', function (req, res) {
|
|
||||||
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/plain' });
|
|
||||||
res.send('{ "glossary": { "title": "example glossary", "bob" : 5 } }');
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Indicates to ExpressJS that the public folder should be used to serve static files.
|
// Indicates to ExpressJS that the public folder should be used to serve static files.
|
||||||
obj.app.use(url, obj.express.static(obj.path.join(__dirname, 'public')));
|
obj.app.use(url, obj.express.static(obj.path.join(__dirname, 'public')));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user