1#!/bin/ksh 2# 3# $OpenBSD: sysupgrade.sh,v 1.39 2020/07/04 18:30:46 ajacoutot Exp $ 4# 5# Copyright (c) 1997-2015 Todd Miller, Theo de Raadt, Ken Westerback 6# Copyright (c) 2015 Robert Peichaer <rpe@openbsd.org> 7# Copyright (c) 2016, 2017 Antoine Jacoutot <ajacoutot@openbsd.org> 8# Copyright (c) 2019 Christian Weisgerber <naddy@openbsd.org> 9# Copyright (c) 2019 Florian Obser <florian@openbsd.org> 10# 11# Permission to use, copy, modify, and distribute this software for any 12# purpose with or without fee is hereby granted, provided that the above 13# copyright notice and this permission notice appear in all copies. 14# 15# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 16# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 18# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 21# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 23set -e 24umask 0022 25export PATH=/usr/bin:/bin:/usr/sbin:/sbin 26 27ARCH=$(uname -m) 28SETSDIR=/home/_sysupgrade 29 30ug_err() 31{ 32 echo "${1}" 1>&2 && return ${2:-1} 33} 34 35usage() 36{ 37 ug_err "usage: ${0##*/} [-fkn] [-r | -s] [installurl]" 38} 39 40unpriv() 41{ 42 local _file _rc=0 _user=_syspatch 43 44 if [[ $1 == -f ]]; then 45 _file=$2 46 shift 2 47 fi 48 if [[ -n ${_file} ]]; then 49 >${_file} 50 chown "${_user}" "${_file}" 51 fi 52 (($# >= 1)) 53 54 eval su -s /bin/sh ${_user} -c "'$@'" || _rc=$? 55 56 [[ -n ${_file} ]] && chown root "${_file}" 57 58 return ${_rc} 59} 60 61# Remove all occurrences of first argument from list formed by the remaining 62# arguments. 63rmel() { 64 local _a=$1 _b _c 65 66 shift 67 for _b; do 68 [[ $_a != "$_b" ]] && _c="${_c:+$_c }$_b" 69 done 70 echo -n "$_c" 71} 72 73RELEASE=false 74SNAP=false 75FORCE=false 76KEEP=false 77REBOOT=true 78 79while getopts fknrs arg; do 80 case ${arg} in 81 f) FORCE=true;; 82 k) KEEP=true;; 83 n) REBOOT=false;; 84 r) RELEASE=true;; 85 s) SNAP=true;; 86 *) usage;; 87 esac 88done 89 90(($(id -u) != 0)) && ug_err "${0##*/}: need root privileges" 91 92if $RELEASE && $SNAP; then 93 usage 94fi 95 96set -A _KERNV -- $(sysctl -n kern.version | 97 sed 's/^OpenBSD \([1-9][0-9]*\.[0-9]\)\([^ ]*\).*/\1 \2/;q') 98 99shift $(( OPTIND -1 )) 100 101case $# in 1020) MIRROR=$(sed 's/#.*//;/^$/d' /etc/installurl) 2>/dev/null || 103 MIRROR=https://cdn.openbsd.org/pub/OpenBSD 104 ;; 1051) MIRROR=$1 106 ;; 107*) usage 108esac 109 110if ! $RELEASE && [[ ${#_KERNV[*]} == 2 ]]; then 111 SNAP=true 112fi 113 114if $RELEASE && [[ ${_KERNV[1]} == '-beta' ]]; then 115 NEXT_VERSION=${_KERNV[0]} 116else 117 NEXT_VERSION=$(echo ${_KERNV[0]} + 0.1 | bc) 118fi 119 120if $SNAP; then 121 URL=${MIRROR}/snapshots/${ARCH}/ 122else 123 URL=${MIRROR}/${NEXT_VERSION}/${ARCH}/ 124fi 125 126install -d -o 0 -g 0 -m 0755 ${SETSDIR} 127cd ${SETSDIR} 128 129echo "Fetching from ${URL}" 130unpriv -f SHA256.sig ftp -N sysupgrade -Vmo SHA256.sig ${URL}SHA256.sig 131 132_KEY=openbsd-${_KERNV[0]%.*}${_KERNV[0]#*.}-base.pub 133_NEXTKEY=openbsd-${NEXT_VERSION%.*}${NEXT_VERSION#*.}-base.pub 134 135read _LINE <SHA256.sig 136case ${_LINE} in 137*\ ${_KEY}) SIGNIFY_KEY=/etc/signify/${_KEY} ;; 138*\ ${_NEXTKEY}) SIGNIFY_KEY=/etc/signify/${_NEXTKEY} ;; 139*) ug_err "invalid signing key" ;; 140esac 141 142[[ -f ${SIGNIFY_KEY} ]] || ug_err "cannot find ${SIGNIFY_KEY}" 143 144unpriv -f SHA256 signify -Ve -p "${SIGNIFY_KEY}" -x SHA256.sig -m SHA256 145rm SHA256.sig 146 147if cmp -s /var/db/installed.SHA256 SHA256 && ! $FORCE; then 148 echo "Already on latest snapshot." 149 exit 0 150fi 151 152# INSTALL.*, bsd*, *.tgz 153SETS=$(sed -n -e 's/^SHA256 (\(.*\)) .*/\1/' \ 154 -e '/^INSTALL\./p;/^bsd/p;/\.tgz$/p' SHA256) 155 156OLD_FILES=$(ls) 157OLD_FILES=$(rmel SHA256 $OLD_FILES) 158DL=$SETS 159 160[[ -n ${OLD_FILES} ]] && echo Verifying old sets. 161for f in ${OLD_FILES}; do 162 if cksum -C SHA256 $f >/dev/null 2>&1; then 163 DL=$(rmel $f ${DL}) 164 OLD_FILES=$(rmel $f ${OLD_FILES}) 165 fi 166done 167 168[[ -n ${OLD_FILES} ]] && rm ${OLD_FILES} 169for f in ${DL}; do 170 unpriv -f $f ftp -N sysupgrade -Vmo ${f} ${URL}${f} 171done 172 173if [[ -n ${DL} ]]; then 174 echo Verifying sets. 175 unpriv cksum -qC SHA256 ${DL} 176fi 177 178cat <<__EOT >/auto_upgrade.conf 179Location of sets = disk 180Pathname to the sets = /home/_sysupgrade/ 181Set name(s) = done 182Directory does not contain SHA256.sig. Continue without verification = yes 183__EOT 184 185if ! ${KEEP}; then 186 CLEAN=$(echo SHA256 ${SETS} | sed -e 's/ /,/g') 187 cat <<__EOT > /etc/rc.firsttime 188rm -f /home/_sysupgrade/{${CLEAN}} 189__EOT 190fi 191 192echo Fetching updated firmware. 193fw_update || echo "Warning: firmware not updated." 194 195install -F -m 700 bsd.rd /bsd.upgrade 196logger -t sysupgrade -p kern.info "installed new /bsd.upgrade. Old kernel version: $(sysctl -n kern.version)" 197sync 198 199if ${REBOOT}; then 200 echo Upgrading. 201 exec reboot 202else 203 echo "Will upgrade on next reboot" 204fi 205