autoupdater 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #!/bin/sh
  2. if test $(uci get autoupdater.settings.enabled) != 1; then
  3. echo "autoupdater is disabled"
  4. exit 0
  5. fi
  6. BRANCH=$(uci get autoupdater.settings.branch)
  7. PROBABILITY=$(uci get autoupdater.${BRANCH}.probability)
  8. if test "a$1" != "a-f"; then
  9. # get one random byte from /dev/urandom, convert it to decimal and check
  10. # against update_probability*255
  11. hexdump -n1 -e '/1 "%d"' /dev/urandom | awk "{exit \$1 > $PROBABILITY * 255}"
  12. if test $? -ne 0; then
  13. echo "No autoupdate this time. Use -f to override"
  14. exit 0
  15. fi
  16. fi
  17. BASE=$(uci get autoupdater.${BRANCH}.url)
  18. PUBKEYS=$(uci get autoupdater.${BRANCH}.pubkey)
  19. GOOD_SIGNATURES=$(uci get autoupdater.${BRANCH}.good_signatures)
  20. VERSION_FILE=/lib/gluon/release
  21. newer_than() {
  22. local old="$(printf '%s\n%s\n' "$1" "$2" | sort -n | head -n 1)"
  23. test "$1" != "$old"
  24. }
  25. cleanup() {
  26. rm -f $manifest
  27. rm -f $fw_image
  28. rm -f $manifest_upper
  29. rm -f $manifest_lower
  30. }
  31. trap cleanup INT TERM EXIT PIPE
  32. . /lib/gluon/functions/model.sh
  33. my_model="$(get_model | tr '[A-Z]' '[a-z]' | sed -r 's/[^a-z0-9]+/-/g;s/-$//')"
  34. if [ ! -f "$VERSION_FILE" ]; then
  35. echo "Couldn't determine firmware version!" >&2
  36. exit 1
  37. fi
  38. my_version="$(cat "$VERSION_FILE")"
  39. fw_image=$(mktemp)
  40. manifest=$(mktemp)
  41. manifest_upper=$(mktemp)
  42. manifest_lower=$(mktemp)
  43. wget -O$manifest "$BASE"/manifest
  44. if test $? -ne 0; then
  45. echo "Couldn't fetch manifest" >&2
  46. exit 1
  47. fi
  48. awk "BEGIN { sep=0 }
  49. /^---\$/ { sep=1; next }
  50. { if(sep==0) print > \"$manifest_upper\";
  51. else print > \"$manifest_lower\"}" \
  52. $manifest
  53. signatures=""
  54. while read sig; do
  55. echo "$sig" | grep -q "^[0-9a-f]\{128\}$"
  56. if test $? -ne 0; then
  57. continue
  58. fi
  59. signatures="$signatures -s $sig"
  60. done < $manifest_lower
  61. pubkeys=""
  62. for key in $PUBKEYS; do
  63. pubkeys="$pubkeys -p $key"
  64. done
  65. ecdsaverify -n $GOOD_SIGNATURES $pubkeys $signatures $manifest_upper
  66. if test $? -ne 0; then
  67. echo "Not enough valid signatures!" >&2
  68. exit 1
  69. fi
  70. grep -q "^BRANCH=${BRANCH}$" $manifest_upper
  71. if test $? -ne 0; then
  72. echo "Wrong branch. We are on ${BRANCH}" >&2
  73. exit 1
  74. fi
  75. my_firmware=$(grep "^${my_model} " $manifest_upper)
  76. if test $? -ne 0; then
  77. echo "No matching firmware found (model ${my_model})" >&2
  78. exit 1
  79. fi
  80. fw_version=$(echo "${my_firmware}"|cut -d' ' -f2)
  81. fw_md5=$(echo "${my_firmware}"|cut -d' ' -f3)
  82. fw_file=$(echo "${my_firmware}"|cut -d' ' -f4)
  83. if newer_than "$fw_version" "$my_version"; then
  84. echo "New version available"
  85. wget -O$fw_image "${BASE}/${fw_file}"
  86. if test $? -ne 0; then
  87. echo "Error downloading image" >&2
  88. exit 1
  89. fi
  90. image_md5=$(md5sum "$fw_image"|cut -b-32)
  91. if test "$image_md5" != "$fw_md5"; then
  92. echo "Invalid image checksum" >&2
  93. exit 1
  94. fi
  95. echo "Upgrading firmware."
  96. sysupgrade "${fw_image}"
  97. else
  98. echo "No new firmware available"
  99. fi
  100. exit 0