#!/bin/bash
# Copyright (C) 2008-2018 Canonical, Ltd.
# Author: Kees Cook <kees@ubuntu.com>
# Author: Jamie Strandboge <jamie@ubuntu.com>
# Author: Steve Beattie <sbeattie@ubuntu.com>
# License: GPLv3
#
# This script attempts to build up statistics for a yearly report on
# security update activity on USNs, triage, and outstanding tasks.
# It is designed to be run on the year _following_ the year one wants
# a report for. e.g. run this script in 2012 if you want the 2011 report.
#
set -e
export LANG=C

help() {
    cat <<EOM
This script attempts to build up statistics for a yearly report on
security update activity on USNs, triage, and outstanding tasks.
It is designed to be run on the year _following_ the year one wants
a report for. e.g. run this script in 2012 if you want the 2011 report.

Typical usage:
$ $UCT/scripts/`basename $0`

Can also specify different years with:
$ $UCT/scripts/`basename $0` <first>

Eg:
$ $UCT/scripts/`basename $0` 2011
EOM
}

if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
    help
    exit 0
fi

# Make sure we won't destroy any pending commits
if [ -n "$(git status --porcelain)" ]; then
    echo "Aborting: git tree is unclean. Please commit changes before contining" >&2
    git status -s 1>&2
    exit 1
fi

REP_MON="January"
REP_MONN="01"
REP_YEAR=$(date +%Y -d 'last year')

if [ -n "$1" ]; then
    REP_YEAR=$(date +%Y -d "$1-01-01")
fi

echo "Fetching USN publication list..." >&2
USNS=
for m in January February March April May June July August September October November December ; do
    tmp=$(echo $(curl -s https://lists.ubuntu.com/archives/ubuntu-security-announce/$REP_YEAR-$m/date.html | fgrep '">[USN-'  | cut -d- -f2,3 | cut -d\] -f1))
    USNS="$USNS $tmp"
done

echo "Fetching USN database..." >&2
#if grep -q people ~/.ssh/config; then
#    rsync -q -e ssh people.canonical.com:~ubuntu-security/public_html/usn/database-all.pickle ./database-all.pickle
#else
#    ./scripts/fetch-db database-all.pickle.bz2
#fi
PUBLISHED=$(./scripts/report-usn-numbers.py --prose database-all.pickle $USNS)

# We depend on a script to perform output while the tree is reverted, so
# copy the script out of the tree for later use.
SCRIPTS=$(mktemp -d -t yearly-report-XXXXXX)
for i in report-todo-numbers check-cves cache_urllib.py cve_lib.py source_map.py usn_lib.py
do
    cp -a scripts/$i "$SCRIPTS"/$i
done

TMP1=$(mktemp -t work1-XXXXXX)
TMP2=$(mktemp -t work2-XXXXXX)
TMP1_UBUNTU=$(mktemp -t work1u-XXXXXX)
TMP2_UBUNTU=$(mktemp -t work2u-XXXXXX)
if [ ! -x "scripts/yearly-report" ]; then
    echo "Please run this from the top-level directory of Ubuntu CVE Tracker"
    exit 1
fi

git_rewind ()
{
    local changed count

    count=0
    changed="$1"
    while :; do
        git checkout -q $(git rev-list  -1  --before="$changed" master) && break
        changed=$(date +%Y-%m-%d -d "$changed - 1 day")
        count=$(( count + 1 ))
        if [ "$count" -gt 32 ]; then
            echo "Eeek, rewound from $1 past $changed.  Something is wrong."
            exit 1
        fi
    done
    #echo "rewound to $changed"
}


echo "Rewinding git tree for stats..." >&2
# Locate the last day something changed
git_rewind "$REP_YEAR-01-01"
# Gather stats at the time
$SCRIPTS/check-cves --known > "$TMP1"
$SCRIPTS/check-cves --known --skip-nfu > "$TMP1_UBUNTU"

echo "Fast-forwarding git tree for stats..." >&2
# Fast-forward to end of year
git checkout -q master
git_rewind "$REP_YEAR-12-31"
$SCRIPTS/check-cves --known > "$TMP2"
$SCRIPTS/check-cves --known --skip-nfu > "$TMP2_UBUNTU"

echo "Returning git tree to present-day..." >&2
# Get back to normal
git checkout -q master

# Calculate difference
TRIAGED=$(diff -u "$TMP1" "$TMP2" | grep '^+CVE' | wc -l)
rm -f "$TMP1" "$TMP2"
FOR_US=$(diff -u "$TMP1_UBUNTU" "$TMP2_UBUNTU" | grep '^+CVE' | wc -l)
rm -f "$TMP1_UBUNTU" "$TMP2_UBUNTU"
rm -rf "$SCRIPTS"

# Report!
echo ""
echo "In the year of $REP_YEAR, the Ubuntu Security team:"
echo " * $PUBLISHED"
echo " * Triaged $TRIAGED public security vulnerability reports, retaining the $FOR_US that applied to Ubuntu."
