You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
4.1 KiB
Bash

#
# Copyright (C) 2012 OpenWrt.org
# Copyright (C) 2018 devolo AG
#
. /lib/delos-functions.sh
signatureFile="/tmp/signature.bin"
publicKeyFile="/etc/keys/fw_pub_key.pem"
# get the first 4 bytes (magic) of a given file starting at offset in hex format
delos_get_magic_long_at() {
dd if="$1" skip=$2 bs=1 count=4 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
}
# scan through the update image pages until matching magic 'deadc0de' @ page start. return the offset.
delos_get_jffs2_trailer_offset() {
local magiclong
local offsetcount=0
local offset
if [ -n "$2" ]; then
offsetcount=$2
fi
while magiclong=$(delos_get_magic_long_at "$1" "$offsetcount") && [ -n "$magiclong" ]; do
[ "$magiclong" = "deadc0de" ] && {
offset="$offsetcount"
}
offsetcount=$(( $offsetcount + $CI_BLKSZ ))
done
[ -n "$offset" ] && echo "$offset"
}
delos_check_image_dvl() {
# check for valid matching dvl image.
local ret
case "$board" in
dlan-pro-1200-ac)
chunk -F "$1" -s inspect || {
echo "Invalid image type."
return 1
}
chunk -F "$1" -s dump -d "$1.$$.device" -v "$1.$$.oem"
ret=$?
if [ $ret = 0 ] ; then
[ -e "$1.$$.device" ] &&
[ -e "$1.$$.oem" ] &&
[ "$(uci_get_state delos baptization DeviceType)" = "$(cat "$1.$$.device")" ] &&
[ "$(uci_get_state delos baptization OemVariant)" = "$(cat "$1.$$.oem")" ] || ret=1
fi
if [ $ret != 0 ] ; then
echo "Invalid image type."
fi
# cleanup working files
rm -f "$1".$$.*
return $ret
;;
esac
echo "Invalid image type."
return 1
}
delos_unpack_image_dvl() {
# convert to image in sysupgrade format
# (only works if image is a file!)
case "$board" in
dlan-pro-1200-ac)
local magicl="$(get_magic_long "$1")"
[ "$magicl" != "8664564c" ] && return
chunk -F "$1" -s dump -k - -f - >"$1.$$.fw"
ret=$?
if [ $ret = 0 ] ; then
rm -f "$1"
mv "$1.$$.fw" "$1"
fi
;;
esac
}
platform_check_image_delos() {
local magicl="$(get_magic_long "$1")"
local magic="$(echo "$magicl" | head -c 4)"
[ "$magicl" = "8664564c" ] && {
delos_check_image_dvl "$1"
return
}
[ "$magic" != "2705" ] && {
echo "Invalid image type."
return 1
}
# Find trailer
local offsetTrailer="$(delos_get_jffs2_trailer_offset "$1")"
if [ -z "$offsetTrailer" ]; then
echo "Invalid image contents."
return 1
fi
trailerLength=$(dd if=$1 skip=$offsetTrailer bs=1 2> /dev/null | tr "\0" "\n" | sed -e '/^SIG:/,$d' | wc -c)
signatureOffset=$((offsetTrailer+trailerLength))
# Extract signature; Verify signature; There is a \0 before SIG: => signatureOffset-1
dd if="$1" skip=$(( $signatureOffset + 4 )) bs=1 2>/dev/null |
openssl base64 -A -d -out "$signatureFile"
if [ ! -s "$signatureFile" ]; then
echo "No signature found."
return 1
fi
output=$(head -c $(($signatureOffset-1)) "$1" | openssl dgst -sha256 -verify /etc/keys/fw_pub_key.pem -signature "$signatureFile")
opensslExitCode="$?"
rm "$signatureFile"
[ "$opensslExitCode" != 0 ] || [ "$output" != "Verified OK" ] && {
echo "Invalid signature."
return 1
}
# Extract trailer
local trailer="$(dd if="$1" skip=$(( $offsetTrailer + 4 )) bs=1 count=$(( $signatureOffset - $offsetTrailer - 4 )) 2>/dev/null)"
if [ -z "$trailer" ]; then
echo "Invalid image contents."
return 1
fi
(
. /usr/share/libubox/jshn.sh
json_load "$trailer"
# compare current and image platform device type / oem variant
json_get_var dev_img device_type
DEVICE_TYPE=
. /etc/delos-image
if [ "$dev_img" = "$DEVICE_TYPE" ] && dvl_check_oemvariant "$trailer"; then
:
else
echo "Image is not qualified for this device."
return 1
fi
) || return 1
return 0
}
platform_do_upgrade_delos() {
default_do_upgrade "$@"
}
platform_check_config_delos() {
# all in one check for gzip, tar, delos config
tar -xzf "$1" -O etc/config/delos >/tmp/config-delos 2>/dev/null || {
return 1
}
local type
type="$(uci -c /tmp -q get config-delos.delos.device_type)" || {
# backward compatibility accept config w/o device-type
return 0
}
. /etc/delos-image
[ "$type" != "$DEVICE_TYPE" ] && {
return 1
}
return 0
}
platform_pre_upgrade_delos() {
delos_unpack_image_dvl "$1"
. /lib/functions/leds.sh
led_set_attr "devolo:status:wlan" operation update
}