#!/bin/sh

# $NetBSD: download-vulnerability-list.sh.in,v 1.5 2008/03/13 08:37:43 wiz Exp $
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#	This product includes software developed by Alistair Crooks
#	for the NetBSD project.
# 4. The name of the author may not be used to endorse or promote
#    products derived from this software without specific prior written
#    permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

: ${PKGVULNDIR="/var/db/pkg"}
: ${COMPRESS_TYPE="gzip"}
: ${FETCH_PRE_ARGS=""}
: ${FETCH_CMD=/usr/pkg/bin/ftp}
: ${FETCH_ARGS=""}
: ${FETCH_PROTO=ftp}

prefix=/usr/pkg
AP=${prefix}/sbin/audit-packages
NEW_VUL_LIST=pkg-vulnerabilities.$$
EXIST_VUL_LIST=pkg-vulnerabilities
FETCH_PATH="ftp.NetBSD.org/pub/NetBSD/packages/vulns"
_CONF_FILE="/usr/pkg/etc/audit-packages.conf"
COMPRESS_TOOL=""

usage()
{
	argv0="${1##*/}"
	cat <<EOF
$2
Usage: $argv0 [-s] [-c config-file]
	-s : Verify the signature on the downloaded file.
	-c : Specify a custom configuration file to use.
EOF
	exit 1
}

verify=no
custom_conf=no
conf_found=no
neednew=no

while [ $# -gt 0 ]; do
	case "$1" in
	-s)
		verify=yes
		;;
	-c)
		custom_conf=yes
		local_conf="$2"
		shift
		;;
	*)
		usage "$0" "Unknown option $1"
	esac
	shift
done

#  generic conf file handler
if [ -r ${_CONF_FILE} ]; then
	conf_found=yes
fi

# see if the user wants us to use a custom config file
if [ "x${custom_conf}" = "xyes" ]; then
	if [ -r ${local_conf} ]; then
		conf_found=yes
		_CONF_FILE=${local_conf}
	fi
fi

# only do the following if we have found a config file to use
if [ "x${conf_found}" = "xyes" ]; then
	if [ -r ${_CONF_FILE} ]; then
		echo "Reading settings from ${_CONF_FILE}"
		. ${_CONF_FILE}
	fi
fi

# setup the compression type
case "${COMPRESS_TYPE}" in
bzip2)		COMPRESS_EXTN=.bz2
		compressed=yes
		;;
gzip)		COMPRESS_EXTN=.gz
		compressed=yes
		;;
none)		COMPRESS_EXTN=""
		compressed=no
		;;
*)		echo "***ERROR*** Unknown COMPRESS_TYPE specified - Only bzip2 and gzip are currently supported."
		exit 1
		;;
esac

# setup the compression tool and arguments
if [ "x${compressed}" = "xyes" ]; then
	if [ "x${COMPRESS_TYPE}" = "xgzip" -a "x${COMPRESS_TOOL}" = "x" ]; then
		COMPRESS_TOOL="/usr/bin/gzip -cd"
	fi

	if [ "x${COMPRESS_TYPE}" != "xgzip" -a "x${COMPRESS_TOOL}" = "x" ]; then
		echo "***ERROR*** A non-default COMPRESS_TYPE has been specified without a COMPRESS_TOOL"
		exit 1
	fi
fi

VUL_SOURCE="${FETCH_PROTO}://${FETCH_PATH}/pkg-vulnerabilities${COMPRESS_EXTN}"

if [ ! -d ${PKGVULNDIR}/. ]; then
	echo "Creating ${PKGVULNDIR}"

	/bin/mkdir ${PKGVULNDIR}
	if [ ! -d  ${PKGVULNDIR} ]; then
		echo "***ERROR*** Can't create: ${PKGVULNDIR}"
		exit 1
	fi
fi

echo "audit-packages" > ${PKGVULNDIR}/.cookie

if [ -f ${PKGVULNDIR}/.cookie ]; then
	rm -f ${PKGVULNDIR}/.cookie
else
	echo "***ERROR*** Can't write to: ${PKGVULNDIR}"
	exit 1
fi

if [ ! "x${FETCH_PROTO}" = "xhttp" -a ! "x${FETCH_PROTO}" = "xftp" ]; then
	echo "***ERROR*** Unknown FETCH_PROTO specified - Only http and ftp are currently supported."
	exit 1
fi

cd ${PKGVULNDIR}
utility=`basename "${FETCH_CMD}"`
case "${utility}" in
curl|fetch|ftp)	${FETCH_PRE_ARGS} ${FETCH_CMD} ${FETCH_ARGS} \
			-o ${NEW_VUL_LIST}${COMPRESS_EXTN} ${VUL_SOURCE} ;;
wget)		${FETCH_PRE_ARGS} ${FETCH_CMD} ${FETCH_ARGS} \
			-O ${NEW_VUL_LIST}${COMPRESS_EXTN} ${VUL_SOURCE} ;;
*)		echo "Unknown fetch command - please use send-pr to send in support for your fetch command" 1>&2
		exit 1
		;;
esac

# see if we got a file
if [ ! -f "${NEW_VUL_LIST}${COMPRESS_EXTN}" ]; then
	echo "***ERROR*** Download of vulnerabilities file failed" 1>&2
	exit 1
fi

# decompress the downloaded file and delete the download
if [ "x${compressed}" = "xyes" ]; then
	${COMPRESS_TOOL} ${NEW_VUL_LIST}${COMPRESS_EXTN} > ${NEW_VUL_LIST}
	/bin/rm -f ${NEW_VUL_LIST}${COMPRESS_EXTN}
fi

# compare the old and new files to see if there's a difference
if [ -f ${EXIST_VUL_LIST} ]; then
	exist_hash=`${AP} -g ${EXIST_VUL_LIST}`
	new_hash=`${AP} -g ${NEW_VUL_LIST}`

	if [ "x${exist_hash}" != "x${new_hash}" ]; then
		neednew=yes
	else
		echo "No change from existing package vulnerabilities file"
		/bin/rm -f ${NEW_VUL_LIST}
		exit 0
	fi
else
	neednew=yes
fi

# check the hash and/or sig on the new file
if [ "x${verify}" = "xyes" ]; then
	${AP} -s -h ${NEW_VUL_LIST}
else
	${AP} -h ${NEW_VUL_LIST}
fi

ec=$?;

if [ $ec -ne 0 ]; then
	echo "***ERROR*** Failed to verify the newly downloaded vulnerabilities file" 1>&2
	/bin/rm -f ${NEW_VUL_LIST}
	exit 1
fi

# move the new file into position
echo "Package vulnerabilities file has been updated"
/bin/chmod a+r ${NEW_VUL_LIST}
/bin/mv -f ${NEW_VUL_LIST} ${EXIST_VUL_LIST}

exit 0
