f0b63da868
Move building blocks of the update into seperate functions.
158 lines
3.3 KiB
Bash
Executable File
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
|