From 2bffda3c4bfac24e610059df112874fec319be9e Mon Sep 17 00:00:00 2001 From: Guillaume Rousse <guillomovitch@gmail.com> Date: Sun, 11 Dec 2016 15:59:34 +0100 Subject: [PATCH 2/2] add support for checking certificate age --- plugins/Makefile.am | 2 +- plugins/check_ldap.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++-- plugins/netutils.h | 1 + plugins/sslutils.c | 11 +++++++++- 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/plugins/Makefile.am b/plugins/Makefile.am index d0e08812..649148b2 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -78,7 +78,7 @@ check_fping_LDADD = $(NETLIBS) check_game_LDADD = $(BASEOBJS) check_http_LDADD = $(SSLOBJS) check_hpjd_LDADD = $(NETLIBS) -check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS) +check_ldap_LDADD = $(SSLOBJS) $(NETLIBS) $(LDAPLIBS) $(SSLLIBS) check_load_LDADD = $(BASEOBJS) check_mrtg_LDADD = $(BASEOBJS) check_mrtgtraf_LDADD = $(BASEOBJS) diff --git a/plugins/check_ldap.c b/plugins/check_ldap.c index 4a03a71d..0d4b5f9e 100644 --- a/plugins/check_ldap.c +++ b/plugins/check_ldap.c @@ -76,6 +76,9 @@ int starttls = FALSE; int ssl_on_connect = FALSE; int verbose = 0; +int check_cert = FALSE; +int days_till_exp_warn, days_till_exp_crit; + /* for ldap tls */ char *SERVICE = "LDAP"; @@ -183,6 +186,9 @@ main (int argc, char *argv[]) printf (_("Could not init TLS at port %i!\n"), ld_port); return STATE_CRITICAL; } + + if (check_cert == TRUE) + return ldap_check_cert(ld); #else printf (_("TLS not supported by the libraries!\n")); return STATE_CRITICAL; @@ -207,6 +213,9 @@ main (int argc, char *argv[]) printf (_("Could not init startTLS at port %i!\n"), ld_port); return STATE_CRITICAL; } + + if (check_cert == TRUE) + return ldap_check_cert(ld); #else printf (_("startTLS not supported by the library, needs LDAPv3!\n")); return STATE_CRITICAL; @@ -296,6 +305,7 @@ int process_arguments (int argc, char **argv) { int c; + char *temp; int option = 0; /* initialize the long option struct */ @@ -315,6 +325,7 @@ process_arguments (int argc, char **argv) #endif {"starttls", no_argument, 0, 'T'}, {"ssl", no_argument, 0, 'S'}, + {"age", required_argument, 0, 'A'}, {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, {"port", required_argument, 0, 'p'}, @@ -335,7 +346,7 @@ process_arguments (int argc, char **argv) } while (1) { - c = getopt_long (argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:U:C:W:", longopts, &option); + c = getopt_long (argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:U:C:W:A:", longopts, &option); if (c == -1 || c == EOF) break; @@ -403,6 +414,33 @@ process_arguments (int argc, char **argv) else usage_va(_("%s cannot be combined with %s"), "-T/--starttls", "-S/--ssl"); break; + case 'A': /* Check SSL cert validity */ +#ifndef HAVE_SSL + usage4 (_("Invalid option - SSL is not available")); +#else + if (starttls || ssl_on_connect || strstr(argv[0],"check_ldaps")) { + if ((temp=strchr(optarg,','))!=NULL) { + *temp = '\0'; + if (!is_intnonneg (temp)) + usage2 (_("Invalid certificate expiration period"), optarg); + days_till_exp_warn = atoi(optarg); + *temp = ','; + temp++; + if (!is_intnonneg (temp)) + usage2 (_("Invalid certificate expiration period"), temp); + days_till_exp_crit = atoi (temp); + } else { + days_till_exp_crit = 0; + if (!is_intnonneg (optarg)) + usage2 (_("Invalid certificate expiration period"), optarg); + days_till_exp_warn = atoi (optarg); + } + check_cert = TRUE; + } else { + usage_va(_("%s requires either %s or %s"), "-A/--age", "-S/--ssl", "-T/--starttls"); + } + break; +#endif case 'S': if (! starttls) { ssl_on_connect = TRUE; @@ -489,6 +527,8 @@ print_help (void) printf (" %s\n", _("use starttls mechanism introduced in protocol version 3")); printf (" %s\n", "-S, --ssl"); printf (" %s %i\n", _("use ldaps (ldap v2 ssl method). this also sets the default port to"), LDAPS_PORT); + printf (" %s\n", "-A, --age=INTEGER[,INTEGER]"); + printf (" %s\n", _("Minimum number of days a certificate has to be valid")); #ifdef HAVE_LDAP_SET_OPTION printf (" %s\n", "-2, --ver2"); @@ -526,7 +566,7 @@ print_usage (void) { printf ("%s\n", _("Usage:")); printf (" %s (-H <host>|-U <uri>) -b <base_dn> [-p <port>] [-a <attr>] [-D <binddn>]\n", progname); - printf (" [-P <password>] [-w <warn_time>] [-c <crit_time>] [-t timeout]%s\n", + printf (" [-P <password>] [-w <warn_time>] [-c <crit_time>] [-t timeout] [-A <age>]%s\n", #ifdef HAVE_LDAP_SET_OPTION "\n [-2|-3] [-4|-6]" #else @@ -534,3 +574,16 @@ print_usage (void) #endif ); } + +int ldap_check_cert (LDAP *ld) +{ + SSL *ssl; + int rc; + + rc = ldap_get_option(ld, LDAP_OPT_X_TLS_SSL_CTX, &ssl); + if (rc == LDAP_OPT_ERROR || ssl == NULL) { + printf ("%s\n",_("CRITICAL - Cannot retrieve ssl session from connection.")); + return STATE_CRITICAL; + } + return np_net_ssl_check_cert_real(ssl, days_till_exp_warn, days_till_exp_crit); +} diff --git a/plugins/netutils.h b/plugins/netutils.h index f8da6dff..927ceb5a 100644 --- a/plugins/netutils.h +++ b/plugins/netutils.h @@ -108,6 +108,7 @@ 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); +int np_net_ssl_check_cert_real(SSL *ssl, int days_till_exp_warn, int days_till_exp_crit); #endif /* HAVE_SSL */ #endif /* NAGIOS_NETUGILS_H_INCLUDED_ */ diff --git a/plugins/sslutils.c b/plugins/sslutils.c index e69207d4..1fc0779b 100644 --- a/plugins/sslutils.c +++ b/plugins/sslutils.c @@ -194,6 +194,15 @@ 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){ +# ifdef USE_OPENSSL + return np_net_ssl_check_cert_real(s, days_till_exp_warn, days_till_exp_crit); +# else /* ifndef USE_OPENSSL */ + printf ("%s\n", _("WARNING - Plugin does not support checking certificates.")); + return STATE_WARNING; +# endif /* USE_OPENSSL */ +} + +int np_net_ssl_check_cert_real(SSL *ssl, int days_till_exp_warn, int days_till_exp_crit){ # ifdef USE_OPENSSL X509 *certificate=NULL; X509_NAME *subj=NULL; @@ -214,7 +223,7 @@ int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){ // Prefix whatever we're about to print with SSL printf("SSL "); - certificate=SSL_get_peer_certificate(s); + certificate=SSL_get_peer_certificate(ssl); if (!certificate) { printf("%s\n",_("CRITICAL - Cannot retrieve server certificate.")); return STATE_CRITICAL; -- 2.14.1