forked from openwrt/openwrt
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
base-files: add sysupgrade-online script as POC
This is a proof of conecpt and requires further work, it show how a device can find upgrades only in a secure way, without any extra packages, especially nothing HTTPS related. The online.sh "library" can be used for CLIs or ubus calls for Luci or other webinterfaces to come. Details about the JSON structure are explained in another PR[0]. To try the script, run `sysupgrade-online --search` or `--unattended`, the former searches for a sysupgrade (only snapshots currently), the latter searches and passes results to a download function, which then downloaded the sysupgrade. Ideally the sysupgrade would be verified aditionally via usign. [0]: openwrt#2192 Signed-off-by: Paul Spooren <mail@aparcar.org>
- Loading branch information
Showing
2 changed files
with
171 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/bin/sh | ||
|
||
# POC to simplify sysupgrade via JSON info files | ||
# based on https://github.com/openwrt/openwrt/pull/2192 | ||
|
||
. /lib/upgrade/online.sh | ||
|
||
while [ -n "$1" ]; do | ||
case "$1" in | ||
-s|--search) sysupgrade_search;; | ||
-d|--download) sysupgrade_download;; | ||
-u|--unattended) sysupgrade_unattended;; | ||
-*) | ||
echo "Invalid option: $1" >&2 | ||
exit 1 | ||
;; | ||
*) break;; | ||
esac | ||
shift; | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
#!/bin/sh | ||
|
||
. /usr/share/libubox/jshn.sh | ||
. /etc/openwrt_release | ||
|
||
# later to be http://downloads.openwrt.org | ||
# find public key at $UPDATE_SERVER/key-build.pub | ||
UPDATE_SERVER="http://update.aparcar.stephen304.com/download/json-demo/openwrt" | ||
|
||
# downloads file and check if sha256sum matches | ||
download_and_check() { | ||
# $1 URL to download | ||
# $2 sha256sum | ||
rm -f "$(basename $1)" | ||
wget "$1" || exit 1 | ||
if [[ "$(sha256sum $(basename $1) | cut -d ' ' -f 1)" != "$2" ]]; then | ||
>&2 echo "$(basename $1): bad checksum" | ||
>&2 echo "URL: $1" | ||
>&2 echo "expected: $2" | ||
exit 1 | ||
fi | ||
} | ||
|
||
# strip revision to a comparable integer | ||
revision_count() { | ||
# $1 revision commit | ||
echo "$1" | cut -d "-" -f 0 | cut -d "+" -f 0 | tail -c +2 | ||
} | ||
|
||
# check if found version is upgrdable | ||
# TODO: currently only checks snapshots for newer revision | ||
upgradable() { | ||
version="$1" | ||
revision="$2" | ||
if [[ "$version" == "SNAPSHOT" -a "$DISTRIB_RELEASE" == "SNAPSHOT" ]]; then | ||
if [[ $(revision_count $revision) -gt $(revision_count $DISTRIB_REVISION) ]]; then | ||
>&2 echo "SNAPSHOT upgrade to $revision found" | ||
echo 1 | ||
fi | ||
fi | ||
} | ||
|
||
# searches for new sysupgrades | ||
sysupgrade_search() { | ||
cd /tmp && { | ||
rm versions.json* | ||
wget "$UPDATE_SERVER/versions.json" | ||
wget "$UPDATE_SERVER/versions.json.sig" | ||
usign -V -P /etc/opkg/keys -m versions.json || { | ||
echo "versions.json: bad usign signature" | ||
exit 1 | ||
} | ||
|
||
json_load_file versions.json | ||
json_get_var metadata_version metadata_version | ||
json_select versions | ||
|
||
idx="1" | ||
while json_get_type Type "$idx" && [ "$Type" == object ]; do | ||
json_select "$idx" | ||
json_get_vars name revision | ||
if [[ -n "$(upgradable $name $revision)" ]]; then | ||
json_get_vars path sha256 | ||
|
||
json_init | ||
json_add_string name "$name" | ||
json_add_string path "$path" | ||
json_add_string revision "$revision" | ||
json_add_string sha256 "$sha256" | ||
json_dump | ||
exit 0 | ||
fi | ||
json_select .. | ||
$((idx++)) 2> /dev/null | ||
done | ||
json_init | ||
json_dump | ||
} | ||
} | ||
|
||
# find sysupgrade file for board | ||
sysupgrade_download() { | ||
cd /tmp && { | ||
path_version="$1" | ||
sha256_targets="$2" | ||
json_load "$(ubus call system board)" | ||
json_get_vars board_name | ||
#board_name="zbtlink,zbt-wd323" | ||
download_and_check "$UPDATE_SERVER/$path_version/targets.json" "$sha256_targets" | ||
|
||
json_load_file targets.json | ||
json_get_var metadata_version metadata_version | ||
json_select targets | ||
json_select "$DISTRIB_TARGET" | ||
#json_select "ath79/generic" | ||
json_get_var path_target path | ||
json_get_var sha256 sha256 | ||
|
||
download_and_check "$UPDATE_SERVER/$path_version/$path_target/map.json" "$sha256" | ||
|
||
json_load_file "map.json" | ||
json_select devices | ||
json_select "$board_name" | ||
json_get_vars info sha256 | ||
|
||
download_and_check "$UPDATE_SERVER/$path_version/$path_target/$info" "$sha256" | ||
|
||
json_load_file "$info" | ||
json_select "images" | ||
|
||
idx="1" | ||
while json_get_type Type "$idx" && [ "$Type" == object ]; do | ||
json_select "$idx" | ||
json_get_var type type | ||
[[ "$type" == "sysupgrade" ]] && break | ||
json_select .. | ||
$((idx++)) 2> /dev/null | ||
done | ||
|
||
json_get_var sysupgrade name | ||
json_get_var sha256 sha256 | ||
|
||
download_and_check "$UPDATE_SERVER/$path_version/$path_target/$sysupgrade" "$sha256" | ||
|
||
json_init | ||
json_add_int "successful" 1 | ||
json_add_string "firmware" "$sysupgrade" | ||
json_close_object | ||
json_dump | ||
} | ||
} | ||
|
||
# combines search, download and sysupgrade | ||
sysupgrade_unattended() { | ||
search_response="$(sysupgrade_search)" | ||
if [[ "$search_response" != "{ }" ]]; then | ||
json_load "$search_response" | ||
json_get_vars path sha256 | ||
download_response="$(sysupgrade_download $path $sha256)" | ||
json_load "$download_response" | ||
json_get_vars successful firmware | ||
if [[ "$successful" -gt 0 ]]; then | ||
# TODO don't to anything really | ||
sysupgrade -T "$firmware" | ||
fi | ||
exit $? | ||
else | ||
>&2 echo "No sysupgrade found" | ||
exit 0 | ||
fi | ||
} |