#!/usr/bin/env -S execlineb -WS0 # SPDX-License-Identifier: EUPL-1.2+ # SPDX-FileCopyrightText: 2025 Alyssa Ross # SPDX-FileCopyrightText: 2025 Demi Marie Obenour export LC_ALL C export LANGUAGE C unshare -mr if { mount -toverlay -olowerdir=/run/virtiofs/virtiofs0/etc:/etc -- overlay /etc } backtick tmpdir { mktemp -d /tmp/sysupdate-XXXXXX } # Not a useless use of cat: if there are NUL bytes in the URL # busybox's awk might misbehave. backtick update_url { cat /etc/update-url } if { backtick sed_rhs { # Use awk to both validate the URL and to escape sed metacharacters. # Reject URLs with control characters, query parameters, or fragments. # They *cannot* work and so are rejected to produce better error messages. # # curl rejects control characters with "Malformed input to a URL function". # Fragment specifiers ("#") and query parameters ("?") break concatenating # /SHA256SUMS and /SHA256SUMS.sha256.asc onto the update URL. Also, it is # simpler to reject update URLs that contain whitespace than to try to # escape them. # # Backslash needs to be escaped once for systemd-sysupdate and again for sed. # Ampersand needs to be escaped once for sed. awk "BEGIN { update_url = ENVIRON[\"update_url\"]; if (update_url ~ /^[^\\001-\\040?#\\x7F]+$/) { # Use & to avoid extra escaping (16 or 32 backslashes!) # and a divergence between POSIX and GNU awk. gsub(/\\\\/, \"&&&&\", update_url); gsub(/&/, \"\\\\\\\\&\", update_url); print update_url; exit 0; } else { print ARGV[2] > \"/dev/stderr\"; exit 100; } }" -- $3 "Bad update URL from host: control characters, whitespace, query parameters, and fragment specifiers not allowed" } elglob -w -0 transfer_file_ /etc/vm-sysupdate.d/*.transfer forx -E transfer_file { $transfer_file_ } backtick target_basename { basename -- $transfer_file } multisubstitute { importas -iuS sed_rhs importas -iuS target_basename importas -iuS tmpdir define sed_input $transfer_file } redirfd -w 1 ${tmpdir}/${target_basename} sed -E -- "s#@UPDATE_URL@#${sed_rhs}#g" $sed_input } multisubstitute { importas -iuS update_url importas -iuS CURL_PATH importas -iuS SYSTEMD_SYSUPDATE_PATH importas -iuS tmpdir } if { forx -x 0 _ { 1 2 3 4 5 } if -nt { $SYSTEMD_SYSUPDATE_PATH --definitions=${tmpdir} update } foreground { sleep 1 } exit 1 } # [ and ] are allowed in update URLs so that IPv6 addresses work, but # they cause globbing in the curl command-line tool by default. Use --globoff # to disable this feature. if { $CURL_PATH -L --proto-redir =http,https --globoff -o /run/virtiofs/virtiofs0/updates/SHA256SUMS -- ${update_url}/SHA256SUMS } $CURL_PATH -L --proto-redir =http,https --globoff -o /run/virtiofs/virtiofs0/updates/SHA256SUMS.sha256.asc -- ${update_url}/SHA256SUMS.sha256.asc