core/source/logic/check_kinds/tls_certificate.ts

251 lines
5.1 KiB
TypeScript
Raw Normal View History

namespace _heimdall.check_kinds.tls_certificate
{
/**
*/
function parameters_schema(
) : _heimdall.helpers.json_schema.type_schema
{
return {
"type": "object",
"additionalProperties": false,
"properties": {
"host": {
"type": "string"
},
"port": {
"type": "integer",
"default": 443
},
"expiry_threshold_concerning": {
"description": "in days; allowed amount of valid days before the certificate expires; threshold for condition 'concerning'; 'null' means 'report at no value'",
"anyOf": [
{
"type": "null",
},
{
"type": "integer",
"minimum": 0
},
],
"default": 7,
},
"expiry_threshold_critical": {
"description": "in days; allowed amount of valid days before the certificate expires; threshold for condition 'critical'; 'null' means 'report at no value'",
"anyOf": [
{
"type": "null",
},
{
"type": "integer",
"minimum": 0
},
],
"default": 1,
},
"expiry_threshold": {
"deprecated": true,
"description": "",
"anyOf": [
{
"type": "null",
},
{
"type": "integer",
"minimum": 0
},
],
"default": null,
},
"strict": {
"deprecated": true,
"description": "",
"anyOf": [
{
"type": "null",
},
{
"type": "boolean",
},
],
"default": null,
},
},
"required": [
"host",
]
};
}
/**
*/
function normalize_order_node(
node : any
) : any
{
const version : string = (
(
(! ("expiry_threshold_concerning" in node))
&&
(! ("expiry_threshold_critical" in node))
)
? "v1"
: "v2"
);
switch (version) {
default: {
throw (new Error("unhandled version"));
break;
}
case "v1": {
if (! ("host" in node)) {
throw new Error("missing mandatory field 'host'");
}
else {
const node_ = Object.assign(
{
"port": 443,
"expiry_threshold": 7,
"strict": true,
},
node
);
return {
"host": node_["host"],
"port": node_["port"],
"expiry_threshold_concerning": (
node_["strict"]
? null
: node_["expiry_threshold"]
),
"expiry_threshold_critical": (
node_["strict"]
? node_["expiry_threshold"]
: null
),
};
}
break;
}
case "v2": {
if (! ("host" in node)) {
throw new Error("missing mandatory field 'host'");
}
else {
const node_ = Object.assign(
{
"port": 443,
"expiry_threshold_concerning": 7,
"expiry_threshold_critical": 1,
},
node
);
return node_;
}
break;
}
}
}
/**
*/
async function run(
parameters
) : Promise<_heimdall.type_result>
{
// TODO: outsource to parameters
const timeout : float = 5.0;
type type_stuff = {
valid_from : int;
valid_to : int;
};
// const nm_child_process = require("x509");
const nm_tls = require("tls");
const nm_ssl_checker = require("ssl-checker");
let faults : Array<string> = [];
let data : Record<string, any> = {};
let condition : _heimdall.enum_condition = _heimdall.enum_condition.ok;
let version : (null | string);
const stuff : (null | type_stuff) = await (
nm_ssl_checker(parameters["host"], {"port": parameters["port"]})
.then(
x => ({
"valid_from": Math.floor((new Date(x["validFrom"])).getTime() / 1000),
"valid_to": Math.floor((new Date(x["validTo"])).getTime() / 1000),
})
)
);
if (stuff === null) {
faults.push(lib_plankton.translate.get("checks.tls_certificate.not_obtainable"));
condition = _heimdall.enum_condition.critical;
version = null;
}
else {
version = "TLSv1.3";
const current_timestamp : int = _heimdall.get_current_timestamp();
const expiry_timestamp = stuff.valid_to;
const days : int = Math.ceil((expiry_timestamp - current_timestamp) / (60 * 60 * 24));
data = Object.assign(
data,
{
"expiry_timestamp": expiry_timestamp,
"days": days,
}
);
if (
(parameters["expiry_threshold_critical"] !== null)
&&
(days <= parameters["expiry_threshold_critical"])
) {
faults.push(lib_plankton.translate.get("checks.tls_certificate.expires_soon"));
condition = _heimdall.enum_condition.critical;
}
else {
if (
(parameters["expiry_threshold_concerning"] !== null)
&&
(days <= parameters["expiry_threshold_concerning"])
) {
faults.push(lib_plankton.translate.get("checks.tls_certificate.expires_soon"));
condition = _heimdall.enum_condition.concerning;
}
else {
// no nothing
}
}
}
return Promise.resolve({
"condition": condition,
"info": {
"host": parameters["host"],
"port": parameters["port"],
"faults": faults,
"data": data,
}
});
}
/**
*/
export function check_kind_implementation(
) : type_check_kind
{
return {
"parameters_schema": parameters_schema,
"normalize_order_node": normalize_order_node,
"run": run,
};
}
}