diff --git a/meshuser.js b/meshuser.js index 78c9160c..ef92b515 100644 --- a/meshuser.js +++ b/meshuser.js @@ -608,6 +608,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // pass through to switch statement until refactoring complete switch (command.action) { + case 'urlargs': + { + console.log(req.query); + console.log(command.args); + break; + } case 'intersession': { // Sends data between sessions of the same user diff --git a/public/scripts/meshcentral.js b/public/scripts/meshcentral.js index c5b3121d..57d6893d 100644 --- a/public/scripts/meshcentral.js +++ b/public/scripts/meshcentral.js @@ -23,9 +23,12 @@ var MeshServerCreateControl = function (domain, authCookie) { if (obj.connectstate != 0) return; obj.connectstate = 0; var url = window.location.protocol.replace('http', 'ws') + '//' + window.location.host + domain + 'control.ashx' + (urlargs.key ? ('?key=' + urlargs.key) : ''); - if (obj.authCookie && (obj.authCookie != '')) { url += '?auth=' + obj.authCookie; } + if (obj.authCookie && (obj.authCookie != '')) { + url += '?moreargs=1' + //url += '?auth=' + obj.authCookie; + } obj.socket = new WebSocket(url); - obj.socket.onopen = function (e) { obj.connectstate = 1; } + obj.socket.onopen = function (e) { obj.connectstate = 1; if (obj.authCookie && (obj.authCookie != '')) { obj.send({ 'action': 'urlargs', 'args': { 'auth': obj.authCookie } }); } } obj.socket.onmessage = obj.xxOnMessage; obj.socket.onclose = function(e) { obj.Stop(e.code); } obj.xxStateChange(1, 0); diff --git a/webserver.js b/webserver.js index 9182c37b..c4ba6dbe 100644 --- a/webserver.js +++ b/webserver.js @@ -5713,18 +5713,20 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { obj.app.ws(url + 'webrelay.ashx', function (ws, req) { PerformWSSessionAuth(ws, req, false, handleRelayWebSocket); }); obj.app.ws(url + 'webider.ashx', function (ws, req) { PerformWSSessionAuth(ws, req, false, function (ws1, req1, domain, user, cookie) { obj.meshIderHandler.CreateAmtIderSession(obj, obj.db, ws1, req1, obj.args, domain, user); }); }); obj.app.ws(url + 'control.ashx', function (ws, req) { - const domain = getDomain(req); - if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { ws.close(); return; } // Check 3FA URL key - PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie) { - if (user == null) { // User is not authenticated, perform inner server authentication - if (req.headers['x-meshauth'] === '*') { - PerformWSSessionInnerAuth(ws, req, domain, function (ws1, req1, domain, user) { obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain, user); }); // User is authenticated + getWebsocketArgs(ws, req, function (ws, req) { + const domain = getDomain(req); + if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { ws.close(); return; } // Check 3FA URL key + PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie) { + if (user == null) { // User is not authenticated, perform inner server authentication + if (req.headers['x-meshauth'] === '*') { + PerformWSSessionInnerAuth(ws, req, domain, function (ws1, req1, domain, user) { obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain, user); }); // User is authenticated + } else { + try { ws.close(); } catch (ex) { } // user is not authenticated and inner authentication was not requested, disconnect now. + } } else { - try { ws.close(); } catch (ex) { } // user is not authenticated and inner authentication was not requested, disconnect now. + obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain, user); // User is authenticated } - } else { - obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain, user); // User is authenticated - } + }); }); }); obj.app.ws(url + 'devicefile.ashx', function (ws, req) { obj.meshDeviceFileHandler.CreateMeshDeviceFile(obj, ws, null, req, domain); }); @@ -7727,5 +7729,30 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { obj.badLoginTableLastClean = 0; } + // Hold a websocket until additional arguments are provided within the socket. + // This is a generic function that can be used for any websocket to avoid passing arguments in the URL. + function getWebsocketArgs(ws, req, func) { + if (req.query.moreargs != '1') { + // No more arguments needed, pass the websocket thru + func(ws, req); + } else { + // More arguments are needed + delete req.query.moreargs; + const xfunc = function getWebsocketArgsEx(msg) { + var command = null; + try { command = JSON.parse(msg.toString('utf8')); } catch (e) { return; } + if ((command != null) && (command.action === 'urlargs') && (typeof command.args == 'object')) { + for (var i in command.args) { getWebsocketArgsEx.req.query[i] = command.args[i]; } + ws.removeEventListener('message', getWebsocketArgsEx); + getWebsocketArgsEx.func(getWebsocketArgsEx.ws, getWebsocketArgsEx.req); + } + } + xfunc.ws = ws; + xfunc.req = req; + xfunc.func = func; + ws.on('message', xfunc); + } + } + return obj; };