Index: /monitoring/plugins/ids/README.txt
===================================================================
--- /monitoring/plugins/ids/README.txt	(revision 1846)
+++ /monitoring/plugins/ids/README.txt	(revision 1847)
@@ -1,9 +1,27 @@
+Name:
+  check_shib_idp - checks status of Shibboleth identitiy provider
+Requirements:
+  Perl-Modules: LWP, Date::Parse, Crypt::OpenSSL::X509
+
+  NB: Shibboleth-IDP needs to have an appropiate ACL in Status handler for
+  monitoring host (see Shibboleth documentation)
+Arguments:
+  -H        host, mandatory
+  -u        url, default: idp/status
+  -t        timeout, default 10 seconds
+  -S        use https
+  -D        maximum clock skew, default 120
+  -C        certificate expiry in days, will warn, if cert expires in less
+
+
+
+
 Name:
   check_shib_sp - checks status of Shibboleth service provider
 Requirements:
   Perl-Modules: LWP, XML::Parser, Date::Parse, Crypt::OpenSSL::X509
-  Shibboleth-IDP needs to put appropiate ACL in Status handler for
-  monitoring host
 
+  NB: Shibboleth-SP needs to have an appropiate ACL in Status handler for
+  monitoring host (see Shibbolteh documentation)
 Arguments:
   -H        host, mandatory
Index: /monitoring/plugins/ids/check_shib_idp
===================================================================
--- /monitoring/plugins/ids/check_shib_idp	(revision 1847)
+++ /monitoring/plugins/ids/check_shib_idp	(revision 1847)
@@ -0,0 +1,196 @@
+#!/usr/bin/perl
+#
+# check_shib_idp, version 2012-04-23
+#
+
+use strict;
+use warnings;
+use Getopt::Long;
+use LWP;
+use Crypt::OpenSSL::X509;
+use Date::Parse;
+use POSIX qw(mktime);
+use constant {
+    OK        => 0,
+    WARNING   => 1,
+    CRITICAL  => 2,
+    UNKNOWN   => 3,
+    DEPENDENT => 4,
+};
+use constant {
+    IDP  => 'idp',
+    JAVA => 'java',
+};
+my $CODE2STRING = {
+    0 => 'OK',
+    1 => 'WARNING',
+    2 => 'CRITICAL',
+    3 => 'UNKNOWN',
+    4 => 'DEPENDENT',
+};
+
+
+sub get_diff {
+    my $ts = shift;
+
+    my ($sec1, $min1, $hour1, $day1, $mon1, $year1) =
+	strptime($ts);
+    my ($sec2, $min2, $hour2, $day2, $mon2, $year2) =
+	gmtime(time());
+    my $t1 = mktime($sec1, $min1, $hour1, $day1, $mon1, $year1);
+    my $t2 = mktime($sec2, $min2, $hour2, $day2, $mon2, $year2);
+    return $t1 - $t2;
+}
+
+
+sub status {
+    my $code    = shift;
+    my $message = shift;
+
+    $message =~ s/\n*$//;
+    printf("%s: %s\n", $CODE2STRING->{$code}, $message);
+    exit $code;
+}
+
+
+my $host           = undef;
+my $url            = 'idp/status';
+my $use_ssl        = 0;
+my $max_clock_diff = 120;
+my $cert_warn_days = 31;
+my $timeout        = 10;
+my $verbose        = 0;
+my $memory_warn    = 80;
+my $memory_crit    = 95;
+
+
+my $result = GetOptions("H=s" => \$host,
+                        "u=s" => \$url,
+                        "t=i" => \$timeout,
+                        "S"   => \$use_ssl,
+                        "D=i" => \$max_clock_diff,
+                        "C=i" => \$cert_warn_days,
+                        "v"   => \$verbose);
+if (!($result)) {
+    status(UNKNOWN, 'USAGE: -H <host> [-u <url>] [-t <timeout>] [-S] [-D <clock skew> -C <age>');
+}
+
+
+if (!defined($host)) {
+    status(UNKNOWN, 'missing manadorty parameter -H <host>');
+}
+
+#
+# arm timeout alarm
+#
+local $SIG{ALRM} = sub {
+    status(UNKNOWN, 'check timed out');
+};
+alarm $timeout;
+
+
+$url =~ s|^/+||g;
+$url =~ s|/+$||g;
+my $sp_status_url = sprintf('%s://%s/%s', ($use_ssl ? 'https' : 'http'),
+                                          $host,
+                                          $url);
+print STDERR "IDP URL: $sp_status_url\n" if ($verbose > 0);
+
+my $browser = LWP::UserAgent->new;
+my $response = $browser->get($sp_status_url);
+if ($response->is_success) {
+    my $code    = OK;
+    my $message = undef;
+    my $result = {};
+    eval {
+        LINE:
+	foreach my $line (split("\r*\n", $response->content)) {
+	    if (($line =~ m/^#/) || $line eq '') {
+		next LINE;
+	    }
+	    if ($line =~ m/^(\w+):\s+(.*?)$/g) {
+		$result->{$1} = $2;
+	    }
+	}
+    };
+    if ($@) {
+        status(CRITICAL, "error parsing response: " . $@);
+    }
+	
+    my $time = $result->{'current_time'};
+    my $diff = get_diff($time);
+    print STDERR "time: $time, difference: $diff\n" if ($verbose > 0);
+    if (abs($diff) > $max_clock_diff) {
+	status(CRITICAL,
+	       sprintf('clock skew too large (IDP time: %s, skew %d)',
+		       $time, $diff));
+    }
+
+    my $mem_used = $result->{'used_memory'};
+    my $mem_max  = $result->{'maximum_memory'};
+    if (defined($mem_used) || defined($mem_max)) {
+	$mem_used =~ s/MB$//;
+	$mem_max  =~ s/MB$//;
+	my $x = int(($mem_used * 10000) / $mem_max) / 100;
+
+	print "memory $mem_used/$mem_max ($x)\n" if ($verbose > 0);
+	if ($x > $memory_crit) {
+	    $code    = CRITICAL;
+	    $message = sprintf('IDP is low on memory (%s MB/%s MB)',
+			       $mem_used, $mem_max);
+	}
+	elsif ($x > $memory_warn) {
+	    $code    = WARNING;
+	    $message = sprintf('IDP is running low on memory (%s MB/%s MB)',
+			       $mem_used, $mem_max);
+	}
+    }
+
+
+    my $versions = {
+        IDP  => $result->{'idp_version'},
+	JAVA => $result->{'jdk_version'},
+    };
+
+
+    my $cert = undef;
+    eval {
+	my $cert_data = $result->{'default_signing_tls_key'};
+	$cert_data =~ s/(.{64})/$1\n/gs;
+	$cert = Crypt::OpenSSL::X509->new_from_string(
+	    sprintf("-----BEGIN CERTIFICATE-----\n%s\n" .
+		    "-----END CERTIFICATE-----\n", $cert_data));
+    };
+    if ($@) {
+	status(UNKNOWN, "cannot parse certificate data: $@");
+    }
+    
+    print STDERR "Certificate: " . $cert->subject() . ", validUntil: " .
+	$cert->notAfter() . "\n" if ($verbose > 0);
+
+    if ($cert->checkend(0)) {
+	$code    = CRITICAL;
+	$message = sprintf('signing certificate is expired since %s',
+			   $cert->notAfter());
+    }
+    elsif ($cert->checkend($cert_warn_days * 86400)) {
+	my $expire_days = int(get_diff($cert->notAfter()) / 86400);
+	$code           = WARNING;
+	$message        = sprintf('signing certificate expires in %d day(s)',
+				  $expire_days);
+    }
+
+    if ($code != OK) {
+	status($code, $message);
+    }
+    else {
+        status(OK, sprintf('Shibboleth IDP version %s (Java version %s)',
+			   $versions->{IDP}, $versions->{JAVA}));
+    }
+}
+else {
+    my $status = $response->status_line || 'unknown';
+    status(CRITICAL, sprintf('error fetching status: %s', $status));
+}
+FOO:
+exit OK;
Index: /monitoring/plugins/ids/check_shib_sp
===================================================================
--- /monitoring/plugins/ids/check_shib_sp	(revision 1846)
+++ /monitoring/plugins/ids/check_shib_sp	(revision 1847)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl
 #
-# check_shib_sp, version 2012-03-28
+# check_shib_sp, version 2012-04-03
 #
 
@@ -139,4 +139,5 @@
     my $message = shift;
 
+    $message =~ s/\n*$//;
     printf("%s: %s\n", $CODE2STRING->{$code}, $message);
     exit $code;
@@ -234,6 +235,6 @@
         if ($cert->checkend(0)) {
             status(CRITICAL,
-                   sprintf('%s certificate is expired',
-                           $key->{'use'}, $cert->subject()));
+                   sprintf('%s certificate is expired since %s',
+                           $key->{'use'}, $cert->notAfter()));
         }
         elsif ($cert->checkend($cert_warn_days * 86400)) {
