1#!/bin/ksh 2# 3# $OpenBSD: sysupgrade.sh,v 1.12 2019/05/03 15:18:14 florian 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 25 26ARCH=$(uname -m) 27SETSDIR=/home/_sysupgrade 28 29ug_err() 30{ 31 echo "${1}" 1>&2 && return ${2:-1} 32} 33 34usage() 35{ 36 ug_err "usage: ${0##*/} [-fn] [-r | -s] [installurl]" 37} 38 39unpriv() 40{ 41 local _file=$2 _user=_syspatch 42 43 if [[ $1 == -f && -n ${_file} ]]; then 44 >${_file} 45 chown "${_user}" "${_file}" 46 shift 2 47 fi 48 (($# >= 1)) 49 50 eval su -s /bin/sh ${_user} -c "'$@'" 51} 52 53# Remove all occurrences of first argument from list formed by the remaining 54# arguments. 55rmel() { 56 local _a=$1 _b _c 57 58 shift 59 for _b; do 60 [[ $_a != "$_b" ]] && _c="${_c:+$_c }$_b" 61 done 62 echo -n "$_c" 63} 64 65RELEASE=false 66SNAP=false 67FORCE=false 68REBOOT=true 69 70while getopts fnrs arg; do 71 case ${arg} in 72 f) FORCE=true;; 73 n) REBOOT=false;; 74 r) RELEASE=true;; 75 s) SNAP=true;; 76 *) usage;; 77 esac 78done 79 80if $RELEASE && $SNAP; then 81 usage 82fi 83 84set -A _KERNV -- $(sysctl -n kern.version | 85 sed 's/^OpenBSD \([0-9]\)\.\([0-9]\)\([^ ]*\).*/\1.\2 \3/;q') 86 87shift $(( OPTIND -1 )) 88 89case $# in 900) MIRROR=$(sed 's/#.*//;/^$/d' /etc/installurl) 2>/dev/null || 91 MIRROR=https://cdn.openbsd.org/pub/OpenBSD 92 ;; 931) MIRROR=$1 94 ;; 95*) usage 96esac 97 98if ! $RELEASE && [[ ${#_KERNV[*]} == 2 ]]; then 99 SNAP=true 100fi 101 102NEXT_VERSION=$(echo ${_KERNV[0]} + 0.1 | bc) 103 104if $SNAP; then 105 URL=${MIRROR}/snapshots/${ARCH}/ 106else 107 URL=${MIRROR}/${NEXT_VERSION}/${ARCH}/ 108fi 109 110if [[ -e ${SETSDIR} ]]; then 111 eval $(stat -s ${SETSDIR}) 112 [[ $st_uid -eq 0 ]] || 113 ug_err "${SETSDIR} needs to be owned by root:wheel" 114 [[ $st_gid -eq 0 ]] || 115 ug_err "${SETSDIR} needs to be owned by root:wheel" 116 [[ $st_mode -eq 040755 ]] || 117 ug_err "${SETSDIR} is not a directory with permissions 0755" 118else 119 mkdir -p ${SETSDIR} 120fi 121 122cd ${SETSDIR} 123 124unpriv -f SHA256.sig ftp -Vmo SHA256.sig ${URL}SHA256.sig 125 126if cmp -s /var/db/installed.SHA256.sig SHA256.sig && ! $FORCE; then 127 ug_err "Already on latest snapshot." 128fi 129 130_KEY=openbsd-${_KERNV[0]%.*}${_KERNV[0]#*.}-base.pub 131_NEXTKEY=openbsd-${NEXT_VERSION%.*}${NEXT_VERSION#*.}-base.pub 132 133read _LINE <SHA256.sig 134case ${_LINE} in 135*\ ${_KEY}) SIGNIFY_KEY=/etc/signify/${_KEY} ;; 136*\ ${_NEXTKEY}) SIGNIFY_KEY=/etc/signify/${_NEXTKEY} ;; 137*) ug_err "invalid signing key" ;; 138esac 139 140[[ -f ${SIGNIFY_KEY} ]] || ug_err "cannot find ${SIGNIFY_KEY}" 141 142unpriv -f SHA256 signify -Veq -p "${SIGNIFY_KEY}" -x SHA256.sig -m SHA256 143 144# INSTALL.*, bsd*, *.tgz 145SETS=$(sed -n -e 's/^SHA256 (\(.*\)) .*/\1/' \ 146 -e '/^INSTALL\./p;/^bsd/p;/\.tgz$/p' SHA256) 147 148OLD_FILES=$(ls) 149OLD_FILES=$(rmel SHA256 $OLD_FILES) 150OLD_FILES=$(rmel SHA256.sig $OLD_FILES) 151DL=$SETS 152 153for f in $SETS; do 154 if cksum -C SHA256 $f >/dev/null 2>&1; then 155 DL=$(rmel $f ${DL}) 156 OLD_FILES=$(rmel $f ${OLD_FILES}) 157 fi 158done 159 160[[ -n ${OLD_FILES} ]] && rm ${OLD_FILES} 161for f in ${DL}; do 162 unpriv -f $f ftp -Vmo ${f} ${URL}${f} 163done 164 165# re-check signature after downloads 166echo Verifying sets. 167unpriv signify -qC -p "${SIGNIFY_KEY}" -x SHA256.sig ${SETS} 168 169cp bsd.rd /nbsd.upgrade 170ln -f /nbsd.upgrade /bsd.upgrade 171rm /nbsd.upgrade 172 173if ${REBOOT}; then 174 echo Upgrading. 175 exec reboot 176else 177 echo "Will upgrade on next reboot" 178fi 179