diff -r 9501cc7d9177 -r af056e82c644 check_cert.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/check_cert.pl Mon Jan 07 12:43:56 2019 +0100 @@ -0,0 +1,243 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; +use File::Basename; +use Getopt::Long; +use Date::Manip; +use IPC::Open2; +use lib "/usr/lib/nagios/plugins"; +use utils qw (%ERRORS &print_revision &support); + +sub print_help(); +sub print_usage(); + +my $ME = basename $0; +my ( $opt_w, $opt_c, $opt_V, $opt_h, $opt_b, $opt_s, @opt_certfiles ); +my ( $w_time, $c_time, $result, $message, %certs ); +my ( @critical, @warning, @ok ); + +$opt_w = "1month"; +$opt_c = "1week"; +$opt_b = "/usr/bin/openssl"; +$opt_s = "md5WithRSAEncryption"; + +Getopt::Long::Configure('bundling'); +GetOptions( + "V" => \$opt_V, + "version" => \$opt_V, + "h" => \$opt_h, + "help" => \$opt_h, + "b=s" => \$opt_b, + "binary" => \$opt_b, + "w=s" => \$opt_w, + "warning=s" => \$opt_w, + "c=s" => \$opt_c, + "critical=s" => \$opt_c, + "s=s" => \$opt_s, + "signature=s" => \$opt_s, + "f=s" => \@opt_certfiles, + "certfile=s" => \@opt_certfiles +); + +if ($opt_V) { + print_revision( $ME, "1.2" ); + exit $ERRORS{"OK"}; +} + +if ($opt_h) { + print_help(); + exit $ERRORS{"OK"}; +} + +# check openssl binary +unless ( -x $opt_b ) { + print "CERT CRITICAL: OpenSSL not found or not executable - $opt_b\n"; + exit $ERRORS{"CRITICAL"}; +} + +unless (@opt_certfiles) { + print "CERT WARNING: Not defined any certificate files\n"; + exit $ERRORS{"WARNING"}; +} + +@opt_certfiles = split( /,/, join( ',', @opt_certfiles ) ); + +# extract certificate data +foreach my $file (@opt_certfiles) { + unless ( -r $file ) { + print +"CERT CRITICAL: $file - not exists or not read permission is granted\n"; + exit $ERRORS{"CRITICAL"}; + } + my $no_print = +"no_header,no_version,no_serial,no_validity,no_subject,no_issuer,no_pubkey,no_sigdump,no_extensions"; + my @cmd_x509 = ( + $opt_b, "x509", "-in", $file, + "-noout", "-text", "-certopt", $no_print, + "-subject", "-enddate", "-purpose" + ); + my @cmd_pkcs12 = ( + $opt_b, "pkcs12", "-in", $file, + "-clcerts", "-nokeys", "-nomacver", "-passin", + "pass:" + ); + my @cmd_pipe = ( + $opt_b, "x509", "-noout", "-text", + "-certopt", $no_print, "-subject", "-enddate", + "-purpose" + ); + my ( $temp, $sig, $cn, $enddate, $rc, $cert_type ); + open( CERT, "-|" ) or do { + open( STDERR, ">&STDOUT" ); + exec(@cmd_x509); + }; + + # check x509 certificates + while () { + /unable to load certificate/ and $rc = 1 and last; + /Signature\sAlgorithm:\s($opt_s)\s+$/ and $sig = $1; + /^subject=\s.*CN=(.*)\s+$/ and $cn = $1; + /^notAfter=(.*)\s+$/ and $enddate = $1; + /^(SSL\sclient)\s:\sYes$/ and $cert_type = $1; + /^(SSL\sserver)\s:\sYes$/ and $cert_type = $1; + } + close(CERT); + + # check pkcs12 certificates + if ($rc) { + open( PKCS12, "@cmd_pkcs12 |" ); + + while () { + $temp .= $_; + } + close(PKCS12); + + local ( *READ, *WRITE ); + open2( \*READ, \*WRITE, @cmd_pipe ) or die "Can't fork: $!\n"; + print WRITE $temp; + close(WRITE); + + while () { + /unable to load certificate/ + and print "CERT CRITICAL: unable to load certificate\n" + and exit $ERRORS{"CRITICAL"}; + /Signature\sAlgorithm:\s($opt_s)\s+$/ and $sig = $1; + /^subject=\s.*CN=(.*)\s+$/ and $cn = $1; + /^notAfter=(.*)\s+$/ and $enddate = $1; + /^(SSL\sclient)\s:\sYes$/ and $cert_type = $1; + /^(SSL\sserver)\s:\sYes$/ and $cert_type = $1; + } + close(READ); + } + + # fill the hash + push( @{ $certs{$file} }, ( $cn, $enddate, $sig, $cert_type ) ); +} + +# calculate the time +$w_time = DateCalc( "today", "+ $opt_w" ); +$c_time = DateCalc( "today", "+ $opt_c" ); + +# check expire date +foreach ( sort keys %certs ) { + my $enddate; + if ( @{ $certs{$_} }[1] =~ /(\w+\s+\d+\s+\d+:\d+:\d+\s+\d+)/ ) { + $enddate = $1; + } + $enddate = ParseDate($enddate); + unless ($enddate) { + print "CERT CRITICAL: Can't parse enddate\n"; + exit $ERRORS{"CRITICAL"}; + } + + &Date_Cmp( $enddate, $w_time ) > 0 and push( @{ $certs{$_} }, "OK" ), next; + &Date_Cmp( $enddate, $c_time ) > 0 + and push( @{ $certs{$_} }, "WARNING" ), next; + push( @{ $certs{$_} }, "CRITICAL" ); +} + +# looking for stats +foreach ( sort keys %certs ) { + if ( @{ $certs{$_} }[2] ) { + if ( @{ $certs{$_} }[2] eq "$opt_s" ) { + push( @warning, +"file: $_, CN=@{$certs{$_}}[0] Signature Algorithm: @{$certs{$_}}[2]" + ); + } + } + + if ( @{ $certs{$_} }[4] eq "WARNING" ) { + push( @warning, +"file: $_, CN=@{$certs{$_}}[0] expires @{$certs{$_}}[1] type: @{$certs{$_}}[3]" + ); + } + elsif ( @{ $certs{$_} }[4] eq "CRITICAL" ) { + push( @critical, +"file: $_, CN=@{$certs{$_}}[0] expires @{$certs{$_}}[1] type: @{$certs{$_}}[3]" + ); + } + else { + push( @ok, +"file: $_, CN=@{$certs{$_}}[0] expires @{$certs{$_}}[1] type: @{$certs{$_}}[3]" + ); + } +} + +# return the state +if (@critical) { + print "CERT CRITICAL: @critical\n"; + exit $ERRORS{"CRITICAL"}; +} +elsif (@warning) { + print "CERT WARNING: @warning\n"; + exit $ERRORS{"WARNING"}; +} +else { + print "CERT OK: @ok\n"; + exit $ERRORS{"OK"}; +} + +sub print_usage() { + print "Usage:\n"; + print +" $ME [-b ] [-w