[monitoring-plugins] check_curl: implement certificate checks
Sven Nierlein
git at monitoring-plugins.org
Wed Mar 15 09:20:14 CET 2017
Module: monitoring-plugins
Branch: feature_check_curl
Commit: 1684deb8f7cc64270edcdff7c9bf40981bff20e3
Author: Sven Nierlein <sven at nierlein.de>
Date: Tue Mar 14 22:52:04 2017 +0100
URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=1684deb
check_curl: implement certificate checks
Signed-off-by: Sven Nierlein <sven at nierlein.de>
---
plugins/Makefile.am | 4 ++--
plugins/check_curl.c | 66 ++++++++++++++++++++++++++++++++++++++++++++--------
plugins/sslutils.c | 33 ++++++++++++++++----------
3 files changed, 79 insertions(+), 24 deletions(-)
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 2c87b4e..ffd8baf 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -71,7 +71,7 @@ check_apt_LDADD = $(BASEOBJS)
check_cluster_LDADD = $(BASEOBJS)
check_curl_CFLAGS = $(AM_CFLAGS) $(LIBCURLCFLAGS)
check_curl_CPPFLAGS = $(AM_CPPFLAGS) $(LIBCURLINCLUDE)
-check_curl_LDADD = $(NETLIBS) $(LIBCURLLIBS)
+check_curl_LDADD = $(NETLIBS) $(LIBCURLLIBS) $(SSLOBJS)
check_dbi_LDADD = $(NETLIBS) $(DBILIBS)
check_dig_LDADD = $(NETLIBS)
check_disk_LDADD = $(BASEOBJS)
@@ -92,7 +92,7 @@ check_mysql_query_CFLAGS = $(AM_CFLAGS) $(MYSQLCFLAGS)
check_mysql_query_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE)
check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS)
check_nagios_LDADD = $(BASEOBJS)
-check_nt_LDADD = $(NETLIBS)
+check_nt_LDADD = $(NETLIBS)
check_ntp_LDADD = $(NETLIBS) $(MATHLIBS)
check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS)
check_nwstat_LDADD = $(NETLIBS)
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index c6a7ab8..e14fb19 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -93,6 +93,7 @@ unsigned short server_port = HTTP_PORT;
char output_string_search[30] = "";
char *warning_thresholds = NULL;
char *critical_thresholds = NULL;
+int days_till_exp_warn, days_till_exp_crit;
thresholds *thlds;
char user_agent[DEFAULT_BUFFER_SIZE];
int verbose = 0;
@@ -122,6 +123,7 @@ int ssl_version = CURL_SSLVERSION_DEFAULT;
char *client_cert = NULL;
char *client_privkey = NULL;
char *ca_cert = NULL;
+X509 *cert = NULL;
int process_arguments (int, char**);
int check_http (void);
@@ -162,6 +164,19 @@ main (int argc, char **argv)
return result;
}
+int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
+{
+ cert = X509_STORE_CTX_get_current_cert(x509_ctx);
+ return 1;
+}
+
+CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm)
+{
+ SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, verify_callback);
+
+ return CURLE_OK;
+}
+
int
check_http (void)
{
@@ -177,6 +192,9 @@ check_http (void)
if (verbose >= 3)
curl_easy_setopt (curl, CURLOPT_VERBOSE, TRUE);
+ /* print everything on stdout like check_http would do */
+ curl_easy_setopt(curl, CURLOPT_STDERR, stdout);
+
/* initialize buffer for body of the answer */
if (curlhelp_initbuffer(&body_buf) < 0)
die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n");
@@ -242,14 +260,16 @@ check_http (void)
curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 2);
curl_easy_setopt( curl, CURLOPT_SSL_VERIFYHOST, 2);
- /* backward-compatible behaviour, be tolerant in checks */
- if (!check_cert) {
- /* TODO: depending on more options have aspects we want
- * to be tolerant about
- * curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 1 );
- */
- curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0);
+ /* backward-compatible behaviour, be tolerant in checks
+ * TODO: depending on more options have aspects we want
+ * to be less tolerant about ssl verfications
+ */
+ curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0);
+
+ /* set callback to extract certificate */
+ if(check_cert) {
+ curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun);
}
/* set default or user-given user agent identification */
@@ -308,6 +328,16 @@ check_http (void)
die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
}
+ /* certificate checks */
+#ifdef HAVE_SSL
+ if (use_ssl == TRUE) {
+ if (check_cert == TRUE) {
+ result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
+ return(result);
+ }
+ }
+#endif /* HAVE_SSL */
+
/* we got the data and we executed the request in a given time, so we can append
* performance data to the answer always
*/
@@ -439,6 +469,7 @@ int
process_arguments (int argc, char **argv)
{
int c = 1;
+ char *temp;
enum {
INVERT_REGEX = CHAR_MAX + 1,
@@ -537,8 +568,23 @@ process_arguments (int argc, char **argv)
break;
case 'C': /* Check SSL cert validity */
#ifdef LIBCURL_FEATURE_SSL
- /* TODO: C:, check age of certificate for backward compatible
- * behaviour, but we would later add more check conditions */
+ if ((temp=strchr(optarg,','))!=NULL) {
+ *temp='\0';
+ if (!is_intnonneg (optarg))
+ 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;
goto enable_ssl;
#endif
diff --git a/plugins/sslutils.c b/plugins/sslutils.c
index e38947e..14f6579 100644
--- a/plugins/sslutils.c
+++ b/plugins/sslutils.c
@@ -1,29 +1,29 @@
/*****************************************************************************
-*
+*
* Monitoring Plugins SSL utilities
-*
+*
* License: GPL
* Copyright (c) 2005-2010 Monitoring Plugins Development Team
-*
+*
* Description:
-*
+*
* This file contains common functions for plugins that require SSL.
-*
+*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-*
+*
+*
*****************************************************************************/
#define MAX_CN_LENGTH 256
@@ -193,12 +193,22 @@ 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
- X509 *certificate=NULL;
+ X509 *certificate = NULL;
+ certificate=SSL_get_peer_certificate(s);
+ return(np_net_ssl_check_certificate(certificate, 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_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;
@@ -210,7 +220,6 @@ int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
int time_remaining;
time_t tm_t;
- certificate=SSL_get_peer_certificate(s);
if (!certificate) {
printf("%s\n",_("CRITICAL - Cannot retrieve server certificate."));
return STATE_CRITICAL;
More information about the Commits
mailing list