check_packages should return CRITICAL for outstanding security updates
authorEvgeni Golov <evgeni.golov@credativ.de>
Sat, 26 Apr 2014 12:47:17 +0000 (14:47 +0200)
committerPeter Palfrader <peter@palfrader.org>
Sat, 26 Apr 2014 12:54:15 +0000 (14:54 +0200)
try to guess if a package is a security update by looking at the mirror
and archive component it comes from.

Original version: Bernd Zeimetz <bernd@bzed.de>
Thanks: Felix Geyer <fgeyer@debian.org>

Signed-off-by: Peter Palfrader <peter@palfrader.org>
dsa-nagios-checks/checks/dsa-check-packages

index 3ea088d..28844e5 100755 (executable)
@@ -94,6 +94,7 @@ sub get_packages {
        chomp(@lines);
 
        my $pkgname = undef;
+       my $candidate_found = 0;
        while (defined($line = shift @lines)) {
                if ($line =~ /^([^ ]*):$/) {
                        # when we have multi-arch capable fu, we require that
@@ -115,6 +116,7 @@ sub get_packages {
                        # For squeeze systems (no m-a), apt-cache policy output
                        # is all different.
                        $pkgname = $1;
+                       $candidate_found = 0;
                        if ($has_arch) {
                                my $from_list = shift @installed_packages;
                                next if ($pkgname eq $from_list); # no :$arch in pkgname we asked for
@@ -132,16 +134,26 @@ sub get_packages {
                } elsif ($line =~ /^ +Installed: (.*)$/) {
                        # etch dpkg -l does not print epochs, so use this info, it's better
                        $installed->{$pkgname}{'installed'} = $1;
+                       # initialize security-update
+                       $installed->{$pkgname}{'security-update'} = 0;
                } elsif ($line =~ /^ +Candidate: (.*)$/) {
                        $installed->{$pkgname}{'candidate'} = $1;
+               } elsif ($line =~ /     ([^ ]+) [0-9]+/) {
+                       # check if the next lines show the sources of our candidate
+                       if ($1 eq $installed->{$pkgname}{'candidate'}) {
+                               $candidate_found = 1;
+                       }
+               } elsif (($line =~ / +[0-9]+ [^ ]+\/(security\.([^ ]+\.)?debian\.org|debian-security).*\/updates\//) && $candidate_found ) {
+                       $installed->{$pkgname}{'security-update'} = 1;
                } elsif ($line =~ /^ +\*\*\*/) {
                        $line = shift @lines;
                        my @l = split(/ +/, $line);
                        $installed->{$pkgname}{'origin'} = $l[2];
+                       $candidate_found = 0;
                }
        }
 
-       my (%current, %obsolete, %outofdate);
+       my (%current, %obsolete, %outofdate, %security_outofdate);
        for my $pkgname (keys %$installed) {
                my $pkg = $installed->{$pkgname};
 
@@ -151,7 +163,11 @@ sub get_packages {
                }
 
                if ($pkg->{'candidate'} ne $pkg->{'installed'}) {
-                       $outofdate{$pkgname} = $pkg;
+                       if ($pkg->{'security-update'}) {
+                               $security_outofdate{$pkgname} = $pkg;
+                       } else {
+                               $outofdate{$pkgname} = $pkg;
+                       }
                        next;
                };
                if ($pkg->{'origin'} eq '/var/lib/dpkg/status') {
@@ -163,6 +179,7 @@ sub get_packages {
 
        $pkgs{'current'} = \%current;
        $pkgs{'outofdate'} = \%outofdate;
+       $pkgs{'security_outofdate'} = \%security_outofdate;
        $pkgs{'obsolete'} = \%obsolete;
        return \%pkgs;
 }
@@ -298,6 +315,12 @@ my @reportform = (
          'short' => "%d pc",
          'perf' => "prg_conf=%d;1;;0",
          'status' => 'WARNING' },
+       { 'key' => 'security_outofdate',
+         'listpackages' => 1,
+         'long' => "%d packages with outstanding security updates: %s",
+         'short' => "%d security-updates",
+         'perf' => "security_outdated=%d;;1;0",
+         'status' => 'CRITICAL' },
        );
 
 my @longout;