Added customization of the web site title logo.

This commit is contained in:
Ylian Saint-Hilaire 2018-12-21 14:39:26 -08:00
parent dc6b9217a9
commit 9d9daaf071
15 changed files with 39 additions and 23 deletions

View File

@ -111,7 +111,8 @@ module.exports.CertificateOperations = function () {
cert.setSubject(attrs); cert.setSubject(attrs);
cert.setIssuer(attrs); cert.setIssuer(attrs);
// Create a root certificate // Create a root certificate
cert.setExtensions([{ name: "basicConstraints", cA: true }, { name: "nsCertType", sslCA: true, emailCA: true, objCA: true }, { name: "subjectKeyIdentifier" }]); //cert.setExtensions([{ name: "basicConstraints", cA: true }, { name: "nsCertType", sslCA: true, emailCA: true, objCA: true }, { name: "subjectKeyIdentifier" }]);
cert.setExtensions([{ name: "basicConstraints", cA: true }, { name: "subjectKeyIdentifier" }]);
cert.sign(keys.privateKey, obj.forge.md.sha384.create()); cert.sign(keys.privateKey, obj.forge.md.sha384.create());
return { cert: cert, key: keys.privateKey }; return { cert: cert, key: keys.privateKey };
@ -135,10 +136,10 @@ module.exports.CertificateOperations = function () {
cert.setIssuer(rootcert.cert.subject.attributes); cert.setIssuer(rootcert.cert.subject.attributes);
if (extKeyUsage == null) { extKeyUsage = { name: "extKeyUsage", serverAuth: true }; } else { extKeyUsage.name = "extKeyUsage"; } if (extKeyUsage == null) { extKeyUsage = { name: "extKeyUsage", serverAuth: true }; } else { extKeyUsage.name = "extKeyUsage"; }
var subjectAltName = null; //var extensions = [{ name: "basicConstraints", cA: false }, { name: "keyUsage", keyCertSign: true, digitalSignature: true, nonRepudiation: true, keyEncipherment: true, dataEncipherment: true }, extKeyUsage, { name: "nsCertType", client: false, server: true, email: false, objsign: false, sslCA: false, emailCA: false, objCA: false }, { name: "subjectKeyIdentifier" }];
if (extKeyUsage.serverAuth === true) { subjectAltName = { name: "subjectAltName", altNames: [{ type: 6, value: "http://" + commonName + "/" }, { type: 6, value: "http://localhost/" }] }; } var extensions = [{ name: "basicConstraints", cA: false }, { name: "keyUsage", keyCertSign: false, digitalSignature: true, nonRepudiation: false, keyEncipherment: true, dataEncipherment: (extKeyUsage.serverAuth !== true) }, extKeyUsage, { name: "subjectKeyIdentifier" }];
var extensions = [{ name: "basicConstraints", cA: false }, { name: "keyUsage", keyCertSign: true, digitalSignature: true, nonRepudiation: true, keyEncipherment: true, dataEncipherment: true }, extKeyUsage, { name: "nsCertType", client: false, server: true, email: false, objsign: false, sslCA: false, emailCA: false, objCA: false }, { name: "subjectKeyIdentifier" }]; if (extKeyUsage.serverAuth === true) { extensions.push({ name: "subjectAltName", altNames: [{ type: 6, value: "http://" + commonName + "/" }, { type: 6, value: "http://localhost/" }] }); }
if (subjectAltName != null) { extensions.push(subjectAltName); }
cert.setExtensions(extensions); cert.setExtensions(extensions);
cert.sign(rootcert.key, obj.forge.md.sha384.create()); cert.sign(rootcert.key, obj.forge.md.sha384.create());
@ -360,7 +361,7 @@ module.exports.CertificateOperations = function () {
var agentCertAndKey, agentCertificate, agentPrivateKey; var agentCertAndKey, agentCertificate, agentPrivateKey;
if (r.agent == null) { if (r.agent == null) {
console.log("Generating MeshAgent certificate..."); console.log("Generating MeshAgent certificate...");
agentCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, true, "MeshCentralAgentServer", null, strongCertificate); agentCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, true, "MeshCentralAgentServer", country, organization, { }, strongCertificate);
agentCertificate = obj.pki.certificateToPem(agentCertAndKey.cert); agentCertificate = obj.pki.certificateToPem(agentCertAndKey.cert);
agentPrivateKey = obj.pki.privateKeyToPem(agentCertAndKey.key); agentPrivateKey = obj.pki.privateKeyToPem(agentCertAndKey.key);
obj.fs.writeFileSync(parent.getConfigFilePath("agentserver-cert-public.crt"), agentCertificate); obj.fs.writeFileSync(parent.getConfigFilePath("agentserver-cert-public.crt"), agentCertificate);

View File

@ -230,7 +230,7 @@ function CreateMeshCentralServer(config, args) {
if (obj.config.domains == null) { obj.config.domains = {}; } if (obj.config.domains == null) { obj.config.domains = {}; }
if (obj.config.domains[''] == null) { obj.config.domains[''] = {}; } if (obj.config.domains[''] == null) { obj.config.domains[''] = {}; }
if (obj.config.domains[''].dns != null) { console.log("ERROR: Default domain can't have a DNS name."); return; } if (obj.config.domains[''].dns != null) { console.log("ERROR: Default domain can't have a DNS name."); return; }
var xdomains = {}; for (i in obj.config.domains) { if (!obj.config.domains[i].title) { obj.config.domains[i].title = 'MeshCentral'; } if (!obj.config.domains[i].title2) { obj.config.domains[i].title2 = '2.0 Beta 2'; } xdomains[i.toLowerCase()] = obj.config.domains[i]; } obj.config.domains = xdomains; var xdomains = {}; for (i in obj.config.domains) { if (obj.config.domains[i].title == null) { obj.config.domains[i].title = 'MeshCentral'; } if (obj.config.domains[i].title2 == null) { obj.config.domains[i].title2 = '2.0 Beta 2'; } xdomains[i.toLowerCase()] = obj.config.domains[i]; } obj.config.domains = xdomains;
var bannedDomains = ['public', 'private', 'images', 'scripts', 'styles', 'views']; // List of banned domains var bannedDomains = ['public', 'private', 'images', 'scripts', 'styles', 'views']; // List of banned domains
for (i in obj.config.domains) { for (var j in bannedDomains) { if (i == bannedDomains[j]) { console.log("ERROR: Domain '" + i + "' is not allowed domain name in ./data/config.json."); return; } } } for (i in obj.config.domains) { for (var j in bannedDomains) { if (i == bannedDomains[j]) { console.log("ERROR: Domain '" + i + "' is not allowed domain name in ./data/config.json."); return; } } }
for (i in obj.config.domains) { for (i in obj.config.domains) {

View File

@ -33,6 +33,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
} }
obj.server.listen(args.mpsport, function () { console.log("MeshCentral Intel(R) AMT server running on " + certificates.AmtMpsName + ":" + args.mpsport + ((args.mpsaliasport != null) ? (", alias port " + args.mpsaliasport) : "") + "."); }).on("error", function (err) { console.error("ERROR: MeshCentral Intel(R) AMT server port " + args.mpsport + " is not available."); if (args.exactports) { process.exit(); } }); obj.server.listen(args.mpsport, function () { console.log("MeshCentral Intel(R) AMT server running on " + certificates.AmtMpsName + ":" + args.mpsport + ((args.mpsaliasport != null) ? (", alias port " + args.mpsaliasport) : "") + "."); }).on("error", function (err) { console.error("ERROR: MeshCentral Intel(R) AMT server port " + args.mpsport + " is not available."); if (args.exactports) { process.exit(); } });
obj.server.on('tlsClientError', function (err, tlssocket) { if (args.mpsdebug) { var remoteAddress = tlssocket.remoteAddress; if (tlssocket.remoteFamily == 'IPv6') { remoteAddress = '[' + remoteAddress + ']'; } console.log('MPS:Invalid TLS connection from ' + remoteAddress + ':' + tlssocket.remotePort + '.'); } });
obj.parent.updateServerState("mps-port", args.mpsport); obj.parent.updateServerState("mps-port", args.mpsport);
obj.parent.updateServerState("mps-name", certificates.AmtMpsName); obj.parent.updateServerState("mps-name", certificates.AmtMpsName);
if (args.mpsaliasport != null) { obj.parent.updateServerState("mps-alias-port", args.mpsaliasport); } if (args.mpsaliasport != null) { obj.parent.updateServerState("mps-alias-port", args.mpsaliasport); }
@ -119,7 +120,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
if (socket.tag.first == true) { if (socket.tag.first == true) {
if (socket.tag.accumulator.length < 3) return; if (socket.tag.accumulator.length < 3) return;
//if (!socket.tag.clientCert.subject) { console.log("MPS Connection, no client cert: " + socket.remoteAddress); socket.write('HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nMeshCentral2 MPS server.\r\nNo client certificate given.'); socket.end(); return; } //if (!socket.tag.clientCert.subject) { console.log("MPS Connection, no client cert: " + socket.remoteAddress); socket.write('HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nMeshCentral2 MPS server.\r\nNo client certificate given.'); socket.end(); return; }
if (socket.tag.accumulator.substring(0, 3) == "GET") { console.log("MPS Connection, HTTP GET detected: " + socket.remoteAddress); socket.write("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<!DOCTYPE html><html><head><meta charset=\"UTF-8\"></head><body>MeshCentral2 MPS server.<br />Intel&reg; AMT computers should connect here.</body></html>"); socket.end(); return; } if (socket.tag.accumulator.substring(0, 3) == "GET") { if (args.mpsdebug) { console.log("MPS Connection, HTTP GET detected: " + socket.remoteAddress); } socket.write("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<!DOCTYPE html><html><head><meta charset=\"UTF-8\"></head><body>MeshCentral2 MPS server.<br />Intel&reg; AMT computers should connect here.</body></html>"); socket.end(); return; }
socket.tag.first = false; socket.tag.first = false;
// Setup this node with certificate authentication // Setup this node with certificate authentication

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.2.5-b", "version": "0.2.5-d",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -18,7 +18,7 @@
<script type="text/javascript" src="scripts/zlib-adler32.js"></script> <script type="text/javascript" src="scripts/zlib-adler32.js"></script>
<script type="text/javascript" src="scripts/zlib-crc32.js"></script> <script type="text/javascript" src="scripts/zlib-crc32.js"></script>
<script keeplink=1 type="text/javascript" src="scripts/filesaver.1.1.20151003.js"></script> <script keeplink=1 type="text/javascript" src="scripts/filesaver.1.1.20151003.js"></script>
<title>MeshCentral - Login</title> <title>MeshCentral</title>
<style> <style>
a { a {
color: #036; color: #036;
@ -186,7 +186,7 @@
<body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif"> <body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
<div id=container> <div id=container>
<div id=mastheadx></div> <div id=mastheadx></div>
<div id=masthead style="background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden"> <div id=masthead style="background:url(logo.png) 0px 0px;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden">
<div style="width:calc(100% - 50px);overflow:hidden"> <div style="width:calc(100% - 50px);overflow:hidden">
<div style="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:6px"> <div style="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:6px">
<strong><font style="font-size:36px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong> <strong><font style="font-size:36px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong>

View File

@ -52,7 +52,7 @@
<div id=container style=max-height:100vh;position:relative> <div id=container style=max-height:100vh;position:relative>
<div id="notifiyBox" class="notifiyBox" style="display:none"></div> <div id="notifiyBox" class="notifiyBox" style="display:none"></div>
<div id=mastheadx></div> <div id=mastheadx></div>
<div id=masthead class=noselect style="background:url(images/logoback.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;"> <div id=masthead class=noselect style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
<div style="float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px"> <div style="float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px">
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong> <strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong>
</div> </div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -28,7 +28,7 @@
<body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif"> <body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
<div id=container> <div id=container>
<div id=mastheadx></div> <div id=mastheadx></div>
<div id=masthead style="background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden"> <div id=masthead style="background:url(logo.png) 0px 0px;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden">
<div style="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:6px"> <div style="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:6px">
<strong><font style="font-size:36px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong> <strong><font style="font-size:36px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong>
</div> </div>

View File

@ -92,7 +92,7 @@
<body onload="if (typeof(startup) !== 'undefined') startup();"> <body onload="if (typeof(startup) !== 'undefined') startup();">
<div id=container style=max-height:100vh> <div id=container style=max-height:100vh>
<div id=mastheadx></div> <div id=mastheadx></div>
<div id=masthead style="background:url(images/logoback.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"> <div id=masthead style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
<div style="float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px"> <div style="float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px">
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong> <strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong>
</div> </div>

View File

@ -356,14 +356,13 @@ function trademarks(x) { return x.replace(/\(R\)/g, '&reg;').replace(/\(TM\)/g,
// 0 = nomedia, 1 = miconly, 2 = mic&cam // 0 = nomedia, 1 = miconly, 2 = mic&cam
function getUserMediaSupport(func) { function getUserMediaSupport(func) {
try { try {
navigator.mediaDevices.enumerateDevices() navigator.mediaDevices.enumerateDevices().then(function (devices) {
.then(devices => {
try { try {
var mic = 0, cam = 0; var mic = 0, cam = 0;
devices.forEach(device => { devices.forEach(function (device) {
if (device.kind === 'audioinput') { mic = 1; } if (device.kind === 'audioinput') { mic = 1; }
if (device.kind === 'videoinput') { cam = 1; } if (device.kind === 'videoinput') { cam = 1; }
}) });
if (mic == 0) { func(0); } if (mic == 0) { func(0); }
func(mic + cam); func(mic + cam);
} catch (ex) { } } catch (ex) { }

View File

@ -101,7 +101,7 @@
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden"> <body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
<div id="container"> <div id="container">
<!-- Begin Masthead --> <!-- Begin Masthead -->
<div id="masthead" class=noselect style="background:url(images/logoback.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;"> <div id="masthead" class=noselect style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:20px; padding-top:8px"> <div style="float:left; height: 66px; color:#c8c8c8; padding-left:20px; padding-top:8px">
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title}}}</font></strong> <strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title}}}</font></strong>
</div> </div>

View File

@ -991,6 +991,20 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
} }
} }
// Handle logo request
function handleLogoRequest(req, res) {
var domain = checkUserIpAddress(req, res);
res.set({ 'Cache-Control': 'max-age=86400' }); // 1 day
if ((domain != null) && domain.titlepicture) {
try { res.sendFile(obj.path.join(obj.parent.datapath, domain.titlepicture)); } catch (e) {
try { res.sendFile(obj.path.join(__dirname, 'public/images/logoback.png')); } catch (e) { res.sendStatus(404); }
}
} else {
try { res.sendFile(obj.path.join(__dirname, 'public/images/logoback.png')); } catch (e) { res.sendStatus(404); }
}
}
// Take a "user/domain/userid/path/file" format and return the actual server disk file path if access is allowed // Take a "user/domain/userid/path/file" format and return the actual server disk file path if access is allowed
obj.getServerFilePath = function (user, domain, path) { obj.getServerFilePath = function (user, domain, path) {
var splitpath = path.split('/'), serverpath = obj.path.join(obj.filespath, 'domain'), filename = ''; var splitpath = path.split('/'), serverpath = obj.path.join(obj.filespath, 'domain'), filename = '';
@ -1881,6 +1895,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
obj.app.get(url + 'webrelay.ashx', function (req, res) { res.send('Websocket connection expected'); }); obj.app.get(url + 'webrelay.ashx', function (req, res) { res.send('Websocket connection expected'); });
obj.app.ws(url + 'webrelay.ashx', function (ws, req) { PerformWSSessionAuth(ws, req, false, handleRelayWebSocket); }); obj.app.ws(url + 'webrelay.ashx', function (ws, req) { PerformWSSessionAuth(ws, req, false, handleRelayWebSocket); });
obj.app.ws(url + 'control.ashx', function (ws, req) { PerformWSSessionAuth(ws, req, false, function (ws1, req1, domain, user, cookie) { obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain, user); }); }); obj.app.ws(url + 'control.ashx', function (ws, req) { PerformWSSessionAuth(ws, req, false, function (ws1, req1, domain, user, cookie) { obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain, user); }); });
obj.app.get(url + 'logo.png', handleLogoRequest);
// Server picture // Server picture
obj.app.get(url + 'serverpic.ashx', function (req, res) { obj.app.get(url + 'serverpic.ashx', function (req, res) {