Module: monitoring-plugins
 Branch: master
 Commit: bc2720abddf8e379c4e1f23ed25f7702ef29ad08
 Author: Lorenz Kästle <[email protected]>
   Date: Sun Nov  9 11:46:36 2025 +0100
    URL: 
https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=bc2720ab

check_smtp: certificate check is no longer opt-in

This is a breaking change.
Testing whether a TLS certificate is still valid (expiration wise)
is now the default in check_smtp.
The reasoning is, that in most scenarios an expired certificate
will effectively mean that the service is not working anymore due to
the refusal of other software to talk to it.

There is a new cli parameter though to explicitly ignore that.

---

 plugins/check_smtp.c          | 88 ++++++++++++++++++++++++-------------------
 plugins/check_smtp.d/config.h |  6 ++-
 2 files changed, 54 insertions(+), 40 deletions(-)

diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c
index cb92421c..e806ad29 100644
--- a/plugins/check_smtp.c
+++ b/plugins/check_smtp.c
@@ -37,6 +37,7 @@
 #include "base64.h"
 #include "regex.h"
 
+#include <bits/getopt_ext.h>
 #include <ctype.h>
 #include <string.h>
 #include "check_smtp.d/config.h"
@@ -347,9 +348,19 @@ int main(int argc, char **argv) {
 
                switch (cert_check_result.errors) {
                case ALL_OK: {
-                       xasprintf(&sc_cert_check.output, "Certificate 
expiration. Remaining time %g days",
-                                         cert_check_result.remaining_seconds / 
86400);
-                       sc_cert_check = mp_set_subcheck_state(sc_cert_check, 
cert_check_result.result_state);
+
+                       if (cert_check_result.result_state != STATE_OK &&
+                               config.ignore_certificate_expiration) {
+                               xasprintf(&sc_cert_check.output,
+                                                 "Remaining certificate 
lifetime: %d days. Expiration will be ignored",
+                                                 
(int)(cert_check_result.remaining_seconds / 86400));
+                               sc_cert_check = 
mp_set_subcheck_state(sc_cert_check, STATE_OK);
+                       } else {
+                               xasprintf(&sc_cert_check.output, "Remaining 
certificate lifetime: %d days",
+                                                 
(int)(cert_check_result.remaining_seconds / 86400));
+                               sc_cert_check =
+                                       mp_set_subcheck_state(sc_cert_check, 
cert_check_result.result_state);
+                       }
                } break;
                case NO_SERVER_CERTIFICATE_PRESENT: {
                        xasprintf(&sc_cert_check.output, "no server certificate 
present");
@@ -366,12 +377,6 @@ int main(int argc, char **argv) {
                };
 
                mp_add_subcheck_to_check(&overall, sc_cert_check);
-
-               if (config.check_cert) {
-                       smtp_quit(config, buffer, socket_descriptor, 
ssl_established);
-                       my_close(socket_descriptor);
-                       mp_exit(overall);
-               }
        }
 #      endif /* USE_OPENSSL */
 
@@ -584,37 +589,40 @@ check_smtp_config_wrapper process_arguments(int argc, 
char **argv) {
        enum {
                SNI_OPTION = CHAR_MAX + 1,
                output_format_index,
+               ignore_certificate_expiration_index,
        };
 
        int option = 0;
-       static struct option longopts[] = {{"hostname", required_argument, 0, 
'H'},
-                                                                          
{"expect", required_argument, 0, 'e'},
-                                                                          
{"critical", required_argument, 0, 'c'},
-                                                                          
{"warning", required_argument, 0, 'w'},
-                                                                          
{"timeout", required_argument, 0, 't'},
-                                                                          
{"port", required_argument, 0, 'p'},
-                                                                          
{"from", required_argument, 0, 'f'},
-                                                                          
{"fqdn", required_argument, 0, 'F'},
-                                                                          
{"authtype", required_argument, 0, 'A'},
-                                                                          
{"authuser", required_argument, 0, 'U'},
-                                                                          
{"authpass", required_argument, 0, 'P'},
-                                                                          
{"command", required_argument, 0, 'C'},
-                                                                          
{"response", required_argument, 0, 'R'},
-                                                                          
{"verbose", no_argument, 0, 'v'},
-                                                                          
{"version", no_argument, 0, 'V'},
-                                                                          
{"use-ipv4", no_argument, 0, '4'},
-                                                                          
{"use-ipv6", no_argument, 0, '6'},
-                                                                          
{"help", no_argument, 0, 'h'},
-                                                                          
{"lmtp", no_argument, 0, 'L'},
-                                                                          
{"ssl", no_argument, 0, 's'},
-                                                                          
{"tls", no_argument, 0, 's'},
-                                                                          
{"starttls", no_argument, 0, 'S'},
-                                                                          
{"sni", no_argument, 0, SNI_OPTION},
-                                                                          
{"certificate", required_argument, 0, 'D'},
-                                                                          
{"ignore-quit-failure", no_argument, 0, 'q'},
-                                                                          
{"proxy", no_argument, 0, 'r'},
-                                                                          
{"output-format", required_argument, 0, output_format_index},
-                                                                          {0, 
0, 0, 0}};
+       static struct option longopts[] = {
+               {"hostname", required_argument, 0, 'H'},
+               {"expect", required_argument, 0, 'e'},
+               {"critical", required_argument, 0, 'c'},
+               {"warning", required_argument, 0, 'w'},
+               {"timeout", required_argument, 0, 't'},
+               {"port", required_argument, 0, 'p'},
+               {"from", required_argument, 0, 'f'},
+               {"fqdn", required_argument, 0, 'F'},
+               {"authtype", required_argument, 0, 'A'},
+               {"authuser", required_argument, 0, 'U'},
+               {"authpass", required_argument, 0, 'P'},
+               {"command", required_argument, 0, 'C'},
+               {"response", required_argument, 0, 'R'},
+               {"verbose", no_argument, 0, 'v'},
+               {"version", no_argument, 0, 'V'},
+               {"use-ipv4", no_argument, 0, '4'},
+               {"use-ipv6", no_argument, 0, '6'},
+               {"help", no_argument, 0, 'h'},
+               {"lmtp", no_argument, 0, 'L'},
+               {"ssl", no_argument, 0, 's'},
+               {"tls", no_argument, 0, 's'},
+               {"starttls", no_argument, 0, 'S'},
+               {"sni", no_argument, 0, SNI_OPTION},
+               {"certificate", required_argument, 0, 'D'},
+               {"ignore-quit-failure", no_argument, 0, 'q'},
+               {"proxy", no_argument, 0, 'r'},
+               {"ignore-certificate-expiration", no_argument, 0, 
ignore_certificate_expiration_index},
+               {"output-format", required_argument, 0, output_format_index},
+               {0, 0, 0, 0}};
 
        check_smtp_config_wrapper result = {
                .config = check_smtp_config_init(),
@@ -766,7 +774,6 @@ check_smtp_config_wrapper process_arguments(int argc, char 
**argv) {
                                }
                                result.config.days_till_exp_warn = atoi(optarg);
                        }
-                       result.config.check_cert = true;
                        result.config.ignore_send_quit_failure = true;
 #else
                        usage(_("SSL support not available - install OpenSSL 
and recompile"));
@@ -827,6 +834,9 @@ check_smtp_config_wrapper process_arguments(int argc, char 
**argv) {
                        result.config.output_format = parser.output_format;
                        break;
                }
+               case ignore_certificate_expiration_index: {
+                       result.config.ignore_certificate_expiration = true;
+               }
                }
        }
 
@@ -1028,6 +1038,8 @@ void print_help(void) {
        printf("    %s\n", _("Send LHLO instead of HELO/EHLO"));
        printf(" %s\n", "-q, --ignore-quit-failure");
        printf("    %s\n", _("Ignore failure when sending QUIT command to 
server"));
+       printf(" %s\n", "--ignore-certificate-expiration");
+       printf("    %s\n", _("Ignore certificate expiration"));
 
        printf(UT_WARN_CRIT);
 
diff --git a/plugins/check_smtp.d/config.h b/plugins/check_smtp.d/config.h
index 11d7fe56..b0d42ed1 100644
--- a/plugins/check_smtp.d/config.h
+++ b/plugins/check_smtp.d/config.h
@@ -40,12 +40,13 @@ typedef struct {
 
        bool use_proxy_prefix;
 #ifdef HAVE_SSL
-       bool check_cert;
        int days_till_exp_warn;
        int days_till_exp_crit;
        bool use_ssl;
        bool use_starttls;
        bool use_sni;
+
+       bool ignore_certificate_expiration;
 #endif
 
        bool output_format_is_set;
@@ -80,12 +81,13 @@ check_smtp_config check_smtp_config_init() {
 
                .use_proxy_prefix = false,
 #ifdef HAVE_SSL
-               .check_cert = false,
                .days_till_exp_warn = 0,
                .days_till_exp_crit = 0,
                .use_ssl = false,
                .use_starttls = false,
                .use_sni = false,
+
+               .ignore_certificate_expiration = false,
 #endif
 
                .output_format_is_set = false,

Reply via email to