Added support for wildcard Let's Encrypt certs.

Ylian Saint-Hilaire committed Jun 7, 2019 at 15:55 UTC c177c25b34f9962e9c5a2234b777ed106d5275f3
7 files changed +27 -16
certoperations.js
+19 -9
@@ -196,7 +196,7 @@ module.exports.CertificateOperations = function (parent) {
196 }
197
198 // Return true if the name is found in the certificates names, we support wildcard certificates
199 - function compareCertificateNames(certNames, name) {
199 + obj.compareCertificateNames = function(certNames, name) {
200 if (certNames == null) return false;
201 if (certNames.indexOf(name.toLowerCase()) >= 0) return true;
202 for (var i in certNames) {
@@ -317,9 +317,14 @@ module.exports.CertificateOperations = function (parent) {
317 if (commonName.startsWith('*.')) { console.log("ERROR: Server can't use a wildcard name: " + commonName); process.exit(0); return; }
318 r.CommonName = commonName;
319 }
320 - r.CommonNames = [r.CommonName.toLowerCase()];
320 + r.CommonNames = [ r.CommonName.toLowerCase() ];
321 var altNames = webCertificate.getExtension("subjectAltName");
322 - if (altNames) { for (i = 0; i < altNames.altNames.length; i++) { r.CommonNames.push(altNames.altNames[i].value.toLowerCase()); } }
322 + if (altNames) {
323 + for (i = 0; i < altNames.altNames.length; i++) {
324 + var acn = altNames.altNames[i].value.toLowerCase();
325 + if (r.CommonNames.indexOf(acn) == -1) { r.CommonNames.push(acn); }
326 + }
327 + }
328 var rootCertificate = obj.pki.certificateFromPem(r.root.cert);
329 r.RootName = rootCertificate.subject.getField("CN").value;
330 }
@@ -330,7 +335,7 @@ module.exports.CertificateOperations = function (parent) {
335 if ((i != "") && (config.domains[i] != null) && (config.domains[i].dns != null)) {
336 dnsname = config.domains[i].dns;
337 // Check if this domain matches a parent wildcard cert, if so, use the parent cert.
333 - if (compareCertificateNames(r.CommonNames, dnsname) == true) {
338 + if (obj.compareCertificateNames(r.CommonNames, dnsname) == true) {
339 r.dns[i] = { cert: obj.fileLoad("webserver-cert-public.crt", "utf8"), key: obj.fileLoad("webserver-cert-private.key", "utf8") };
340 } else {
341 if (args.tlsoffload) {
@@ -374,7 +379,7 @@ module.exports.CertificateOperations = function (parent) {
379 if (certargs == null) { commonName = r.CommonName; country = xcountry; organization = xorganization; }
380
381 // Check if we have correct certificates
377 - if (compareCertificateNames(r.CommonNames, commonName) == false) { forceWebCertGen = 1; }
382 + if (obj.compareCertificateNames(r.CommonNames, commonName) == false) { forceWebCertGen = 1; }
383 if (r.AmtMpsName != mpsCommonName) { forceMpsCertGen = 1; }
384
385 // If the certificates matches what we want, use them.
@@ -426,9 +431,14 @@ module.exports.CertificateOperations = function (parent) {
431 obj.fs.writeFileSync(parent.getConfigFilePath("webserver-cert-private.key"), webPrivateKey);
432 } else {
433 // Keep the console certificate we have
429 - webCertAndKey = { cert: obj.pki.certificateFromPem(r.web.cert), key: obj.pki.privateKeyFromPem(r.web.key) };
430 - webCertificate = r.web.cert;
431 - webPrivateKey = r.web.key;
434 + if (args.tlsoffload) {
435 + webCertAndKey = { cert: obj.pki.certificateFromPem(r.web.cert) };
436 + webCertificate = r.web.cert;
437 + } else {
438 + webCertAndKey = { cert: obj.pki.certificateFromPem(r.web.cert), key: obj.pki.privateKeyFromPem(r.web.key) };
439 + webCertificate = r.web.cert;
440 + webPrivateKey = r.web.key;
441 + }
442 }
443 var webIssuer = webCertAndKey.cert.issuer.getField("CN").value;
444
@@ -486,7 +496,7 @@ module.exports.CertificateOperations = function (parent) {
496 if ((i != "") && (config.domains[i] != null) && (config.domains[i].dns != null)) {
497 dnsname = config.domains[i].dns;
498 // Check if this domain matches a parent wildcard cert, if so, use the parent cert.
489 - if (compareCertificateNames(r.CommonNames, dnsname) == true) {
499 + if (obj.compareCertificateNames(r.CommonNames, dnsname) == true) {
500 r.dns[i] = { cert: obj.fileLoad("webserver-cert-public.crt", "utf8"), key: obj.fileLoad("webserver-cert-private.key", "utf8") };
501 } else {
502 if (!args.tlsoffload) {
letsEncrypt.js
+1 -1
@@ -92,7 +92,7 @@ module.exports.CreateLetsEncrypt = function (parent) {
92 certs.web.ca = [results.chain];
93 }
94 for (var i in obj.parent.config.domains) {
95 - if ((obj.parent.config.domains[i].dns != null) && (results.altnames.indexOf(obj.parent.config.domains[i].dns) >= 0)) {
95 + if ((obj.parent.config.domains[i].dns != null) && (obj.parent.certificateOperations.compareCertificateNames(results.altnames, obj.parent.config.domains[i].dns))) {
96 certs.dns[i].cert = results.cert;
97 certs.dns[i].key = results.privkey;
98 certs.dns[i].ca = [results.chain];
meshcentral.js
+1
@@ -816,6 +816,7 @@ function CreateMeshCentralServer(config, args) {
816 if ((obj.config.smtp != null) && (obj.config.smtp.host != null) && (obj.config.smtp.from != null)) {
817 obj.mailserver = require('./meshmail.js').CreateMeshMail(obj);
818 obj.mailserver.verify();
819 + if (obj.args.lanonly == true) { console.log("WARNING: SMTP server has limited use in LAN mode."); }
820 }
821
822 // Start periodic maintenance
meshuser.js
+1 -1
@@ -283,7 +283,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
283 var httpport = ((args.aliasport != null) ? args.aliasport : args.port);
284
285 // Build server information object
286 - var serverinfo = { name: domain.dns ? domain.dns : parent.certificates.CommonName, mpsname: parent.certificates.AmtMpsName, mpsport: mpsport, mpspass: args.mpspass, port: httpport, emailcheck: ((parent.parent.mailserver != null) && (domain.auth != 'sspi') && (domain.auth != 'ldap')), domainauth: ((domain.auth == 'sspi') || (domain.auth == 'ldap')) };
286 + var serverinfo = { name: domain.dns ? domain.dns : parent.certificates.CommonName, mpsname: parent.certificates.AmtMpsName, mpsport: mpsport, mpspass: args.mpspass, port: httpport, emailcheck: ((parent.parent.mailserver != null) && (domain.auth != 'sspi') && (domain.auth != 'ldap') && (args.lanonly != true) && (parent.certificates.CommonName != null) && (parent.certificates.CommonName.indexOf('.') != -1)), domainauth: ((domain.auth == 'sspi') || (domain.auth == 'ldap')) };
287 if (args.notls == true) { serverinfo.https = false; } else { serverinfo.https = true; serverinfo.redirport = args.redirport; }
288 if (typeof domain.userconsentflags == 'number') { serverinfo.consent = domain.userconsentflags; }
289 if ((typeof domain.usersessionidletimeout == 'number') && (domain.usersessionidletimeout > 0)) { serverinfo.timeout = (domain.usersessionidletimeout * 60 * 1000); }
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.3.6-f",
3 + "version": "0.3.6-g",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
views/agentinvite.handlebars
+2 -2
@@ -31,7 +31,7 @@
31 }
32
33 .tab button.active {
34 - background-color: #ccc;
34 + background-color: #8f8;
35 }
36
37 .tabcontent {
@@ -39,7 +39,7 @@
39 padding: 6px 12px;
40 border: 1px solid #ccc;
41 border-top: none;
42 - }
42 + }
43 </style>
44 </head>
45 <body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
webserver.js
+2 -2
@@ -911,7 +911,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
911 // Called to process an account reset request
912 function handleResetAccountRequest(req, res) {
913 const domain = checkUserIpAddress(req, res);
914 - if ((domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap')) { res.sendStatus(404); return; }
914 + if ((domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap') || (obj.args.lanonly == true) || (obj.parent.certificates.CommonName == null) || (obj.parent.certificates.CommonName.indexOf('.') == -1)) { res.sendStatus(404); return; }
915
916 // Get the email from the body or session.
917 var email = req.body.email;
@@ -1416,7 +1416,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1416 var message = '';
1417 if (err != null) message = '<p class="msg error">' + err + '</p>';
1418 if (msg != null) message = '<p class="msg success">' + msg + '</p>';
1419 - var emailcheck = ((obj.parent.mailserver != null) && (domain.auth != 'sspi'));
1419 + var emailcheck = ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
1420
1421 // Check if we are allowed to create new users using the login screen
1422 var newAccountsAllowed = true;