mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Fixed usernames that include a dot (.)
This commit is contained in:
		
							parent
							
								
									5949c7456c
								
							
						
					
					
						commit
						81ccbae15c
					
				
					 16 changed files with 139 additions and 91 deletions
				
			
		
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -1095,6 +1095,11 @@ function kvmCtrlData(channel, cmd) {
 | 
			
		|||
    try { cmd = JSON.parse(cmd); } catch (ex) { console.error('Invalid JSON: ' + cmd); return; }
 | 
			
		||||
    if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
 | 
			
		||||
    switch (cmd.action) {
 | 
			
		||||
        case 'ping': {
 | 
			
		||||
            // This is a keep alive
 | 
			
		||||
            channel.write({ action: 'pong' });
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        case 'ls': {
 | 
			
		||||
            /*
 | 
			
		||||
            // Close the watcher if required
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1518,6 +1518,11 @@ function createMeshCore(agent) {
 | 
			
		|||
        try { cmd = JSON.parse(cmd); } catch (ex) { console.error('Invalid JSON: ' + cmd); return; }
 | 
			
		||||
        if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
 | 
			
		||||
        switch (cmd.action) {
 | 
			
		||||
            case 'ping': {
 | 
			
		||||
                // This is a keep alive
 | 
			
		||||
                channel.write({ action: 'pong' });
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'ls': {
 | 
			
		||||
                /*
 | 
			
		||||
                // Close the watcher if required
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -130,7 +130,7 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // Returns the web server TLS certificate and private key, if not present, create demonstration ones.
 | 
			
		||||
    obj.GetMeshServerCertificate = function (directory, args, config, parent, func) {
 | 
			
		||||
    obj.GetMeshServerCertificate = function (parent, args, config, func) {
 | 
			
		||||
        var certargs = args.cert;
 | 
			
		||||
        var mpscertargs = args.mpscert;
 | 
			
		||||
        var strongCertificate = (args.fastcert ? false : true);
 | 
			
		||||
| 
						 | 
				
			
			@ -138,68 +138,68 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
        // commonName, country, organization
 | 
			
		||||
        
 | 
			
		||||
        // If the certificates directory does not exist, create it.
 | 
			
		||||
        if (!obj.dirExists(directory)) { obj.fs.mkdirSync(directory); }
 | 
			
		||||
        if (!obj.dirExists(parent.datapath)) { obj.fs.mkdirSync(parent.datapath); }
 | 
			
		||||
        var r = {}, rcount = 0;
 | 
			
		||||
        
 | 
			
		||||
        // If the root certificate already exist, load it
 | 
			
		||||
        if (obj.fileExists(directory + '/root-cert-public.crt') && obj.fileExists(directory + '/root-cert-private.key')) {
 | 
			
		||||
            var rootCertificate = obj.fs.readFileSync(directory + '/root-cert-public.crt', 'utf8');
 | 
			
		||||
            var rootPrivateKey = obj.fs.readFileSync(directory + '/root-cert-private.key', 'utf8');
 | 
			
		||||
        if (obj.fileExists(parent.getConfigFilePath('root-cert-public.crt')) && obj.fileExists(parent.getConfigFilePath('root-cert-private.key'))) {
 | 
			
		||||
            var rootCertificate = obj.fs.readFileSync(parent.getConfigFilePath('root-cert-public.crt'), 'utf8');
 | 
			
		||||
            var rootPrivateKey = obj.fs.readFileSync(parent.getConfigFilePath('root-cert-private.key'), 'utf8');
 | 
			
		||||
            r.root = { cert: rootCertificate, key: rootPrivateKey };
 | 
			
		||||
            rcount++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (args.tlsoffload == true) {
 | 
			
		||||
            // If the web certificate already exist, load it. Load just the certificate since we are in TLS offload situation
 | 
			
		||||
            if (obj.fileExists(directory + '/webserver-cert-public.crt')) {
 | 
			
		||||
                var webCertificate = obj.fs.readFileSync(directory + '/webserver-cert-public.crt', 'utf8');
 | 
			
		||||
            if (obj.fileExists(parent.getConfigFilePath('webserver-cert-public.crt'))) {
 | 
			
		||||
                var webCertificate = obj.fs.readFileSync(parent.getConfigFilePath('webserver-cert-public.crt'), 'utf8');
 | 
			
		||||
                r.web = { cert: webCertificate };
 | 
			
		||||
                rcount++;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            // If the web certificate already exist, load it. Load both certificate and private key
 | 
			
		||||
            if (obj.fileExists(directory + '/webserver-cert-public.crt') && obj.fileExists(directory + '/webserver-cert-private.key')) {
 | 
			
		||||
                var webCertificate = obj.fs.readFileSync(directory + '/webserver-cert-public.crt', 'utf8');
 | 
			
		||||
                var webPrivateKey = obj.fs.readFileSync(directory + '/webserver-cert-private.key', 'utf8');
 | 
			
		||||
            if (obj.fileExists(parent.getConfigFilePath('webserver-cert-public.crt')) && obj.fileExists(parent.getConfigFilePath('webserver-cert-private.key'))) {
 | 
			
		||||
                var webCertificate = obj.fs.readFileSync(parent.getConfigFilePath('webserver-cert-public.crt'), 'utf8');
 | 
			
		||||
                var webPrivateKey = obj.fs.readFileSync(parent.getConfigFilePath('webserver-cert-private.key'), 'utf8');
 | 
			
		||||
                r.web = { cert: webCertificate, key: webPrivateKey };
 | 
			
		||||
                rcount++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // If the mps certificate already exist, load it
 | 
			
		||||
        if (obj.fileExists(directory + '/mpsserver-cert-public.crt') && obj.fileExists(directory + '/mpsserver-cert-private.key')) {
 | 
			
		||||
            var mpsCertificate = obj.fs.readFileSync(directory + '/mpsserver-cert-public.crt', 'utf8');
 | 
			
		||||
            var mpsPrivateKey = obj.fs.readFileSync(directory + '/mpsserver-cert-private.key', 'utf8');
 | 
			
		||||
        if (obj.fileExists(parent.getConfigFilePath('mpsserver-cert-public.crt')) && obj.fileExists(parent.getConfigFilePath('mpsserver-cert-private.key'))) {
 | 
			
		||||
            var mpsCertificate = obj.fs.readFileSync(parent.getConfigFilePath('mpsserver-cert-public.crt'), 'utf8');
 | 
			
		||||
            var mpsPrivateKey = obj.fs.readFileSync(parent.getConfigFilePath('mpsserver-cert-private.key'), 'utf8');
 | 
			
		||||
            r.mps = { cert: mpsCertificate, key: mpsPrivateKey };
 | 
			
		||||
            rcount++;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // If the agent certificate already exist, load it
 | 
			
		||||
        if (obj.fileExists(directory + '/agentserver-cert-public.crt') && obj.fileExists(directory + '/agentserver-cert-private.key')) {
 | 
			
		||||
            var agentCertificate = obj.fs.readFileSync(directory + '/agentserver-cert-public.crt', 'utf8');
 | 
			
		||||
            var agentPrivateKey = obj.fs.readFileSync(directory + '/agentserver-cert-private.key', 'utf8');
 | 
			
		||||
        if (obj.fileExists(parent.getConfigFilePath('agentserver-cert-public.crt')) && obj.fileExists(parent.getConfigFilePath('agentserver-cert-private.key'))) {
 | 
			
		||||
            var agentCertificate = obj.fs.readFileSync(parent.getConfigFilePath('agentserver-cert-public.crt'), 'utf8');
 | 
			
		||||
            var agentPrivateKey = obj.fs.readFileSync(parent.getConfigFilePath('agentserver-cert-private.key'), 'utf8');
 | 
			
		||||
            r.agent = { cert: agentCertificate, key: agentPrivateKey };
 | 
			
		||||
            rcount++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If the console certificate already exist, load it
 | 
			
		||||
        if (obj.fileExists(directory + '/amtconsole-cert-public.crt') && obj.fileExists(directory + '/agentserver-cert-private.key')) {
 | 
			
		||||
            var amtConsoleCertificate = obj.fs.readFileSync(directory + '/amtconsole-cert-public.crt', 'utf8');
 | 
			
		||||
            var amtConsolePrivateKey = obj.fs.readFileSync(directory + '/amtconsole-cert-private.key', 'utf8');
 | 
			
		||||
        if (obj.fileExists(parent.getConfigFilePath('amtconsole-cert-public.crt')) && obj.fileExists(parent.getConfigFilePath('agentserver-cert-private.key'))) {
 | 
			
		||||
            var amtConsoleCertificate = obj.fs.readFileSync(parent.getConfigFilePath('amtconsole-cert-public.crt'), 'utf8');
 | 
			
		||||
            var amtConsolePrivateKey = obj.fs.readFileSync(parent.getConfigFilePath('amtconsole-cert-private.key'), 'utf8');
 | 
			
		||||
            r.console = { cert: amtConsoleCertificate, key: amtConsolePrivateKey };
 | 
			
		||||
            rcount++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If the swarm server certificate exist, load it (This is an optional certificate)
 | 
			
		||||
        if (obj.fileExists(directory + '/swarmserver-cert-public.crt') && obj.fileExists(directory + '/swarmserver-cert-private.key')) {
 | 
			
		||||
            var swarmServerCertificate = obj.fs.readFileSync(directory + '/swarmserver-cert-public.crt', 'utf8');
 | 
			
		||||
            var swarmServerPrivateKey = obj.fs.readFileSync(directory + '/swarmserver-cert-private.key', 'utf8');
 | 
			
		||||
        if (obj.fileExists(parent.getConfigFilePath('swarmserver-cert-public.crt')) && obj.fileExists(parent.getConfigFilePath('swarmserver-cert-private.key'))) {
 | 
			
		||||
            var swarmServerCertificate = obj.fs.readFileSync(parent.getConfigFilePath('swarmserver-cert-public.crt'), 'utf8');
 | 
			
		||||
            var swarmServerPrivateKey = obj.fs.readFileSync(parent.getConfigFilePath('swarmserver-cert-private.key'), 'utf8');
 | 
			
		||||
            r.swarmserver = { cert: swarmServerCertificate, key: swarmServerPrivateKey };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If the swarm server root certificate exist, load it (This is an optional certificate)
 | 
			
		||||
        if (obj.fileExists(directory + '/swarmserverroot-cert-public.crt')) {
 | 
			
		||||
            var swarmServerRootCertificate = obj.fs.readFileSync(directory + '/swarmserverroot-cert-public.crt', 'utf8');
 | 
			
		||||
        if (obj.fileExists(parent.getConfigFilePath('swarmserverroot-cert-public.crt'))) {
 | 
			
		||||
            var swarmServerRootCertificate = obj.fs.readFileSync(parent.getConfigFilePath('swarmserverroot-cert-public.crt'), 'utf8');
 | 
			
		||||
            r.swarmserverroot = { cert: swarmServerRootCertificate };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -208,8 +208,8 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
            var caok, caindex = 1, calist = [];
 | 
			
		||||
            do {
 | 
			
		||||
                caok = false;
 | 
			
		||||
                if (obj.fileExists(directory + '/webserver-cert-chain' + caindex + '.crt')) {
 | 
			
		||||
                    var caCertificate = obj.fs.readFileSync(directory + '/webserver-cert-chain' + caindex + '.crt', 'utf8');
 | 
			
		||||
                if (obj.fileExists(parent.getConfigFilePath('webserver-cert-chain' + caindex + '.crt'))) {
 | 
			
		||||
                    var caCertificate = obj.fs.readFileSync(parent.getConfigFilePath('webserver-cert-chain' + caindex + '.crt'), 'utf8');
 | 
			
		||||
                    calist.push(caCertificate);
 | 
			
		||||
                    caok = true;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -243,23 +243,23 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
                var dnsname = config.domains[i].dns;
 | 
			
		||||
                if (args.tlsoffload == true) {
 | 
			
		||||
                    // If the web certificate already exist, load it. Load just the certificate since we are in TLS offload situation
 | 
			
		||||
                    if (obj.fileExists(directory + '/webserver-' + i + '-cert-public.crt')) {
 | 
			
		||||
                        r.dns[i] = { cert: obj.fs.readFileSync(directory + '/webserver-' + i + '-cert-public.crt', 'utf8') };
 | 
			
		||||
                    if (obj.fileExists(parent.getConfigFilePath('webserver-' + i + '-cert-public.crt'))) {
 | 
			
		||||
                        r.dns[i] = { cert: obj.fs.readFileSync(parent.getConfigFilePath('webserver-' + i + '-cert-public.crt'), 'utf8') };
 | 
			
		||||
                        config.domains[i].certs = r.dns[i];
 | 
			
		||||
                    } else {
 | 
			
		||||
                        console.log('WARNING: File "webserver-' + i + '-cert-public.crt" missing, domain "' + i + '" will not work correctly.');
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    // If the web certificate already exist, load it. Load both certificate and private key
 | 
			
		||||
                    if (obj.fileExists(directory + '/webserver-' + i + '-cert-public.crt') && obj.fileExists(directory + '/webserver-' + i + '-cert-private.key')) {
 | 
			
		||||
                        r.dns[i] = { cert: obj.fs.readFileSync(directory + '/webserver-' + i + '-cert-public.crt', 'utf8'), key: obj.fs.readFileSync(directory + '/webserver-' + i + '-cert-private.key', 'utf8') };
 | 
			
		||||
                    if (obj.fileExists(parent.getConfigFilePath('webserver-' + i + '-cert-public.crt')) && obj.fileExists(parent.getConfigFilePath('webserver-' + i + '-cert-private.key'))) {
 | 
			
		||||
                        r.dns[i] = { cert: obj.fs.readFileSync(parent.getConfigFilePath('webserver-' + i + '-cert-public.crt'), 'utf8'), key: obj.fs.readFileSync(parent.getConfigFilePath('webserver-' + i + '-cert-private.key'), 'utf8') };
 | 
			
		||||
                        config.domains[i].certs = r.dns[i];
 | 
			
		||||
                        // If CA certificates are present, load them
 | 
			
		||||
                        var caok, caindex = 1, calist = [];
 | 
			
		||||
                        do {
 | 
			
		||||
                            caok = false;
 | 
			
		||||
                            if (obj.fileExists(directory + '/webserver-' + i + '-cert-chain' + caindex + '.crt')) {
 | 
			
		||||
                                var caCertificate = obj.fs.readFileSync(directory + '/webserver-' + i + '-cert-chain' + caindex + '.crt', 'utf8');
 | 
			
		||||
                            if (obj.fileExists(parent.getConfigFilePath('webserver-' + i + '-cert-chain' + caindex + '.crt'))) {
 | 
			
		||||
                                var caCertificate = obj.fs.readFileSync(parent.getConfigFilePath('webserver-' + i + '-cert-chain' + caindex + '.crt'), 'utf8');
 | 
			
		||||
                                calist.push(caCertificate);
 | 
			
		||||
                                caok = true;
 | 
			
		||||
                            }
 | 
			
		||||
| 
						 | 
				
			
			@ -323,8 +323,8 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
            rootCertAndKey = obj.GenerateRootCertificate(true, 'MeshCentralRoot', null, null, strongCertificate);
 | 
			
		||||
            rootCertificate = obj.pki.certificateToPem(rootCertAndKey.cert);
 | 
			
		||||
            rootPrivateKey = obj.pki.privateKeyToPem(rootCertAndKey.key);
 | 
			
		||||
            obj.fs.writeFileSync(directory + '/root-cert-public.crt', rootCertificate);
 | 
			
		||||
            obj.fs.writeFileSync(directory + '/root-cert-private.key', rootPrivateKey);
 | 
			
		||||
            obj.fs.writeFileSync(parent.getConfigFilePath('root-cert-public.crt'), rootCertificate);
 | 
			
		||||
            obj.fs.writeFileSync(parent.getConfigFilePath('root-cert-private.key'), rootPrivateKey);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Keep the root certificate we have
 | 
			
		||||
            rootCertAndKey = { cert: obj.pki.certificateFromPem(r.root.cert), key: obj.pki.privateKeyFromPem(r.root.key) };
 | 
			
		||||
| 
						 | 
				
			
			@ -340,8 +340,8 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
            webCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, commonName, country, organization, null, strongCertificate);
 | 
			
		||||
            webCertificate = obj.pki.certificateToPem(webCertAndKey.cert);
 | 
			
		||||
            webPrivateKey = obj.pki.privateKeyToPem(webCertAndKey.key);
 | 
			
		||||
            obj.fs.writeFileSync(directory + '/webserver-cert-public.crt', webCertificate);
 | 
			
		||||
            obj.fs.writeFileSync(directory + '/webserver-cert-private.key', webPrivateKey);
 | 
			
		||||
            obj.fs.writeFileSync(parent.getConfigFilePath('webserver-cert-public.crt'), webCertificate);
 | 
			
		||||
            obj.fs.writeFileSync(parent.getConfigFilePath('webserver-cert-private.key'), webPrivateKey);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Keep the console certificate we have
 | 
			
		||||
            webCertAndKey = { cert: obj.pki.certificateFromPem(r.web.cert), key: obj.pki.privateKeyFromPem(r.web.key) };
 | 
			
		||||
| 
						 | 
				
			
			@ -356,8 +356,8 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
            agentCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, true, 'MeshCentralAgentServer', null, strongCertificate);
 | 
			
		||||
            agentCertificate = obj.pki.certificateToPem(agentCertAndKey.cert);
 | 
			
		||||
            agentPrivateKey = obj.pki.privateKeyToPem(agentCertAndKey.key);
 | 
			
		||||
            obj.fs.writeFileSync(directory + '/agentserver-cert-public.crt', agentCertificate);
 | 
			
		||||
            obj.fs.writeFileSync(directory + '/agentserver-cert-private.key', agentPrivateKey);
 | 
			
		||||
            obj.fs.writeFileSync(parent.getConfigFilePath('agentserver-cert-public.crt'), agentCertificate);
 | 
			
		||||
            obj.fs.writeFileSync(parent.getConfigFilePath('agentserver-cert-private.key'), agentPrivateKey);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Keep the mesh agent server certificate we have
 | 
			
		||||
            agentCertAndKey = { cert: obj.pki.certificateFromPem(r.agent.cert), key: obj.pki.privateKeyFromPem(r.agent.key) };
 | 
			
		||||
| 
						 | 
				
			
			@ -372,8 +372,8 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
            mpsCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, mpsCommonName, mpsCountry, mpsOrganization, null, false);
 | 
			
		||||
            mpsCertificate = obj.pki.certificateToPem(mpsCertAndKey.cert);
 | 
			
		||||
            mpsPrivateKey = obj.pki.privateKeyToPem(mpsCertAndKey.key);
 | 
			
		||||
            obj.fs.writeFileSync(directory + '/mpsserver-cert-public.crt', mpsCertificate);
 | 
			
		||||
            obj.fs.writeFileSync(directory + '/mpsserver-cert-private.key', mpsPrivateKey);
 | 
			
		||||
            obj.fs.writeFileSync(parent.getConfigFilePath('mpsserver-cert-public.crt'), mpsCertificate);
 | 
			
		||||
            obj.fs.writeFileSync(parent.getConfigFilePath('mpsserver-cert-private.key'), mpsPrivateKey);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Keep the console certificate we have
 | 
			
		||||
            mpsCertAndKey = { cert: obj.pki.certificateFromPem(r.mps.cert), key: obj.pki.privateKeyFromPem(r.mps.key) };
 | 
			
		||||
| 
						 | 
				
			
			@ -388,8 +388,8 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
            consoleCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, amtConsoleName, country, organization, { name: 'extKeyUsage', clientAuth: true, '2.16.840.1.113741.1.2.1': true, '2.16.840.1.113741.1.2.2': true, '2.16.840.1.113741.1.2.3': true }, false); // Intel AMT Remote, Agent and Activation usages
 | 
			
		||||
            consoleCertificate = obj.pki.certificateToPem(consoleCertAndKey.cert);
 | 
			
		||||
            consolePrivateKey = obj.pki.privateKeyToPem(consoleCertAndKey.key);
 | 
			
		||||
            obj.fs.writeFileSync(directory + '/amtconsole-cert-public.crt', consoleCertificate);
 | 
			
		||||
            obj.fs.writeFileSync(directory + '/amtconsole-cert-private.key', consolePrivateKey);
 | 
			
		||||
            obj.fs.writeFileSync(parent.getConfigFilePath('amtconsole-cert-public.crt'), consoleCertificate);
 | 
			
		||||
            obj.fs.writeFileSync(parent.getConfigFilePath('amtconsole-cert-private.key'), consolePrivateKey);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Keep the console certificate we have
 | 
			
		||||
            consoleCertAndKey = { cert: obj.pki.certificateFromPem(r.console.cert), key: obj.pki.privateKeyFromPem(r.console.key) };
 | 
			
		||||
| 
						 | 
				
			
			@ -406,13 +406,13 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
                var dnsname = config.domains[i].dns;
 | 
			
		||||
                if (args.tlsoffload != true) {
 | 
			
		||||
                    // If the web certificate does not exist, create it
 | 
			
		||||
                    if ((obj.fileExists(directory + '/webserver-' + i + '-cert-public.crt') == false) || (obj.fileExists(directory + '/webserver-' + i + '-cert-private.key') == false)) {
 | 
			
		||||
                    if ((obj.fileExists(parent.getConfigFilePath('webserver-' + i + '-cert-public.crt')) == false) || (obj.fileExists(parent.getConfigFilePath('webserver-' + i + '-cert-private.key')) == false)) {
 | 
			
		||||
                        console.log('Generating HTTPS certificate for ' + i + '...');
 | 
			
		||||
                        var xwebCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, dnsname, country, organization, null, strongCertificate);
 | 
			
		||||
                        var xwebCertificate = obj.pki.certificateToPem(xwebCertAndKey.cert);
 | 
			
		||||
                        var xwebPrivateKey = obj.pki.privateKeyToPem(xwebCertAndKey.key);
 | 
			
		||||
                        obj.fs.writeFileSync(directory + '/webserver-' + i + '-cert-public.crt', xwebCertificate);
 | 
			
		||||
                        obj.fs.writeFileSync(directory + '/webserver-' + i + '-cert-private.key', xwebPrivateKey);
 | 
			
		||||
                        obj.fs.writeFileSync(parent.getConfigFilePath('webserver-' + i + '-cert-public.crt'), xwebCertificate);
 | 
			
		||||
                        obj.fs.writeFileSync(parent.getConfigFilePath('webserver-' + i + '-cert-private.key'), xwebPrivateKey);
 | 
			
		||||
                        r.dns[i] = { cert: xwebCertificate, key: xwebPrivateKey };
 | 
			
		||||
                        config.domains[i].certs = r.dns[i];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -420,8 +420,8 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
                        var caok, caindex = 1, calist = [];
 | 
			
		||||
                        do {
 | 
			
		||||
                            caok = false;
 | 
			
		||||
                            if (obj.fileExists(directory + '/webserver-' + i + '-cert-chain' + caindex + '.crt')) {
 | 
			
		||||
                                var caCertificate = obj.fs.readFileSync(directory + '/webserver-' + i + '-cert-chain' + caindex + '.crt', 'utf8');
 | 
			
		||||
                            if (obj.fileExists(parent.getConfigFilePath('webserver-' + i + '-cert-chain' + caindex + '.crt'))) {
 | 
			
		||||
                                var caCertificate = obj.fs.readFileSync(parent.getConfigFilePath('webserver-' + i + '-cert-chain' + caindex + '.crt'), 'utf8');
 | 
			
		||||
                                calist.push(caCertificate);
 | 
			
		||||
                                caok = true;
 | 
			
		||||
                            }
 | 
			
		||||
| 
						 | 
				
			
			@ -434,15 +434,15 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        // If the swarm server certificate exist, load it (This is an optional certificate)
 | 
			
		||||
        if (obj.fileExists(directory + '/swarmserver-cert-public.crt') && obj.fileExists(directory + '/swarmserver-cert-private.key')) {
 | 
			
		||||
            var swarmServerCertificate = obj.fs.readFileSync(directory + '/swarmserver-cert-public.crt', 'utf8');
 | 
			
		||||
            var swarmServerPrivateKey = obj.fs.readFileSync(directory + '/swarmserver-cert-private.key', 'utf8');
 | 
			
		||||
        if (obj.fileExists(parent.getConfigFilePath('swarmserver-cert-public.crt')) && obj.fileExists(parent.getConfigFilePath('swarmserver-cert-private.key'))) {
 | 
			
		||||
            var swarmServerCertificate = obj.fs.readFileSync(parent.getConfigFilePath('swarmserver-cert-public.crt'), 'utf8');
 | 
			
		||||
            var swarmServerPrivateKey = obj.fs.readFileSync(parent.getConfigFilePath('swarmserver-cert-private.key'), 'utf8');
 | 
			
		||||
            r.swarmserver = { cert: swarmServerCertificate, key: swarmServerPrivateKey };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If the swarm server root certificate exist, load it (This is an optional certificate)
 | 
			
		||||
        if (obj.fileExists(directory + '/swarmserverroot-cert-public.crt')) {
 | 
			
		||||
            var swarmServerRootCertificate = obj.fs.readFileSync(directory + '/swarmserverroot-cert-public.crt', 'utf8');
 | 
			
		||||
        if (obj.fileExists(parent.getConfigFilePath('swarmserverroot-cert-public.crt'))) {
 | 
			
		||||
            var swarmServerRootCertificate = obj.fs.readFileSync(parent.getConfigFilePath('swarmserverroot-cert-public.crt'), 'utf8');
 | 
			
		||||
            r.swarmserverroot = { cert: swarmServerRootCertificate };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -451,8 +451,8 @@ module.exports.CertificateOperations = function () {
 | 
			
		|||
            var caok, caindex = 1, calist = [];
 | 
			
		||||
            do {
 | 
			
		||||
                caok = false;
 | 
			
		||||
                if (obj.fileExists(directory + '/webserver-cert-chain' + caindex + '.crt')) {
 | 
			
		||||
                    var caCertificate = obj.fs.readFileSync(directory + '/webserver-cert-chain' + caindex + '.crt', 'utf8');
 | 
			
		||||
                if (obj.fileExists(parent.getConfigFilePath('webserver-cert-chain' + caindex + '.crt'))) {
 | 
			
		||||
                    var caCertificate = obj.fs.readFileSync(parent.getConfigFilePath('webserver-cert-chain' + caindex + '.crt'), 'utf8');
 | 
			
		||||
                    calist.push(caCertificate);
 | 
			
		||||
                    caok = true;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								common.js
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								common.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -127,6 +127,16 @@ module.exports.objKeysToLower = function (obj) {
 | 
			
		|||
    return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Escape and unexcape feild names so there are no invalid characters for MongoDB
 | 
			
		||||
module.exports.escapeFieldName = function (name) { return name.split('%').join('%25').split('.').join('%2E').split('$').join('%24'); }
 | 
			
		||||
module.exports.unEscapeFieldName = function (name) { return name.split('%2E').join('.').split('%24').join('$').split('%25').join('%'); }
 | 
			
		||||
 | 
			
		||||
// Escape all links
 | 
			
		||||
module.exports.escapeLinksFieldName = function (docx) { var doc = module.exports.Clone(docx); if (doc.links != null) { for (var j in doc.links) { var ue = module.exports.escapeFieldName(j); if (ue !== j) { doc.links[ue] = doc.links[j]; delete doc.links[j]; } } } return doc; }
 | 
			
		||||
module.exports.unEscapeLinksFieldName = function (doc) { if (doc.links != null) { for (var j in doc.links) { var ue = module.exports.unEscapeFieldName(j); if (ue !== j) { doc.links[ue] = doc.links[j]; delete doc.links[j]; } } } return doc; }
 | 
			
		||||
//module.exports.escapeAllLinksFieldName = function (docs) { for (var i in docs) { module.exports.escapeLinksFieldName(docs[i]); } }
 | 
			
		||||
module.exports.unEscapeAllLinksFieldName = function (docs) { for (var i in docs) { docs[i] = module.exports.unEscapeLinksFieldName(docs[i]); } }
 | 
			
		||||
 | 
			
		||||
// Validation methods
 | 
			
		||||
module.exports.validateString = function(str, minlen, maxlen) { return ((str != null) && (typeof str == 'string') && ((minlen == null) || (str.length >= minlen)) && ((maxlen == null) || (str.length <= maxlen))); }
 | 
			
		||||
module.exports.validateInt = function(int, minval, maxval) { return ((int != null) && (typeof int == 'number') && ((minval == null) || (int >= minval)) && ((maxval == null) || (int <= maxval))); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								db.js
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								db.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -17,24 +17,25 @@
 | 
			
		|||
// Just run with --mongodb [connectionstring], where the connection string is documented here: https://docs.mongodb.com/manual/reference/connection-string/
 | 
			
		||||
// The default collection is "meshcentral", but you can override it using --mongodbcol [collection]
 | 
			
		||||
//
 | 
			
		||||
module.exports.CreateDB = function (args, datapath) {
 | 
			
		||||
module.exports.CreateDB = function (parent) {
 | 
			
		||||
    var obj = {};
 | 
			
		||||
    obj.path = require('path');
 | 
			
		||||
    obj.parent = parent;
 | 
			
		||||
    obj.identifier = null;
 | 
			
		||||
 | 
			
		||||
    if (args.mongodb) {
 | 
			
		||||
    if (obj.parent.args.mongodb) {
 | 
			
		||||
        // Use MongoDB
 | 
			
		||||
        obj.databaseType = 2;
 | 
			
		||||
        var Datastore = require('mongojs');
 | 
			
		||||
        var db = Datastore(args.mongodb);
 | 
			
		||||
        var db = Datastore(obj.parent.args.mongodb);
 | 
			
		||||
        var dbcollection = 'meshcentral';
 | 
			
		||||
        if (args.mongodbcol) { dbcollection = args.mongodbcol; }
 | 
			
		||||
        if (obj.parent.args.mongodbcol) { dbcollection = obj.parent.args.mongodbcol; }
 | 
			
		||||
        obj.file = db.collection(dbcollection);
 | 
			
		||||
    } else {
 | 
			
		||||
        // Use NeDB (The default)
 | 
			
		||||
        obj.databaseType = 1;
 | 
			
		||||
        var Datastore = require('nedb');
 | 
			
		||||
        obj.file = new Datastore({ filename: obj.path.join(datapath, 'meshcentral.db'), autoload: true });
 | 
			
		||||
        obj.file = new Datastore({ filename: obj.parent.getConfigFilePath('meshcentral.db'), autoload: true });
 | 
			
		||||
        obj.file.persistence.setAutocompactionInterval(3600);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,6 +99,7 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
            console.log('   --redirport [number]              Creates an additional HTTP server to redirect users to the HTTPS server.');
 | 
			
		||||
            console.log('   --exactports                      Server must run with correct ports or exit.');
 | 
			
		||||
            console.log('   --noagentupdate                   Server will not update mesh agent native binaries.');
 | 
			
		||||
            console.log('   --fastcert                        Generate weaker RSA2048 certificates.');
 | 
			
		||||
            console.log('   --cert [name], (country), (org)   Create a web server certificate with [name] server name.');
 | 
			
		||||
            console.log('                                     country and organization can optionaly be set.');
 | 
			
		||||
            return;
 | 
			
		||||
| 
						 | 
				
			
			@ -169,7 +170,7 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
        xprocess.stdout.on('data', function (data) { if (data[data.length - 1] == '\n') { data = data.substring(0, data.length - 1); } if (data.indexOf('Updating settings folder...') >= 0) { xprocess.xrestart = 1; } else if (data.indexOf('Updating server certificates...') >= 0) { xprocess.xrestart = 1; } else if (data.indexOf('Server Ctrl-C exit...') >= 0) { xprocess.xrestart = 2; } else if (data.indexOf('Starting self upgrade...') >= 0) { xprocess.xrestart = 3; } console.log(data); });
 | 
			
		||||
        xprocess.stderr.on('data', function (data) {
 | 
			
		||||
            if (data.startsWith('le.challenges[tls-sni-01].loopback')) { return; } // Ignore this error output from GreenLock
 | 
			
		||||
            if (data[data.length - 1] == '\n') { data = data.substring(0, data.length - 1); } obj.fs.appendFileSync(obj.path.join(obj.datapath, 'mesherrors.txt'), '-------- ' + new Date().toLocaleString() + ' --------\r\n\r\n' + data + '\r\n\r\n\r\n');
 | 
			
		||||
            if (data[data.length - 1] == '\n') { data = data.substring(0, data.length - 1); } obj.fs.appendFileSync(obj.getConfigFilePath('mesherrors.txt'), '-------- ' + new Date().toLocaleString() + ' --------\r\n\r\n' + data + '\r\n\r\n\r\n');
 | 
			
		||||
        });
 | 
			
		||||
        xprocess.on('close', function (code) { if ((code != 0) && (code != 123)) { /* console.log("Exited with code " + code); */ } });
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +238,7 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
        if (obj.args.notls == null && obj.args.redirport == null) obj.args.redirport = 80;
 | 
			
		||||
        if (typeof obj.args.debug == 'number') obj.debugLevel = obj.args.debug;
 | 
			
		||||
        if (obj.args.debug == true) obj.debugLevel = 1;
 | 
			
		||||
        obj.db = require('./db.js').CreateDB(obj.args, obj.datapath);
 | 
			
		||||
        obj.db = require('./db.js').CreateDB(obj);
 | 
			
		||||
        obj.db.SetupDatabase(function (dbversion) {
 | 
			
		||||
            // See if any database operations needs to be completed
 | 
			
		||||
            if (obj.args.deletedomain) { obj.db.DeleteDomain(obj.args.deletedomain, function () { console.log('Deleted domain ' + obj.args.deletedomain + '.'); process.exit(); }); return; }
 | 
			
		||||
| 
						 | 
				
			
			@ -254,7 +255,7 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
            if (obj.args.logintokenkey) { obj.showLoginTokenKey(function (r) { console.log(r); process.exit(); }); return; }
 | 
			
		||||
            if (obj.args.dbexport) {
 | 
			
		||||
                // Export the entire database to a JSON file
 | 
			
		||||
                if (obj.args.dbexport == true) { obj.args.dbexport = obj.path.join(obj.datapath, 'meshcentral.db.json'); }
 | 
			
		||||
                if (obj.args.dbexport == true) { obj.args.dbexport = obj.getConfigFilePath('meshcentral.db.json'); }
 | 
			
		||||
                obj.db.GetAll(function (err, docs) {
 | 
			
		||||
                    obj.fs.writeFileSync(obj.args.dbexport, JSON.stringify(docs));
 | 
			
		||||
                    console.log('Exported ' + docs.length + ' objects(s) to ' + obj.args.dbexport + '.'); process.exit();
 | 
			
		||||
| 
						 | 
				
			
			@ -263,12 +264,14 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
            }
 | 
			
		||||
            if (obj.args.dbimport) {
 | 
			
		||||
                // Import the entire database from a JSON file
 | 
			
		||||
                if (obj.args.dbimport == true) { obj.args.dbimport = obj.path.join(obj.datapath, 'meshcentral.db.json'); }
 | 
			
		||||
                var json = null;
 | 
			
		||||
                if (obj.args.dbimport == true) { obj.args.dbimport = obj.getConfigFilePath('meshcentral.db.json'); }
 | 
			
		||||
                var json = null, json2 = "";
 | 
			
		||||
                try { json = obj.fs.readFileSync(obj.args.dbimport); } catch (e) { console.log('Invalid JSON file: ' + obj.args.dbimport + '.'); process.exit(); }
 | 
			
		||||
                try { json = JSON.parse(json); } catch (e) { console.log('Invalid JSON format: ' + obj.args.dbimport + '.'); process.exit(); }
 | 
			
		||||
                for (var i = 0; i < json.length; i++) { if (json[i] >= 32) json2 += String.fromCharCode(json[i]); } // Remove all bad chars
 | 
			
		||||
                try { json = JSON.parse(json2); } catch (e) { console.log('Invalid JSON format: ' + obj.args.dbimport + ': ' + e); process.exit(); }
 | 
			
		||||
                if ((json == null) || (typeof json.length != 'number') || (json.length < 1)) { console.log('Invalid JSON format: ' + obj.args.dbimport + '.'); }
 | 
			
		||||
                obj.db.RemoveAll(function () { obj.db.InsertMany(json, function () { console.log('Imported ' + json.length + ' objects(s) from ' + obj.args.dbimport + '.'); process.exit(); }); });
 | 
			
		||||
                for (var i in json) { if ((json[i].type == "mesh") && (json[i].links != null)) { for (var j in json[i].links) { var esc = obj.common.escapeFieldName(j); if (esc !== j) { json[i].links[esc] = json[i].links[j]; delete json[i].links[j]; } } } } // Escape MongoDB invalid field chars
 | 
			
		||||
                obj.db.RemoveAll(function () { obj.db.InsertMany(json, function (err) { if (err != null) { console.log(err); } else { console.log('Imported ' + json.length + ' objects(s) from ' + obj.args.dbimport + '.'); } process.exit(); }); });
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -330,7 +333,7 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
    obj.StartEx2 = function () {
 | 
			
		||||
        // Load server certificates
 | 
			
		||||
        obj.certificateOperations = require('./certoperations.js').CertificateOperations()
 | 
			
		||||
        obj.certificateOperations.GetMeshServerCertificate(obj.datapath, obj.args, obj.config, obj, function (certs) {
 | 
			
		||||
        obj.certificateOperations.GetMeshServerCertificate(obj, obj.args, obj.config, function (certs) {
 | 
			
		||||
            if (obj.config.letsencrypt == null) {
 | 
			
		||||
                obj.StartEx3(certs); // Just use the configured certificates
 | 
			
		||||
            } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -496,8 +499,8 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
                            zipfile.openReadStream(entry, function (err, readStream) {
 | 
			
		||||
                                if (err) throw err;
 | 
			
		||||
                                readStream.on("end", function () { zipfile.readEntry(); });
 | 
			
		||||
                                // console.log('Extracting:', obj.path.join(obj.datapath, entry.fileName));
 | 
			
		||||
                                readStream.pipe(obj.fs.createWriteStream(obj.path.join(obj.datapath, entry.fileName)));
 | 
			
		||||
                                // console.log('Extracting:', obj.getConfigFilePath(entry.fileName));
 | 
			
		||||
                                readStream.pipe(obj.fs.createWriteStream(obj.getConfigFilePath(entry.fileName)));
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
| 
						 | 
				
			
			@ -1044,7 +1047,7 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
        }
 | 
			
		||||
        r = 'time=' + Date.now() + '\r\n';
 | 
			
		||||
        for (var i in meshServerState) { r += (i + '=' + meshServerState[i] + '\r\n'); }
 | 
			
		||||
        obj.fs.writeFileSync(obj.path.join(obj.datapath, 'serverstate.txt'), r);
 | 
			
		||||
        obj.fs.writeFileSync(obj.getConfigFilePath('serverstate.txt'), r);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Logging funtions
 | 
			
		||||
| 
						 | 
				
			
			@ -1074,6 +1077,16 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
        } catch (e) { console.log(e); if (called == false) { func(null); } }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Return the path of a file into the meshcentral-data path
 | 
			
		||||
    obj.getConfigFilePath = function (filename) {
 | 
			
		||||
        if ((obj.config != null) && (obj.config.configfiles != null) && (obj.config.configfiles[filename] != null) && (typeof obj.config.configfiles[filename] == 'string')) {
 | 
			
		||||
            //console.log('getConfigFilePath(\"' + filename + '\") = ' + obj.config.configfiles[filename]);
 | 
			
		||||
            return obj.config.configfiles[filename];
 | 
			
		||||
        }
 | 
			
		||||
        //console.log('getConfigFilePath(\"' + filename + '\") = ' + obj.path.join(obj.datapath, filename));
 | 
			
		||||
        return obj.path.join(obj.datapath, filename);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										13
									
								
								meshuser.js
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								meshuser.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -111,6 +111,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
 | 
			
		|||
            if ((user == null) || (obj.common.validateString(command.action, 3, 32) == false)) return; // User must be set and action must be a string between 3 and 32 chars
 | 
			
		||||
 | 
			
		||||
            switch (command.action) {
 | 
			
		||||
                case 'ping': { ws.send(JSON.stringify({ action: 'pong' })); break; }
 | 
			
		||||
                case 'meshes':
 | 
			
		||||
                    {
 | 
			
		||||
                        // Request a list of all meshes this user as rights to
 | 
			
		||||
| 
						 | 
				
			
			@ -565,7 +566,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
 | 
			
		|||
                                var links = {}
 | 
			
		||||
                                links[user._id] = { name: user.name, rights: 0xFFFFFFFF };
 | 
			
		||||
                                var mesh = { type: 'mesh', _id: meshid, name: command.meshname, mtype: command.meshtype, desc: command.desc, domain: domain.id, links: links };
 | 
			
		||||
                                obj.db.Set(mesh);
 | 
			
		||||
                                obj.db.Set(obj.common.escapeLinksFieldName(mesh));
 | 
			
		||||
                                obj.parent.meshes[meshid] = mesh;
 | 
			
		||||
                                obj.parent.parent.AddEventDispatch([meshid], ws);
 | 
			
		||||
                                if (user.links == null) user.links = {};
 | 
			
		||||
| 
						 | 
				
			
			@ -583,7 +584,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
 | 
			
		|||
                        if (obj.common.validateString(command.meshid, 1, 1024) == false) break; // Check the meshid
 | 
			
		||||
                        obj.db.Get(command.meshid, function (err, meshes) {
 | 
			
		||||
                            if (meshes.length != 1) return;
 | 
			
		||||
                            var mesh = meshes[0];
 | 
			
		||||
                            var mesh = obj.common.unEscapeLinksFieldName(meshes[0]);
 | 
			
		||||
 | 
			
		||||
                            // Check if this user has rights to do this
 | 
			
		||||
                            if (mesh.links[user._id] == null || mesh.links[user._id].rights != 0xFFFFFFFF) return;
 | 
			
		||||
| 
						 | 
				
			
			@ -627,7 +628,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
 | 
			
		|||
 | 
			
		||||
                            if ((obj.common.validateString(command.meshname, 1, 64) == true) && (command.meshname != mesh.name)) { change = 'Mesh name changed from "' + mesh.name + '" to "' + command.meshname + '"'; mesh.name = command.meshname; }
 | 
			
		||||
                            if ((obj.common.validateString(command.desc, 0, 1024) == true) && (command.desc != mesh.desc)) { if (change != '') change += ' and description changed'; else change += 'Mesh "' + mesh.name + '" description changed'; mesh.desc = command.desc; }
 | 
			
		||||
                            if (change != '') { obj.db.Set(mesh); obj.parent.parent.DispatchEvent(['*', mesh._id, user._id], obj, { etype: 'mesh', username: user.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id }) }
 | 
			
		||||
                            if (change != '') { obj.db.Set(obj.common.escapeLinksFieldName(mesh)); obj.parent.parent.DispatchEvent(['*', mesh._id, user._id], obj, { etype: 'mesh', username: user.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id }) }
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -659,7 +660,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
 | 
			
		|||
 | 
			
		||||
                            // Add a user to the mesh
 | 
			
		||||
                            mesh.links[newuserid] = { name: newuser.name, rights: command.meshadmin };
 | 
			
		||||
                            obj.db.Set(mesh);
 | 
			
		||||
                            obj.db.Set(obj.common.escapeLinksFieldName(mesh));
 | 
			
		||||
 | 
			
		||||
                            // Notify mesh change
 | 
			
		||||
                            var change = 'Added user ' + newuser.name + ' to mesh ' + mesh.name;
 | 
			
		||||
| 
						 | 
				
			
			@ -685,7 +686,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
 | 
			
		|||
                                // Remove mesh from user
 | 
			
		||||
                                if (deluser.links != null && deluser.links[command.meshid] != null) {
 | 
			
		||||
                                    var delmeshrights = deluser.links[command.meshid].rights;
 | 
			
		||||
                                    if ((delmeshrights == 0xFFFFFFFF) && (mesh.links[user._id].rights != 0xFFFFFFFF)) return; // A non-admin can't kick out an admin
 | 
			
		||||
                                    if ((delmeshrights == 0xFFFFFFFF) && (mesh.links[deluserid].rights != 0xFFFFFFFF)) return; // A non-admin can't kick out an admin
 | 
			
		||||
                                    delete deluser.links[command.meshid];
 | 
			
		||||
                                    obj.db.Set(deluser);
 | 
			
		||||
                                    obj.parent.parent.DispatchEvent([deluser._id], obj, 'resubscribe');
 | 
			
		||||
| 
						 | 
				
			
			@ -695,7 +696,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
 | 
			
		|||
                            // Remove user from the mesh
 | 
			
		||||
                            if (mesh.links[command.userid] != null) {
 | 
			
		||||
                                delete mesh.links[command.userid];
 | 
			
		||||
                                obj.db.Set(mesh);
 | 
			
		||||
                                obj.db.Set(obj.common.escapeLinksFieldName(mesh));
 | 
			
		||||
 | 
			
		||||
                                // Notify mesh change
 | 
			
		||||
                                var change = 'Removed user ' + deluser.name + ' from mesh ' + mesh.name;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -669,7 +669,6 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
 | 
			
		|||
            var node = nodes[0];
 | 
			
		||||
 | 
			
		||||
            // See if any changes need to be made
 | 
			
		||||
            console.log(node.intelamt);
 | 
			
		||||
            if ((node.intelamt != undefined) && (node.intelamt.host == host) && (node.name != '') && (node.intelamt.state == 2)) return;
 | 
			
		||||
            
 | 
			
		||||
            // Get the mesh for this device
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
{
 | 
			
		||||
  "name": "meshcentral",
 | 
			
		||||
  "version": "0.1.8-m",
 | 
			
		||||
  "version": "0.1.8-r",
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "Remote Management",
 | 
			
		||||
    "Intel AMT",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -272,6 +272,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    obj.SendKeyMsgKC = function (action, kc) {
 | 
			
		||||
        console.log('SendKeyMsgKC', action, kc);
 | 
			
		||||
        if (obj.State != 3) return;
 | 
			
		||||
        if (typeof action == 'object') { for (var i in action) { obj.SendKeyMsgKC(action[i][0], action[i][1]); } }
 | 
			
		||||
        else { obj.send(String.fromCharCode(0x00, obj.InputType.KEY, 0x00, 0x06, (action - 1), kc)); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,11 +79,7 @@ function hex2rstr(d) {
 | 
			
		|||
function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); }
 | 
			
		||||
 | 
			
		||||
// Convert a raw string to a hex string
 | 
			
		||||
function rstr2hex(input) {
 | 
			
		||||
    var r = '', i;
 | 
			
		||||
    for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); }
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
function rstr2hex(input) { var r = '', i; for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); } return r; }
 | 
			
		||||
 | 
			
		||||
// UTF-8 encoding & decoding functions
 | 
			
		||||
function encode_utf8(s) { return unescape(encodeURIComponent(s)); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ var MeshServerCreateControl = function (domain) {
 | 
			
		|||
    var obj = {};
 | 
			
		||||
    obj.State = 0;
 | 
			
		||||
    obj.connectstate = 0;
 | 
			
		||||
    obj.pingTimer = null;
 | 
			
		||||
    
 | 
			
		||||
    obj.xxStateChange = function (newstate) {
 | 
			
		||||
        if (obj.State == newstate) return;
 | 
			
		||||
| 
						 | 
				
			
			@ -22,11 +23,14 @@ var MeshServerCreateControl = function (domain) {
 | 
			
		|||
        obj.socket.onmessage = obj.xxOnMessage;
 | 
			
		||||
        obj.socket.onclose = function () { obj.Stop(); }
 | 
			
		||||
        obj.xxStateChange(1);
 | 
			
		||||
        if (obj.pingTimer != null) { clearInterval(obj.pingTimer); }
 | 
			
		||||
        obj.pingTimer = setInterval(function () { obj.send({ action: 'ping' }); }, 29000); // Ping the server every 29 seconds, stops corporate proxies from disconnecting.
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    obj.Stop = function () {
 | 
			
		||||
        obj.connectstate = 0;
 | 
			
		||||
        if (obj.socket) { obj.socket.close(); delete obj.socket; }
 | 
			
		||||
        if (obj.pingTimer != null) { clearInterval(obj.pingTimer); obj.pingTimer = null; }
 | 
			
		||||
        obj.xxStateChange(0);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +38,7 @@ var MeshServerCreateControl = function (domain) {
 | 
			
		|||
        // console.log('xxOnMessage', e.data);
 | 
			
		||||
        var message;
 | 
			
		||||
        try { message = JSON.parse(e.data); } catch (e) { return; }
 | 
			
		||||
        if (message.action == 'pong') { return; }
 | 
			
		||||
        if (obj.onMessage) obj.onMessage(obj, message);
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -391,6 +391,7 @@
 | 
			
		|||
                                </div>
 | 
			
		||||
                                <div>
 | 
			
		||||
                                    <select style="margin-left:6px" id="deskkeys">
 | 
			
		||||
                                        <option value=5>Win</option>
 | 
			
		||||
                                        <option value=0>Win+Down</option>
 | 
			
		||||
                                        <option value=1>Win+Up</option>
 | 
			
		||||
                                        <option value=2>Win+L</option>
 | 
			
		||||
| 
						 | 
				
			
			@ -3598,7 +3599,11 @@
 | 
			
		|||
                if (desktop.contype == 2) {
 | 
			
		||||
                    desktop.m.sendkey([[0xffe7,1],[0x6c,1],[0x6c,0],[0xffe7,0]]); // Intel AMT: Meta-left down, 'l' press, 'l' release, Meta-left release
 | 
			
		||||
                } else {
 | 
			
		||||
                    desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,0x5B],[desktop.m.KeyAction.DOWN,76],[desktop.m.KeyAction.UP,76],[desktop.m.KeyAction.EXUP,0x5B]]); // MeshAgent: L-Winkey press, 'L' press, 'L' release, L-Winkey release
 | 
			
		||||
                    //desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,0x5B],[desktop.m.KeyAction.DOWN,76],[desktop.m.KeyAction.UP,76],[desktop.m.KeyAction.EXUP,0x5B]]); // MeshAgent: L-Winkey press, 'L' press, 'L' release, L-Winkey release
 | 
			
		||||
                    desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXDOWN, 0x5B);
 | 
			
		||||
                    //desktop.m.SendKeyMsgKC(desktop.m.KeyAction.DOWN, 76);
 | 
			
		||||
                    //desktop.m.SendKeyMsgKC(desktop.m.KeyAction.UP, 76);
 | 
			
		||||
                    desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXUP, 0x5B);
 | 
			
		||||
                }
 | 
			
		||||
            } else if (ks == 3) { // WIN+M arrow
 | 
			
		||||
                if (desktop.contype == 2) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3612,6 +3617,12 @@
 | 
			
		|||
                } else {
 | 
			
		||||
                    desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.DOWN,16],[desktop.m.KeyAction.EXDOWN,0x5B],[desktop.m.KeyAction.DOWN,77],[desktop.m.KeyAction.UP,77],[desktop.m.KeyAction.EXUP,0x5B],[desktop.m.KeyAction.UP, 16]]);     // MeshAgent: L-shift press, L-Winkey press, 'M' press, 'M' release, L-Winkey release, L-shift release
 | 
			
		||||
                }
 | 
			
		||||
            } else if (ks == 5) { // WIN
 | 
			
		||||
                if (desktop.contype == 2) {
 | 
			
		||||
                    desktop.m.sendkey([[0xffe7,1],[0xffe7,0]]); // Intel AMT: Meta-left down, Meta-left release
 | 
			
		||||
                } else {
 | 
			
		||||
                    desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,0x5B], [desktop.m.KeyAction.EXUP,0x5B]]); // MeshAgent: L-Winkey press, L-Winkey release
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								webserver.js
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								webserver.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -189,7 +189,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
 | 
			
		|||
    });
 | 
			
		||||
 | 
			
		||||
    // Fetch all meshes from the database, keep this in memory
 | 
			
		||||
    obj.db.GetAllType('mesh', function (err, docs) { for (var i in docs) { obj.meshes[docs[i]._id] = docs[i]; } });
 | 
			
		||||
    obj.db.GetAllType('mesh', function (err, docs) { obj.common.unEscapeAllLinksFieldName(docs); for (var i in docs) { obj.meshes[docs[i]._id] = docs[i]; } });
 | 
			
		||||
 | 
			
		||||
    // Authenticate the user
 | 
			
		||||
    obj.authenticate = function (name, pass, domain, fn) {
 | 
			
		||||
| 
						 | 
				
			
			@ -550,7 +550,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
 | 
			
		|||
                        var mesh = obj.meshes[meshid];
 | 
			
		||||
                        if (mesh) {
 | 
			
		||||
                            // Remove user from the mesh
 | 
			
		||||
                            if (mesh.links[userid] != null) { delete mesh.links[userid]; obj.db.Set(mesh); }
 | 
			
		||||
                            var escUserId = obj.common.escapeFieldName(userid);
 | 
			
		||||
                            if (mesh.links[escUserId] != null) { delete mesh.links[escUserId]; obj.db.Set(mesh); }
 | 
			
		||||
                            // Notify mesh change
 | 
			
		||||
                            var change = 'Removed user ' + user.name + ' from mesh ' + mesh.name;
 | 
			
		||||
                            obj.parent.DispatchEvent(['*', mesh._id, user._id, userid], obj, { etype: 'mesh', username: user.name, userid: userid, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id })
 | 
			
		||||
| 
						 | 
				
			
			@ -997,9 +998,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
 | 
			
		|||
            if (user.siteadmin == 0xFFFFFFFF) subscriptions.push('*');
 | 
			
		||||
            if ((user.siteadmin & 2) != 0) subscriptions.push('server-users');
 | 
			
		||||
        }
 | 
			
		||||
        if (user.links != null) {
 | 
			
		||||
            for (var i in user.links) { subscriptions.push(i); }
 | 
			
		||||
        }
 | 
			
		||||
        if (user.links != null) { for (var i in user.links) { subscriptions.push(i); } }
 | 
			
		||||
        obj.parent.RemoveAllEventDispatch(target);
 | 
			
		||||
        obj.parent.AddEventDispatch(subscriptions, target);
 | 
			
		||||
        return subscriptions;
 | 
			
		||||
| 
						 | 
				
			
			@ -1458,7 +1457,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
 | 
			
		|||
                    // If required, check if this user has rights to do this
 | 
			
		||||
                    if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true)) {
 | 
			
		||||
                        var user = obj.users[req.session.userid];
 | 
			
		||||
                        if ((user == null) || (mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { res.sendStatus(401); return; }
 | 
			
		||||
                        var escUserId = obj.common.escapeFieldName(user._id);
 | 
			
		||||
                        if ((user == null) || (mesh.links[escUserId] == null) || ((mesh.links[escUserId].rights & 1) == 0)) { res.sendStatus(401); return; }
 | 
			
		||||
                        if (domain.id != mesh.domain) { res.sendStatus(401); return; }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1591,7 +1591,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
 | 
			
		|||
            // If needed, check if this user has rights to do this
 | 
			
		||||
            if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true)) {
 | 
			
		||||
                var user = obj.users[req.session.userid];
 | 
			
		||||
                if ((user == null) || (mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { res.sendStatus(401); return; }
 | 
			
		||||
                var escUserId = obj.common.escapeFieldName(user._id);
 | 
			
		||||
                if ((user == null) || (mesh.links[escUserId] == null) || ((mesh.links[escUserId].rights & 1) == 0)) { res.sendStatus(401); return; }
 | 
			
		||||
                if (domain.id != mesh.domain) { res.sendStatus(401); return; }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue