summaryrefslogtreecommitdiffstats
path: root/bin/bts-update
blob: 99e15d9a7dd3de8db593b67d29ffa994ade47068 (plain) (blame)
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;
}

© 2014-2024 Faster IT GmbH | imprint | privacy policy