1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#!/usr/bin/perl
use warnings;
use strict;
my $user="debian-security\@lists.debian.org";
my $list=shift;
my $oldlist="$list.old";
if (! -e $list) {
die "$list does not exist\n";
}
if (! -e $oldlist) {
die "$oldlist does not exist (touch it if running for first time)\n";
}
my %old = processlist($oldlist);
my %new = processlist($list);
# Build up a list of changes between the two lists.
my @changes;
# Remove anything that is on both lists from both,
# so the lists only contain changes.
foreach my $bug (keys %old) {
foreach my $cve (keys %{$old{$bug}}) {
if (exists $new{$bug} && exists $new{$bug}{$cve}) {
delete $new{$bug}{$cve};
delete $old{$bug}{$cve};
}
}
}
# Remove tags for all old stuff. Hs to come before adding tags for new
# stuff, to deal with edge cases where bugs move between CVE ids.
foreach my $bug (keys %old) {
foreach my $cve (keys %{$old{$bug}}) {
push @changes, "usertag $bug - $cve"
unless $cve =~ /CVE-\d+-XXXX/;
push @changes, "usertag $bug - tracked";
}
}
# Add tags for all new stuff.
foreach my $bug (keys %new) {
foreach my $cve (keys %{$new{$bug}}) {
push @changes, "usertag $bug + $cve"
unless $cve =~ /CVE-\d+-XXXX/;
push @changes, "usertag $bug + tracked";
}
}
if (system("cp", $list, $oldlist) != 0) {
die "failed to copy $list to $oldlist, didn't send any mail";
}
if (@changes) {
open(MAIL, "| mail -s \"CVE usertag update\" control\@bugs.debian.org");
#open(MAIL, ">&STDOUT");
print MAIL "user $user\n";
print MAIL "$_\n" foreach @changes;
close MAIL;
}
print int(@changes)." tags changed\n";
sub processlist {
my $list=shift;
my %ret;
open (IN, $list) || die "read $list: $!\n";
my $cve;
while (<IN>) {
chomp;
if (/^(CVE-(?:[0-9]+|[A-Z]+)-(?:[0-9]+|[A-Z]+))\s*(.*)/) {
$cve=$1;
}
elsif (/\s+-\s+.*\((.*)\)/) {
my @notes=split(/\s*;\s+/, $1);
foreach my $note (@notes) {
if ($note =~ /bug #(\d+)/) {
if (! defined $cve) {
print STDERR "no cve for bug at line $.!\n";
next;
}
$ret{$1}{$cve}=1;
}
}
}
}
close IN;
return %ret;
}
|