diff --git a/gluon/gluon-autoupdater/files/usr/sbin/autoupdater b/gluon/gluon-autoupdater/files/usr/sbin/autoupdater index 3c03a8b..773d67c 100755 --- a/gluon/gluon-autoupdater/files/usr/sbin/autoupdater +++ b/gluon/gluon-autoupdater/files/usr/sbin/autoupdater @@ -19,7 +19,7 @@ if test "a$1" != "a-f"; then fi fi -BASE=$(uci get autoupdater.${BRANCH}.url) +MIRRORS=$(uci get autoupdater.${BRANCH}.mirror) PUBKEYS=$(uci get autoupdater.${BRANCH}.pubkey) GOOD_SIGNATURES=$(uci get autoupdater.${BRANCH}.good_signatures) @@ -30,14 +30,131 @@ newer_than() { test "$1" != "$old" } -cleanup() { - rm -f $manifest - rm -f $fw_image - rm -f $manifest_upper - rm -f $manifest_lower +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 } -trap cleanup INT TERM EXIT PIPE +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/-$//')" @@ -49,82 +166,13 @@ fi my_version="$(cat "$VERSION_FILE")" -fw_image=$(mktemp) -manifest=$(mktemp) -manifest_upper=$(mktemp) -manifest_lower=$(mktemp) +for mirror in $MIRRORS; do -wget -O$manifest "$BASE"/manifest + autoupdate $mirror && exit 0 -if test $? -ne 0; then - echo "Couldn't fetch manifest" >&2 - exit 1 -fi + unset fw_version + unset fw_md5 + unset fw_file -awk "BEGIN { sep=0 } - /^---\$/ { sep=1; next } - { if(sep==0) print > \"$manifest_upper\"; - else print > \"$manifest_lower\"}" \ - $manifest - -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 - -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 - exit 1 -fi - -grep -q "^BRANCH=${BRANCH}$" $manifest_upper - -if test $? -ne 0; then - echo "Wrong branch. We are on ${BRANCH}" >&2 - exit 1 -fi - -my_firmware=$(grep "^${my_model} " $manifest_upper) - -if test $? -ne 0; then - echo "No matching firmware found (model ${my_model})" >&2 - exit 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) - -if newer_than "$fw_version" "$my_version"; then - echo "New version available" - wget -O$fw_image "${BASE}/${fw_file}" - if test $? -ne 0; then - echo "Error downloading image" >&2 - exit 1 - fi - - image_md5=$(md5sum "$fw_image"|cut -b-32) - if test "$image_md5" != "$fw_md5"; then - echo "Invalid image checksum" >&2 - exit 1 - fi - - echo "Upgrading firmware." - - sysupgrade "${fw_image}" -else - echo "No new firmware available" -fi - -exit 0 diff --git a/gluon/gluon-autoupdater/invariant.pl b/gluon/gluon-autoupdater/invariant.pl index 3184813..493eb29 100644 --- a/gluon/gluon-autoupdater/invariant.pl +++ b/gluon/gluon-autoupdater/invariant.pl @@ -28,10 +28,14 @@ delete autoupdater.$name set autoupdater.$name=branch END - for (qw(url probability good_signatures)) { + for (qw(probability good_signatures)) { print "set autoupdater.$name.$_=$branch->{$_}\n"; } + for (@{$branch->{mirrors}}) { + print "add_list autoupdater.$name.mirror=$_\n"; + } + for (@{$branch->{pubkeys}}) { print "add_list autoupdater.$name.pubkey=$_\n"; }