#!/bin/sh
#
# Extracts a .fon bundle, verifies the signature against
# the FON public key, and performs the upgrade
#
# Usage:
#   fonverify [public_key_file] [fon_file]
#
# 20060711 Pablo Martin <pablo@fon.com>
#
# $Id: fonverify 35 2006-07-17 21:29:36Z pablo.martin $
#
#
# Check if the dependencies on the "hotfix" file
# are satisfied by the system
#
# Assigns variables:
# HOTFIX_NAME       -> Name of the hotfix
# HOTFIX_VERSION    -> Firmware version the hotfix applies
# HOTFIX_ARCH       -> Architecture the hotfix runs on
# HOTFIX_DEPENDS_ON ->
do_exit() {
	rm $TAR_FILE 2> /dev/null
	rm -R $UPGRADE_DIRECTORY 2> /dev/null
	exit $1
}
check_dependencies() {
	HOTFIX_NAME=$(cat $1 | grep "^Name:" | awk '{ for (i=2; i<=NF; i++)  print $i}')
	HOTFIX_VERSION=$(cat $1 | grep "^Version:" | awk '{ for (i=2; i<=NF; i++)  print $i}')
	HOTFIX_ARCHITECTURE=$(cat $1 | grep "^Arch:" | awk '{ for (i=2; i<=NF; i++)  print $i}')
	HOTFIX_DEPENDS_ON=$(cat $1 | grep "^Depends:" | awk '{ for (i=2; i<=NF; i++)  print $i}')
	HOTFIX_INCOMPATIBLE_WITH=$(cat $1 | grep "^Incompatible:" | awk '{ for (i=2; i<=NF;i++) print $i}')
	if [ "$HOTFIX_NAME" = "" -o "$HOTFIX_VERSION" = "" -o "$HOTFIX_ARCHITECTURE" = "" -o "$HOTFIX_DEPENDS_ON" = "" -o "$HOTFIX_INCOMPATIBLE_WITH" = "" ]; then
		echo "Bad formed hotfix file"
		do_exit 1
	fi
	echo "Upgrade name: $HOTFIX_NAME"
	grep "^$HOTFIX_NAME" /etc/hotfix > /dev/null
	if [ $? -eq 0 ]; then
		echo "This hotfix has been already applied. Bailing out..."
		do_exit 1
	fi
	if [ ! "$HOTFIX_DEPENDS_ON" = "nothing" ]; then
		for DEPENDENCY in $HOTFIX_DEPENDS_ON; do
			grep "^$DEPENDENCY" /etc/hotfix > /dev/null
			if [ ! $? -eq 0 ]; then
				echo "This package depends on $DEPENDENCY, not installed"
				do_exit 1
			fi
		done
	fi
	if [ ! "$HOTFIX_INCOMPATIBLE_WITH" = "nothing" ]; then
		for INCOMPATIBLE in $HOTFIX_INCOMPATIBLE_WITH; do
			grep "^$INCOMPATIBLE" /etc/hotfix > /dev/null
			if [ $? -eq 0 ]; then
				echo "This package is incompatible with $INCOMPATIBLE"
				do_exit 1
			fi
		done
	fi
	FON_VERSION=$(cat /etc/fon_version)
	echo $FON_VERSION | grep "^$HOTFIX_VERSION" > /dev/null
	if [ ! $? -eq 0 ]; then
		echo "This hotfix is intended for $HOTFIX_VERSION. The firmware version on this router is $FON_VERSION."	
		do_exit 1
	fi
	ARCH_FOUND=0
	for ARCHITECTURE in $HOTFIX_ARCHITECTURE; do
		if [ "$ARCHITECTURE" = "fonera" ]; then
			ARCH_FOUND=1
		fi
	done
	if [ $ARCH_FOUND -eq 0 ]; then
		echo "Wrong arch. This hotfix is not intended to be installed in a fonera."
		do_exit 1
	fi
	return 0
}

if [ ! $# -eq 2 ]; then
	echo "Usage: fonverify [public_key_file] [fon_file]"
	exit 0
fi
KEY_FILE=$1
FON_FILE=$2
SHA1_FILE=/tmp/$$image.sha1
SIGNATURE_FILE=/tmp/$$signature.bin
MIN_FON_FILE_SIZE=100
EXTENSION=$(basename $FON_FILE | cut -d'.' -s -f2)
DIRECTORY=$(dirname $FON_FILE)
if [ ! $EXTENSION = "fon" ]; then
        echo "ERROR: This isn't a FON archive. Refusing to verify it"
	rm $FON_FILE
        exit 1
fi
NAME=$(basename $FON_FILE | sed 's/....$//')
UPGRADE_DIRECTORY=/tmp/$$upgrade/
mkdir $UPGRADE_DIRECTORY
TAR_FILE=$UPGRADE_DIRECTORY/$NAME.tgz
VERSION_FILE=/tmp/$$version
OFFSET_FILE=/tmp/$$offset
SIGNATURE_FILE=/tmp/$$signature
for i in $FON_FILE $KEY_FILE; do
	if [ ! -f $i ]; then
		echo "ERROR: $i does not exist. Bailing out..."
		exit 1
	fi
done
FON_FILE_SIZE=$(ls -l $FON_FILE | awk '{ print $5 }')
if [ $FON_FILE_SIZE -lt $MIN_FON_FILE_SIZE ]; then
	echo "ERROR: input file size too small"
	exit 1
fi
dd if=$FON_FILE of=$VERSION_FILE bs=1 count=4 > /dev/null 2>&1
VERSION=$(cat $VERSION_FILE)
if [ "$VERSION" = "FON5" ]; then
	echo "This is a FON reflash v2 archive"
elif [ "$VERSION" = "FON6" ]; then
	echo "This is a FON hotfix v2 archive"
else
	echo "ERROR: This is not a FON v2 archive"
	rm $VERSION_FILE
	rm $FON_FILE
	exit 1
fi
rm $VERSION_FILE
dd if=$FON_FILE of=$OFFSET_FILE bs=1 count=3 skip=4 > /dev/null 2>&1
OFFSET=$(expr $(cat $OFFSET_FILE))
if [ $OFFSET -eq 0 ]; then
	echo "ERROR: Offset too small"
	rm $OFFSET_FILE
	rm $FON_FILE
	exit 1
fi
dd if=$FON_FILE of=$SIGNATURE_FILE bs=1 count=$OFFSET skip=7 > /dev/null 2>&1
TO_SKIP=$(expr $OFFSET + 7)
dd if=$FON_FILE of=$TAR_FILE bs=1 skip=$TO_SKIP > /dev/null 2>&1
foncheckrsa $KEY_FILE $SIGNATURE_FILE $TAR_FILE
RESULT=$?
rm $FON_FILE
rm $OFFSET_FILE
rm $SIGNATURE_FILE
if [ ! $RESULT -eq 0 ]; then
	echo "ERROR: Validation failure"
	rm $TAR_FILE
	rm -R $UPGRADE_DIRECTORY
	exit 1
fi
cd $UPGRADE_DIRECTORY
busybox tar zx -f $TAR_FILE > /dev/null 2>&1
if [ ! $? -eq 0 ]; then
	echo "ERROR: Decompressing tgz"
	rm $TAR_FILE
	rm -R $UPGRADE_DIRECTORY
	exit 1
fi
rm $TAR_FILE
if [ -f $UPGRADE_DIRECTORY/upgrade ]; then
	cd $UPGRADE_DIRECTORY
	check_dependencies ./hotfix
	RESULT=$?
	if [ $RESULT -eq 0 ]; then
		./upgrade
	fi		
	RESULT=$?
else
	exit 0
fi
if [ ! $RESULT -eq 0 ]; then
	echo "ERROR: Error performing upgrade"
	rm -r $UPGRADE_DIRECTORY
	exit 1
else
	echo "$HOTFIX_NAME" >> /etc/hotfix
fi
rm -r $UPGRADE_DIRECTORY
exit 0

