#!/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 # # $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" = "FON3" ]; then echo "This is a FON reflash v2 archive" elif [ "$VERSION" = "FON4" ]; 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