From 0926e73e0e3e125555ca4b06510334f98e57646a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:32:50 +0200 Subject: sslutils.c: clang-format --- plugins/sslutils.c | 65 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 24 deletions(-) (limited to 'plugins/sslutils.c') diff --git a/plugins/sslutils.c b/plugins/sslutils.c index 96740b3a..92e0cc84 100644 --- a/plugins/sslutils.c +++ b/plugins/sslutils.c @@ -37,13 +37,16 @@ static SSL *s = NULL; int np_net_ssl_init(int sd) { return np_net_ssl_init_with_hostname(sd, NULL); } -int np_net_ssl_init_with_hostname(int sd, char *host_name) { return np_net_ssl_init_with_hostname_and_version(sd, host_name, 0); } +int np_net_ssl_init_with_hostname(int sd, char *host_name) { + return np_net_ssl_init_with_hostname_and_version(sd, host_name, 0); +} int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version) { return np_net_ssl_init_with_hostname_version_and_cert(sd, host_name, version, NULL, NULL); } -int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, char *privkey) { +int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, + char *privkey) { long options = 0; if ((ctx = SSL_CTX_new(TLS_client_method())) == NULL) { @@ -75,7 +78,8 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int # endif case MP_TLSv1_1: /* TLSv1.1 protocol */ # if !defined(SSL_OP_NO_TLSv1_1) - printf("%s\n", _("UNKNOWN - TLS protocol version 1.1 is not supported by your SSL library.")); + printf("%s\n", + _("UNKNOWN - TLS protocol version 1.1 is not supported by your SSL library.")); return STATE_UNKNOWN; # else SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION); @@ -84,7 +88,8 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int # endif case MP_TLSv1_2: /* TLSv1.2 protocol */ # if !defined(SSL_OP_NO_TLSv1_2) - printf("%s\n", _("UNKNOWN - TLS protocol version 1.2 is not supported by your SSL library.")); + printf("%s\n", + _("UNKNOWN - TLS protocol version 1.2 is not supported by your SSL library.")); return STATE_UNKNOWN; # else SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); @@ -145,8 +150,9 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); if ((s = SSL_new(ctx)) != NULL) { # ifdef SSL_set_tlsext_host_name - if (host_name != NULL) + if (host_name != NULL) { SSL_set_tlsext_host_name(s, host_name); + } # endif SSL_set_fd(s, sd); if (SSL_connect(s) == 1) { @@ -182,7 +188,8 @@ int np_net_ssl_write(const void *buf, int num) { return SSL_write(s, buf, num); int np_net_ssl_read(void *buf, int num) { return SSL_read(s, buf, num); } -int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int days_till_exp_crit) { +int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, + int days_till_exp_crit) { # ifdef USE_OPENSSL X509_NAME *subj = NULL; char timestamp[50] = ""; @@ -213,8 +220,9 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int return STATE_CRITICAL; } cnlen = X509_NAME_get_text_by_NID(subj, NID_commonName, cn, sizeof(cn)); - if (cnlen == -1) + if (cnlen == -1) { strcpy(cn, _("Unknown CN")); + } /* Retrieve timestamp of certificate */ tm = X509_get_notAfter(certificate); @@ -226,8 +234,9 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int return STATE_CRITICAL; } else { stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0'); - if (stamp.tm_year < 50) + if (stamp.tm_year < 50) { stamp.tm_year += 100; + } offset = 0; } } else { @@ -235,7 +244,8 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int printf("%s\n", _("CRITICAL - Wrong time format in certificate.")); return STATE_CRITICAL; } else { - stamp.tm_year = (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); + stamp.tm_year = (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + + (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); stamp.tm_year -= 1900; offset = 2; } @@ -254,41 +264,48 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int setenv("TZ", "GMT", 1); tzset(); strftime(timestamp, 50, "%c %z", localtime(&tm_t)); - if (tz) + if (tz) { setenv("TZ", tz, 1); - else + } else { unsetenv("TZ"); + } tzset(); if (days_left > 0 && days_left <= days_till_exp_warn) { - printf(_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, - days_left, timestamp); - if (days_left > days_till_exp_crit) + printf(_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), + (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, days_left, timestamp); + if (days_left > days_till_exp_crit) { status = STATE_WARNING; - else + } else { status = STATE_CRITICAL; + } } else if (days_left == 0 && time_left > 0) { - if (time_left >= 3600) + if (time_left >= 3600) { time_remaining = (int)time_left / 3600; - else + } else { time_remaining = (int)time_left / 60; + } - printf(_("%s - Certificate '%s' expires in %u %s (%s)\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, - time_remaining, time_left >= 3600 ? "hours" : "minutes", timestamp); + printf(_("%s - Certificate '%s' expires in %u %s (%s)\n"), + (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, time_remaining, + time_left >= 3600 ? "hours" : "minutes", timestamp); - if (days_left > days_till_exp_crit) + if (days_left > days_till_exp_crit) { status = STATE_WARNING; - else + } else { status = STATE_CRITICAL; + } } else if (time_left < 0) { printf(_("CRITICAL - Certificate '%s' expired on %s.\n"), cn, timestamp); status = STATE_CRITICAL; } else if (days_left == 0) { - printf(_("%s - Certificate '%s' just expired (%s).\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, timestamp); - if (days_left > days_till_exp_crit) + printf(_("%s - Certificate '%s' just expired (%s).\n"), + (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, timestamp); + if (days_left > days_till_exp_crit) { status = STATE_WARNING; - else + } else { status = STATE_CRITICAL; + } } else { printf(_("OK - Certificate '%s' will expire on %s.\n"), cn, timestamp); status = STATE_OK; -- cgit v1.2.3-74-g34f1 From 572ad994b136c443c5d59509a28b8343c3e40ab3 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:41:22 +0200 Subject: plugins-netutils: return proper state from test functions --- plugins/netutils.h | 2 +- plugins/sslutils.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'plugins/sslutils.c') diff --git a/plugins/netutils.h b/plugins/netutils.h index 0ca524f2..c53b3cef 100644 --- a/plugins/netutils.h +++ b/plugins/netutils.h @@ -113,7 +113,7 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int void np_net_ssl_cleanup(); int np_net_ssl_write(const void *buf, int num); int np_net_ssl_read(void *buf, int num); -int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit); +mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit); #endif /* HAVE_SSL */ #endif /* _NETUTILS_H_ */ diff --git a/plugins/sslutils.c b/plugins/sslutils.c index 92e0cc84..b20a2b2c 100644 --- a/plugins/sslutils.c +++ b/plugins/sslutils.c @@ -30,6 +30,7 @@ #include "common.h" #include "netutils.h" #include "../lib/monitoringplug.h" +#include "states.h" #ifdef HAVE_SSL static SSL_CTX *ctx = NULL; @@ -318,7 +319,7 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, # endif /* USE_OPENSSL */ } -int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit) { +mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit) { # ifdef USE_OPENSSL X509 *certificate = NULL; certificate = SSL_get_peer_certificate(s); -- cgit v1.2.3-74-g34f1 From a2ca373e2d6a9903126e152254c83245ad202ff8 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:41:46 +0200 Subject: sslutils: some refactoring to improve readability --- plugins/sslutils.c | 64 ++++++++++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 36 deletions(-) (limited to 'plugins/sslutils.c') diff --git a/plugins/sslutils.c b/plugins/sslutils.c index b20a2b2c..bea1307f 100644 --- a/plugins/sslutils.c +++ b/plugins/sslutils.c @@ -189,67 +189,54 @@ int np_net_ssl_write(const void *buf, int num) { return SSL_write(s, buf, num); int np_net_ssl_read(void *buf, int num) { return SSL_read(s, buf, num); } -int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, - int days_till_exp_crit) { +mp_state_enum np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, + int days_till_exp_crit) { # ifdef USE_OPENSSL - X509_NAME *subj = NULL; - char timestamp[50] = ""; - char cn[MAX_CN_LENGTH] = ""; - char *tz; - - int cnlen = -1; - int status = STATE_UNKNOWN; - - ASN1_STRING *tm; - int offset; - struct tm stamp; - float time_left; - int days_left; - int time_remaining; - time_t tm_t; - if (!certificate) { printf("%s\n", _("CRITICAL - No server certificate present to inspect.")); return STATE_CRITICAL; } /* Extract CN from certificate subject */ - subj = X509_get_subject_name(certificate); + X509_NAME *subj = X509_get_subject_name(certificate); if (!subj) { printf("%s\n", _("CRITICAL - Cannot retrieve certificate subject.")); return STATE_CRITICAL; } - cnlen = X509_NAME_get_text_by_NID(subj, NID_commonName, cn, sizeof(cn)); + + char cn[MAX_CN_LENGTH] = ""; + int cnlen = X509_NAME_get_text_by_NID(subj, NID_commonName, cn, sizeof(cn)); if (cnlen == -1) { strcpy(cn, _("Unknown CN")); } /* Retrieve timestamp of certificate */ - tm = X509_get_notAfter(certificate); + ASN1_STRING *tm = X509_get_notAfter(certificate); + int offset = 0; + struct tm stamp = {}; /* Generate tm structure to process timestamp */ if (tm->type == V_ASN1_UTCTIME) { if (tm->length < 10) { printf("%s\n", _("CRITICAL - Wrong time format in certificate.")); return STATE_CRITICAL; - } else { - stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0'); - if (stamp.tm_year < 50) { - stamp.tm_year += 100; - } - offset = 0; } + stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0'); + if (stamp.tm_year < 50) { + stamp.tm_year += 100; + } + offset = 0; + } else { if (tm->length < 12) { printf("%s\n", _("CRITICAL - Wrong time format in certificate.")); return STATE_CRITICAL; - } else { - stamp.tm_year = (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + - (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); - stamp.tm_year -= 1900; - offset = 2; } + stamp.tm_year = (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + + (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); + stamp.tm_year -= 1900; + offset = 2; } stamp.tm_mon = (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1; stamp.tm_mday = (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0'); @@ -258,20 +245,25 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, stamp.tm_sec = (tm->data[10 + offset] - '0') * 10 + (tm->data[11 + offset] - '0'); stamp.tm_isdst = -1; - tm_t = timegm(&stamp); - time_left = difftime(tm_t, time(NULL)); - days_left = time_left / 86400; - tz = getenv("TZ"); + time_t tm_t = timegm(&stamp); + float time_left = difftime(tm_t, time(NULL)); + int days_left = time_left / 86400; + char *tz = getenv("TZ"); setenv("TZ", "GMT", 1); tzset(); + + char timestamp[50] = ""; strftime(timestamp, 50, "%c %z", localtime(&tm_t)); if (tz) { setenv("TZ", tz, 1); } else { unsetenv("TZ"); } + tzset(); + int time_remaining; + mp_state_enum status = STATE_UNKNOWN; if (days_left > 0 && days_left <= days_till_exp_warn) { printf(_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, days_left, timestamp); -- cgit v1.2.3-74-g34f1 From f5f4a021a2760d553e3e4cdedd291eb815750369 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 15 Sep 2025 01:57:40 +0200 Subject: Add new cert check function --- plugins/check_curl.c | 3 +- plugins/netutils.h | 3 +- plugins/sslutils.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+), 2 deletions(-) (limited to 'plugins/sslutils.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 680ecef7..b1021045 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -569,8 +569,9 @@ mp_subcheck check_http(const check_curl_config config, check_curl_working_state sc_body_regex = mp_set_subcheck_state(sc_body_regex, STATE_OK); } } else if (errcode == REG_NOMATCH) { - xasprintf(&sc_body_regex.output, "%s not", sc_body_regex.output); // got no match + xasprintf(&sc_body_regex.output, "%s not", sc_body_regex.output); + if (config.invert_regex) { sc_body_regex = mp_set_subcheck_state(sc_body_regex, STATE_OK); } else { diff --git a/plugins/netutils.h b/plugins/netutils.h index c53b3cef..6adb8e01 100644 --- a/plugins/netutils.h +++ b/plugins/netutils.h @@ -32,6 +32,7 @@ #define _NETUTILS_H_ #include "common.h" +#include "output.h" #include "states.h" #include "utils.h" #include @@ -114,6 +115,6 @@ void np_net_ssl_cleanup(); int np_net_ssl_write(const void *buf, int num); int np_net_ssl_read(void *buf, int num); mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit); +mp_subcheck mp_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit); #endif /* HAVE_SSL */ - #endif /* _NETUTILS_H_ */ diff --git a/plugins/sslutils.c b/plugins/sslutils.c index bea1307f..3ce6afed 100644 --- a/plugins/sslutils.c +++ b/plugins/sslutils.c @@ -26,6 +26,7 @@ * *****************************************************************************/ +#include "output.h" #define MAX_CN_LENGTH 256 #include "common.h" #include "netutils.h" @@ -322,4 +323,138 @@ mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_cr # endif /* USE_OPENSSL */ } +mp_subcheck mp_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, + int days_till_exp_crit) { + mp_subcheck sc_cert = mp_subcheck_init(); +# ifdef USE_OPENSSL + if (!certificate) { + xasprintf(&sc_cert.output, _("No server certificate present to inspect")); + sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); + return sc_cert; + } + + /* Extract CN from certificate subject */ + X509_NAME *subj = X509_get_subject_name(certificate); + + if (!subj) { + xasprintf(&sc_cert.output, _("Cannot retrieve certificate subject")); + sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); + return sc_cert; + } + + char commonName[MAX_CN_LENGTH] = ""; + int cnlen = X509_NAME_get_text_by_NID(subj, NID_commonName, commonName, sizeof(commonName)); + if (cnlen == -1) { + strcpy(commonName, _("Unknown CN")); + } + + /* Retrieve timestamp of certificate */ + ASN1_STRING *expiry_timestamp = X509_get_notAfter(certificate); + + int offset = 0; + struct tm stamp = {}; + /* Generate tm structure to process timestamp */ + if (expiry_timestamp->type == V_ASN1_UTCTIME) { + if (expiry_timestamp->length < 10) { + xasprintf(&sc_cert.output, _("Wrong time format in certificate")); + sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); + return sc_cert; + } + + stamp.tm_year = (expiry_timestamp->data[0] - '0') * 10 + (expiry_timestamp->data[1] - '0'); + if (stamp.tm_year < 50) { + stamp.tm_year += 100; + } + + offset = 0; + } else { + if (expiry_timestamp->length < 12) { + xasprintf(&sc_cert.output, _("Wrong time format in certificate")); + sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); + return sc_cert; + } + stamp.tm_year = (expiry_timestamp->data[0] - '0') * 1000 + + (expiry_timestamp->data[1] - '0') * 100 + + (expiry_timestamp->data[2] - '0') * 10 + (expiry_timestamp->data[3] - '0'); + stamp.tm_year -= 1900; + offset = 2; + } + + stamp.tm_mon = (expiry_timestamp->data[2 + offset] - '0') * 10 + + (expiry_timestamp->data[3 + offset] - '0') - 1; + stamp.tm_mday = (expiry_timestamp->data[4 + offset] - '0') * 10 + + (expiry_timestamp->data[5 + offset] - '0'); + stamp.tm_hour = (expiry_timestamp->data[6 + offset] - '0') * 10 + + (expiry_timestamp->data[7 + offset] - '0'); + stamp.tm_min = (expiry_timestamp->data[8 + offset] - '0') * 10 + + (expiry_timestamp->data[9 + offset] - '0'); + stamp.tm_sec = (expiry_timestamp->data[10 + offset] - '0') * 10 + + (expiry_timestamp->data[11 + offset] - '0'); + stamp.tm_isdst = -1; + + time_t tm_t = timegm(&stamp); + double time_left = difftime(tm_t, time(NULL)); + int days_left = (int)(time_left / 86400); + char *timeZone = getenv("TZ"); + setenv("TZ", "GMT", 1); + tzset(); + + char timestamp[50] = ""; + strftime(timestamp, 50, "%c %z", localtime(&tm_t)); + if (timeZone) { + setenv("TZ", timeZone, 1); + } else { + unsetenv("TZ"); + } + + tzset(); + + int time_remaining; + if (days_left > 0 && days_left <= days_till_exp_warn) { + xasprintf(&sc_cert.output, _("Certificate '%s' expires in %d day(s) (%s)"), commonName, + days_left, timestamp); + if (days_left > days_till_exp_crit) { + sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING); + } else { + sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); + } + } else if (days_left == 0 && time_left > 0) { + if (time_left >= 3600) { + time_remaining = (int)time_left / 3600; + } else { + time_remaining = (int)time_left / 60; + } + + xasprintf(&sc_cert.output, _("Certificate '%s' expires in %u %s (%s)"), commonName, + time_remaining, time_left >= 3600 ? "hours" : "minutes", timestamp); + + if (days_left > days_till_exp_crit) { + sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING); + } else { + sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); + } + } else if (time_left < 0) { + xasprintf(&sc_cert.output, _("Certificate '%s' expired on %s"), commonName, timestamp); + sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); + } else if (days_left == 0) { + xasprintf(&sc_cert.output, _("Certificate '%s' just expired (%s)"), commonName, + timestamp); + if (days_left > days_till_exp_crit) { + sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING); + } else { + sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); + } + } else { + xasprintf(&sc_cert.output, _("Certificate '%s' will expire on %s"), commonName, + timestamp); + sc_cert = mp_set_subcheck_state(sc_cert, STATE_OK); + } + X509_free(certificate); + return sc_cert; +# else /* ifndef USE_OPENSSL */ + xasprintf(&sc_cert.output, _("Plugin does not support checking certificates")); + sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING); + return sc_cert; +# endif /* USE_OPENSSL */ +} #endif /* HAVE_SSL */ -- cgit v1.2.3-74-g34f1