From 740fbb1e56e61d8e287d2693301a7eb82ebc884f Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Wed, 13 Apr 2022 18:58:37 -0700 Subject: [PATCH] Completed initial version of agent-less deivce group reached thru a agent, #3867 --- apprelays.js | 76 +++++++++++++++++++++++++++++++++++----- views/default.handlebars | 6 ++-- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/apprelays.js b/apprelays.js index 0a3cdddc..593b3057 100644 --- a/apprelays.js +++ b/apprelays.js @@ -105,7 +105,7 @@ module.exports.CreateMstscRelay = function (parent, db, ws, req, args, domain) { var protocol = (args.tlsoffload) ? 'ws' : 'wss'; var domainadd = ''; if ((domain.dns == null) && (domain.id != '')) { domainadd = domain.id + '/' } - var url = protocol + '://127.0.0.1:' + args.port + '/' + domainadd + ((obj.cookie.lc == 1) ? 'local' : 'mesh') + 'relay.ashx?noping=1&p=10&auth=' + obj.infos.ip; // Protocol 10 is Web-RDP + var url = protocol + '://127.0.0.1:' + args.port + '/' + domainadd + (((obj.mtype == 3) && (obj.relaynodeid == null)) ? 'local' : 'mesh') + 'relay.ashx?noping=1&p=10&auth=' + obj.infos.ip; // Protocol 10 is Web-RDP parent.parent.debug('relay', 'RDP: Connection websocket to ' + url); obj.wsClient = new WebSocket(url, options); obj.wsClient.on('open', function () { parent.parent.debug('relay', 'RDP: Relay websocket open'); }); @@ -210,7 +210,20 @@ module.exports.CreateMstscRelay = function (parent, db, ws, req, args, domain) { parent.parent.db.Get(obj.nodeid, function (err, nodes) { if ((err != null) || (nodes == null) || (nodes.length != 1)) { obj.close(); return; } const node = nodes[0]; - obj.meshid = node.meshid; + obj.mtype = node.mtype; // Store the device group type + obj.meshid = node.meshid; // Store the MeshID + + // Check if we need to relay thru a different agent + // TODO: Check if we have rights to the relayid device + var mesh = parent.meshes[obj.meshid]; + if (mesh && mesh.relayid) { + obj.relaynodeid = mesh.relayid; + obj.tcpaddr = node.host; + + // Re-encode a cookie with a device relay + const cookieContent = { userid: obj.cookie.userid, domainid: obj.cookie.domainid, nodeid: mesh.relayid, tcpaddr: node.host, tcpport: obj.cookie.tcpport }; + obj.infos.ip = parent.parent.encodeCookie(cookieContent, parent.parent.loginCookieEncryptionKey); + } // Check if we need to load server stored credentials if ((typeof obj.infos.options == 'object') && (obj.infos.options.useServerCreds == true)) { @@ -382,7 +395,7 @@ module.exports.CreateSshRelay = function (parent, db, ws, req, args, domain) { if (args.tlsoffload) { protocol = 'ws'; } var domainadd = ''; if ((domain.dns == null) && (domain.id != '')) { domainadd = domain.id + '/' } - var url = protocol + '://127.0.0.1:' + args.port + '/' + domainadd + ((obj.cookie.lc == 1) ? 'local' : 'mesh') + 'relay.ashx?noping=1&p=11&auth=' + req.query.auth; // Protocol 11 is Web-SSH + var url = protocol + '://127.0.0.1:' + args.port + '/' + domainadd + (((obj.mtype == 3) && (obj.relaynodeid == null)) ? 'local' : 'mesh') + 'relay.ashx?noping=1&p=11&auth=' + obj.xcookie; // Protocol 11 is Web-SSH parent.parent.debug('relay', 'SSH: Connection websocket to ' + url); obj.wsClient = new WebSocket(url, options); obj.wsClient.on('open', function () { parent.parent.debug('relay', 'SSH: Relay websocket open'); }); @@ -533,6 +546,21 @@ module.exports.CreateSshRelay = function (parent, db, ws, req, args, domain) { const node = nodes[0]; obj.nodeid = node._id; // Store the NodeID obj.meshid = node.meshid; // Store the MeshID + obj.mtype = node.mtype; // Store the device group type + + // Check if we need to relay thru a different agent + // TODO: Check if we have rights to the relayid device + var mesh = parent.meshes[obj.meshid]; + if (mesh && mesh.relayid) { + obj.relaynodeid = mesh.relayid; + obj.tcpaddr = node.host; + + // Re-encode a cookie with a device relay + const cookieContent = { userid: obj.cookie.userid, domainid: obj.cookie.domainid, nodeid: mesh.relayid, tcpaddr: node.host, tcpport: obj.cookie.tcpport }; + obj.xcookie = parent.parent.encodeCookie(cookieContent, parent.parent.loginCookieEncryptionKey); + } else { + obj.xcookie = req.query.auth; + } }); return obj; @@ -650,7 +678,7 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u if (args.tlsoffload) { protocol = 'ws'; } var domainadd = ''; if ((domain.dns == null) && (domain.id != '')) { domainadd = domain.id + '/' } - var url = protocol + '://127.0.0.1:' + args.port + '/' + domainadd + ((obj.mtype == 3) ? 'local' : 'mesh') + 'relay.ashx?noping=1&p=11&auth=' + authCookie // Protocol 11 is Web-SSH + var url = protocol + '://127.0.0.1:' + args.port + '/' + domainadd + (((obj.mtype == 3) && (obj.relaynodeid == null)) ? 'local' : 'mesh') + 'relay.ashx?noping=1&p=11&auth=' + authCookie // Protocol 11 is Web-SSH parent.parent.debug('relay', 'SSH: Connection websocket to ' + url); obj.wsClient = new WebSocket(url, options); obj.wsClient.on('open', function () { parent.parent.debug('relay', 'SSH: Relay websocket open'); }); @@ -753,7 +781,12 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u // Create a mesh relay authentication cookie var cookieContent = { userid: user._id, domainid: user.domain, nodeid: obj.nodeid, tcpport: obj.tcpport }; - if (obj.mtype == 3) { cookieContent.lc = 1; } // This is a local device + if (obj.relaynodeid) { + cookieContent.nodeid = obj.relaynodeid; + cookieContent.tcpaddr = obj.tcpaddr; + } else { + if (obj.mtype == 3) { cookieContent.lc = 1; } // This is a local device + } startRelayConnection(parent.parent.encodeCookie(cookieContent, parent.parent.loginCookieEncryptionKey)); break; } @@ -766,7 +799,12 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u // Create a mesh relay authentication cookie var cookieContent = { userid: user._id, domainid: user.domain, nodeid: obj.nodeid, tcpport: obj.tcpport }; - if (obj.mtype == 3) { cookieContent.lc = 1; } // This is a local device + if (obj.relaynodeid) { + cookieContent.nodeid = obj.relaynodeid; + cookieContent.tcpaddr = obj.tcpaddr; + } else { + if (obj.mtype == 3) { cookieContent.lc = 1; } // This is a local device + } startRelayConnection(parent.parent.encodeCookie(cookieContent, parent.parent.loginCookieEncryptionKey)); break; } @@ -806,6 +844,11 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u obj.tcpport = 22; if (typeof node.sshport == 'number') { obj.tcpport = node.sshport; } + // Check if we need to relay thru a different agent + // TODO: Check if we have rights to the relayid device + var mesh = parent.meshes[obj.meshid]; + if (mesh && mesh.relayid) { obj.relaynodeid = mesh.relayid; obj.tcpaddr = node.host; } + // We are all set, start receiving data ws._socket.resume(); @@ -943,7 +986,7 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user if (args.tlsoffload) { protocol = 'ws'; } var domainadd = ''; if ((domain.dns == null) && (domain.id != '')) { domainadd = domain.id + '/' } - var url = protocol + '://127.0.0.1:' + args.port + '/' + domainadd + ((obj.mtype == 3) ? 'local' : 'mesh') + 'relay.ashx?noping=1&p=13&auth=' + authCookie // Protocol 13 is Web-SSH-Files + var url = protocol + '://127.0.0.1:' + args.port + '/' + domainadd + (((obj.mtype == 3) && (obj.relaynodeid == null)) ? 'local' : 'mesh') + 'relay.ashx?noping=1&p=13&auth=' + authCookie // Protocol 13 is Web-SSH-Files parent.parent.debug('relay', 'SSH: Connection websocket to ' + url); obj.wsClient = new WebSocket(url, options); obj.wsClient.on('open', function () { parent.parent.debug('relay', 'SSH: Relay websocket open'); }); @@ -1221,7 +1264,12 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user // Create a mesh relay authentication cookie var cookieContent = { userid: user._id, domainid: user.domain, nodeid: obj.nodeid, tcpport: obj.tcpport }; - if (obj.mtype == 3) { cookieContent.lc = 1; } // This is a local device + if (obj.relaynodeid) { + cookieContent.nodeid = obj.relaynodeid; + cookieContent.tcpaddr = obj.tcpaddr; + } else { + if (obj.mtype == 3) { cookieContent.lc = 1; } // This is a local device + } startRelayConnection(parent.parent.encodeCookie(cookieContent, parent.parent.loginCookieEncryptionKey)); break; } @@ -1279,6 +1327,11 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user obj.tcpport = 22; if (typeof node.sshport == 'number') { obj.tcpport = node.sshport; } + // Check if we need to relay thru a different agent + // TODO: Check if we have rights to the relayid device + var mesh = parent.meshes[obj.meshid]; + if (mesh && mesh.relayid) { obj.relaynodeid = mesh.relayid; obj.tcpaddr = node.host; } + // We are all set, start receiving data ws._socket.resume(); @@ -1302,7 +1355,12 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user // Create a mesh relay authentication cookie var cookieContent = { userid: user._id, domainid: user.domain, nodeid: obj.nodeid, tcpport: obj.tcpport }; - if (obj.mtype == 3) { cookieContent.lc = 1; } // This is a local device + if (obj.relaynodeid) { + cookieContent.nodeid = obj.relaynodeid; + cookieContent.tcpaddr = obj.tcpaddr; + } else { + if (obj.mtype == 3) { cookieContent.lc = 1; } // This is a local device + } startRelayConnection(parent.parent.encodeCookie(cookieContent, parent.parent.loginCookieEncryptionKey)); } }); diff --git a/views/default.handlebars b/views/default.handlebars index b199d95c..5465017c 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -7932,7 +7932,8 @@ function p10MCRouter(nodeid, protocol, port, ip, localport) { var node = getNodeFromId(nodeid); - if ((protocol == 3) && (port == null)) { if (node.rdpport != null) { port = node.rdpport; } else { port = 3389; } } + if ((protocol == 3) && (port == null)) { if (node.rdpport != null) { port = node.rdpport; } else { port = 3389; } } // Adjust RDP port if needed + if (node.mtype == 3) { var mesh = meshes[node.meshid]; if (mesh.relayid) { nodeid = mesh.relayid; ip = node.host; } } // Setup device replay if needed meshserver.send({ action: 'getcookie', nodeid: nodeid, tcpport: port, ip: ip, tag: 'MCRouter', protocol: protocol, localport: localport }); // Protocol: 0 = Custom, 1 = HTTP, 2 = HTTPS, 3 = RDP, 4 = PuTTY, 5 = WinSCP, 6 = MCRDesktop, 7 = MCRFiles return false; } @@ -7940,12 +7941,13 @@ function p10rfb(nodeid, port) { var node = getNodeFromId(nodeid); if (port == null) { if (node.rfbport != null) { port = node.rfbport; } else { port = 5900; } } + if (node.mtype == 3) { var mesh = meshes[node.meshid]; if (mesh.relayid) { nodeid = mesh.relayid; ip = node.host; } } // Setup device replay if needed meshserver.send({ action: 'getcookie', nodeid: nodeid, tcpport: port, tag: 'novnc' }); } function p10mstsc(nodeid, port) { var node = getNodeFromId(nodeid); - if (port == null) { if (node.rdpport != null) { port = node.rdpport; } else { port = 3389; } } + if (port == null) { if (node.rdpport != null) { port = node.rdpport; } else { port = 3389; } } // Adjust RDP port if needed meshserver.send({ action: 'getcookie', nodeid: nodeid, tcpport: port, tag: 'mstsc' }); }