Handle all configured paths as potentially absolute

Linus Heckemann committed Jul 29, 2021 at 16:38 UTC 63b52fa1f61033330adcdfc4797456f3fca3b34e
5 files changed +22 -29
amtprovisioningserver.js
+1 -1
@@ -619,7 +619,7 @@ module.exports.CreateAmtProvisioningServer = function (parent, config) {
619 if ((domain.amtacmactivation == null) || (domain.amtacmactivation.log == null) || (typeof domain.amtacmactivation.log != 'string')) {
620 if (domain.id == '') { logpath = parent.path.join(obj.parent.datapath, 'amtactivation.log'); } else { logpath = parent.path.join(obj.parent.datapath, 'amtactivation-' + domain.id + '.log'); }
621 } else {
622 - if ((domain.amtacmactivation.log.length >= 2) && ((domain.amtacmactivation.log[0] == '/') || (domain.amtacmactivation.log[1] == ':'))) { logpath = domain.amtacmactivation.log; } else { logpath = parent.path.join(obj.parent.datapath, domain.amtacmactivation.log); }
622 + logpath = parent.common.joinPath(obj.parent.datapath, domain.amtacmactivation.log);
623 }
624 try { parent.fs.appendFileSync(logpath, JSON.stringify(x) + '\r\n'); } catch (ex) { console.log(ex); return false; }
625 return true;
certoperations.js
+4 -4
@@ -158,7 +158,7 @@ module.exports.CertificateOperations = function (parent) {
158 if ((domain.amtacmactivation == null) || (domain.amtacmactivation.log == null) || (typeof domain.amtacmactivation.log != 'string')) {
159 if (domain.id == '') { logpath = parent.path.join(obj.parent.datapath, 'amtactivation.log'); } else { logpath = parent.path.join(obj.parent.datapath, 'amtactivation-' + domain.id + '.log'); }
160 } else {
161 - if ((domain.amtacmactivation.log.length >= 2) && ((domain.amtacmactivation.log[0] == '/') || (domain.amtacmactivation.log[1] == ':'))) { logpath = domain.amtacmactivation.log; } else { logpath = parent.path.join(obj.parent.datapath, domain.amtacmactivation.log); }
161 + logpath = parent.common.joinPath(obj.parent.datapath, domain.amtacmactivation.log);
162 }
163 try { obj.fs.appendFileSync(logpath, JSON.stringify(x) + '\r\n'); } catch (ex) { console.log(ex); return false; }
164 return true;
@@ -175,13 +175,13 @@ module.exports.CertificateOperations = function (parent) {
175
176 if ((typeof acmconfig.certpfx == 'string') && (typeof acmconfig.certpfxpass == 'string')) {
177 // P12 format, certpfx and certpfxpass
178 - try { r = obj.loadPfxCertificate(obj.parent.path.join(obj.parent.datapath, acmconfig.certpfx), acmconfig.certpfxpass); } catch (ex) { console.log(ex); }
178 + try { r = obj.loadPfxCertificate(obj.parent.common.joinPath(obj.parent.datapath, acmconfig.certpfx), acmconfig.certpfxpass); } catch (ex) { console.log(ex); }
179 if ((r == null) || (r.certs == null) || (r.keys == null) || (r.certs.length < 2) || (r.keys.length != 1)) continue;
180 } else if ((typeof acmconfig.certfiles == 'object') && (typeof acmconfig.keyfile == 'string')) {
181 // PEM format, certfiles and keyfile
182 r = { certs: [], keys: [] };
183 - for (var k in acmconfig.certfiles) { r.certs.push(obj.pki.certificateFromPem(obj.fs.readFileSync(obj.parent.path.join(obj.parent.datapath, acmconfig.certfiles[k])))); }
184 - r.keys.push(obj.pki.privateKeyFromPem(obj.fs.readFileSync(obj.parent.path.join(obj.parent.datapath, acmconfig.keyfile))));
183 + for (var k in acmconfig.certfiles) { r.certs.push(obj.pki.certificateFromPem(obj.fs.readFileSync(obj.common.joinPath(obj.parent.datapath, acmconfig.certfiles[k])))); }
184 + r.keys.push(obj.pki.privateKeyFromPem(obj.fs.readFileSync(obj.parent.joinPath(obj.parent.datapath, acmconfig.keyfile))));
185 if ((r.certs.length < 2) || (r.keys.length != 1)) continue;
186 }
187
common.js
+3 -1
@@ -16,6 +16,7 @@
16
17 const fs = require('fs');
18 const crypto = require('crypto');
19 +const path = require('path');
20
21 // Binary encoding and decoding functions
22 module.exports.ReadShort = function (v, p) { return (v.charCodeAt(p) << 8) + v.charCodeAt(p + 1); };
@@ -31,6 +32,7 @@ module.exports.SplitArray = function (v) { return v.split(','); };
32 module.exports.Clone = function (v) { return JSON.parse(JSON.stringify(v)); };
33 module.exports.IsFilenameValid = (function () { var x1 = /^[^\\/:\*\?"<>\|]+$/, x2 = /^\./, x3 = /^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; return function isFilenameValid(fname) { return module.exports.validateString(fname, 1, 4096) && x1.test(fname) && !x2.test(fname) && !x3.test(fname) && (fname[0] != '.'); }; })();
34 module.exports.makeFilename = function (v) { return v.split('\\').join('').split('/').join('').split(':').join('').split('*').join('').split('?').join('').split('"').join('').split('<').join('').split('>').join('').split('|').join('').split(' ').join('').split('\'').join(''); }
35 +module.exports.joinPath = function (base, path_) { return path.isAbsolute(path_) ? path_ : path.join(base, path_); }
36
37 // Move an element from one position in an array to a new position
38 module.exports.ArrayElementMove = function(arr, from, to) { arr.splice(to, 0, arr.splice(from, 1)[0]); };
@@ -315,4 +317,4 @@ function validateObjectForMongoRec(obj, maxStrLen) {
317 if ((typeof obj[i] == 'object') && (Array.isArray(obj[i]) == false) && (validateObjectForMongoRec(obj[i], maxStrLen) == false)) return false;
318 }
319 return true;
318 -}
\ No newline at end of file
320 +}
meshcentral.js
+6 -16
@@ -14,6 +14,8 @@
14 /*jshint esversion: 6 */
15 "use strict";
16
17 +const common = require('./common.js');
18 +
19 // If app metrics is available
20 if (process.argv[2] == '--launch') { try { require('appmetrics-dash').monitor({ url: '/', title: 'MeshCentral', port: 88, host: '127.0.0.1' }); } catch (e) { } }
21
@@ -40,7 +42,7 @@ function CreateMeshCentralServer(config, args) {
42 obj.exeHandler = require('./exeHandler.js');
43 obj.platform = require('os').platform();
44 obj.args = args;
43 - obj.common = require('./common.js');
45 + obj.common = common;
46 obj.configurationFiles = null;
47 obj.certificates = null;
48 obj.connectivityByNode = {}; // This object keeps a list of all connected CIRA and agents, by nodeid->value (value: 1 = Agent, 2 = CIRA, 4 = AmtDirect)
@@ -666,13 +668,7 @@ function CreateMeshCentralServer(config, args) {
668 obj.args = args = config2.settings;
669
670 // Lower case all keys in the config file
669 - try {
670 - require('./common.js').objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate']);
671 - } catch (ex) {
672 - console.log('CRITICAL ERROR: Unable to access the file \"./common.js\".\r\nCheck folder & file permissions.');
673 - process.exit();
674 - return;
675 - }
671 + obj.common.objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate']);
672
673 // Grad some of the values from the original config.json file if present.
674 if ((config.settings.vault != null) && (config2.settings != null)) { config2.settings.vault = config.settings.vault; }
@@ -1148,13 +1144,7 @@ function CreateMeshCentralServer(config, args) {
1144 for (i in args) { config2.settings[i] = args[i]; }
1145
1146 // Lower case all keys in the config file
1151 - try {
1152 - require('./common.js').objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate']);
1153 - } catch (ex) {
1154 - console.log("CRITICAL ERROR: Unable to access the file \"./common.js\".\r\nCheck folder & file permissions.");
1155 - process.exit();
1156 - return;
1157 - }
1147 + common.objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate']);
1148
1149 // Grad some of the values from the original config.json file if present.
1150 config2['mysql'] = config['mysql'];
@@ -3051,7 +3041,7 @@ function getConfig(createSampleConfig) {
3041 // Read configuration file if present and change arguments.
3042 var config = {}, configFilePath = path.join(datapath, 'config.json');
3043 if (args.configfile) {
3054 - configFilePath = path.isAbsolute(args.configfile) ? args.configfile : path.join(datapath, args.configfile);
3044 + configFilePath = common.joinPath(datapath, args.configfile);
3045 }
3046 if (fs.existsSync(configFilePath)) {
3047 // Load and validate the configuration file
webserver.js
+8 -7
@@ -3152,7 +3152,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3152 //res.set({ 'Cache-Control': 'max-age=86400' }); // 1 day
3153 if (domain.meshmessengerpicture) {
3154 // Use the configured messenger logo picture
3155 - try { res.sendFile(obj.path.join(obj.parent.datapath, domain.meshmessengerpicture)); return; } catch (ex) { }
3155 + try { res.sendFile(obj.common.joinPath(obj.parent.datapath, domain.meshmessengerpicture)); return; } catch (ex) { }
3156 }
3157
3158 var imagefile = 'images/messenger.png';
@@ -3288,7 +3288,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3288 return;
3289 } else {
3290 // Use the logo on file
3291 - try { res.sendFile(obj.path.join(obj.parent.datapath, domain.titlepicture)); return; } catch (ex) { }
3291 + try { res.sendFile(obj.common.joinPath(obj.parent.datapath, domain.titlepicture)); return; } catch (ex) { }
3292 }
3293 }
3294
@@ -3318,7 +3318,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3318 return;
3319 } else {
3320 // Use the logo on file
3321 - try { res.sendFile(obj.path.join(obj.parent.datapath, domain.loginpicture)); return; } catch (ex) { res.sendStatus(404); }
3321 + try { res.sendFile(obj.common.joinPath(obj.parent.datapath, domain.loginpicture)); return; } catch (ex) { res.sendStatus(404); }
3322 }
3323 } else {
3324 res.sendStatus(404);
@@ -3404,7 +3404,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3404 }
3405
3406 // Use the configured logo picture
3407 - try { res.sendFile(obj.path.join(obj.parent.datapath, domain.welcomepicture)); return; } catch (ex) { }
3407 + try { res.sendFile(obj.common.joinPath(obj.parent.datapath, domain.welcomepicture)); return; } catch (ex) { }
3408 }
3409
3410 var imagefile = 'images/mainwelcome.jpg';
@@ -5916,7 +5916,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
5916 if ((typeof domain.authstrategies.saml.cert != 'string') || (typeof domain.authstrategies.saml.idpurl != 'string')) {
5917 console.log('ERROR: Missing SAML configuration.');
5918 } else {
5919 - var cert = obj.fs.readFileSync(obj.path.join(obj.parent.datapath, domain.authstrategies.saml.cert));
5919 + const certPath = common.joinPath(obj.parent.datapath, domain.authstrategies.saml.cert);
5920 + var cert = obj.fs.readFileSync(certPath);
5921 if (cert == null) {
5922 console.log('ERROR: Unable to read SAML IdP certificate: ' + domain.authstrategies.saml.cert);
5923 } else {
@@ -5956,7 +5957,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
5957 if ((typeof domain.authstrategies.intel.cert != 'string') || (typeof domain.authstrategies.intel.idpurl != 'string')) {
5958 console.log('ERROR: Missing Intel SAML configuration.');
5959 } else {
5959 - var cert = obj.fs.readFileSync(obj.path.join(obj.parent.datapath, domain.authstrategies.intel.cert));
5960 + var cert = obj.fs.readFileSync(obj.common.joinPath(obj.parent.datapath, domain.authstrategies.intel.cert));
5961 if (cert == null) {
5962 console.log('ERROR: Unable to read Intel SAML IdP certificate: ' + domain.authstrategies.intel.cert);
5963 } else {
@@ -5998,7 +5999,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
5999 if ((typeof domain.authstrategies.jumpcloud.cert != 'string') || (typeof domain.authstrategies.jumpcloud.idpurl != 'string')) {
6000 console.log('ERROR: Missing JumpCloud SAML configuration.');
6001 } else {
6001 - var cert = obj.fs.readFileSync(obj.path.join(obj.parent.datapath, domain.authstrategies.jumpcloud.cert));
6002 + var cert = obj.fs.readFileSync(common.joinPath(obj.parent.datapath, domain.authstrategies.jumpcloud.cert));
6003 if (cert == null) {
6004 console.log('ERROR: Unable to read JumpCloud IdP certificate: ' + domain.authstrategies.jumpcloud.cert);
6005 } else {