mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-11-23 23:04:04 +00:00
Fix parseCertificateInfo possibly in dead loop
This commit is contained in:
parent
c92153c97e
commit
41a6d1b701
3 changed files with 139 additions and 2 deletions
|
@ -367,7 +367,7 @@ class Monitor extends BeanModel {
|
||||||
await Monitor.sendNotification(isFirstBeat, this, bean);
|
await Monitor.sendNotification(isFirstBeat, this, bean);
|
||||||
|
|
||||||
// Clear Status Page Cache
|
// Clear Status Page Cache
|
||||||
debug(`[${this.name}] Check isImportant`);
|
debug(`[${this.name}] apicache clear`);
|
||||||
apicache.clear();
|
apicache.clear();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -201,8 +201,13 @@ const getDaysRemaining = (validFrom, validTo) => {
|
||||||
// param: info - the chain obtained from getPeerCertificate()
|
// param: info - the chain obtained from getPeerCertificate()
|
||||||
const parseCertificateInfo = function (info) {
|
const parseCertificateInfo = function (info) {
|
||||||
let link = info;
|
let link = info;
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
const existingList = {};
|
||||||
|
|
||||||
while (link) {
|
while (link) {
|
||||||
|
debug(`[${i}] ${link.fingerprint}`);
|
||||||
|
|
||||||
if (!link.valid_from || !link.valid_to) {
|
if (!link.valid_from || !link.valid_to) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -210,15 +215,24 @@ const parseCertificateInfo = function (info) {
|
||||||
link.validFor = link.subjectaltname?.replace(/DNS:|IP Address:/g, "").split(", ");
|
link.validFor = link.subjectaltname?.replace(/DNS:|IP Address:/g, "").split(", ");
|
||||||
link.daysRemaining = getDaysRemaining(new Date(), link.validTo);
|
link.daysRemaining = getDaysRemaining(new Date(), link.validTo);
|
||||||
|
|
||||||
|
existingList[link.fingerprint] = true;
|
||||||
|
|
||||||
// Move up the chain until loop is encountered
|
// Move up the chain until loop is encountered
|
||||||
if (link.issuerCertificate == null) {
|
if (link.issuerCertificate == null) {
|
||||||
break;
|
break;
|
||||||
} else if (link.fingerprint == link.issuerCertificate.fingerprint) {
|
} else if (link.issuerCertificate.fingerprint in existingList) {
|
||||||
|
debug(`[Last] ${link.issuerCertificate.fingerprint}`);
|
||||||
link.issuerCertificate = null;
|
link.issuerCertificate = null;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
link = link.issuerCertificate;
|
link = link.issuerCertificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should be no use, but just in case.
|
||||||
|
if (i > 500) {
|
||||||
|
throw new Error("Dead loop occurred in parseCertificateInfo");
|
||||||
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
@ -228,6 +242,7 @@ exports.checkCertificate = function (res) {
|
||||||
const info = res.request.res.socket.getPeerCertificate(true);
|
const info = res.request.res.socket.getPeerCertificate(true);
|
||||||
const valid = res.request.res.socket.authorized || false;
|
const valid = res.request.res.socket.authorized || false;
|
||||||
|
|
||||||
|
console.log("Parsing Certificate Info");
|
||||||
const parsedInfo = parseCertificateInfo(info);
|
const parsedInfo = parseCertificateInfo(info);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,4 +1,125 @@
|
||||||
const { genSecret, sleep } = require("../src/util");
|
const { genSecret, sleep } = require("../src/util");
|
||||||
|
const utilServerRewire = require("../server/util-server");
|
||||||
|
|
||||||
|
describe("Test parseCertificateInfo", () => {
|
||||||
|
it("should handle undefined", async () => {
|
||||||
|
const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo");
|
||||||
|
const info = parseCertificateInfo(undefined);
|
||||||
|
expect(info).toEqual(undefined);
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
it("should handle normal cert chain", async () => {
|
||||||
|
const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo");
|
||||||
|
|
||||||
|
const chain1 = {
|
||||||
|
fingerprint: "CF:2C:F3:6A:FE:6B:10:EC:44:77:C8:95:BB:96:2E:06:1F:0E:15:DA",
|
||||||
|
valid_from: "Oct 22 12:00:00 2013 GMT",
|
||||||
|
valid_to: "Oct 22 12:00:00 2028 GMT",
|
||||||
|
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
|
||||||
|
};
|
||||||
|
|
||||||
|
const chain2 = {
|
||||||
|
fingerprint: "A0:31:C4:67:82:E6:E6:C6:62:C2:C8:7C:76:DA:9A:A6:2C:CA:BD:8E",
|
||||||
|
valid_from: "Oct 22 12:00:00 2013 GMT",
|
||||||
|
valid_to: "Oct 22 12:00:00 2028 GMT",
|
||||||
|
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
|
||||||
|
};
|
||||||
|
|
||||||
|
const chain3 = {
|
||||||
|
fingerprint: "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
|
||||||
|
valid_from: "Oct 22 12:00:00 2013 GMT",
|
||||||
|
valid_to: "Oct 22 12:00:00 2028 GMT",
|
||||||
|
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
|
||||||
|
};
|
||||||
|
|
||||||
|
chain1.issuerCertificate = chain2;
|
||||||
|
chain2.issuerCertificate = chain3;
|
||||||
|
chain3.issuerCertificate = chain3;
|
||||||
|
|
||||||
|
const info = parseCertificateInfo(chain1);
|
||||||
|
expect(chain1).toEqual(info);
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
it("should handle cert chain with strange circle", async () => {
|
||||||
|
const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo");
|
||||||
|
|
||||||
|
const chain1 = {
|
||||||
|
fingerprint: "CF:2C:F3:6A:FE:6B:10:EC:44:77:C8:95:BB:96:2E:06:1F:0E:15:DA",
|
||||||
|
valid_from: "Oct 22 12:00:00 2013 GMT",
|
||||||
|
valid_to: "Oct 22 12:00:00 2028 GMT",
|
||||||
|
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
|
||||||
|
};
|
||||||
|
|
||||||
|
const chain2 = {
|
||||||
|
fingerprint: "A0:31:C4:67:82:E6:E6:C6:62:C2:C8:7C:76:DA:9A:A6:2C:CA:BD:8E",
|
||||||
|
valid_from: "Oct 22 12:00:00 2013 GMT",
|
||||||
|
valid_to: "Oct 22 12:00:00 2028 GMT",
|
||||||
|
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
|
||||||
|
};
|
||||||
|
|
||||||
|
const chain3 = {
|
||||||
|
fingerprint: "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
|
||||||
|
valid_from: "Oct 22 12:00:00 2013 GMT",
|
||||||
|
valid_to: "Oct 22 12:00:00 2028 GMT",
|
||||||
|
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
|
||||||
|
};
|
||||||
|
|
||||||
|
const chain4 = {
|
||||||
|
fingerprint: "haha",
|
||||||
|
valid_from: "Oct 22 12:00:00 2013 GMT",
|
||||||
|
valid_to: "Oct 22 12:00:00 2028 GMT",
|
||||||
|
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
|
||||||
|
};
|
||||||
|
|
||||||
|
chain1.issuerCertificate = chain2;
|
||||||
|
chain2.issuerCertificate = chain3;
|
||||||
|
chain3.issuerCertificate = chain4;
|
||||||
|
chain4.issuerCertificate = chain2;
|
||||||
|
|
||||||
|
const info = parseCertificateInfo(chain1);
|
||||||
|
expect(chain1).toEqual(info);
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
it("should handle cert chain with last undefined (should be happen in real, but just in case)", async () => {
|
||||||
|
const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo");
|
||||||
|
|
||||||
|
const chain1 = {
|
||||||
|
fingerprint: "CF:2C:F3:6A:FE:6B:10:EC:44:77:C8:95:BB:96:2E:06:1F:0E:15:DA",
|
||||||
|
valid_from: "Oct 22 12:00:00 2013 GMT",
|
||||||
|
valid_to: "Oct 22 12:00:00 2028 GMT",
|
||||||
|
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
|
||||||
|
};
|
||||||
|
|
||||||
|
const chain2 = {
|
||||||
|
fingerprint: "A0:31:C4:67:82:E6:E6:C6:62:C2:C8:7C:76:DA:9A:A6:2C:CA:BD:8E",
|
||||||
|
valid_from: "Oct 22 12:00:00 2013 GMT",
|
||||||
|
valid_to: "Oct 22 12:00:00 2028 GMT",
|
||||||
|
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
|
||||||
|
};
|
||||||
|
|
||||||
|
const chain3 = {
|
||||||
|
fingerprint: "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
|
||||||
|
valid_from: "Oct 22 12:00:00 2013 GMT",
|
||||||
|
valid_to: "Oct 22 12:00:00 2028 GMT",
|
||||||
|
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
|
||||||
|
};
|
||||||
|
|
||||||
|
const chain4 = {
|
||||||
|
fingerprint: "haha",
|
||||||
|
valid_from: "Oct 22 12:00:00 2013 GMT",
|
||||||
|
valid_to: "Oct 22 12:00:00 2028 GMT",
|
||||||
|
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
|
||||||
|
};
|
||||||
|
|
||||||
|
chain1.issuerCertificate = chain2;
|
||||||
|
chain2.issuerCertificate = chain3;
|
||||||
|
chain3.issuerCertificate = chain4;
|
||||||
|
chain4.issuerCertificate = undefined;
|
||||||
|
|
||||||
|
const info = parseCertificateInfo(chain1);
|
||||||
|
expect(chain1).toEqual(info);
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
|
||||||
describe("Test genSecret", () => {
|
describe("Test genSecret", () => {
|
||||||
|
|
||||||
|
@ -42,3 +163,4 @@ describe("Test reset-password", () => {
|
||||||
await require("../extra/reset-password").main();
|
await require("../extra/reset-password").main();
|
||||||
}, 120000);
|
}, 120000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue