From 1031eca8533f834c0c01c52a20de3bef2ce6c1a8 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Sun, 17 Sep 2017 17:22:18 -0700 Subject: [PATCH] Added relay peering support --- mesherrors.txt | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ meshrelay.js | 49 ++++++++++++++++++++++++--------- multiserver.js | 71 +++++++++++++++++++++++++++++++++++++---------- package.json | 2 +- webserver.js | 4 ++- 5 files changed, 172 insertions(+), 29 deletions(-) diff --git a/mesherrors.txt b/mesherrors.txt index 4cc15d4a..bccabb7d 100644 --- a/mesherrors.txt +++ b/mesherrors.txt @@ -1942,3 +1942,78 @@ TypeError: Cannot read property 'send' of null at emitOne (events.js:96:13) +-------- 9/17/2017, 2:06:23 PM -------- + +C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\multiserver.js:577 + if (obj.ws.socket == null) return; + ^ + +TypeError: Cannot read property 'socket' of undefined + at WebSocketClient. (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\multiserver.js:577:27) + at emitOne (events.js:96:13) + at WebSocketClient.emit (events.js:188:7) + at WebSocketClient.succeedHandshake (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\websocket\lib\WebSocketClient.js:335:10) + at WebSocketClient.validateHandshake (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\websocket\lib\WebSocketClient.js:319:10) + at ClientRequest.handleRequestUpgrade (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\websocket\lib\WebSocketClient.js:248:14) + at emitThree (events.js:116:13) + at ClientRequest.emit (events.js:194:7) + at TLSSocket.socketOnData (_http_client.js:391:11) + at emitOne (events.js:96:13) + + +-------- 9/17/2017, 4:34:12 PM -------- + +C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\multiserver.js:517 + obj.parent.createPeerRelay(rsession.peer1.ws, rsession.peer1.req, peerServerId, rsession.peer1.req.session.userid); + ^ + +TypeError: obj.parent.createPeerRelay is not a function + at Object.obj.ProcessPeerServerMessage (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\multiserver.js:517:36) + at processServerData (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\multiserver.js:377:32) + at WebSocket. (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\multiserver.js:262:49) + at emitTwo (events.js:106:13) + at WebSocket.emit (events.js:191:7) + at Receiver.ontext (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\WebSocket.js:841:10) + at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\Receiver.js:536:18 + at Receiver.applyExtensions (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\Receiver.js:371:5) + at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\Receiver.js:508:14 + at Receiver.flush (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\Receiver.js:347:3) + + +-------- 9/17/2017, 4:37:53 PM -------- + +C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshrelay.js:115 + if (relayinfo.state == 2) { + ^ + +TypeError: Cannot read property 'state' of undefined + at WebSocket. (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshrelay.js:115:26) + at emitTwo (events.js:111:20) + at WebSocket.emit (events.js:191:7) + at WebSocket.cleanupWebsocketResources (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\WebSocket.js:950:8) + at emitNone (events.js:91:20) + at TLSSocket.emit (events.js:185:7) + at endReadableNT (_stream_readable.js:926:12) + at _combinedTickCallback (internal/process/next_tick.js:74:11) + at process._tickCallback (internal/process/next_tick.js:98:9) + + +-------- 9/17/2017, 4:45:04 PM -------- + +C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\WebSocket.js:144 + if (this.readyState !== WebSocket.OPEN) throw new Error('not opened'); + ^ + +Error: not opened + at WebSocket.pauser [as pause] (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\WebSocket.js:144:49) + at WebSocket. (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\multiserver.js:630:74) + at emitTwo (events.js:111:20) + at WebSocket.emit (events.js:191:7) + at Receiver.onbinary (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\WebSocket.js:848:10) + at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\Receiver.js:628:18 + at Receiver.applyExtensions (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\Receiver.js:371:5) + at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\Receiver.js:604:14 + at Receiver.flush (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\Receiver.js:347:3) + at Receiver.opcodes.2.finish (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\Receiver.js:633:12) + + diff --git a/meshrelay.js b/meshrelay.js index 1652e148..9939880b 100644 --- a/meshrelay.js +++ b/meshrelay.js @@ -16,6 +16,7 @@ module.exports.CreateMeshRelayKey = function (parent, func) { module.exports.CreateMeshRelay = function (parent, ws, req) { var obj = {}; obj.ws = ws; + obj.req = req; obj.peer = null; obj.parent = parent; obj.id = req.query['id']; @@ -24,8 +25,13 @@ module.exports.CreateMeshRelay = function (parent, ws, req) { if (obj.id == undefined) { obj.ws.close(); obj.id = null; return null; } // Attempt to connect without id, drop this. - // Check if this session is a logged in user, at least one of the two connections will need to be authenticated. - try { if ((req.session) && (req.session.userid) || (req.session.domainid == getDomain(req).id)) { obj.authenticated = true; } } catch (e) { } + if (req.query.auth == null) { + // Use ExpressJS session, check if this session is a logged in user, at least one of the two connections will need to be authenticated. + try { if ((req.session) && (req.session.userid) || (req.session.domainid == getDomain(req).id)) { obj.authenticated = true; } } catch (e) { } + } else { + // Get the session from the cookie + if ((obj.parent.parent.multiServer != null) && (obj.parent.parent.multiServer.decodeCookie(req.query.auth) != null)) { obj.authenticated = true; } + } // Validate that the id is valid, we only need to do this on non-authenticated sessions. // TODO: Figure out when this needs to be done. @@ -60,6 +66,7 @@ module.exports.CreateMeshRelay = function (parent, ws, req) { relayinfo.state = 2; obj.ws.send('c'); // Send connect to both peers relayinfo.peer1.ws.send('c'); + relayinfo.peer1.ws.resume(); // Release the traffic relayinfo.peer1.ws.peer = relayinfo.peer2.ws; relayinfo.peer2.ws.peer = relayinfo.peer1.ws; @@ -73,9 +80,23 @@ module.exports.CreateMeshRelay = function (parent, ws, req) { return null; } } else { - // Setup the connection, wait for peer + // Wait for other relay connection + ws.pause(); // Hold traffic until the other connection parent.wsrelays[obj.id] = { peer1: obj, state: 1 }; obj.parent.parent.debug(1, 'Relay holding: ' + obj.id + ' (' + obj.remoteaddr + ')'); + + // Check if a peer server has this connection + if (parent.parent.multiServer != null) { + var rsession = obj.parent.wsPeerRelays[obj.id]; + if ((rsession != null) && (rsession.serverId > obj.parent.parent.serverId)) { + // We must initiate the connection to the peer + parent.parent.multiServer.createPeerRelay(ws, req, rsession.serverId, req.session.userid); + delete parent.wsrelays[obj.id]; + } else { + // Send message to other peers that we have this connection + parent.parent.multiServer.DispatchMessage(JSON.stringify({ action: 'relay', id: obj.id })); + } + } } } @@ -95,17 +116,19 @@ module.exports.CreateMeshRelay = function (parent, ws, req) { ws.on('close', function (req) { if (obj.id != null) { var relayinfo = parent.wsrelays[obj.id]; - if (relayinfo.state == 2) { - // Disconnect the peer - var peer = (relayinfo.peer1 == obj) ? relayinfo.peer2 : relayinfo.peer1; - obj.parent.parent.debug(1, 'Relay disconnect: ' + obj.id + ' (' + obj.remoteaddr + ' --> ' + peer.remoteaddr + ')'); - peer.id = null; - try { peer.ws.close(); } catch (e) { } // Soft disconnect - try { peer.ws._socket._parent.end(); } catch (e) { } // Hard disconnect - } else { - obj.parent.parent.debug(1, 'Relay disconnect: ' + obj.id + ' (' + obj.remoteaddr + ')'); + if (relayinfo != null) { + if (relayinfo.state == 2) { + // Disconnect the peer + var peer = (relayinfo.peer1 == obj) ? relayinfo.peer2 : relayinfo.peer1; + obj.parent.parent.debug(1, 'Relay disconnect: ' + obj.id + ' (' + obj.remoteaddr + ' --> ' + peer.remoteaddr + ')'); + peer.id = null; + try { peer.ws.close(); } catch (e) { } // Soft disconnect + try { peer.ws._socket._parent.end(); } catch (e) { } // Hard disconnect + } else { + obj.parent.parent.debug(1, 'Relay disconnect: ' + obj.id + ' (' + obj.remoteaddr + ')'); + } + delete parent.wsrelays[obj.id]; } - delete parent.wsrelays[obj.id]; obj.peer = null; obj.id = null; } diff --git a/multiserver.js b/multiserver.js index ce4334a9..619766ae 100644 --- a/multiserver.js +++ b/multiserver.js @@ -37,6 +37,7 @@ module.exports.CreateMultiServer = function (parent, args) { obj.agentCertificatAsn1 = obj.parent.parent.webserver.agentCertificatAsn1; obj.peerServerId = null; obj.authenticated = 0; + obj.serverCertHash = null; // Disconnect from the server and/or stop trying obj.stop = function () { @@ -61,7 +62,6 @@ module.exports.CreateMultiServer = function (parent, args) { // Register the connection event obj.ws.on('connect', function (connection) { obj.parent.parent.debug(1, 'OutPeer ' + obj.serverid + ': Connected'); - if (obj.meshScanner != null) { obj.meshScanner.stop(); } obj.connectionState |= 2; obj.conn = connection; obj.nonce = obj.forge.random.getBytesSync(32); @@ -125,20 +125,20 @@ module.exports.CreateMultiServer = function (parent, args) { // Connection is a success, clean up delete obj.nonce; delete obj.servernonce; - delete obj.serverCertHash; + obj.serverCertHash = obj.common.rstr2hex(obj.serverCertHash).toLowerCase(); // Change this value to hex obj.connectionState |= 4; obj.retryBackoff = 0; // Set backoff connection timer back to fast. obj.parent.parent.debug(1, 'OutPeer ' + obj.serverid + ': Verified peer connection to ' + obj.url); // Send information about our server to the peer - if (obj.connectionState == 15) { obj.conn.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey })); } + if (obj.connectionState == 15) { obj.conn.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey, serverCertHash: obj.parent.parent.webserver.webCertificatHashHex })); } //if ((obj.connectionState == 15) && (obj.connectHandler != null)) { obj.connectHandler(1); } break; } case 4: { // Server confirmed authentication, we are allowed to send commands to the server obj.connectionState |= 8; - if (obj.connectionState == 15) { obj.conn.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey })); } + if (obj.connectionState == 15) { obj.conn.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey, serverCertHash: obj.parent.parent.webserver.webCertificatHashHex })); } //if ((obj.connectionState == 15) && (obj.connectHandler != null)) { obj.connectHandler(1); } break; } @@ -199,6 +199,7 @@ module.exports.CreateMultiServer = function (parent, args) { 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.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; } obj.peerServerId = command.serverid; obj.peerServerKey = command.key; obj.authenticated = 3; @@ -232,6 +233,7 @@ module.exports.CreateMultiServer = function (parent, args) { obj.agentCertificatAsn1 = obj.parent.parent.webserver.agentCertificatAsn1; obj.infoSent = 0; obj.peerServerId = null; + obj.serverCertHash = null; if (obj.remoteaddr.startsWith('::ffff:')) { obj.remoteaddr = obj.remoteaddr.substring(7); } // Send a message to the peer server @@ -328,7 +330,7 @@ module.exports.CreateMultiServer = function (parent, args) { function completePeerServerConnection() { if (obj.authenticated != 1) return; 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 })); + obj.send(JSON.stringify({ action: 'info', serverid: obj.parent.serverid, dbid: obj.parent.parent.db.identifier, key: obj.parent.serverKey, serverCertHash: obj.parent.parent.webserver.webCertificatHashHex })); obj.authenticated = 2; } @@ -365,6 +367,7 @@ module.exports.CreateMultiServer = function (parent, args) { if (obj.parent.peerConfig.servers[command.serverid] == null) { console.log('ERROR: Unknown peer serverid: ' + command.serverid + ' (' + obj.remoteaddr + ').'); return; } obj.peerServerId = command.serverid; obj.peerServerKey = command.key; + obj.serverCertHash = command.serverCertHash; obj.authenticated = 3; obj.parent.SetupPeerServer(obj, obj.peerServerId); } @@ -484,7 +487,7 @@ module.exports.CreateMultiServer = function (parent, args) { // Process a message coming from a peer server obj.ProcessPeerServerMessage = function (server, peerServerId, msg) { - //console.log('ProcessPeerServerMessage', peerServerId, msg.action, typeof msg, msg); + //console.log('ProcessPeerServerMessage', peerServerId, msg); switch (msg.action) { case 'bus': { obj.parent.DispatchEvent(msg.ids, null, msg.event, true); // Dispatch the peer event @@ -503,6 +506,28 @@ module.exports.CreateMultiServer = function (parent, args) { obj.parent.ClearConnectivityState(msg.meshid, msg.nodeid, msg.connectType, peerServerId); break; } + case 'relay': { + // Check if there is a waiting session + var rsession = obj.parent.webserver.wsrelays[msg.id]; + if (rsession != null) { + // Yes, there is a waiting session, see if we must initiate. + if (peerServerId > obj.parent.serverId) { + // We must initiate the connection to the peer + var userid = null; + if (rsession.peer1.req.session != null) { userid = rsession.peer1.req.session.userid; } + obj.createPeerRelay(rsession.peer1.ws, rsession.peer1.req, peerServerId, userid); + delete obj.parent.webserver.wsrelays[msg.id]; + } + } else { + // Add this relay session to the peer relay list + obj.parent.webserver.wsPeerRelays[msg.id] = { serverId: peerServerId, time: Date.now() }; + + // Clear all relay sessions that are more than 1 minute + var oneMinuteAgo = Date.now() - 60000; + for (var id in obj.parent.webserver.wsPeerRelays) { if (obj.parent.webserver.wsPeerRelays[id].time < oneMinuteAgo) { delete obj.parent.webserver.wsPeerRelays[id]; } } + } + break; + } case 'msg': { if (msg.sessionid != null) { // Route this message to a connected user session @@ -541,13 +566,16 @@ module.exports.CreateMultiServer = function (parent, args) { if ((server == null) || (server.peerServerKey == null)) { return null; } var cookieKey = server.peerServerKey; + // Parse the user if needed + if (typeof user == 'string') { user = { _id: user, domain: user.split('/')[1] }; } + // Build the connection URL var path = req.path; if (path[0] == '/') path = path.substring(1); if (path.substring(path.length - 11) == '/.websocket') { path = path.substring(0, path.length - 11); } var queryStr = '' for (var i in req.query) { queryStr += ((queryStr == '') ? '?' : '&') + i + '=' + req.query[i]; } - queryStr += ((queryStr == '') ? '?' : '&') + 'auth=' + obj.encodeCookie({ userid: user._id, domainid: user.domain }, cookieKey); + if (user != null) { queryStr += ((queryStr == '') ? '?' : '&') + 'auth=' + obj.encodeCookie({ userid: user._id, domainid: user.domain }, cookieKey); } var url = obj.peerConfig.servers[serverid].url + path + queryStr; // Setup an connect the web socket @@ -566,10 +594,20 @@ module.exports.CreateMultiServer = function (parent, args) { peerTunnel.wsclient = new WebSocketClient(); // Register the connection failed event - peerTunnel.wsclient.on('connectFailed', function (error) { peerTunnel.parent.parent.debug(1, 'FTunnel ' + obj.serverid + ': Failed connection'); disconnect(); }); + peerTunnel.wsclient.on('connectFailed', function (error) { peerTunnel.parent.parent.debug(1, 'FTunnel ' + obj.serverid + ': Failed connection'); peerTunnel.ws1.close(); }); // Register the connection event peerTunnel.wsclient.on('connect', function (connection) { + // Get the peer server's certificate and compute the server public key hash + var rawcertbuf = connection.socket.getPeerCertificate().raw, rawcert = ''; + for (var i = 0; i < rawcertbuf.length; i++) { rawcert += String.fromCharCode(rawcertbuf[i]); } + var serverCert = obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(rawcert)); + var serverCertHashHex = obj.forge.pki.getPublicKeyFingerprint(serverCert.publicKey, { encoding: 'hex', md: obj.forge.md.sha256.create() }); + + // 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.ws1.close(); return; } + + // Connection accepted. peerTunnel.ws2 = connection; // If error, do nothing @@ -579,14 +617,19 @@ module.exports.CreateMultiServer = function (parent, args) { peerTunnel.ws2.on('close', function (req) { peerTunnel.parent.parent.debug(1, 'FTunnel disconnect ' + peerTunnel.nodeid); peerTunnel.close(); }); // If a message is received from the peer, Peer ---> Browser - peerTunnel.ws2.on('message', function (msg) { if (msg.type == 'binary') { peerTunnel.ws2.pause(); peerTunnel.ws1.send(msg.binaryData, function () { peerTunnel.ws2.resume(); }); } }); + peerTunnel.ws2.on('message', function (msg) { + try { + if (msg.type == 'utf8') { peerTunnel.ws2.pause(); peerTunnel.ws1.send(msg.utf8Data, function () { peerTunnel.ws2.resume(); }); } + else if (msg.type == 'binary') { peerTunnel.ws2.pause(); peerTunnel.ws1.send(msg.binaryData, function () { peerTunnel.ws2.resume(); }); } + } catch (e) { } + }); // Resume the web socket to start the data flow peerTunnel.ws1.resume(); }); // If a message is received from the browser, Browser ---> Peer - peerTunnel.ws1.on('message', function (msg) { peerTunnel.ws1.pause(); peerTunnel.ws2.send(msg, function () { peerTunnel.ws1.resume(); }); }); + peerTunnel.ws1.on('message', function (msg) { try { peerTunnel.ws1.pause(); peerTunnel.ws2.send(msg, function () { peerTunnel.ws1.resume(); }); } catch (e) { } }); // If error, do nothing peerTunnel.ws1.on('error', function (err) { console.log(err); peerTunnel.close(); }); @@ -601,12 +644,12 @@ module.exports.CreateMultiServer = function (parent, args) { peerTunnel.close = function (arg) { if (arg == 2) { // Hard close, close the TCP socket - try { peerTunnel.ws1._socket._parent.end(); peerTunnel.parent.parent.debug(1, 'FTunnel1: Hard disconnect'); } catch (e) { console.log(e); } - try { peerTunnel.ws2._socket._parent.end(); peerTunnel.parent.parent.debug(1, 'FTunnel2: Hard disconnect'); } catch (e) { console.log(e); } + if (peerTunnel.ws1 != null) { try { peerTunnel.ws1._socket._parent.end(); peerTunnel.parent.parent.debug(1, 'FTunnel1: Hard disconnect'); } catch (e) { console.log(e); } } + if (peerTunnel.ws2 != null) { try { peerTunnel.ws2._socket._parent.end(); peerTunnel.parent.parent.debug(1, 'FTunnel2: Hard disconnect'); } catch (e) { console.log(e); } } } else { // Soft close, close the websocket - try { peerTunnel.ws1.close(); peerTunnel.parent.parent.debug(1, 'FTunnel1: Soft disconnect '); } catch (e) { console.log(e); } - try { peerTunnel.ws2.close(); peerTunnel.parent.parent.debug(1, 'FTunnel2: Soft disconnect '); } catch (e) { console.log(e); } + if (peerTunnel.ws1 != null) { try { peerTunnel.ws1.close(); peerTunnel.parent.parent.debug(1, 'FTunnel1: Soft disconnect '); } catch (e) { console.log(e); } } + if (peerTunnel.ws2 != null) { try { peerTunnel.ws2.close(); peerTunnel.parent.parent.debug(1, 'FTunnel2: Soft disconnect '); } catch (e) { console.log(e); } } } } diff --git a/package.json b/package.json index 8b41d3b4..8aaf3ee7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.0.7-w", + "version": "0.0.7-y", "keywords": [ "Remote Management", "Intel AMT", diff --git a/webserver.js b/webserver.js index ce5b22cb..89939733 100644 --- a/webserver.js +++ b/webserver.js @@ -68,6 +68,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, 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.sha256.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.sha256.create(), encoding: 'hex' }); obj.agentCertificatHashHex = parent.certificateOperations.forge.pki.getPublicKeyFingerprint(parent.certificateOperations.forge.pki.certificateFromPem(obj.certificates.agent.cert).publicKey, { md: parent.certificateOperations.forge.md.sha256.create(), encoding: 'hex' }); obj.agentCertificatAsn1 = parent.certificateOperations.forge.asn1.toDer(parent.certificateOperations.forge.pki.certificateToAsn1(parent.certificateOperations.forge.pki.certificateFromPem(parent.certificates.agent.cert))).getBytes(); @@ -75,7 +76,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate obj.wsagents = {}; obj.wssessions = {}; // UserId --> Array Of Sessions obj.wssessions2 = {}; // UserId + SessionId --> Session - obj.wsrelays = {}; + obj.wsrelays = {}; // Id -> Relay + obj.wsPeerRelays = {}; // Id -> { ServerId, Time } // Setup randoms obj.crypto.randomBytes(32, function (err, buf) { obj.httpAuthRandom = buf; });