# ./scripts/report-packages.py hardy
#
# export REL="hardy"; export NAMED=10; (./scripts/report-packages.py --action plot $REL | sort -n -k 8 | awk '{print $1 " " $8}' | tail -n $NAMED; echo -n "others "; ./scripts/report-packages.py --action plot $REL | sort -n -k 8 | head -n -$NAMED | awk '{ sum+=$8 }END{print sum}') | ./scripts/pie-chart.py ; scp pie.png vinyl:outflux.net/html/

from __future__ import print_function

import os
import re
import sys
import optparse

import cve_lib
import usn_lib

import source_map
source_map = source_map.load()
releases = cve_lib.releases
config = cve_lib.read_config()

parser = optparse.OptionParser()
parser.add_option(
    "-S",
    "--skip-devel",
    help="Show only those CVEs *not* in the current devel release",
    action="store_true")
parser.add_option("-D",
                  "--only-devel",
                  help="Show only those CVEs in the current devel release",
                  action="store_true")
parser.add_option("--db",
                  help="Specify the USN database to load",
Example #2
0
def htmlize_package(outfd, pkg, cvefiles, commit=None):
    html_header('%s CVEs in Ubuntu' % pkg,
                'Ubuntu Package CVE Entry for %s' % pkg, outfd)
    print('<h2 class="card-header">Package: %s</h2>' % (quote(pkg)),
          file=outfd)
    print('<div class="card-body text-left">', file=outfd)

    notes = set()

    # Loading the source map is expensive, which is unfortunate.  We will
    # do it only for pkg html output, since the generate-pkg-makefile script
    # is already trying to minimize how much we run this function.
    global map
    if not map:
        import source_map
        map = source_map.load()

    # Merged package reports (linux-source-2.6.15 should appear in
    # linux) only work when a package (linux) does not exist in a given
    # release (dapper) but the replacement does (linux-source-2.6.15).
    # So, figure out which pkg should be used for lookups in each in release:
    pkgname = dict()
    for rel in releases:
        rel_orig = rel
        if rel == cve_lib.devel_release:
            rel = 'devel'
        pkgname[rel_orig] = pkg
        if pkg not in map[rel_orig] and pkg in cve_lib.pkg_aliases:
            # Aliases: 'linux-source-2.6.15' should appear in 'linux' output
            for alias in cve_lib.pkg_aliases[pkg]:
                if alias in map[rel_orig]:
                    #print >>sys.stderr, "\tfound alias '%s' for '%s'" % (alias, pkg)
                    pkgname[rel_orig] = alias
                    notes.add(
                        'CVEs from <a href="%s.html">%s</a> in %s have been merged into this report'
                        % (quote(alias), escape(alias), escape(rel_orig)))
                    break

    # For a given source package, if it is supported for a release, but
    # there is a CVE that is marked as affecting a universe binary only,
    # we need to mark it as "community supported".  Start by building up
    # a map of supportability per-release for the source package.
    starred = False
    src_supported = dict()
    headings = []
    entire_release_starred = set()
    for rel in releases:
        heading = rel
        if '/' in rel:
            (base, ppa) = rel.split('/')
            heading = "%s/" % (base)
            if ppa == "ubuntu-core":
                heading += "Core"
            elif ppa == "stable-phone-overlay":
                heading += "Touch"
            else:  # abbreviate the ppa name if we don't know about it
                for i in ppa.split('-'):
                    heading += i[0]

        src_supported[rel] = False
        if pkgname[rel] and pkgname[rel] in map[rel]:
            src_supported[rel] = cve_lib.is_supported(map, pkgname[rel], rel)
            if not src_supported[rel]:
                starred = True
                entire_release_starred.add(rel)
                heading += "*"
        headings.append(heading)

    if len(cvefiles) == 0:
        print(
            '<div class="item text-center"><h3>Status</h3> <div class="value">No known vulnerable public CVEs</div></div>',
            file=outfd)
    else:
        cvefiles.sort(cve_lib.cve_sort)
        print(
            '<div class="item text-center"><h3>Status</h3> <div class="value">%d known public CVEs</div></div>'
            % (len(cvefiles)),
            file=outfd)

        if len(notes) > 0:
            print('<div class="item text-center"><h3>Notes</h3>', file=outfd)
            for note in sorted(notes):
                print('<div class="value">%s</div>' % (note), file=outfd)
            print('</div>', file=outfd)

        print('<h3 class="text-center">CVEs</h3>', file=outfd)
        print(
            '<table id="cves" class="table table-bordered table-hover text-center">'
            + htmlTableHeader(headings),
            file=outfd)
        for cvefile in cvefiles:
            data = cve_lib.load_cve(cvefile)

            # Sort out priority
            priority = cve_lib.contextual_priority(data)[1]
            print('<tr class="%s">' % (quote(priority)), end=' ', file=outfd)

            # fields...
            # 'pkgs' -> dict(  pkg -> dict(  release ->  (state, notes)   ) )
            cve = data['Candidate']
            #print >>sys.stderr, 'cve: %s' % (cve)
            print('<td class="cve"><a href="../%s">%s</a></td>' %
                  (quote(cve), escape(cve)),
                  end=' ',
                  file=outfd)
            for rel in releases:
                rel_orig = rel
                if rel == cve_lib.devel_release:
                    rel = 'devel'

                report_pkg = pkgname[rel_orig]

                # Sort out priority override
                priority_override = cve_lib.contextual_priority(data,
                                                                pkg=report_pkg,
                                                                rel=rel)[1]
                #print >>sys.stderr, '\tlooking for %s' % (report_pkg)
                if report_pkg in data['pkgs'] and rel in data['pkgs'][
                        report_pkg]:
                    pkgstatus = data['pkgs'][report_pkg][rel][0]
                    pkgnotes = data['pkgs'][report_pkg][rel][1]
                    pkgclass = pkgstatus
                    #print >>sys.stderr, '\t\tstatus for %s is %s' % (report_pkg, pkgclass)

                    if pkgclass == 'DNE':
                        pkgstatus = "--"
                    if pkgstatus == 'pending' and pkgnotes != '':
                        pkgclass = 'pendingversion'
                    priority_class = ""
                    priority_start = ""
                    priority_end = ""
                    if priority_override != priority:
                        priority_class = " override"
                        priority_start = '<div class="%s">' % (
                            quote(priority_override))
                        priority_end = '</div>'

                    # Sort out supportability override
                    if pkgstatus not in ["--", "not-affected"] and \
                       src_supported[rel_orig] and \
                       not cve_lib.is_supported(map, report_pkg, rel_orig, data):
                        starred = True
                        pkgstatus += "*"

                    print('<td class="%s%s">%s%s%s</td>' %
                          (quote(pkgclass), priority_class, priority_start,
                           escape(pkgstatus), priority_end),
                          end=' ',
                          file=outfd)
                else:
                    print('<td class="DNE">--</td>', end=' ', file=outfd)
            print('</tr>', file=outfd)
        print('</table>', file=outfd)
        if starred:
            print('<p class="note text-right">* community supported</p>',
                  file=outfd)

    html_footer(outfd, commit)
Example #3
0
                  help="Specify release (default is 'devel')",
                  default="devel")
parser.add_option(
    "-s",
    "--status",
    help=
    "Specify status, default is 'not-affected' for the devel release and 'released' for stable"
)
(opt, args) = parser.parse_args()

# The script expects the devel release to be specified as 'devel', so make
# it easier on the user.
if opt.release == cve_lib.devel_release:
    opt.release = 'devel'

pkgs = source_map.load()

cves = glob.glob(
    '%s/CVE-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9]{[0-9],[0-9][0-9],[0-9][0-9][0-9],[0-9][0-9][0-9][0-9]}'
    % cve_lib.active_dir)
if os.path.islink('embargoed'):
    cves += glob.glob(
        'embargoed/CVE-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9]{[0-9],[0-9][0-9],[0-9][0-9][0-9],[0-9][0-9][0-9][0-9]}'
    )
    cves += glob.glob('embargoed/EMB-*')


def get_status(opt_status, release, version=None, release_version=None):
    status = ""
    if opt_status:
        status = opt_status
Example #4
0
    if source[0]:
        return source

    # this package wasn't in any source map most likely because it is
    # packaged only for an EOL'd release such as precise
    return ('unknown', 'unknown')

parser = argparse.ArgumentParser(description="Takes a list of binary packages "\
        "and determines what source packages produce those binaries.")
parser.add_argument("release" , action="store", help="An Ubuntu release")
parser.add_argument("bin_list_path" , action="store", help="Path to a file containing a list of binaries")

opt = parser.parse_args()

try:
    srcmap = source_map.load('packages', releases=[opt.release])
    source_packages = set()
    with open(opt.bin_list_path) as fp:
        binary_package = fp.readline().strip()
        while binary_package:
            source = which_source(srcmap, binary_package, opt.release)
            source_packages.add(source)
            binary_package = fp.readline().strip()

    for sp in sorted(source_packages):
        print(sp[0])
except KeyError as ke:
    print("KeyError detected. It's possible that the specified Ubuntu release" \
            " is nonexistant or has reached end-of-life. Key=%s" % str(ke),
           file=sys.stderr)
                  metavar="COMPONENT")
parser.add_option("--all",
                  help="Show all packages that use Built-Using",
                  default=False,
                  action='store_true')
(opt, args) = parser.parse_args()

if len(args) == 0 and not opt.all:
    print >> sys.stderr, "ERROR: must supply source package name(s)"
    sys.exit(1)

if opt.all and len(args) > 0:
    print >> sys.stderr, "ERROR: do not specify packages with --all"
    sys.exit(1)

pmap = source_map.load(data_type='packages')
releases = cve_lib.releases

for eol in cve_lib.eol_releases:
    if eol in releases:
        releases.remove(eol)

if opt.release:
    releases = [opt.release]

built_using = source_map.load_built_using_collection(pmap,
                                                     releases=releases,
                                                     component=opt.component)

out = ""