# $Id: Fedora.pm,v 1.13 2009/11/18 17:32:30 thoger Exp $ # Fedora specific routines and constants # Lubomir Kundrak package Libexig::Fedora; use warnings; use strict; use Data::Dumper; %Libexig::Fedora::srt_bz_map = ( 'critical' => 'urgent', 'important' => 'high', 'moderate' => 'medium', 'low' => 'low', ); ### ### Parent bugs from CVE ### # Get the text to include in the CVE bug descripiton sub cve_bug_desc { my $cve = shift; my $desc = shift; my $refs = shift; return "Common Vulnerabilities and Exposures assigned an ". "identifier $cve to the following vulnerability:". "\n\n". ($desc ? $desc : '(Please paste the CVE details manually)'). "\n\n". "References:\n\n". ($refs ? join ("\n", @{$refs}) : '(References here, one per line)'); } # Construct the parent bug sub cve_bug { my $cve = shift; my $component = shift; my $summary = shift; my $desc = shift; my $impact = shift; my $bugzilla = shift; # Get CC list # TODO: get rid of duplicates my @cc; foreach (split (/,/,$component)) { push (@cc,$bugzilla->owners ($_)); } return ( 'bug_file_loc' => "http://nvd.nist.gov/nvd.cfm?cvename=$cve", 'rep_platform' => 'All', 'op_sys' => 'Linux', 'short_desc' => "$cve $summary", 'keywords' => 'Security', 'product' => 'Security Response', 'comment' => $desc, 'component' => 'vulnerability', 'bug_severity' => $Libexig::Fedora::srt_bz_map{$impact}, 'priority' => $Libexig::Fedora::srt_bz_map{$impact}, 'version' => 'unspecified', 'cc' => join (',', @cc), 'alias' => $cve, ); } ### ### Tracking bugs ### my $comment_head = 'This is an automatically created tracking bug! '. 'It was created to ensure that one or more security '. 'vulnerabilities are fixed in affected Fedora versions.'. "\n\n". # 'You should *not* refer to this bug publicly, as it is a '. # 'private "Fedora Project Contributors" bug.'. # "\n\n". 'For comments that are specific to the vulnerability please use bugs '. 'filed against "Security Response" product referenced in "Blocks" '. 'field.'. "\n\n"; my $comment_tail = 'For more information see: '. 'http://fedoraproject.org/wiki/Security/TrackingBugs'; my $comment_update = # Following the list of parent bugs "\n". 'When creating a Bodhi update request, please include the bug IDs of '. 'the respective parent bugs filed against the "Security Response" product. '. 'Please mention CVE ids in the RPM changelog when available.'. "\n\n"; # 'When creating an update for the version this this bug is reported '. # 'against please include the bug IDs of respective bugs filed '. # 'against "Security Response" product as well as of this bug and let the '. # 'update system close them.'. # 'Please note that the update announcement will (and should) contain only '. # 'references to "Security Response" bugs as long as the tracking '. # 'bug is restricted to "Fedora Project Contributors".'. # "\n\n"; my $comment_rawhide = "\n". 'Please close this bug with RAWHIDE (referencing appropriate N-V-R in '. 'Fixed In field if possible) once is it fixed in devel branch. '. # 'Please note it\'s currently not possible to file bugs against F9, '. # 'so please make sure to fix in both rawhide and upcoming F9. '. # 'Do *not* include the bug id of this bug in the RPM changelog and the '. # 'commit message.'. "\n\n"; my $comment_all = "\n". 'Please note: this issue affects multiple supported versions of '. 'Fedora. Only one tracking bug has been filed; please only close it '. 'when all affected versions are fixed.'. "\n\n"; my $bodhi_link = 'https://admin.fedoraproject.org/updates/new/?type_=security'; my %priorities = ( 'urgent', => 4, 'high', => 3, 'medium', => 2, 'low' => 1, ); # Valid versions my %versions = ( '10', => '10', 'f10', => '10', 'fc10', => '10', '11', => '11', 'f11', => '11', 'fc11', => '11', '12', => '12', 'f12', => '12', 'fc12', => '12', '13', => 'rawhide', 'f13', => 'rawhide', 'fc13', => 'rawhide', 'devel', => 'rawhide', 'rawhide', => 'rawhide', 'all', => 'all' ); my $rawhide_version= '13'; sub tracking_bugs { my $bugs = shift; my $component = shift; my @versions = @_; my @retval; # Construct a tracking bug template my %bug_tmpl = ( 'bug_file_loc' => 'http://fedoraproject.org/wiki/Security/TrackingBugs', 'rep_platform' => 'All', 'op_sys' => 'Linux', 'short_desc' => '', 'keywords' => 'Security', 'product' => 'Fedora', 'component' => $component, 'bug_severity' => 'low', 'priority' => 'low', 'bit-58' => '1', # Fedora Project Contributors ); my $comment_parents = ''; my $parent_list = undef; foreach my $bug (@{$bugs}) { # Take the highest of priorities $bug_tmpl{'bug_severity'} = $bug->{'bug_severity'} if ($priorities{$bug->{'bug_severity'}} > $priorities{$bug_tmpl{'bug_severity'}}); $bug_tmpl{'priority'} = $bug->{'priority'} if ($priorities{$bug->{'priority'}} > $priorities{$bug_tmpl{'priority'}}); # This will be overwriten if we block just one parent bug $bug_tmpl{'short_desc'} .= $bug->{'alias'}.' '; # Add the parent bug to the comment $comment_parents .= "bug #$bug->{'bug_id'}:\n$bug->{'short_short_desc'}\n"; if (!$parent_list) { $parent_list = $bug->{'bug_id'}; } else { $parent_list .= "," . $bug->{'bug_id'}; } } if (@{$bugs} > 1) { $bug_tmpl{'short_desc'} .= "Multiple $component vulnerabilities"; } else { $bug_tmpl{'short_desc'} = $bugs->[0]->{'short_short_desc'}; } # Create a bug hash for each version foreach my $version (@versions) { my %bug = %bug_tmpl; $bug{'short_desc'} .= " [Fedora $versions{$version}]"; $bug{'version'} = $versions{$version}; $bug{'comment'} = $comment_head. $comment_parents. ($bug{'version'} eq 'rawhide' ? $comment_rawhide : $comment_update). ($bug{'version'} ne 'all' ? '' : "Bodhi update submission link:\n". "$bodhi_link&bugs=$parent_list\n". $comment_all ). $comment_tail; push @retval, \%bug; } return \@retval; } # file_tracking_bugs # # Arguments: # - ref to list of parent bug ids # - ref to list of bugs to file (each element must be hash as expected by BZ) # this list is prepared by tracking_bugs # - Bugzilla object reference # - component sub file_tracking_bugs { my $parent_bugs = shift; my $tracking_bugs = shift; my $bugzilla = shift; my $component = shift; my @created_bugs; my @created_versions; my $comment = "Created Fedora tracking bugs for $component:\n\n"; foreach my $bug (@{$tracking_bugs}) { my $allvers; if ($bug->{'version'} eq 'all') { $allvers = 1; $bug->{'version'} = 'rawhide'; } else { $allvers = 0; } my $bug_id = $bugzilla->file_bug ($bug); if (!defined($bug_id)) { print STDERR "Error: Bug creation failed! (dryrun mode?)\n"; #return undef; } ### XXX: Move this somewhere else? if ($bug->{'version'} ne 'rawhide') { my $tr_comment = "Bodhi update submission link:\n". "$bodhi_link&bugs=$bug_id"; foreach my $bug (@{$parent_bugs}) { $tr_comment .= ','.$bug; } $bugzilla->add_comment ($bug_id, $tr_comment); push @created_versions, $bug->{'version'}; } else { push @created_versions, $rawhide_version; } $bugzilla->add_blockers ($bug_id, $parent_bugs); if (! $allvers) { $comment .= $bug->{'version'}.": bug #$bug_id\n"; } else { $comment .= "All versions: bug #$bug_id\n"; } push @created_bugs, $bug_id; } foreach my $bug (@{$parent_bugs}) { $bugzilla->add_private_comment ($bug, $comment); } # Generate also add-issue command hint my $command_hint= './tools/scripts/add-issue'; $command_hint.= " --component '".$tracking_bugs->[0]->{'component'}."'"; $command_hint.= " --bugs ".join(',', @created_bugs); $command_hint.= " --versions ".join(',', @created_versions); $command_hint.= " --cve\n"; # not needed any more $command_hint = ''; return $comment."\n".$command_hint; }