check_exec.pl
changeset 1 9b0a5c2b7ebc
parent 0 9732a762d17c
child 2 ded3b78c61b1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/check_exec.pl	Tue Dec 21 15:19:21 2010 +0100
@@ -0,0 +1,212 @@
+#!/usr/bin/perl -w
+
+use strict;
+use File::Basename;
+use Getopt::Long;
+use LWP::Simple;
+use HTTP::Status;
+use File::Path;
+
+use lib "/usr/lib/nagios/plugins";
+use utils qw (%ERRORS &print_revision &support);
+
+$ENV{LANG} = "POSIX";
+
+my $ME      = basename $0;
+my $VERSION = "0.2";
+my $USAGE   = <<EOF;
+Usage: $ME -u | --url
+       $ME [ -b | --binary ]
+       $ME [ -p | --path ]
+       $ME [ -h | --help ]
+       $ME [ -V | --version ]
+EOF
+
+sub print_help();
+sub print_usage();
+
+sub download($$);
+sub verify($);
+sub cleanup($);
+sub execute($);
+
+my $opt_url;
+my $opt_path   = "/var/tmp/nagios";
+my $opt_binary = "/usr/bin/gpg";
+
+MAIN: {
+    Getopt::Long::Configure('bundling');
+    GetOptions(
+        "u|url=s"    => \$opt_url,
+        "b|binary=s" => \$opt_binary,
+        "p|path=s"   => \$opt_path,
+        "h|help"     => sub { print_help(); exit $ERRORS{OK}; },
+        "V|version"  => sub { print_revision($ME, $VERSION); exit $ERRORS{OK}; }
+      )
+      or do {
+        print $USAGE;
+        exit $ERRORS{CRITICAL};
+      };
+
+    unless ($opt_url) {
+        print $USAGE;
+        exit $ERRORS{CRITICAL};
+    }
+
+    download($opt_url, $opt_path);
+}
+
+sub execute($) {
+    my $run_file = shift;
+    chmod 0755, $run_file or do {
+        print "EXEC CRITICAL: Can't chmod $run_file ($!)\n";
+        cleanup($run_file);
+        exit $ERRORS{CRITICAL};
+    };
+
+    my @cmd = ($run_file);
+
+    open(OUTPUT, "-|") or do {
+        open(STDERR, ">&STDOUT");
+        system(@cmd);
+    };
+
+    my $result = <OUTPUT>;
+
+    close(OUTPUT);
+
+    if ($? == -1) {
+        print "EXEC CRITICAL: Failed to execute: $!\n";
+        cleanup($run_file);
+        exit $ERRORS{CRITICAL};
+    }
+    elsif ($? & 127) {
+        printf "EXEC CRITICAL: Child died with signal %d, %s coredump\n",
+          ($? & 127), ($? & 128) ? 'with' : 'without';
+        cleanup($run_file);
+        exit $ERRORS{CRITICAL};
+    }
+    else {
+        my $rc = $? >> 8;
+        if ($rc == $ERRORS{OK}) {
+            print "EXEC OK: $result";
+            cleanup($run_file);
+            exit $ERRORS{OK};
+        }
+        elsif ($rc == $ERRORS{WARNING}) {
+            print "EXEC WARNING: $result";
+            cleanup($run_file);
+            exit $ERRORS{WARNING};
+        }
+        elsif ($rc == $ERRORS{CRITICAL}) {
+            print "EXEC CRITICAL: $result";
+            cleanup($run_file);
+            exit $ERRORS{CRITICAL};
+        }
+        elsif ($rc == $ERRORS{UNKNOWN}) {
+            print "EXEC UNKNOWN: $result";
+            cleanup($run_file);
+            exit $ERRORS{UNKNOWN};
+        }
+        elsif ($rc == $ERRORS{DEPENDENT}) {
+            print "EXEC DEPENDENT: $result";
+            cleanup($run_file);
+            exit $ERRORS{DEPENDENT};
+        }
+    }
+}
+
+sub cleanup($) {
+    my $file = shift;
+
+    if (-f $file) {
+        unlink $file or do {
+            print "EXEC WARNING: Can't remove $file ($!)\n";
+            exit $ERRORS{WARNING};
+          }
+    }
+}
+
+sub download($$) {
+    my $url  = shift;
+    my $path = shift;
+
+    my $file = basename $url;
+
+    unless (-d $path) {
+        mkpath($path, { mode => 0700, error => \my $err });
+        for my $diag (@$err) {
+            my ($directory, $message) = each %$diag;
+            print
+              "EXEC CRITICAL: Can't create directory $directory: $message\n";
+            exit $ERRORS{CRITICAL};
+        }
+    }
+
+    $file = "$path/$file";
+
+    my $rc = getstore($url, $file);
+    if (is_error($rc)) {
+        if ($rc == 404) {
+            print "EXEC OK: $url ", status_message($rc), "\n";
+            cleanup($file);
+            exit $ERRORS{OK};
+        }
+        else {
+            print "EXEC CRITICAL: $url ", status_message($rc), "\n";
+            cleanup($file);
+            exit $ERRORS{CRITICAL};
+        }
+    }
+
+    verify($file);
+}
+
+sub verify($) {
+    my $file     = shift;
+    my $dir      = dirname($file);
+    my $run_file = fileparse($file, qw/\.[^.]*/);
+
+    my $vc = qq{$opt_binary --verify};
+    my $dc = qq{$opt_binary --batch --yes};
+
+    my @r = qx/$vc $file 2>&1/;
+    if ($?) {
+        print "EXEC CRITICAL: @r";
+        exit $ERRORS{CRITICAL};
+    }
+
+    @r = qx/$dc $file 2>&1/;
+    if ($?) {
+        print "EXEC CRITICAL: @r";
+        exit $ERRORS{CRITICAL};
+    }
+
+    execute("$dir/$run_file");
+}
+
+sub print_usage() { print $USAGE }
+
+sub print_help() {
+    print_revision($ME, $VERSION);
+    print <<EOF;
+Copyright (c) 2010 Christian Arnold
+
+This plugin loads a program file via http or https from a
+server and verifies its validity based on a gpg key.
+
+$USAGE
+    -u, --url
+        download url for generic script
+    -b, --binary
+        path to gpg (default: /usr/bin/gpg)
+    -p, --path
+        location for store download script (default: /var/tmp/nagios)
+    -h, --help
+        print detailed help screen
+    -V, --version
+        print version information
+
+EOF
+    support();
+}