gluon/package/gluon-autoupdater/files/usr/sbin/autoupdater
Daniel Ehlers f0b63da868 gluon-autoupdater: Refactor code.
Move building blocks of the update into seperate functions.
2014-01-20 13:26:58 +01:00

158 lines
3.3 KiB
Bash
Executable File

#!/bin/sh
if test $(uci get autoupdater.settings.enabled) != 1; then
echo "autoupdater is disabled"
exit 0
fi
BRANCH=$(uci get autoupdater.settings.branch)
PROBABILITY=$(uci get autoupdater.${BRANCH}.probability)
if test "a$1" != "a-f"; then
# get one random byte from /dev/urandom, convert it to decimal and check
# against update_probability*255
hexdump -n1 -e '/1 "%d"' /dev/urandom | awk "{exit \$1 > $PROBABILITY * 255}"
if test $? -ne 0; then
echo "No autoupdate this time. Use -f to override"
exit 0
fi
fi
BASE=$(uci get autoupdater.${BRANCH}.url)
PUBKEYS=$(uci get autoupdater.${BRANCH}.pubkey)
GOOD_SIGNATURES=$(uci get autoupdater.${BRANCH}.good_signatures)
VERSION_FILE=/lib/gluon/release
newer_than() {
local old="$(printf '%s\n%s\n' "$1" "$2" | sort -n | head -n 1)"
test "$1" != "$old"
}
cleanup() {
rm -f $manifest
rm -f $fw_image
rm -f $manifest_upper
rm -f $manifest_lower
}
trap cleanup INT TERM EXIT PIPE
. /lib/gluon/functions/model.sh
my_model="$(get_model | tr '[A-Z]' '[a-z]' | sed -r 's/[^a-z0-9]+/-/g;s/-$//')"
if [ ! -f "$VERSION_FILE" ]; then
echo "Couldn't determine firmware version!" >&2
exit 1
fi
my_version="$(cat "$VERSION_FILE")"
fetch_manifest() {
local MIRROR=$1
wget -O$manifest "$MIRROR"/manifest
if test $? -ne 0; then
echo "Couldn't fetch manifest from $MIRROR" >&2
return 1
fi
}
verify_and_analyse_manifest() {
awk "BEGIN { sep=0 }
/^---\$/ { sep=1; next }
{ if(sep==0) print > \"$manifest_upper\";
else print > \"$manifest_lower\"}" \
$manifest
local signatures=""
while read sig; do
echo "$sig" | grep -q "^[0-9a-f]\{128\}$"
if test $? -ne 0; then
continue
fi
signatures="$signatures -s $sig"
done < $manifest_lower
local pubkeys=""
for key in $PUBKEYS; do
pubkeys="$pubkeys -p $key"
done
ecdsaverify -n $GOOD_SIGNATURES $pubkeys $signatures $manifest_upper
if test $? -ne 0; then
echo "Not enough valid signatures!" >&2
return 1
fi
grep -q "^BRANCH=${BRANCH}$" $manifest_upper
if test $? -ne 0; then
echo "Wrong branch. We are on ${BRANCH}" >&2
return 1
fi
local my_firmware=$(grep "^${my_model} " $manifest_upper)
if test $? -ne 0; then
echo "No matching firmware found (model ${my_model})" >&2
return 1
fi
fw_version=$(echo "${my_firmware}"|cut -d' ' -f2)
fw_md5=$(echo "${my_firmware}"|cut -d' ' -f3)
fw_file=$(echo "${my_firmware}"|cut -d' ' -f4)
return 0
}
fetch_firmware() {
local MIRROR=$1
wget -O$fw_image "${MIRROR}/${fw_file}"
if test $? -ne 0; then
echo "Error downloading image from $MIRROR" >&2
return 1
else
return 0
fi
}
autoupdate() {
local MIRROR=$1
fw_image=$(mktemp)
manifest=$(mktemp)
manifest_upper=$(mktemp)
manifest_lower=$(mktemp)
fetch_manifest $MIRROR || return 1
verify_and_analyse_manifest || return 1
if newer_than "$fw_version" "$my_version"; then
echo "New version available"
fetch_firmware $MIRROR || return 1
image_md5=$(md5sum "$fw_image"|cut -b-32)
if test "$image_md5" != "$fw_md5"; then
echo "Invalid image checksum" >&2
return 1
fi
echo "Upgrading firmware."
sysupgrade "${fw_image}"
else
echo "No new firmware available"
fi
return 0
}
autoupdate $BASE && exit 0