#! /bin/bash harmony-ve-opnsense-img-src()( set -eu [ "${1:-}" != "-d" ] || { set -x ; shift ; } trap '[ "$?" = "0" ] || >&2 echo ABNORMAL TERMINATION' EXIT SCRIPTS_DIR=$(readlink -f "$(dirname "${BASH_SOURCE}")") . "${SCRIPTS_DIR}/common" . "${SCRIPTS_DIR}/default-env-var" _short_help(){ cat <<-EOM NAME harmony-ve-opnsense-img-src DESCRIPTION Manage opnsense source images needed by Harmony Virtual Execution Environment SYNOPSYS harmony-vee-opnsense-img-src [GLOBAL_OPTIONS] COMMAND [OPTIONS] harmony-vee-opnsense-img-src list [--remote] harmony-vee-opnsense-img-src download [VERSION] harmony-vee-opnsense-img-src check [VERSION] harmony-vee-opnsense-img-src delete [VERSION] EOM } _extra_help(){ cat <<-EOM GLOBAL_OPTIONS -d Debug mode. WARNINGS This script is experimetal. Use with caution. DETAILS - for 'list', show local images available - for 'list --remote', show available upstream images - for 'download', when no VERSION is specified, use the latest - for 'delete', when no VERSION is specified, delete all image - use the 'nano' flavor EOM } # Implement functions _parse_version_from_image_file_string(){ #https://pkg.opnsense.org/releases/25.7/OPNsense-25.7-nano-amd64.img.bz2 echo "$1" | cut -d '/' -f 5 } _list_local_images(){ ls "${_HVE_OPNSENSE_SRC_IMG}" | grep "OPNsense-" | grep "\-nano\-amd64\.img" | cut -d'-' -f 2 | sort -u -r } _list_remote_images(){ curl -L -s "${_HVE_OPNSENSE_URL}" | sed 's/' -f 2 | cut -d '/' -f 1 | sort -r } _latest_version(){ _list_remote_images | head -n 1 } _is_downloaded(){ version=$1 name="${_HVE_OPNSENSE_SRC_IMG}/OPNsense-${version}-nano-amd64.img" [ -f "$name" ] && return 0 || return 1 } _is_valid_version(){ version=${1} matched_version=$(_list_remote_images | grep "$version") [ "$matched_version" != "" ] && return 0 || return 1 } _download_img(){ version=$1 _download_crypto_files $version name="OPNsense-${version}-nano-amd64.img" compressed_name=$name.bz2 _is_downloaded $version && { _warn "Image '$name' is already downloaded" } || { url=$_HVE_OPNSENSE_URL/$version/$compressed_name >&2 echo DOWNLOAD $url wget -q -c "${url}" _verify_image_checksum $version >&2 echo DECOMPRESS $url bzip2 -d $compressed_name } } _compare_files_checksum(){ file1=$1 file2=$2 sha256_1=$(openssl sha256 $file1 | cut -d" " -f2) sha256_2=$(openssl sha256 $file2 | cut -d" " -f2) [ "$sha256_1" = "$sha256_2" ] || return 1 } _download_crypto_files(){ # see: https://docs.opnsense.org/manual/install.html#download-and-verification version=$1 # download multiple pubkeys from different server pubkey="OPNsense-${version}.pub" rm -f $pubkey $pubkey.sig $pubkey.alt1 $pubkey.alt2 url=$_HVE_OPNSENSE_URL/$version/$pubkey wget -q -c "${url}" # failing: wget -q -c "${url}.sig" rm -f /tmp/file.sig openssl base64 -d -in $pubkey.sig -out /tmp/file.sig openssl dgst -sha256 -verify $pubkey -signature /tmp/file.sig $pubkey || _fatal "Can't verify the signature of the public key" url_alt1=$_HVE_OPNSENSE_URL_ALT1/$version/$pubkey wget -q -c -O "$pubkey.alt1" "${url_alt1}" url_alt2=$_HVE_OPNSENSE_URL_ALT2/$version/$pubkey wget -q -c -O "$pubkey.alt2" "${url_alt2}" _compare_files_checksum $pubkey $pubkey.alt1 || _fatal "Fail to compare pubkeys" ; _compare_files_checksum $pubkey $pubkey.alt2 || _fatal "Fail to compare pubkeys" ; img_sig="OPNsense-${version}-nano-amd64.img.sig" sha256_name="OPNsense-${version}-checksums-amd64.sha256" sha256_sig=$sha256_name.sig [ ! -f "$img_sig" ] || rm $img_sig [ ! -f "$sha256_name" ] || rm $sha256_name [ ! -f "$sha256_sig" ] || rm $sha256_sig for file in $img_sig $sha256_name $sha256_sig; do url=$_HVE_OPNSENSE_URL/$version/$file wget -q -c "${url}" done rm -f /tmp/file.sig openssl base64 -d -in $sha256_sig -out /tmp/file.sig openssl dgst -sha256 -verify $pubkey -signature /tmp/file.sig $sha256_name || _fatal "Can't verify the signature of the checksum file" } _download(){ version=${1:-} [ "${version:-}" != "" ] || _fatal "Must pass a VERSION for downloading" _is_valid_version $version || _fatal "'$version' is not a valid version number" _download_img ${version} } _verify_image_checksum(){ version=$1 name="OPNsense-${version}-nano-amd64.img.bz2" sha256_file="OPNsense-${version}-checksums-amd64.sha256" sha256=$(cat $sha256_file | grep "$name" | cut -d'=' -f 2 | tr -s [:space:]) echo "$sha256 $name" | sha256sum -c || _fatal "Checksum failed for '$name'" } _verify_image_signature(){ version=$1 # download multiple pubkeys from different server pubkey="OPNsense-${version}.pub" img_name="OPNsense-${version}-nano-amd64.img" img_sig="${img_name}.sig" rm -f /tmp/file.sig openssl base64 -d -in $img_sig -out /tmp/file.sig openssl dgst -sha256 -verify $pubkey -signature /tmp/file.sig $img_name || _fatal "Can't verify image signature" } _check(){ version=${1:-} if [ "${version:-}" = "" ] ; then for version in $(_list_local_images); do >&2 echo check $version _download_crypto_files $version _verify_image_signature $version done else _download_crypto_files $version _verify_image_signature $version fi } _delete(){ version=${1:-} if [ -z "${version:-1}" ]; then _clear rm -f *.img else rm -f *$version*.img fi } _clear(){ rm -f *.pub *.sig *.bz2 *.alt1 *.alt2 *.sha256 } case "${1:-}" in "") _short_help ;; -h|--help) _short_help _extra_help ;; ls|list) if [ "${2:-}" == "" ]; then _list_local_images elif [ "${2:-}" == "--remote" ]; then _list_remote_images else _warn "Unknown option '$2'" fi ;; download) pushd "${_HVE_OPNSENSE_SRC_IMG}" _download "${2:-"$(_latest_version)"}" popd ;; delete) pushd "${_HVE_OPNSENSE_SRC_IMG}" _delete "${@:2}" popd ;; check) pushd "${_HVE_OPNSENSE_SRC_IMG}" _check "${@:2}" popd ;; show) ls $_HVE_OPNSENSE_SRC_IMG | cat ;; clear) pushd "${_HVE_OPNSENSE_SRC_IMG}" _clear "${@:2}" popd ;; *) _warn "Unknown COMMAND '$1'" exit 1 ;; esac ) [ "$0" != "${BASH_SOURCE}" ] || harmony-ve-opnsense-img-src "${@}"