/[secure-testing]/bin/checklist
ViewVC logotype

Diff of /bin/checklist

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

sarge-checks/checklist revision 230 by joeyh, Tue Jan 4 22:53:54 2005 UTC bin/checklist revision 3479 by joeyh, Tue Feb 14 20:56:53 2006 UTC
# Line 1  Line 1 
1  #!/usr/bin/perl  #!/usr/bin/perl
2  # Must run on a machine with madison.  # Must run on a machine with madison.
3    #
4    # To check for un-updated binary kernel packages, also needs grep-dctrl
5    # and a Sources file for the distribution. Set the location of the Sources
6    # file in SOURCES_FILE in the environment.
7    use warnings;
8    use strict;
9    use URI::Escape;
10    use Getopt::Long;
11    
12  my $html=0;  my $html=0;
13  if ($ARGV[0] eq 'html') {  my $debug=0;
14          shift;  my $suite="testing";
15          $html=1;  my $sta="http://secure-testing.debian.net/debian-secure-testing/dists/etch/security-updates/main/source/Sources.gz";
16    my $output;
17    if (! GetOptions(
18                    "html" => \$html,
19                    "debug" => \$debug,
20                    "suite=s" => \$suite,
21                    "sta=s" => \$sta,
22                    "output=s", \$output)
23        || ! @ARGV) {
24            die "usage: $0 [--suite suite] [--sta sta-mirror] [--html] [--output=file] [--debug] list ...\n";
25  }  }
26    
27  if (! @ARGV) {  my $stasources=`tempfile`;
28          die "usage: $0 [html] list\n";  chomp $stasources;
29    system("wget -q -O $stasources $sta");
30    
31    if (defined $output) {
32            open (OUT, ">$output.tmp.$$") || die "output.tmp.$$: $!"; # Set the output to a file
33    }
34    else {
35            open (OUT, ">&STDOUT"); # Set the output to stdout
36  }  }
37    
38  if ($html) {  if ($html) { # It's HTML, so we need a header
39          print "<title>testing security issues</title>\n";          print OUT "<html><title>$suite security issues</title>\n";
40          print "<ul>\n";  
41            # This is being run against something it's not meant to be, so print a warning
42            if ($suite ne 'testing' && $suite ne 'unstable') {
43                    print OUT <<"EOF";
44    <p>
45    <em>Warning:</em> This page is the result of running the testing security
46    check script against the $suite distribution. As data is only gathered for
47    the testing distribution, results may be innacurate if a package has
48    changed its name, if a vulnerability affects $suite and not testing, or if a
49    vulnerability has been fixed in $suite by the security team.
50    </p>
51    EOF
52            }
53            print OUT "<ul>\n";
54  }  }
55    
56  sub printid {  
57          my $id=shift;  my %data;
58          $id=~s#((?:CAN|CVE)-\d+-\d+)#<a href="http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=$1">$1</a>#g if $html;  my %advlist;
59          return $id;  my %needkernel=qw/2.4.27 0 2.6.11 0/;
60    my $list_unknown=1; #set to 1 to display kernel images with unknown source version
61    my $sources=$ENV{SOURCES_FILE};
62    my $need_rebuild=0;
63    
64    # Set some colours for the urgency types
65    my @urgencies=("high", "medium", "low", "unimportant", "unknown", "fixed");
66    my %colormap=(
67            high => "#FF0000",
68            medium => "#FF9999",
69            low => "#FFFFFF",
70            unknown => "#FFFF00",
71            fixed => "#00FF00",
72    );
73    
74    my $unprop = my $unprop_all = my $unfixed = my $todos = my $fixedsta = 0;
75    
76    # Add an item into the data array.
77    sub record {
78            my ($package, $condition, $item, $urgency)=@_;
79    
80            if (! defined $item) {
81                    $item='';
82            }
83    
84            if ($html) {
85                    $condition=~s{bug #(\d+)}{<a href="http://bugs.debian.org/$1">bug #$1</a>}g;
86                    $condition=~s{unfixed}{<b>unfixed</b>}g;
87                    $item=~s#(CVE-\d+-\d+)#<a href="http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=$1">$1</a>#g;
88                    $item=~s#(DTSA-\d+-\d+)#<a href="http://secure-testing-master.debian.net/DTSA/$1.html">$1</a>#g;
89            }
90    
91            push @{$data{$package}{$condition}}, {item => $item, urgency => $urgency};
92  }  }
93    
94  foreach my $list (@ARGV) {  foreach my $list (@ARGV) {
95            # Each of the @ARGVs we've got passed need parsing. So lets do that
96    
97            # If it's a directory, set the file to list, cause we need that.
98          if (-d $list) {          if (-d $list) {
99                  $list="$list/list";                  $list="$list/list";
100          }          }
101    
102            my $id;
103          open (IN, $list) || die "open $list: $!";          open (IN, $list) || die "open $list: $!";
104          while (<IN>) {          while (<IN>) {
105                    print STDERR "line: $_" if $debug;
106                  chomp;                  chomp;
107                  if (/^\[/) {                  if (/\s+TODO/) { # It's a todo item. Add it to the count, and ignore it
108                          ($id)=m/((?:DSA|CAN|CVE)-.*?) /;                          $todos++;
109                    }
110                    elsif (/^\[/) { # Checking adv. number for a line starting with [ : Set $id to it
111                            ($id)=m/((?:DSA|DTSA|CVE)-[^\s]+) /;
112                    }
113                    elsif (/^((?:DSA|DTSA|CVE)-[^\s]+)/) { # Check for a line with an advisory at the start : Set $id to it
114                            $id=$1;
115                  }                  }
116                  elsif (/^(DSA|CAN|CVE)-/) {                  elsif (/^\s+\[\w+\]\s+/) { # line tagged with a debian codename
117                          $id=$_;                          next; # don't handle these for now
118                  }                  }
119                  elsif (/^\s+[!-]\s+(.*?)\s+(.*)$/) {                  elsif (/^\s+(?:\[\w+\]\s+)?[!-]\s+(\S+)\s+(.*?)\s*$/) { # Deal with the rest of the lines
120                          my $package=$1;                          my $package=$1; # We know which package it is.
121                          my $version=$2;                          my $rest=$2;
122                          if ($version=~/unfixed/) {                          my $version;
123                                  if ($html) {                          my $notes;
124                                          print "<li>";                          if ($rest=~/([^\(\s]+)\s+\((.*)\)/) {
125                                          $version=~s!bug #(\d+)!<a href="http://bugs.debian.org/$1">bug #$1</a>!g;                                  $version=$1;
126                                    $notes=$2;
127                            }
128                            elsif ($rest=~/\((.*)\)/) {
129                                    $version="";
130                                    $notes=$1;
131                            }
132                            else {
133                                    $version=$rest;
134                                    $notes="";
135                            }
136    
137                            # by now, we also have the version that's affected by the security problem.
138                            # This is stored in $version
139                            next if $version eq '<not-affected>' || $version eq '<removed>' || $version eq '<no-dsa>';
140    
141                            my @notes=split(/\s*;\s+/, $notes);
142    
143                            # Fetch the urgency, if we can.
144                            my $urgency="unknown";
145                            foreach my $u (@urgencies) {
146                                    if (grep { $_ eq $u } @notes) {
147                                            $urgency=$u;
148                                            @notes = grep { $_ ne $u } @notes;
149                                            last;
150                                    }
151                            }
152                            next if $urgency eq 'unimportant';
153    
154                            # It's a kernel. Add it to the list of kernels that need to be looked at.
155                            if ($package=~/kernel-source-([0-9.]+)/ && $version ne '<unfixed>') {
156                                    my $kernversion=$1;
157                                    if (exists $needkernel{$kernversion} &&
158                                        length $version &&
159                                        system("dpkg --compare-versions $needkernel{$kernversion} lt $version") != 0) {
160                                            $needkernel{$kernversion}=$version;
161                                  }                                  }
162                                  print "$package $version for ".printid($id)."\n";                          }
163    
164                            # Fire up madison.
165                            my @maddy;
166                            for (1..5) {
167                                    @maddy=`madison -s '$suite' '$package'`;
168                                    if ($? & 127 || ($? >> 8 != 0 && $? >> 8 != 1)) {
169                                            # good old unrelaible newraff,
170                                            # home of our archive..
171                                            next;
172                                    }
173                                    last;
174                            }
175                            if ($? & 127) {
176                                    record($package, "<em>[madison segfaulted 5 times in a row.. Medic!]</em>", $id);
177                            }
178                            elsif ($? >> 8 != 0 && $? >> 8 != 1) {
179                                    record($package, "<em>[madison exited with ".($? >> 8)."]</em>", $id);
180                            }
181                            if (! @maddy) {
182                                  next;                                  next;
183                          }                          }
184                          my $maddy=`madison -s testing '$package'`;  
185                          if (length $maddy) {                          if ($version eq '<unfixed>' || grep { $_ eq 'pending' } @notes) {
186                                  my @fields = split(/\s*\|\s*/, $maddy);                                  record($package, '('.join("; ", "unfixed", @notes).')', $id, $urgency);
187                                  my $havver=$fields[1];                                  $unfixed++;
188                                  my $cmp=system("dpkg --compare-versions '$havver' '>=' '$version'");                                  # It's not been fixed!
189                                  if ($cmp != 0) {                          }
190                                          if ($html) {                          else {
191                                                  print "<li>";                                  foreach my $maddy (@maddy) {
192                                                  $havver='<a href="http://bjorn.haxx.se/debian/testing.pl?package='.$package.'">'.$havever.'</a>';                                          my @fields = split(/\s*\|\s*/, $maddy);
193                                            my $havver=$fields[1]; # It's this version in the archive I'm checking.
194                                            my $arches=$fields[3];
195                                            $version=~s/\s+//; # strip whitespace
196                                            $arches=~s/\s+$//;
197                                            next if $arches eq 'hurd-i386';
198                                            # Is the version in the archive the same or newer than the fix?
199                                            my $cmp=system("dpkg --compare-versions '$havver' '>=' '$version'");
200                                            if ($cmp != 0){ # No, so the archive is vulnerable.
201                                                    # Does the version exist in the secure-testing archive?
202                                                    my $staversion = `zcat $stasources |grep-dctrl -F Package -e ^$package\$ -s Version -`;
203                                                    chomp $staversion;
204                                                    $staversion=~s/Version: //;
205                                                    $staversion=~s/\s+//;
206                                                    if (length ($staversion)) {
207                                                            # Yes, but what version is in s-t?
208                                                            my $stacmp = system("dpkg --compare-versions '$staversion' '>=' '$version'");
209                                                            if ($stacmp == 0){
210                                                                    # Well, the version in the s-t archive fixes the issue
211                                                                    # but it's still vulnerable in the main archive
212                                                                    $urgency='fixed';
213                                                                    $fixedsta++;
214                                                            }
215                                                    }
216    
217                                                    if ($html && $suite eq 'testing') {
218                                                            $havver='<a href="http://bjorn.haxx.se/debian/testing.pl?package='.uri_escape($package).'">'.$havver.'</a>';
219                                                    }
220                                                    record($package, "$version needed, have $havver".(@maddy > 1 ? " [$arches]" : ""), $id, $urgency);
221                                                    $unprop++;
222                                                    $unprop_all++ unless @maddy > 1;
223                                          }                                          }
                                         print "$package $version needed, have $havver for ".printid($id)."\n";  
224                                  }                                  }
225                          }                          }
226                  }                  }
227          }          }
228  }  }
229    
230    
231    foreach my $package (sort keys %data) {
232            foreach my $condition (sort keys %{$data{$package}}) {
233                    print OUT "<li>" if $html;
234                    print OUT "$package $condition for ";
235                    my $items=0;
236                    foreach my $i (sort @{$data{$package}{$condition}}) {
237                            print OUT ", " if $items > 0;
238    
239                            if ($html) {
240                                    my $color=$colormap{$i->{urgency}};
241                                    print OUT "<span style=\"background:$color\">";
242                            }
243                            print OUT $i->{item};
244                            if ($html) {
245                                    print OUT "</span>";
246                            }
247    
248                            $items++;
249                    }
250                    print OUT "\n";
251            }
252    }
253    
254    my %needkern;
255    
256    foreach my $version (sort keys %needkernel) {
257            my %images;
258    
259            if (defined $needkern{$version} && $needkern{$version} eq "0") {
260                    next;
261            }
262    
263            my @dctrl;
264            if (defined $sources && length $sources) {
265                    my $cat=($sources=~/\.gz/) ? "zcat" : "cat";
266                    @dctrl=`$cat $sources | grep-dctrl -F Binary kernel-image-$version -s Package,Build-Depends -`;
267            }
268    
269            my $package="";
270            my $haveversion;
271    
272            foreach my $line (@dctrl) {
273                    chomp $line;
274                    if ($line=~/Package:\s*(\S+)/) {
275                            $package=$1;
276                            $haveversion="0";
277                    } elsif ($line=~/Build-Depends/) {
278                            if ($line=~/kernel-tree-$version-([^,\s]+)/) {
279                                    $haveversion="$version-$1";
280                            } elsif ($line=~/kernel-source-$version\s+\(>?=\s*([^\s\)]+)\)/) {
281                                    $haveversion="$1";
282                            }
283                    } else {
284                            if ($package=~/linux-kernel-di/ || $package eq "") {
285                                    next;
286                            }
287                            $images{$package}=$haveversion;
288                            $package="";
289                    }
290            }
291    
292            foreach my $package (sort keys %images) {
293                    if ($images{$package} eq "0") {
294                            print OUT "<li>" if ($html && $list_unknown);
295                            print OUT "$package built from kernel-source-$version $needkernel{$version} needed, current version unknown\n" if $list_unknown;
296                    } elsif (!system("dpkg --compare-versions $needkernel{$version} gt $images{$package}")) {
297                            print OUT "<li>" if $html;
298                            print OUT "$package built from kernel-source-$version $needkernel{$version} needed, have $images{$package}\n";
299                            $need_rebuild++;
300                    }
301            }
302    
303    
304    }
305    
306    
307  if ($html) {  if ($html) {
308          print "</ul>\n";          print OUT "</ul>\n";
309            print OUT "<hr>\n";
310            print OUT "Key: ";
311            foreach my $keyline (@urgencies) {
312                    next if $keyline eq 'unimportant';
313                    print OUT "<span style=\"border: 1px dashed; background:".$colormap{$keyline}."\">&nbsp;$keyline&nbsp;</span> ";
314            }
315            print OUT "<br>";
316            print OUT "Total holes unfixed: $unfixed<br>\n";
317            print OUT "Total holes fixed in unstable but not $suite: $unprop_all ($fixedsta fixed in secure-testing archive)";
318            if ($unprop_all != $unprop) {
319                    print OUT " (+".($unprop - $unprop_all)." on some arches)";
320            }
321            print OUT "<br>\n";
322            print OUT "Total number of kernel image packages not up to date: $need_rebuild<br>\n";
323            print OUT "Number of TODO lines in <a href=\"http://svn.debian.org/wsvn/secure-testing/data/?rev=0&sc=0\">records</a>: $todos<br>\n";
324            print OUT "Maintained by the <a href=\"http://secure-testing-master.debian.net/\">testing security team</a><br>\n";
325            print OUT "Last update: ".`date`."<br>\n";
326            print OUT "</html>\n";
327    }
328    
329    close OUT;
330    if (defined $output) {
331            rename("$output.tmp.$$", $output) || die "rename: $!";
332  }  }
333    unlink $stasources;

Legend:
Removed from v.230  
changed lines
  Added in v.3479

  ViewVC Help
Powered by ViewVC 1.1.5