cb6c025a7f
This also removes the need for the cleanup function. Instead the cleanup code is moved in place.
170 lines
3.6 KiB
Bash
Executable File
170 lines
3.6 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"
|
|
}
|
|
|
|
fetch_manifest() {
|
|
local MIRROR=$1
|
|
local manifest=$2
|
|
|
|
wget -O$manifest "$MIRROR"/manifest
|
|
|
|
if test $? -ne 0; then
|
|
echo "Couldn't fetch manifest from $MIRROR" >&2
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
verify_manifest() {
|
|
local manifest=$1
|
|
local manifest_upper=$2
|
|
local manifest_lower=$(mktemp)
|
|
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
|
|
|
|
rm -f $manifest_lower
|
|
|
|
ecdsaverify -n $GOOD_SIGNATURES $pubkeys $signatures $manifest_upper
|
|
|
|
if test $? -ne 0; then
|
|
echo "Not enough valid signatures!" >&2
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
analyse_manifest() {
|
|
local manifest_upper=$1
|
|
|
|
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
|
|
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
|
|
local fw_image=$2
|
|
|
|
wget -O$fw_image "${MIRROR}/${fw_file}"
|
|
|
|
if test $? -ne 0; then
|
|
echo "Error downloading image from $MIRROR" >&2
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
autoupdate() {
|
|
local MIRROR=$1
|
|
|
|
local manifest=$(mktemp)
|
|
fetch_manifest $MIRROR $manifest || { rm -f $manifest; return 1; }
|
|
|
|
local manifest_upper=$(mktemp)
|
|
verify_manifest $manifest $manifest_upper || { rm -f $manifest $manifest_upper; return 1; }
|
|
rm -f $manifest
|
|
|
|
analyse_manifest $manifest_upper || { rm -f $manifest_upper; return 1; }
|
|
rm -f $manifest_upper
|
|
|
|
if newer_than "$fw_version" "$my_version"; then
|
|
echo "New version available"
|
|
|
|
local fw_image=$(mktemp)
|
|
fetch_firmware $MIRROR $fw_image || { rm -f $fw_image; return 1; }
|
|
|
|
image_md5=$(md5sum "$fw_image"|cut -b-32)
|
|
if test "$image_md5" != "$fw_md5"; then
|
|
echo "Invalid image checksum" >&2
|
|
rm -f $fw_image
|
|
return 1
|
|
fi
|
|
echo "Upgrading firmware."
|
|
|
|
sysupgrade "${fw_image}"
|
|
else
|
|
echo "No new firmware available"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
trap 'echo Signal ignored.' INT TERM 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")"
|
|
|
|
autoupdate $BASE && exit 0
|