From 4611e41bc50d15275b316c6f21b688997a9c78c4 Mon Sep 17 00:00:00 2001
From: Thomas Guyot-Sionnest <dermoth@aei.ca>
Date: Fri, 4 Feb 2011 00:54:52 -0500
Subject: check_http: check for and print the certificate cn
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch adds a check for the certificate cn (hostname) to normal
certificate checks. It returns CRITICAL if th cn is missing, otherwise it
prints it in the normal output.

Patch by Stéphane Urbanovski

diff --git a/NEWS b/NEWS
index 540e0cf..d7fea27 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ This file documents the major additions and syntax changes between releases.
 	check_nt UPTIME accepts warning/critical thresholds (Ryan Kelly)
 	check_disk_smb now allows spaces in share names (#990948, #1370031, Debian #601699)
 	check_http now uses standard threshold functions (enables floating point and ranges)
+	check_http now checks for and prints the certificate cn (hostname) in SSL certificate checks (Stéphane Urbanovski)
 
 	FIXES
 	Fix check_disk free space calculation if blocksizes differ within a disk group (Bekar - #2973603)
diff --git a/THANKS.in b/THANKS.in
index ac2b1c2..387a379 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -266,3 +266,4 @@ Stephane Chazelas
 Craig Leres
 Brian Landers
 Ryan Kelly
+Stéphane Urbanovski
diff --git a/plugins/sslutils.c b/plugins/sslutils.c
index 64f4d61..0bc61ed 100644
--- a/plugins/sslutils.c
+++ b/plugins/sslutils.c
@@ -3,7 +3,7 @@
 * Nagios plugins SSL utilities
 * 
 * License: GPL
-* Copyright (c) 2005-2007 Nagios Plugins Development Team
+* Copyright (c) 2005-2010 Nagios Plugins Development Team
 * 
 * Description:
 * 
@@ -26,6 +26,7 @@
 * 
 *****************************************************************************/
 
+#define MAX_CN_LENGTH 256
 #define LOCAL_TIMEOUT_ALARM_HANDLER
 #include "common.h"
 #include "netutils.h"
@@ -97,6 +98,11 @@ int np_net_ssl_read(void *buf, int num){
 int np_net_ssl_check_cert(int days_till_exp){
 #  ifdef USE_OPENSSL
 	X509 *certificate=NULL;
+	X509_NAME *subj=NULL;
+	char cn[MAX_CN_LENGTH]= "";
+	int cnlen =-1;
+	int status=STATE_UNKNOWN;
+
 	ASN1_STRING *tm;
 	int offset;
 	struct tm stamp;
@@ -110,6 +116,17 @@ int np_net_ssl_check_cert(int days_till_exp){
 		return STATE_CRITICAL;
 	}
 
+	/* Extract CN from certificate subject */
+	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));
+	if ( cnlen == -1 )
+		strcpy(cn , _("Unknown CN"));
+
 	/* Retrieve timestamp of certificate */
 	tm = X509_get_notAfter (certificate);
 
@@ -155,19 +172,20 @@ int np_net_ssl_check_cert(int days_till_exp){
 		 stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min);
 
 	if (days_left > 0 && days_left <= days_till_exp) {
-		printf (_("WARNING - Certificate expires in %d day(s) (%s).\n"), days_left, timestamp);
-		return STATE_WARNING;
+		printf (_("WARNING - Certificate '%s' expires in %d day(s) (%s).\n"), cn, days_left, timestamp);
+		status=STATE_WARNING;
 	} else if (time_left < 0) {
-		printf (_("CRITICAL - Certificate expired on %s.\n"), timestamp);
-		return STATE_CRITICAL;
+		printf (_("CRITICAL - Certificate '%s' expired on %s.\n"), cn, timestamp);
+		status=STATE_CRITICAL;
 	} else if (days_left == 0) {
-		printf (_("WARNING - Certificate expires today (%s).\n"), timestamp);
-		return STATE_WARNING;
+		printf (_("WARNING - Certificate '%s' expires today (%s).\n"), cn, timestamp);
+		status=STATE_WARNING;
+	} else {
+		printf (_("OK - Certificate '%s' will expire on %s.\n"), cn, timestamp);
+		status=STATE_OK;
 	}
-
-	printf (_("OK - Certificate will expire on %s.\n"), timestamp);
 	X509_free (certificate);
-	return STATE_OK;
+	return status;
 #  else /* ifndef USE_OPENSSL */
 	printf ("%s\n", _("WARNING - Plugin does not support checking certificates."));
 	return STATE_WARNING;
diff --git a/plugins/t/check_http.t b/plugins/t/check_http.t
index c43a64a..55a5a53 100644
--- a/plugins/t/check_http.t
+++ b/plugins/t/check_http.t
@@ -102,7 +102,7 @@ SKIP: {
 
         $res = NPTest->testCmd( "./check_http -C 1 --ssl www.verisign.com" );
         cmp_ok( $res->return_code, '==', 0, "Checking certificate for www.verisign.com");
-        like  ( $res->output, '/Certificate will expire on/', "Output OK" );
+        like  ( $res->output, "/Certificate 'www.verisign.com' will expire on/", "Output OK" );
         my $saved_cert_output = $res->output;
 
         $res = NPTest->testCmd( "./check_http www.verisign.com -C 1" );
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t
index 74eff17..9ae6bbd 100755
--- a/plugins/tests/check_http.t
+++ b/plugins/tests/check_http.t
@@ -182,17 +182,17 @@ SKIP: {
 	
 	$result = NPTest->testCmd( "$command -p $port_https -S -C 14" );
 	is( $result->return_code, 0, "$command -p $port_https -S -C 14" );
-	is( $result->output, 'OK - Certificate will expire on 03/03/2019 21:41.', "output ok" );
+	is( $result->output, 'OK - Certificate \'Ton Voon\' will expire on 03/03/2019 21:41.', "output ok" );
 
 	$result = NPTest->testCmd( "$command -p $port_https -S -C 14000" );
 	is( $result->return_code, 1, "$command -p $port_https -S -C 14000" );
-	like( $result->output, '/WARNING - Certificate expires in \d+ day\(s\) \(03/03/2019 21:41\)./', "output ok" );
+	like( $result->output, '/WARNING - Certificate \'Ton Voon\' expires in \d+ day\(s\) \(03/03/2019 21:41\)./', "output ok" );
 
 	# Expired cert tests
 	$result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" );
 	is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" );
 	is( $result->output, 
-		'CRITICAL - Certificate expired on 03/05/2009 00:13.',
+		'CRITICAL - Certificate \'Ton Voon\' expired on 03/05/2009 00:13.',
 		"output ok" );
 
 }
-- 
cgit v0.10-9-g596f

