mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Added early server support for agent binary installer on Linux.
This commit is contained in:
		
							parent
							
								
									8ea198b831
								
							
						
					
					
						commit
						cbda9382e9
					
				
					 5 changed files with 1773 additions and 1580 deletions
				
			
		
							
								
								
									
										109
									
								
								agents/meshinstall-linux.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								agents/meshinstall-linux.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,109 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2020 Intel Corporation
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
TODO: in msh, when:
 | 
			
		||||
InstallFlags=1    --> Interactive only, show connect button, not install/uninstal.
 | 
			
		||||
InstallFlags=2    --> Background only, show only install/uninstal, not connect.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
var msh = {};
 | 
			
		||||
var s = null;
 | 
			
		||||
try { s = require('service-manager').manager.getService('meshagent'); } catch (e) { }
 | 
			
		||||
 | 
			
		||||
var buttons = ["Connect", "Cancel"];
 | 
			
		||||
if (s) {
 | 
			
		||||
    buttons.unshift("Uninstall");
 | 
			
		||||
    buttons.unshift("Update");
 | 
			
		||||
} else {
 | 
			
		||||
    buttons.unshift("Install");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if ((require('message-box').zenity == null) || (!require('message-box').zenity.extra)) {
 | 
			
		||||
    console.log('\n' + "This installer cannot run on this system.");
 | 
			
		||||
    console.log("Try installing/updating Zenity, and run again." + '\n');
 | 
			
		||||
    process.exit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (!s) {
 | 
			
		||||
    msg = "Agent: " + "NOT INSTALLED" + '\n';
 | 
			
		||||
} else {
 | 
			
		||||
    msg = "Agent: " + (s.isRunning() ? "RUNNING" : "NOT RUNNING") + '\n';
 | 
			
		||||
}
 | 
			
		||||
msg += ("Device Group: " + msh.MeshName + '\n');
 | 
			
		||||
msg += ("Server URL: " + msh.MeshServer + '\n');
 | 
			
		||||
 | 
			
		||||
var p = require('message-box').create("MeshCentral Agent Setup", msg, 99999, buttons);
 | 
			
		||||
p.then(function (v) {
 | 
			
		||||
    switch (v) {
 | 
			
		||||
        case "Cancel":
 | 
			
		||||
            process.exit();
 | 
			
		||||
            break;
 | 
			
		||||
        case "Connect":
 | 
			
		||||
            global._child = require('child_process').execFile(process.execPath,
 | 
			
		||||
                [process.execPath.split('/').pop(), '--no-embedded=1', '--disableUpdate=1',
 | 
			
		||||
                    '--MeshName="' + msh.MeshName + '"', '--MeshType="' + msh.MeshType + '"',
 | 
			
		||||
                    '--MeshID="' + msh.MeshID + '"',
 | 
			
		||||
                    '--ServerID="' + msh.ServerID + '"',
 | 
			
		||||
                    '--MeshServer="' + msh.MeshServer + '"',
 | 
			
		||||
                    '--AgentCapabilities="0x00000020"']);
 | 
			
		||||
 | 
			
		||||
            global._child.stdout.on('data', function (c) { });
 | 
			
		||||
            global._child.stderr.on('data', function (c) { });
 | 
			
		||||
            global._child.on('exit', function (code) { process.exit(code); });
 | 
			
		||||
 | 
			
		||||
            msg = ("Device Group: " + msh.MeshName + '\n');
 | 
			
		||||
            msg += ("Server URL: " + msh.MeshServer + '\n');
 | 
			
		||||
 | 
			
		||||
            var d = require('message-box').create("MeshCentral Agent", msg, 99999, ["Disconnect"]);
 | 
			
		||||
            d.then(function (v) { process.exit(); }).catch(function (v) { process.exit(); });
 | 
			
		||||
            break;
 | 
			
		||||
        case "Uninstall":
 | 
			
		||||
            global._child = require('child_process').execFile(process.execPath,
 | 
			
		||||
                [process.execPath.split('/').pop(), '-fulluninstall', '--no-embedded=1']);
 | 
			
		||||
 | 
			
		||||
            global._child.stdout.on('data', function (c) { process.stdout.write(c.toString()); });
 | 
			
		||||
            global._child.stderr.on('data', function (c) { process.stdout.write(c.toString()); });
 | 
			
		||||
            global._child.waitExit();
 | 
			
		||||
            process.exit();
 | 
			
		||||
            break;
 | 
			
		||||
        case "Install":
 | 
			
		||||
        case "Update":
 | 
			
		||||
            var mstr = require('fs').createWriteStream(process.execPath + '.msh', { flags: 'wb' });
 | 
			
		||||
            mstr.write('MeshName=' + msh.MeshName + '\n');
 | 
			
		||||
            mstr.write('MeshType=' + msh.MeshType + '\n');
 | 
			
		||||
            mstr.write('MeshID=' + msh.MeshID + '\n');
 | 
			
		||||
            mstr.write('ServerID=' + msh.ServerID + '\n');
 | 
			
		||||
            mstr.write('MeshServer=' + msh.MeshServer + '\n');
 | 
			
		||||
            mstr.end();
 | 
			
		||||
 | 
			
		||||
            global._child = require('child_process').execFile(process.execPath,
 | 
			
		||||
                [process.execPath.split('/').pop(), '-fullinstall', '--no-embedded=1', '--copy-msh=1']);
 | 
			
		||||
 | 
			
		||||
            global._child.stdout.on('data', function (c) { process.stdout.write(c.toString()); });
 | 
			
		||||
            global._child.stderr.on('data', function (c) { process.stdout.write(c.toString()); });
 | 
			
		||||
            global._child.waitExit();
 | 
			
		||||
            process.exit();
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            console.log(v);
 | 
			
		||||
            process.exit();
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}).catch(function (e) {
 | 
			
		||||
    process.exit();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +130,7 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
        try { require('./pass').hash('test', function () { }, 0); } catch (e) { console.log('Old version of node, must upgrade.'); return; } // TODO: Not sure if this test works or not.
 | 
			
		||||
 | 
			
		||||
        // Check for invalid arguments
 | 
			
		||||
        var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'rediraliasport', 'cert', 'mpscert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'showitem', 'listuserids', 'showusergroups', 'shownodes', 'showmeshes', 'showevents', 'showsmbios', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'xinstall', 'xuninstall', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbexportmin', 'dbimport', 'dbmerge', 'dbencryptkey', 'selfupdate', 'tlsoffload', 'userallowedip', 'userblockedip', 'swarmallowedip', 'agentallowedip', 'agentblockedip', 'fastcert', 'swarmport', 'logintoken', 'logintokenkey', 'logintokengen', 'mailtokengen', 'admin', 'unadmin', 'sessionkey', 'sessiontime', 'minify', 'minifycore', 'dblistconfigfiles', 'dbshowconfigfile', 'dbpushconfigfiles', 'dbpullconfigfiles', 'dbdeleteconfigfiles', 'vaultpushconfigfiles', 'vaultpullconfigfiles', 'vaultdeleteconfigfiles', 'configkey', 'loadconfigfromdb', 'npmpath', 'serverid', 'recordencryptionrecode', 'vault', 'token', 'unsealkey', 'name', 'log', 'dbstats', 'translate', 'createaccount', 'resetaccount', 'pass', 'adminaccount', 'removeaccount', 'domain', 'email'];
 | 
			
		||||
        var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'rediraliasport', 'cert', 'mpscert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'showitem', 'listuserids', 'showusergroups', 'shownodes', 'showallmeshes', 'showmeshes', 'showevents', 'showsmbios', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'xinstall', 'xuninstall', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbexportmin', 'dbimport', 'dbmerge', 'dbencryptkey', 'selfupdate', 'tlsoffload', 'userallowedip', 'userblockedip', 'swarmallowedip', 'agentallowedip', 'agentblockedip', 'fastcert', 'swarmport', 'logintoken', 'logintokenkey', 'logintokengen', 'mailtokengen', 'admin', 'unadmin', 'sessionkey', 'sessiontime', 'minify', 'minifycore', 'dblistconfigfiles', 'dbshowconfigfile', 'dbpushconfigfiles', 'dbpullconfigfiles', 'dbdeleteconfigfiles', 'vaultpushconfigfiles', 'vaultpullconfigfiles', 'vaultdeleteconfigfiles', 'configkey', 'loadconfigfromdb', 'npmpath', 'serverid', 'recordencryptionrecode', 'vault', 'token', 'unsealkey', 'name', 'log', 'dbstats', 'translate', 'createaccount', 'resetaccount', 'pass', 'adminaccount', 'removeaccount', 'domain', 'email'];
 | 
			
		||||
        for (var arg in obj.args) { obj.args[arg.toLocaleLowerCase()] = obj.args[arg]; if (validArguments.indexOf(arg.toLocaleLowerCase()) == -1) { console.log('Invalid argument "' + arg + '", use --help.'); return; } }
 | 
			
		||||
        if (obj.args.mongodb == true) { console.log('Must specify: --mongodb [connectionstring] \r\nSee https://docs.mongodb.com/manual/reference/connection-string/ for MongoDB connection string.'); return; }
 | 
			
		||||
        for (i in obj.config.settings) { obj.args[i] = obj.config.settings[i]; } // Place all settings into arguments, arguments have already been placed into settings so arguments take precedence.
 | 
			
		||||
| 
						 | 
				
			
			@ -675,7 +675,8 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
                    if (obj.args.listuserids) { obj.db.GetAllType('user', function (err, docs) { for (var i in docs) { console.log(docs[i]._id); } process.exit(); }); return; }
 | 
			
		||||
                    if (obj.args.showusergroups) { obj.db.GetAllType('ugrp', function (err, docs) { console.log(JSON.stringify(docs, null, 2)); process.exit(); }); return; }
 | 
			
		||||
                    if (obj.args.shownodes) { obj.db.GetAllType('node', function (err, docs) { console.log(JSON.stringify(docs, null, 2)); process.exit(); }); return; }
 | 
			
		||||
                    if (obj.args.showmeshes) { obj.db.GetAllType('mesh', function (err, docs) { console.log(JSON.stringify(docs, null, 2)); process.exit(); }); return; }
 | 
			
		||||
                    if (obj.args.showallmeshes) { obj.db.GetAllType('mesh', function (err, docs) { console.log(JSON.stringify(docs, null, 2)); process.exit(); }); return; }
 | 
			
		||||
                    if (obj.args.showmeshes) { obj.db.GetAllType('mesh', function (err, docs) { var x = []; for (var i in docs) { if (docs[i].deleted == null) { x.push(docs[i]); } } console.log(JSON.stringify(x, null, 2)); process.exit(); }); return; }
 | 
			
		||||
                    if (obj.args.showevents) { obj.db.GetAllEvents(function (err, docs) { console.log(JSON.stringify(docs, null, 2)); process.exit(); }); return; }
 | 
			
		||||
                    if (obj.args.showsmbios) { obj.db.GetAllSMBIOS(function (err, docs) { console.log(JSON.stringify(docs, null, 2)); process.exit(); }); return; }
 | 
			
		||||
                    if (obj.args.showpower) { obj.db.getAllPower(function (err, docs) { console.log(JSON.stringify(docs, null, 2)); process.exit(); }); return; }
 | 
			
		||||
| 
						 | 
				
			
			@ -2052,7 +2053,8 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
    var meshAgentsInstallScriptList = {
 | 
			
		||||
        1: { id: 1, localname: 'meshinstall-linux.sh', rname: 'meshinstall.sh', linux: true },
 | 
			
		||||
        2: { id: 2, localname: 'meshinstall-initd.sh', rname: 'meshagent', linux: true },
 | 
			
		||||
        5: { id: 5, localname: 'meshinstall-bsd-rcd.sh', rname: 'meshagent', linux: true }
 | 
			
		||||
        5: { id: 5, localname: 'meshinstall-bsd-rcd.sh', rname: 'meshagent', linux: true },
 | 
			
		||||
        6: { id: 6, localname: 'meshinstall-linux.js', rname: 'meshinstall.js', linux: true }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Update the list of available mesh agents
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -4105,8 +4105,19 @@
 | 
			
		|||
 | 
			
		||||
        function addAgentToMesh(meshid) {
 | 
			
		||||
            if (xxdialogMode) return false;
 | 
			
		||||
            var mesh = meshes[meshid], x = '', installType = 0;
 | 
			
		||||
            x += addHtmlValue("Operating System", '<select id=aginsSelect onchange=addAgentToMeshClick() style=width:236px><option value=0>' + "Windows" + '</option><option value=1>' + "Linux / BSD" + '</option><option value=2>' + "Apple MacOS" + '</option><option value=3>' + "Windows (UnInstall)" + '</option><option value=4>' + "Linux / BSD (UnInstall)" + '</option></select>');
 | 
			
		||||
            var mesh = meshes[meshid], x = '', installType = 0, moreoptions = '';
 | 
			
		||||
            if (debugmode > 0) { moreoptions = '<option value=5>' + "Linux/macOS Binary Installer" + '</option>'; }
 | 
			
		||||
            x += addHtmlValue("Operating System", '<select id=aginsSelect onchange=addAgentToMeshClick() style=width:236px><option value=0>' + "Windows" + '</option><option value=1>' + "Linux / BSD" + '</option>' + moreoptions + '<option value=2>' + "Apple MacOS" + '</option><option value=3>' + "Windows (UnInstall)" + '</option><option value=4>' + "Linux / BSD (UnInstall)" + '</option></select>');
 | 
			
		||||
 | 
			
		||||
            if (debugmode > 0) { 
 | 
			
		||||
                var binaryInstallAgents = { 5 : 'Linux x86-32', 6 : 'Linux x86-64', 16 : 'Apple OSX x86-64', 25 : 'Linux ARM-HF, Rasberry Pi', 26 : 'Linux ARM64', 30 : 'FreeBSD x86-64' };
 | 
			
		||||
                moreoptions = '';
 | 
			
		||||
                for (var i in binaryInstallAgents) { moreoptions += '<option value=' + i + '>' + binaryInstallAgents[i] + '</option>' }
 | 
			
		||||
                x += '<div id=aginsSysTypeDiv>';
 | 
			
		||||
                x += addHtmlValue("System Type", '<select id=aginsSysType onchange=addAgentToMeshClick() style=width:236px>' + moreoptions + '</select>');
 | 
			
		||||
                x += '</div>';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            x += '<div id=aginsTypeDiv>';
 | 
			
		||||
            x += addHtmlValue("Installation Type", '<select id=aginsType onchange=addAgentToMeshClick() style=width:236px><option value=0>' + "Background & interactive" + '</option><option value=2>' + "Background only" + '</option><option value=1>' + "Interactive only" + '</option></select>');
 | 
			
		||||
            x += '</div><hr>';
 | 
			
		||||
| 
						 | 
				
			
			@ -4144,6 +4155,13 @@
 | 
			
		|||
            x += '<textarea id=agins_linux_area_un rows=2 cols=20 readonly=readonly style=width:100%;resize:none;height:120px;overflow:scroll;font-size:12px readonly></textarea>';
 | 
			
		||||
            x += '</div>';
 | 
			
		||||
 | 
			
		||||
            if (debugmode > 0) { 
 | 
			
		||||
                // Linux binary installer
 | 
			
		||||
                x += '<div id=agins_linux_inst style=display:none>' + "This is a executable that will only run as root and on OS's with graphical user interfaces." + '<br /><br />';
 | 
			
		||||
                x += addHtmlValue("Mesh Agent", '<a id=aginsbinlnk href="meshagents?id=' + meshid.split('/')[2] + '&installflags=0' + (urlargs.key?('&key=' + urlargs.key):'') + '" download onclick="setDialogMode(0)">' + "meshagent" + '</a> <img src=images/link4.png height=10 width=10 title="' + "Copy agent URL to clipboard" + '" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=' + meshid.split('/')[2] + '&installflags=",1)>');
 | 
			
		||||
                x += '</div>';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            setDialogMode(2, "Add Mesh Agent", 2, null, x, 'fileDownload');
 | 
			
		||||
            var servername = serverinfo.name;
 | 
			
		||||
            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.
 | 
			
		||||
| 
						 | 
				
			
			@ -4192,6 +4210,7 @@
 | 
			
		|||
            var c = 'https://' + servername + portStr + domainUrl + url;
 | 
			
		||||
            if (addflag == 1) c += Q('aginsType').value;
 | 
			
		||||
            c += (urlargs.key?('&key=' + urlargs.key):'');
 | 
			
		||||
            if (debugmode > 0) { if (Q('aginsSelect').value == 5) { c += '&meshinstall=' + Q('aginsSysType').value; } }
 | 
			
		||||
            copyTextToClip(c);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4202,7 +4221,12 @@
 | 
			
		|||
            QV('agins_osx', v == 2);
 | 
			
		||||
            QV('agins_windows_un', v == 3);
 | 
			
		||||
            QV('agins_linux_un', v == 4);
 | 
			
		||||
            QV('aginsTypeDiv', v == 0);
 | 
			
		||||
            if (debugmode > 0) {
 | 
			
		||||
                QV('agins_linux_inst', v == 5);
 | 
			
		||||
                QV('aginsSysTypeDiv', v == 5);
 | 
			
		||||
                Q('aginsbinlnk').href = (Q('aginsbinlnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'') + '&meshinstall=' + Q('aginsSysType').value;
 | 
			
		||||
            }
 | 
			
		||||
            QV('aginsTypeDiv', (v == 0) || (v == 5));
 | 
			
		||||
 | 
			
		||||
            // Fix the links if needed
 | 
			
		||||
            Q('aginsw32lnk').href = (Q('aginsw32lnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'');
 | 
			
		||||
| 
						 | 
				
			
			@ -12012,9 +12036,9 @@
 | 
			
		|||
            for (var i=0;i<elements.length;i++) { if (elements[i].checked) { checkedRecordings.push(elements[i].value); } }
 | 
			
		||||
 | 
			
		||||
            if (p52recordings == null) {
 | 
			
		||||
                x += '<div style=width:100%;text-align:center;margin-top:20px><i>' + "Loading..." + "</i></div>";
 | 
			
		||||
                x += '<div style=width:100%;text-align:center;margin-top:20px><i>' + "Loading..." + '</i></div>';
 | 
			
		||||
            } else if (p52recordings.length == 0) {
 | 
			
		||||
                x += '<div style=width:100%;text-align:center;margin-top:20px><i>' + "No recordings." + "</i></div>";
 | 
			
		||||
                x += '<div style=width:100%;text-align:center;margin-top:20px><i>' + "No recordings." + '</i></div>';
 | 
			
		||||
            } else {
 | 
			
		||||
                // Display the users using the sorted list
 | 
			
		||||
                x += '<table class=p3usersTable cellpadding=0 cellspacing=0>';
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										53
									
								
								webserver.js
									
										
									
									
									
								
							
							
						
						
									
										53
									
								
								webserver.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -3911,7 +3911,29 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
        // If required, check if this user has rights to do this
 | 
			
		||||
        if ((obj.parent.config.settings != null) && ((obj.parent.config.settings.lockagentdownload == true) || (domain.lockagentdownload == true)) && (req.session.userid == null)) { res.sendStatus(401); return; }
 | 
			
		||||
 | 
			
		||||
        if (req.query.id != null) {
 | 
			
		||||
        if ((req.query.meshinstall != null) && (req.query.id != null)) {
 | 
			
		||||
            if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
 | 
			
		||||
 | 
			
		||||
            // Send meshagent with included self installer for a specific platform back
 | 
			
		||||
            // Start by getting the .msh for this request
 | 
			
		||||
            var meshsettings = getMshFromRequest(req, res, domain);
 | 
			
		||||
            if (meshsettings == null) { res.sendStatus(401); return; }
 | 
			
		||||
 | 
			
		||||
            // Get the interactive install script, this only works for non-Windows agents
 | 
			
		||||
            var agentid = parseInt(req.query.meshinstall);
 | 
			
		||||
            var argentInfo = obj.parent.meshAgentBinaries[agentid];
 | 
			
		||||
            var scriptInfo = obj.parent.meshAgentInstallScripts[6];
 | 
			
		||||
            if ((argentInfo == null) || (scriptInfo == null) || (argentInfo.platform == 'win32')) { res.sendStatus(404); return; }
 | 
			
		||||
 | 
			
		||||
            // Change the .msh file into JSON format and merge it into the install script
 | 
			
		||||
            var tokens, msh = {}, meshsettingslines = meshsettings.split('\r').join('').split('\n');
 | 
			
		||||
            for (var i in meshsettingslines) { tokens = meshsettingslines[i].split('='); if (tokens.length == 2) { msh[tokens[0]] = tokens[1]; } }
 | 
			
		||||
            var js = scriptInfo.data.replace('var msh = {};', 'var msh = ' + JSON.stringify(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"' });
 | 
			
		||||
            res.statusCode = 200;
 | 
			
		||||
            obj.parent.exeHandler.streamExeWithJavaScript({ platform: argentInfo.platform, sourceFileName: argentInfo.path, destinationStream: res, js: Buffer.from(js, 'utf8'), peinfo: argentInfo.pe });
 | 
			
		||||
        } else if (req.query.id != null) {
 | 
			
		||||
            // Send a specific mesh agent back
 | 
			
		||||
            var argentInfo = obj.parent.meshAgentBinaries[req.query.id];
 | 
			
		||||
            if (argentInfo == null) { res.sendStatus(404); return; }
 | 
			
		||||
| 
						 | 
				
			
			@ -4012,7 +4034,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
            res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshcmd' + ((req.query.meshcmd <= 4) ? '.exe' : '') + '"' });
 | 
			
		||||
            res.statusCode = 200;
 | 
			
		||||
            if (argentInfo.signedMeshCmdPath != null) {
 | 
			
		||||
                // If we hav a pre-signed MeshCmd, send that.
 | 
			
		||||
                // If we have a pre-signed MeshCmd, send that.
 | 
			
		||||
                res.sendFile(argentInfo.signedMeshCmdPath);
 | 
			
		||||
            } else {
 | 
			
		||||
                // Merge JavaScript to a unsigned agent and send that.
 | 
			
		||||
| 
						 | 
				
			
			@ -4073,6 +4095,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
            domain = checkUserIpAddress(req, res); // Recheck the domain to apply user IP filtering.
 | 
			
		||||
            if (domain == null) return;
 | 
			
		||||
            if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
 | 
			
		||||
            if ((req.session == null) || (req.session.userid == null)) { res.sendStatus(404); return; }
 | 
			
		||||
 | 
			
		||||
            // Send a list of available mesh agents
 | 
			
		||||
            var response = '<html><head><title>Mesh Agents</title><style>table,th,td { border:1px solid black;border-collapse:collapse;padding:3px; }</style></head><body><table>';
 | 
			
		||||
            response += '<tr style="background-color:lightgray"><th>ID</th><th>Description</th><th>Link</th><th>Size</th><th>SHA384</th><th>MeshCmd</th></tr>';
 | 
			
		||||
| 
						 | 
				
			
			@ -4200,14 +4224,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Handle a request to download a mesh settings
 | 
			
		||||
    obj.handleMeshSettingsRequest = function (req, res) {
 | 
			
		||||
        const domain = getDomain(req);
 | 
			
		||||
        if (domain == null) { return; }
 | 
			
		||||
        //if ((domain.id !== '') || (!req.session) || (req.session == null) || (!req.session.userid)) { res.sendStatus(401); return; }
 | 
			
		||||
 | 
			
		||||
    // Return a .msh file from a given request, id is the device group identifier or encrypted cookie with the identifier.
 | 
			
		||||
    function getMshFromRequest(req, res, domain) {
 | 
			
		||||
        // If required, check if this user has rights to do this
 | 
			
		||||
        if ((obj.parent.config.settings != null) && ((obj.parent.config.settings.lockagentdownload == true) || (domain.lockagentdownload == true)) && (req.session.userid == null)) { res.sendStatus(401); return; }
 | 
			
		||||
        if ((obj.parent.config.settings != null) && ((obj.parent.config.settings.lockagentdownload == true) || (domain.lockagentdownload == true)) && (req.session.userid == null)) { return null; }
 | 
			
		||||
 | 
			
		||||
        // Check if the meshid is a time limited, encrypted cookie
 | 
			
		||||
        var meshcookie = obj.parent.decodeCookie(req.query.id, obj.parent.invitationLinkEncryptionKey);
 | 
			
		||||
| 
						 | 
				
			
			@ -4215,11 +4235,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
 | 
			
		||||
        // Fetch the mesh object
 | 
			
		||||
        var mesh = obj.meshes['mesh/' + domain.id + '/' + req.query.id];
 | 
			
		||||
        if (mesh == null) { res.sendStatus(401); return; }
 | 
			
		||||
        if (mesh == null) { return null; }
 | 
			
		||||
 | 
			
		||||
        // If needed, check if this user has rights to do this
 | 
			
		||||
        if ((obj.parent.config.settings != null) && ((obj.parent.config.settings.lockagentdownload == true) || (domain.lockagentdownload == true))) {
 | 
			
		||||
            if ((domain.id != mesh.domain) || ((obj.GetMeshRights(req.session.userid, mesh) & 1) == 0)) { res.sendStatus(401); return; }
 | 
			
		||||
            if ((domain.id != mesh.domain) || ((obj.GetMeshRights(req.session.userid, mesh) & 1) == 0)) { return null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var meshidhex = Buffer.from(req.query.id.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
 | 
			
		||||
| 
						 | 
				
			
			@ -4245,6 +4265,17 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
        if ((domain.agentnoproxy === true) || (obj.args.lanonly == true)) { meshsettings += 'ignoreProxyFile=1\r\n'; }
 | 
			
		||||
        if (obj.args.agentconfig) { for (var i in obj.args.agentconfig) { meshsettings += obj.args.agentconfig[i] + '\r\n'; } }
 | 
			
		||||
        if (domain.agentconfig) { for (var i in domain.agentconfig) { meshsettings += domain.agentconfig[i] + '\r\n'; } }
 | 
			
		||||
        return meshsettings;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Handle a request to download a mesh settings
 | 
			
		||||
    obj.handleMeshSettingsRequest = function (req, res) {
 | 
			
		||||
        const domain = getDomain(req);
 | 
			
		||||
        if (domain == null) { return; }
 | 
			
		||||
        //if ((domain.id !== '') || (!req.session) || (req.session == null) || (!req.session.userid)) { res.sendStatus(401); return; }
 | 
			
		||||
 | 
			
		||||
        var meshsettings = getMshFromRequest(req, res, domain);
 | 
			
		||||
        if (meshsettings == null) { res.sendStatus(401); return; }
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue