251 lines
5.1 KiB
TypeScript
251 lines
5.1 KiB
TypeScript
|
|
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,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|