check_curl: implement certificate checks

Signed-off-by: Sven Nierlein <sven@nierlein.de>
This commit is contained in:
Sven Nierlein 2017-03-14 22:52:04 +01:00
parent c6c4890702
commit 16121a9b55
3 changed files with 79 additions and 24 deletions

View file

@ -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)

View file

@ -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

View file

@ -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;