mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-24 06:05:53 -05:00
MeshRouter now supports new icon, fixed server crash when running on single CPU, Removed Let's Encrypt wildcard altname being added by GreenLock.
This commit is contained in:
parent
fa929b3467
commit
607cdf888f
Binary file not shown.
@ -854,7 +854,7 @@ module.exports.CertificateOperations = function (parent) {
|
||||
obj.acceleratorPerformOperation = function (operation, data, tag, func) {
|
||||
if (acceleratorTotalCount <= 1) {
|
||||
// No accelerators available
|
||||
program.processMessage({ action: operation, data: data, tag: tag, func: func });
|
||||
require(program).processMessage({ action: operation, data: data, tag: tag, func: func });
|
||||
} else {
|
||||
var acc = obj.getAccelerator();
|
||||
if (acc == null) {
|
||||
|
@ -261,13 +261,28 @@ module.exports.CreateLetsEncrypt = function (parent) {
|
||||
|
||||
// GreenLock v3 Manager
|
||||
module.exports.create = function (options) {
|
||||
//console.log('xxx-create', options);
|
||||
var manager = { parent: globalLetsEncrypt };
|
||||
manager.find = async function (options) {
|
||||
//console.log('LE-FIND', options);
|
||||
try {
|
||||
// GreenLock sometimes has the bad behavior of adding a wildcard cert request, remove it here if needed.
|
||||
if ((options.wildname != null) && (options.wildname != '')) { options.wildname = ''; }
|
||||
if (options.altnames) {
|
||||
var altnames2 = [];
|
||||
for (var i in options.altnames) { if (options.altnames[i].indexOf('*') == -1) { altnames2.push(options.altnames[i]); } }
|
||||
options.altnames = altnames2;
|
||||
}
|
||||
if (options.servernames) {
|
||||
var servernames2 = [];
|
||||
for (var i in options.servernames) { if (options.servernames[i].indexOf('*') == -1) { servernames2.push(options.servernames[i]); } }
|
||||
options.servernames = servernames2;
|
||||
}
|
||||
} catch (ex) { console.log(ex); }
|
||||
return Promise.resolve([{ subject: options.servername, altnames: options.altnames }]);
|
||||
};
|
||||
|
||||
manager.set = function (options) {
|
||||
//console.log('xxx-set', options);
|
||||
manager.parent.parent.debug('cert', "Certificate has been set: " + JSON.stringify(options));
|
||||
if (manager.parent.parent.config.letsencrypt.production == manager.parent.runAsProduction) { manager.parent.performRestart = true; }
|
||||
else if ((manager.parent.parent.config.letsencrypt.production === true) && (manager.parent.runAsProduction === false)) { manager.parent.performMoveToProduction = true; }
|
||||
@ -275,6 +290,7 @@ module.exports.create = function (options) {
|
||||
};
|
||||
|
||||
manager.remove = function (options) {
|
||||
//console.log('xxx-remove', options);
|
||||
manager.parent.parent.debug('cert', "Certificate has been removed: " + JSON.stringify(options));
|
||||
if (manager.parent.parent.config.letsencrypt.production == manager.parent.runAsProduction) { manager.parent.performRestart = true; }
|
||||
else if ((manager.parent.parent.config.letsencrypt.production === true) && (manager.parent.runAsProduction === false)) { manager.parent.performMoveToProduction = true; }
|
||||
@ -283,6 +299,7 @@ module.exports.create = function (options) {
|
||||
|
||||
// set the global config
|
||||
manager.defaults = async function (options) {
|
||||
//console.log('xxx-defaults', options);
|
||||
var r;
|
||||
if (manager.parent.runAsProduction === true) {
|
||||
// Production
|
||||
|
@ -1079,6 +1079,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
var leok = true;
|
||||
if (typeof obj.config.letsencrypt.email != 'string') { leok = false; addServerWarning("Missing Let's Encrypt email address."); }
|
||||
else if (typeof obj.config.letsencrypt.names != 'string') { leok = false; addServerWarning("Invalid Let's Encrypt host names."); }
|
||||
else if (obj.config.letsencrypt.names.indexOf('*') >= 0) { leok = false; addServerWarning("Invalid Let's Encrypt names, can't contain a *."); }
|
||||
else if (obj.config.letsencrypt.email.split('@').length != 2) { leok = false; addServerWarning("Invalid Let's Encrypt email address."); }
|
||||
else if (obj.config.letsencrypt.email.trim() !== obj.config.letsencrypt.email) { leok = false; addServerWarning("Invalid Let's Encrypt email address."); }
|
||||
else {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.4.9-o",
|
||||
"version": "0.4.9-q",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
@ -760,7 +760,7 @@ function AmtStackCreateService(wsmanStack) {
|
||||
// ###BEGIN###{Certificates}
|
||||
|
||||
// Forge MD5
|
||||
function hex_md5(str) { return forge.md.md5.create().update(str).digest().toHex(); }
|
||||
function hex_md5(str) { if (str == null) { str = ''; } return forge.md.md5.create().update(str).digest().toHex(); }
|
||||
|
||||
// ###END###{Certificates}
|
||||
|
||||
@ -774,6 +774,7 @@ for (var i = 0; i < 64;) { md5_k[i] = 0 | (Math.abs(Math.sin(++i)) * 4294967296)
|
||||
|
||||
// Perform MD5 on raw string and return hex
|
||||
function hex_md5(str) {
|
||||
if (str == null) { str = ''; }
|
||||
var b, c, d, j,
|
||||
x = [],
|
||||
str2 = unescape(encodeURI(str)),
|
||||
|
@ -80,12 +80,12 @@ var CreateWsmanComm = function (host, port, user, pass, tls) {
|
||||
|
||||
// Websocket relay specific private method (Content Length Encoding)
|
||||
obj.sendRequest = function (postdata, url, action) {
|
||||
url = url ? url : "/wsman";
|
||||
action = action ? action : "POST";
|
||||
var h = action + " " + url + " HTTP/1.1\r\n";
|
||||
url = url ? url : '/wsman';
|
||||
action = action ? action : 'POST';
|
||||
var h = action + ' ' + url + ' HTTP/1.1\r\n';
|
||||
if (obj.challengeParams != null) {
|
||||
var response = hex_md5(hex_md5(obj.user + ':' + obj.challengeParams["realm"] + ':' + obj.pass) + ':' + obj.challengeParams["nonce"] + ':' + obj.noncecounter + ':' + obj.cnonce + ':' + obj.challengeParams["qop"] + ':' + hex_md5(action + ':' + url));
|
||||
h += 'Authorization: ' + obj.renderDigest({ "username": obj.user, "realm": obj.challengeParams["realm"], "nonce": obj.challengeParams["nonce"], "uri": url, "qop": obj.challengeParams["qop"], "response": response, "nc": obj.noncecounter++, "cnonce": obj.cnonce }) + '\r\n';
|
||||
var response = hex_md5(hex_md5(obj.user + ':' + obj.challengeParams['realm'] + ':' + obj.pass) + ':' + obj.challengeParams['nonce'] + ':' + obj.noncecounter + ':' + obj.cnonce + ':' + obj.challengeParams['qop'] + ':' + hex_md5(action + ':' + url + ((obj.challengeParams['qop'] == 'auth-int') ? (':' + hex_md5(postdata)) : '')));
|
||||
h += 'Authorization: ' + obj.renderDigest({ 'username': obj.user, 'realm': obj.challengeParams['realm'], 'nonce': obj.challengeParams['nonce'], 'uri': url, 'qop': obj.challengeParams['qop'], 'response': response, 'nc': obj.noncecounter++, 'cnonce': obj.cnonce }) + '\r\n';
|
||||
}
|
||||
//h += 'Host: ' + obj.host + ':' + obj.port + '\r\nContent-Length: ' + postdata.length + '\r\n\r\n' + postdata; // Use Content-Length
|
||||
h += 'Host: ' + obj.host + ':' + obj.port + '\r\nTransfer-Encoding: chunked\r\n\r\n' + postdata.length.toString(16).toUpperCase() + '\r\n' + postdata + '\r\n0\r\n\r\n'; // Use Chunked-Encoding
|
||||
@ -93,12 +93,11 @@ var CreateWsmanComm = function (host, port, user, pass, tls) {
|
||||
//obj.Debug("SEND: " + h); // Display send packet
|
||||
}
|
||||
|
||||
// Websocket relay specific private method
|
||||
obj.parseDigest = function (header) {
|
||||
var t = header.substring(7).split(',');
|
||||
for (i in t) t[i] = t[i].trim();
|
||||
return t.reduce(function (obj, s) { var parts = s.split('='); obj[parts[0]] = parts[1].replace(/"/g, ''); return obj; }, {})
|
||||
}
|
||||
// Parse the HTTP digest header and return a list of key & values.
|
||||
obj.parseDigest = function (header) { return correctedQuoteSplit(header.substring(7)).reduce(function (obj, s) { var parts = s.trim().split('='); obj[parts[0]] = parts[1].replace(new RegExp('\"', 'g'), ''); return obj; }, {}) }
|
||||
|
||||
// Split a string on quotes but do not do it when in quotes
|
||||
function correctedQuoteSplit(str) { return str.split(',').reduce(function (a, c) { if (a.ic) { a.st[a.st.length - 1] += ',' + c } else { a.st.push(c) } if (c.split('"').length % 2 == 0) { a.ic = !a.ic } return a; }, { st: [], ic: false }).st }
|
||||
|
||||
// Websocket relay specific private method
|
||||
obj.renderDigest = function (params) {
|
||||
@ -117,7 +116,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls) {
|
||||
obj.socketState = 1;
|
||||
|
||||
console.log(obj.tlsv1only);
|
||||
obj.socket = new WebSocket(window.location.protocol.replace("http", "ws") + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + "/webrelay.ashx?p=1&host=" + obj.host + "&port=" + obj.port + "&tls=" + obj.tls + "&tlsv1only=" + obj.tlsv1only + ((user == '*') ? "&serverauth=1" : "") + ((typeof pass === "undefined") ? ("&serverauth=1&user=" + user) : "")); // The "p=1" indicates to the relay that this is a WSMAN session
|
||||
obj.socket = new WebSocket(window.location.protocol.replace('http', 'ws') + '//' + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + '/webrelay.ashx?p=1&host=' + obj.host + '&port=' + obj.port + '&tls=' + obj.tls + '&tlsv1only=' + obj.tlsv1only + ((user == '*') ? '&serverauth=1' : '') + ((typeof pass === 'undefined') ? ('&serverauth=1&user=' + user) : '')); // The "p=1" indicates to the relay that this is a WSMAN session
|
||||
obj.socket.onopen = _OnSocketConnected;
|
||||
obj.socket.onmessage = _OnMessage;
|
||||
obj.socket.onclose = _OnSocketClosed;
|
||||
@ -154,7 +153,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls) {
|
||||
fileReader.readAsArrayBuffer(e.data);
|
||||
} else {
|
||||
// IE10, readAsBinaryString does not exist, use an alternative.
|
||||
var binary = "", bytes = new Uint8Array(e.data), length = bytes.byteLength;
|
||||
var binary = '', bytes = new Uint8Array(e.data), length = bytes.byteLength;
|
||||
for (var i = 0; i < length; i++) { binary += String.fromCharCode(bytes[i]); }
|
||||
_OnSocketData(binary);
|
||||
}
|
||||
@ -169,7 +168,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls) {
|
||||
|
||||
if (typeof data === 'object') {
|
||||
// This is an ArrayBuffer, convert it to a string array (used in IE)
|
||||
var binary = "", bytes = new Uint8Array(data), length = bytes.byteLength;
|
||||
var binary = '', bytes = new Uint8Array(data), length = bytes.byteLength;
|
||||
for (var i = 0; i < length; i++) { binary += String.fromCharCode(bytes[i]); }
|
||||
data = binary;
|
||||
}
|
||||
@ -180,10 +179,10 @@ var CreateWsmanComm = function (host, port, user, pass, tls) {
|
||||
obj.socketAccumulator += data;
|
||||
while (true) {
|
||||
if (obj.socketParseState == 0) {
|
||||
var headersize = obj.socketAccumulator.indexOf("\r\n\r\n");
|
||||
var headersize = obj.socketAccumulator.indexOf('\r\n\r\n');
|
||||
if (headersize < 0) return;
|
||||
//obj.Debug(obj.socketAccumulator.substring(0, headersize)); // Display received HTTP header
|
||||
obj.socketHeader = obj.socketAccumulator.substring(0, headersize).split("\r\n");
|
||||
obj.socketHeader = obj.socketAccumulator.substring(0, headersize).split('\r\n');
|
||||
obj.socketAccumulator = obj.socketAccumulator.substring(headersize + 4);
|
||||
obj.socketParseState = 1;
|
||||
obj.socketData = '';
|
||||
@ -197,12 +196,12 @@ var CreateWsmanComm = function (host, port, user, pass, tls) {
|
||||
}
|
||||
if (obj.socketParseState == 1) {
|
||||
var csize = -1;
|
||||
if ((obj.socketXHeader["connection"] != undefined) && (obj.socketXHeader["connection"].toLowerCase() == 'close') && ((obj.socketXHeader["transfer-encoding"] == undefined) || (obj.socketXHeader["transfer-encoding"].toLowerCase() != 'chunked'))) {
|
||||
if ((obj.socketXHeader['connection'] != undefined) && (obj.socketXHeader['connection'].toLowerCase() == 'close') && ((obj.socketXHeader["transfer-encoding"] == undefined) || (obj.socketXHeader["transfer-encoding"].toLowerCase() != 'chunked'))) {
|
||||
// The body ends with a close, in this case, we will only process the header
|
||||
csize = 0;
|
||||
} else if (obj.socketXHeader["content-length"] != undefined) {
|
||||
} else if (obj.socketXHeader['content-length'] != undefined) {
|
||||
// The body length is specified by the content-length
|
||||
csize = parseInt(obj.socketXHeader["content-length"]);
|
||||
csize = parseInt(obj.socketXHeader['content-length']);
|
||||
if (obj.socketAccumulator.length < csize) return;
|
||||
var data = obj.socketAccumulator.substring(0, csize);
|
||||
obj.socketAccumulator = obj.socketAccumulator.substring(csize);
|
||||
@ -239,6 +238,11 @@ var CreateWsmanComm = function (host, port, user, pass, tls) {
|
||||
if (isNaN(s)) s = 602;
|
||||
if (s == 401 && ++(obj.authcounter) < 3) {
|
||||
obj.challengeParams = obj.parseDigest(header['www-authenticate']); // Set the digest parameters, after this, the socket will close and we will auto-retry
|
||||
if (obj.challengeParams['qop'] != null) {
|
||||
var qopList = obj.challengeParams['qop'].split(',');
|
||||
for (var i in qopList) { qopList[i] = qopList[i].trim(); }
|
||||
if (qopList.indexOf('auth-int') >= 0) { obj.challengeParams['qop'] = 'auth-int'; } else { obj.challengeParams['qop'] = 'auth'; }
|
||||
}
|
||||
} else {
|
||||
var r = obj.pendingAjaxCall.shift();
|
||||
// if (s != 200) { obj.Debug("Error, status=" + s + "\r\n\r\nreq=" + r[0] + "\r\n\r\nresp=" + data); } // Debug: Display the request & response if something did not work.
|
||||
|
@ -75,7 +75,15 @@ module.exports.CreateRedirServer = function (parent, db, args, func) {
|
||||
parent.letsencrypt.challenge(req.url.slice(leChallengePrefix.length), getCleanHostname(req), function (response) { if (response == null) { res.sendStatus(404); } else { res.send(response); } });
|
||||
} else {
|
||||
// Everything else
|
||||
res.set({ 'strict-transport-security': "max-age=60000; includeSubDomains", "Referrer-Policy": "no-referrer", "x-frame-options": "SAMEORIGIN", "X-XSS-Protection": "1; mode=block", "X-Content-Type-Options": "nosniff", "Content-Security-Policy": "default-src http: ws: \"self\" \"unsafe-inline\"" });
|
||||
var selfurl = ((args.notls !== true) ? (' wss://' + req.headers.host) : (' ws://' + req.headers.host));
|
||||
res.set({
|
||||
'strict-transport-security': 'max-age=60000; includeSubDomains',
|
||||
'Referrer-Policy': 'no-referrer',
|
||||
'x-frame-options': 'SAMEORIGIN',
|
||||
'X-XSS-Protection': '1; mode=block',
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
'Content-Security-Policy': "default-src 'none'; style-src 'self' 'unsafe-inline';"
|
||||
});
|
||||
return next();
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user