]> git.michaelhowe.org Git - packages/n/nagios-plugins-local.git/commitdiff
nagios-plugins-local check_cert plugin now handles SMTP TLS, which gnutls-cli needed...
authorMichael Howe <michael@michaelhowe.org>
Sun, 19 Jun 2011 18:53:03 +0000 (18:53 +0000)
committerMichael Howe <michael@michaelhowe.org>
Sun, 19 Jun 2011 18:53:03 +0000 (18:53 +0000)
debian/changelog
plugins/check_cert

index b279b73db0af4087fe342ea3236fd4756f233d25..1dc1d0a6ba4455688c448c887bbd565f0bac83e8 100644 (file)
@@ -1,3 +1,9 @@
+nagios-plugins-local (0.4) unstable; urgency=low
+
+  * check_cert plugin now handles SMTP TLS. 
+
+ -- Michael Howe <michael@michaelhowe.org>  Sun, 19 Jun 2011 19:51:30 +0100
+
 nagios-plugins-local (0.3) unstable; urgency=low
 
   * check_cert plugin now handles IPv6 
index 204cd0398ffa77fa2cc8cadd99018af5b3d8942b..ba48c541261e0218b08127611ae6ebbe69f0e0d3 100755 (executable)
@@ -9,13 +9,16 @@
 #use 5.6.1;
 use strict;
 use warnings;
-no warnings qw(redefine);
+no warnings qw(redefine once);
 
 use Date::Parse qw(str2time);
 use English;
 use Getopt::Long;
 use URI;
 
+use IPC::Open3;
+use Sys::Hostname;
+
 #use lib '/usr/local/nagios/libexec';
 use lib '/usr/lib/nagios/plugins';
 use utils qw(%ERRORS);
@@ -64,6 +67,7 @@ GetOptions(\%opt,
     'name=s',
     'url=s',
     'warning=i',
+    'debug',
 ) || usage();
 
 if (defined($opt{'help'})) {
@@ -128,7 +132,7 @@ if ($scheme eq 'file') {
 } elsif ($scheme eq 'smtp') {
     $port ||= 25;
 
-    $certdata = s_client("quit", "--starttls --port $port $host");
+    $certdata = get_smtp_starttls_cert( $port, $host );
 
 } elsif ($scheme eq 'smtps') {
     $port ||= 465;
@@ -201,6 +205,7 @@ exit($ERRORS{'OK'});
 sub s_client {
     my ($command, $arguments) = @_;
 
+    print scalar(`/bin/echo $command | /usr/bin/gnutls-cli --insecure --print-cert $arguments 2>/dev/null | /usr/bin/openssl x509 -text 2>/dev/null`);
     return(parse_certificate(scalar(`/bin/echo $command | /usr/bin/gnutls-cli --insecure --print-cert $arguments 2>/dev/null | /usr/bin/openssl x509 -text 2>/dev/null`)));
 }
 
@@ -233,3 +238,102 @@ sub parse_certificate {
     return(\%result);
 }
 
+# Much of this inspired by http://www.moeding.net/archives/15-Testing-SMTP-AUTH-after-STARTTLS.html
+sub get_smtp_starttls_cert {
+    my ( $port, $host ) = @_;
+
+    my $hostname = hostname();
+
+    my $has_starttls;
+    my $pid;
+
+    my $return;
+    my $certreturn;
+
+    eval {
+        $pid = open3(\*TLSOUT, \*TLSIN, \*TLSERR, "gnutls-cli", "--crlf", "--starttls", "--insecure", "--print-cert", "--port", $port, $host );
+    };
+    if( $@ ){
+        die "open3: $!\n$@\n";
+    }
+
+    # Wait until we receive a welcome message from SMTP server:
+    while( <TLSIN> ){
+        debug( "< ", $_ );
+        last if( /^220/ );
+    }
+
+    # Introduce ourselves:
+    debug( ">\n> EHLO $hostname\n>\n" );
+    print TLSOUT "EHLO $hostname\n";
+
+    # Wait until we have capabalities returned:
+    while( <TLSIN> ){
+        debug( "< ", $_ );
+
+        $has_starttls = 1 if( /^250-STARTTLS/ );
+        last if( /^250 / );
+    }
+    if( ! $has_starttls ){
+        print "CRITICAL: SMTP server does not offer STARTTLS\n";
+        exit( $ERRORS{'CRITICAL'} );
+    }
+
+    # Initialize STARTTLS
+    debug( ">\n> STARTTLS\n>\n" );
+    print TLSOUT "STARTTLS\n";
+
+    # Wait until server is ready:
+    while( <TLSIN> ){
+        debug( "< ", $_ );
+
+        last if( /^220 / );
+    }
+
+    # Signal gnutls-cli to perform TLS negotiation
+    kill( "ALRM", $pid );
+
+    # Print output from process; recover from blocking read after 5s
+    $SIG{ALRM} = sub { die "timeout" };
+
+    eval {
+        alarm( 5 );
+
+        while( <TLSIN> ){
+            debug( "> ", $_ );
+            $return .= $_;
+        }
+    };
+
+    debug( ">\n> QUIT\n>\n" );
+    print TLSOUT "QUIT\n";
+    while( <TLSIN> ){
+        debug( "< ", $_ );
+    }
+    waitpid $pid, 0;
+
+    my $sslpid;
+    eval{
+        $sslpid = open3( \*SSLOUT, \*SSLIN, \*SSLERR, "openssl", "x509", "-text" );
+    };
+    if( $@ ){
+        die "open3: $!\n$@\n";
+    }
+    print SSLOUT $return;
+
+    while( <SSLIN> ){
+        debug( "> ", $_ );
+        $certreturn .= $_;
+    }
+
+    waitpid $sslpid, 0;
+
+    return( parse_certificate( $certreturn ) );
+
+}
+
+sub debug {
+    if( $opt{'debug'} ){
+        print @_;
+    }
+}