Changed the web relay system to correctly with multiple DNS names, #4242

Ylian Saint-Hilaire committed Jul 9, 2022 at 13:32 UTC bd9739e1067f01d8bb34692f7ae61b3d5bb0f748
4 files changed +30 -12
meshuser.js
+1 -1
@@ -5635,7 +5635,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5635 ws.send(JSON.stringify({
5636 action: 'authcookie',
5637 cookie: parent.parent.encodeCookie({ userid: user._id, domainid: domain.id, ip: req.clientIp }, parent.parent.loginCookieEncryptionKey),
5638 - rcookie: parent.parent.encodeCookie({ ruserid: user._id }, parent.parent.loginCookieEncryptionKey)
5638 + rcookie: parent.parent.encodeCookie({ ruserid: user._id, x: req.session.x }, parent.parent.loginCookieEncryptionKey)
5639 }));
5640 } catch (ex) { }
5641 }
views/default.handlebars
+1 -1
@@ -8119,7 +8119,7 @@
8119 var servername = serverinfo.name;
8120 if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
8121 if (webRelayDns != '') { servername = webRelayDns; }
8122 - var url = 'https://' + servername + ':' + webRelayPort + '/control-redirect.ashx?n=' + nodeid + '&p=' + port + '&appid=' + protocol; // Protocol: 1 = HTTP, 2 = HTTPS
8122 + var url = 'https://' + servername + ':' + webRelayPort + '/control-redirect.ashx?n=' + nodeid + '&p=' + port + '&appid=' + protocol + '&c=' + authRelayCookie; // Protocol: 1 = HTTP, 2 = HTTPS
8123 if (addr != null) { url += '&addr=' + addr; }
8124 if (relayid != null) { url += '&relayid=' + relayid; }
8125 safeNewWindow(url, 'WebRelay');
webrelayserver.js
+13 -4
@@ -120,7 +120,7 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
120 return next();
121 } else {
122 // If this is a normal request (GET, POST, etc) handle it here
123 - if ((req.session.userid != null) && (req.session.x != null)) {
123 + if ((req.session.userid != null) && (req.session.x != null) && (parent.webserver.destroyedSessions[req.session.userid + '/' + req.session.x] == null)) {
124 var relaySession = relaySessions[req.session.userid + '/' + req.session.x];
125 if (relaySession != null) {
126 // The web relay session is valid, use it
@@ -153,7 +153,7 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
153
154 // Handle incoming web socket calls
155 obj.app.ws('/*', function (ws, req) {
156 - if ((req.session.userid != null) && (req.session.x != null)) {
156 + if ((req.session.userid != null) && (req.session.x != null) && (parent.webserver.destroyedSessions[req.session.userid + '/' + req.session.x] == null)) {
157 var relaySession = relaySessions[req.session.userid + '/' + req.session.x];
158 if (relaySession != null) {
159 // The multi-tunnel session is valid, use it
@@ -170,12 +170,21 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
170
171 // This is the magic URL that will setup the relay session
172 obj.app.get('/control-redirect.ashx', function (req, res) {
173 - if ((req.session == null) || (req.session.userid == null)) { res.redirect('/'); return; }
173 res.set({ 'Cache-Control': 'no-store' });
174 parent.debug('webrelay', 'webRelaySetup');
175
176 + // Decode the relay cookie
177 + if (req.query.c != null) {
178 + // Decode and check if this relay cookie is valid
179 + const urlCookie = obj.parent.decodeCookie(req.query.c, parent.loginCookieEncryptionKey);
180 + if ((urlCookie != null) && (urlCookie.ruserid != null) && (urlCookie.x != null) && (parent.webserver.destroyedSessions[urlCookie.ruserid + '/' + urlCookie.x] == null)) {
181 + if (req.session.x != urlCookie.x) { req.session.x = urlCookie.x; } // Set the sessionid if missing
182 + if (req.session.userid != urlCookie.ruserid) { req.session.userid = urlCookie.ruserid; } // Set the session userid if missing
183 + }
184 + }
185 +
186 // Check that all the required arguments are present
178 - if ((req.session.userid == null) || (req.session.x == null) || (req.query.n == null) || (req.query.p == null) || ((req.query.appid != 1) && (req.query.appid != 2))) { res.redirect('/'); return; }
187 + if ((req.session.userid == null) || (req.session.x == null) || (req.query.n == null) || (req.query.p == null) || (parent.webserver.destroyedSessions[req.session.userid + '/' + req.session.x] != null) || ((req.query.appid != 1) && (req.query.appid != 2))) { res.redirect('/'); return; }
188
189 // Get the user and domain information
190 const userid = req.session.userid;
webserver.js
+15 -6
@@ -84,7 +84,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
84 obj.blockedAgents = 0;
85 obj.renderPages = null;
86 obj.renderLanguages = [];
87 - obj.destroyedSessions = {};
87 + obj.destroyedSessions = {}; // userid/req.session.x --> destroyed session time
88
89 // Web relay sessions
90 var webRelayNextSessionId = 1;
@@ -2799,7 +2799,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
2799
2800 // Create a authentication cookie
2801 const authCookie = obj.parent.encodeCookie({ userid: dbGetFunc.user._id, domainid: domain.id, ip: req.clientIp }, obj.parent.loginCookieEncryptionKey);
2802 - const authRelayCookie = obj.parent.encodeCookie({ ruserid: dbGetFunc.user._id, domainid: domain.id }, obj.parent.loginCookieEncryptionKey);
2802 + const authRelayCookie = obj.parent.encodeCookie({ ruserid: dbGetFunc.user._id, x: req.session.x }, obj.parent.loginCookieEncryptionKey);
2803
2804 // Send the main web application
2805 var extras = (dbGetFunc.req.query.key != null) ? ('&key=' + dbGetFunc.req.query.key) : '';
@@ -6587,12 +6587,21 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6587 obj.webRelayRouter.get('/control-redirect.ashx', function (req, res, next) {
6588 if (req.headers.host != obj.args.relaydns) { res.sendStatus(404); return; }
6589 if ((req.session.userid == null) && obj.args.user && obj.users['user//' + obj.args.user.toLowerCase()]) { req.session.userid = 'user//' + obj.args.user.toLowerCase(); } // Use a default user if needed
6590 - if ((req.session == null) || (req.session.userid == null)) { res.redirect('/'); return; }
6590 res.set({ 'Cache-Control': 'no-store' });
6591 parent.debug('web', 'webRelaySetup');
6592
6593 + // Decode the relay cookie
6594 + if (req.query.c != null) {
6595 + // Decode and check if this relay cookie is valid
6596 + const urlCookie = obj.parent.decodeCookie(req.query.c, obj.parent.loginCookieEncryptionKey);
6597 + if ((urlCookie != null) && (urlCookie.ruserid != null) && (urlCookie.x != null)) {
6598 + if (req.session.x != urlCookie.x) { req.session.x = urlCookie.x; } // Set the sessionid if missing
6599 + if (req.session.userid != urlCookie.ruserid) { req.session.userid = urlCookie.ruserid; } // Set the session userid if missing
6600 + }
6601 + }
6602 +
6603 // Check that all the required arguments are present
6595 - if ((req.session.userid == null) || (req.session.x == null) || (req.query.n == null) || (req.query.p == null) || ((req.query.appid != 1) && (req.query.appid != 2))) { res.redirect('/'); return; }
6604 + if ((req.session.userid == null) || (req.session.x == null) || (req.query.n == null) || (req.query.p == null) || ((obj.destroyedSessions[req.session.userid + '/' + req.session.x] != null)) || ((req.query.appid != 1) && (req.query.appid != 2))) { res.redirect('/'); return; }
6605
6606 // Get the user and domain information
6607 const userid = req.session.userid;
@@ -6691,7 +6700,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6700
6701 // Handle an incoming request as a web relay
6702 function handleWebRelayRequest(req, res) {
6694 - if ((req.session.userid != null) && (req.session.x != null)) {
6703 + if ((req.session.userid != null) && (req.session.x != null) && (obj.destroyedSessions[req.session.userid + '/' + req.session.x] == null)) {
6704 var relaySession = webRelaySessions[req.session.userid + '/' + req.session.x];
6705 if (relaySession != null) {
6706 // The web relay session is valid, use it
@@ -6708,7 +6717,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6717
6718 // Handle an incoming websocket connection as a web relay
6719 function handleWebRelayWebSocket(ws, req) {
6711 - if ((req.session.userid != null) && (req.session.x != null)) {
6720 + if ((req.session.userid != null) && (req.session.x != null) && (obj.destroyedSessions[req.session.userid + '/' + req.session.x] == null)) {
6721 var relaySession = webRelaySessions[req.session.userid + '/' + req.session.x];
6722 if (relaySession != null) {
6723 // The multi-tunnel session is valid, use it