#!/bin/bash # Bash script to download current ubuntu releases # This script is not a remplacement for wget or any browser, this is just # a BASH V2+ sample script, that deal with binary files, through pipes, # play with ncurses and redirections # FEATURES: # - This script get a cd image at ubuntu's official mirror, # - Allow ``continue'' http transfert in case of interruption # - Display progress bar # - adjust progbar length when window width change, by trapping WINCH # - Adjust creation time of downloaded file # - Check sha1sum (with progress bar) after transfert # - Check validity of the signature of sha1sum file. # The essential of this script do the same as: # $ wget -c --post-data="$POSTMSG" --trust-server-names \ # http://www.ubuntu.com/start-download # But take the SHA1SUM and PGP(1) files at same server, than do the check, # that wget don't. # CONCERN PGP UBUNTU's KEY: # For Ubuntu users, the public key is on ubuntu's installation keyring. # For other users, the following command could get independant key: # $ mkdir -m 700 /tmp/ubuntu && cd $_ && \ # gpg --homedir $PWD --keyserver hkp://keyserver.ubuntu.com --recv-keys 0xFBB75451 # # (c) 2011 F-Hauri.ch # This script is licensed under terms of LGPL V3 # There is defaults values export RELEASE=latest export BITS=32 export DISTRO=desktop export KEYRING=/etc/apt/trusted.gpg # from https://help.ubuntu.com/community/VerifyIsoHowto export UBUNTUFINGERPRINT="C598 6B4F 1257 FFA8 6632 CBA7 4618 1433 FBB7 5451" # Some terminal commands (ncurses) export WIDTH=$(tput cols) # current useable width export DEOL=$(tput el) # blank line from cursor to end of line export CR=$(tput cr) # hope this is a carriage return export CUB3="$(tput cub 3)" # cursor back 3 chars export HIDCU="$(tput civis)" # hide cursor export SHOCU="$(tput cnorm)" # show cursor export BOLD="$(tput bold)" # enter bold mode export NORM="$(tput sgr0)" # clear all mode, return to normal fontface # A ``standard'' introduction for shell scripts die() { echo >&2 $@ ; exit 1 ; } usage() { cat < ALPHA] [<-r|--release> ALPHA] [<-b|--bits> NUM] \\ [<-k|--keyring> ALPHA] where distro must match one of ``desktop'',``alternate'' or ``server'' release is either latest or lts (long term support) bits stand for target processor's number of bits (32 or 64) by default, this script get: ubuntu-${DISTRO}-${RELEASE}-${BITS}bits keyring is where to look for public PGP keyring default: $KEYRING eof }; # Checking command line arguments while [ "${1:0:1}" == "-" ] ;do case ${1:1:99} in d|-distro ) shift echo $1 | grep -q '^\(desktop\|alternate\|server\)$' && DISTRO=$1 shift ;; r|-release ) shift echo $1 | grep -q '^\(latest\|lts\)$' && RELEASE=$1 shift ;; b|-bits ) shift echo $1 | grep -q '^\(32\|64\)$' && BITS=$1 shift ;; k|-keyring ) shift; [ -f "$1" ] && file "$1" | grep -q "GPG key.*ring" && KEYRING="$1" shift ;; h|-help ) shift; usage exit 0 ;; * ) usage die "Error: '$1' unknow arg." ;; esac done if [ "$1" ] ;then usage die "Error: '$1' not understand" fi # First: validating gpg and keyring env LANG=C gpg --no-default-keyring --keyring "$KEYRING" --fingerprint | grep -q "Key fingerprint = $UBUNTUFINGERPRINT" || die "Can't find Ubuntu's gpg public key in $KEYRING (or no gpg executable)." export POSTMSG=$(printf "distro=%s&release=%s&bits=%s" $DISTRO $RELEASE $BITS) # HTTP Protocol requier that lines ends whith CR+LF, so we # need to add one at each lines, but no eol on the last line # because FORM-DATAs don't have one, so 'tr' change LF to CR # so 'sed' can consider the whole block as one line, delete # only the last CR, than change all CR to CR+LF. # # the ``start-download'' url from ubuntu is a cgi wrapper that redirect # request to the right iso image and choose the best?? mirror for this # transfert. So we will recieve a HTTP Redirect Header, where the only # thing is the 'Location' of redirection. MIRROR=( $( tr <>$FILE touch -d "${FDATE%$'\r'}" $FILE # so, this is run IN the fork fi done & export CPID=$! NCPID=($(ps ho sid $CPID | xargs ps --sid | grep nc)) export NCPID trap "kill $NCPID $CPID;echo \"$SHOCU\";exit" 0 1 2 3 6 9 15 trap 'WIDTH=$(tput cols)' 28 # SIGWINCHG will change bar length echo -n "$HIDCU" sleep .2 while [ -d /proc/$CPID/fd ];do VALS=($( stat -c "stat=%s; scale=0; stat*($WIDTH-32)/$SIZE; scale=30; stat/1024^2; stat*100.0/$SIZE; data=stat-$START; elaps=$(cut -d\ -f1 ${FILE%-desktop-*}.sha1sums echo -n "$CUB3 and signature..." echo GET ${MIRROR[1]%/*}/SHA1SUMS.gpg HTTP/1.0$'\r\nHost:' $MIRROR$'\r\n\r' | nc -q -1 $MIRROR 80 | sed -e 1,/^\\r$/d >${FILE%-desktop-*}.sha1sums.sig echo "$CUB3.$DEOL" echo "Validating '$FILE' by SHA1SUM verification..." SHA1SUM=($(grep $FILE ${FILE%-desktop-*}.sha1sums)) SHA1VER=($( STARTED=($(/dev/tty;exit" 0 1 2 3 6 9 15 trap 'WIDTH=$(tput cols)' 28 echo -n "$HIDCU" >/dev/tty sleep .2 while [ -d /proc/$CPID/fd ];do VALS=($( sed -ne "s/pos:[ \t]\([0-9]*\)$/s=\1;\ t=$( cut -d\ -f1 /dev/tty sleep .5 done echo "$SHOCU" >/dev/tty trap "" 0 1 2 3 6 9 15 28 )) if [ "$SHA1VER" == "$SHA1SUM" ] ;then echo -e "$SHA1VER ==\n$SHA1SUM,$BOLD All right!$NORM" else echo -e "$SHA1VER !=\n$SHA1SUM,$BOLD Something wrong!$NORM" fi echo "Verifying SHA1SUM file's signature..." eval $( env LANG=C gpg --no-default-keyring --keyring "$KEYRING" \ -v ${FILE%-desktop-*}.sha1sums.sig 2>&1 | sed -ne ' s/^.*Signature made \(.*\) using \([^ ]*\) key ID \([A-F0-9]*\)/\ VALS=(\3 \2 "\1"/p; s/^gpg: \(.*\) signature from "\(.*\)"/\1 "\2")/p' ) if [ "$VALS" ] ;then export FSEC=$(date -r $FILE +%s) export SSEC=$(date -d "${VALS[2]}" +%s) printf "Signature is '%s%s%s'! \n" "$BOLD" "${VALS[3]}" "$NORM" printf "Made: %s\n" "${VALS[2]}" printf "\t(%s seconds after %s)\n" $((SSEC-FSEC)) $FILE printf "From: %s (%s ID:%s)\n" "${VALS[4]}" "${VALS[1]}" "${VALS[0]}" else echo "WARNING: signature file may not be verified." echo "Maybe you need to use other keyring than $KEYRING (try '-k' option)" fi