Browse Source

check for keys on startup, and test for failed d/l's.

Make sure that the necessary keys are present before starting.

Make sure that a failed download will be properly detected and not
leave behind invalid files.
main
John-Mark Gurney 6 years ago
parent
commit
dcecd2d3e5
1 changed files with 138 additions and 25 deletions
  1. +138
    -25
      snapaid.sh

+ 138
- 25
snapaid.sh View File

@@ -1,6 +1,8 @@
#!/bin/sh - #!/bin/sh -


STOREDIR="$HOME/.snapaid" STOREDIR="$HOME/.snapaid"
KEYS="0x524F0C37A0B946A3"
KEY_URLS='https://svnweb.freebsd.org/doc/head/share/pgpkeys/gjb.key?view=co'


setdefaults() { setdefaults() {
GPG=$(which gpg2) GPG=$(which gpg2)
@@ -27,9 +29,9 @@ fi
#wget: #wget:
# -N for timestamps # -N for timestamps
# --backups=x for backing up # --backups=x for backing up
completeurl="https://www.funkthat.com/~jmg/FreeBSD-snap/snapshot.complete.idx.xz"
currenturl="https://www.funkthat.com/~jmg/FreeBSD-snap/snapshot.idx.xz"
hostname=people.FreeBSD.org
completeurl="https://${hostname}/~jmg/FreeBSD-snap/snapshot.complete.idx.xz"
currenturl="https://${hostname}/~jmg/FreeBSD-snap/snapshot.idx.xz"


# type release arch platform date svnrev xxx fname url mid # type release arch platform date svnrev xxx fname url mid
# 1 2 3 4 5 6 7 8 9 10 # 1 2 3 4 5 6 7 8 9 10
@@ -55,9 +57,31 @@ gpg_first_fails() {
return 1 return 1
} }


# When first arg is --, just touch the file to fake a bad d/l
bad_file_dl() {
if [ x"$1" = x"--" ]; then
touch $(basename "$2")
else
$WGET_orig "$@"
fi
}

# Make sure that the storage directory is present # Make sure that the storage directory is present
mkstore() { mkstore() {
mkdir "$STOREDIR" 2>/dev/null || : mkdir "$STOREDIR" 2>/dev/null || :
if ! [ -x "$STOREDIR" -a -w "$STOREDIR" -a -d "$STOREDIR" ]; then
echo "$STOREDIR is not a writable directory."
fi
}

check_keys() {
for i in $KEYS; do
if ! $GPG --list-keys "$i" >/dev/null 2>&1; then
return 1
fi
done

return 0
} }


# Given a message id, get the raw body and store it. # Given a message id, get the raw body and store it.
@@ -72,6 +96,13 @@ get_raw() {
# get the location, it's a database lookup # get the location, it's a database lookup
loc=$($WGET --max-redirect=0 --method=HEAD -S -o - -O - 'https://docs.freebsd.org/cgi/mid.cgi?'"$mid" 2>/dev/null | awk 'tolower($1) == "location:" { print $2; exit }') loc=$($WGET --max-redirect=0 --method=HEAD -S -o - -O - 'https://docs.freebsd.org/cgi/mid.cgi?'"$mid" 2>/dev/null | awk 'tolower($1) == "location:" { print $2; exit }')


# Some emails are sent to both -current and -snapshot,
# we can't handle them for now
# such as 20160529215940.GA11785@FreeBSD.org
if [ x"$loc" = x"" ]; then
return 1
fi

# if it's relative, add https # if it's relative, add https
if [ x"$loc" != x"${loc#//}" ]; then if [ x"$loc" != x"${loc#//}" ]; then
# add https # add https
@@ -118,7 +149,9 @@ get_raw() {
fetch() { fetch() {
mkstore mkstore


(cd "$STOREDIR" && $WGET -N "$1" >/dev/null 2>&1)
if ! (cd "$STOREDIR" && $WGET -N "$1" >/dev/null 2>&1); then
return 1
fi
} }


getvermid() { getvermid() {
@@ -184,10 +217,52 @@ EOF
echo "$hash $2" | $SHASUM -a "${algo#SHA}" -c - echo "$hash $2" | $SHASUM -a "${algo#SHA}" -c -
} }


dlverify() {
fname="$8"
dlurl="$9"
vermid="${10}"

# verify snap email
if ! get_raw "$vermid"; then
echo "Unable to fetch/verify snapshot email for: $fname"
return 1
fi

# fetch link
$WGET -- "$dlurl"

if ! verifyfile "$vermid" "$fname"; then
echo 'Removing bad file.'
rm "$fname"
return 1
fi
}

if ! check_keys; then
echo 'Necessary keys have not been imported into key ring.'
echo "Please obtain they following keyid(s):"
echo $KEYS
echo ""
echo "The keys may be obtained from the following URLs:"
for i in $KEY_URLS; do
echo "$i"
done
echo ""
echo "and imported into GPG w/ the --import option."
echo ""
echo "For extra security, additional verification should be done, such"
echo "as manually verifying finger prints."

exit 3
fi

if [ x"$1" = x"verify" ]; then if [ x"$1" = x"verify" ]; then
shift shift


fetch "$completeurl"
if ! fetch "$completeurl"; then
echo Failed to fetch the complete index.
exit 1
fi


for i in "$@"; do for i in "$@"; do
vermid=$(getvermid "$i") vermid=$(getvermid "$i")
@@ -196,12 +271,12 @@ if [ x"$1" = x"verify" ]; then
continue continue
fi fi


get_raw "$vermid"
if ! verifygpg "$vermid".raw; then
echo "Unable to verify: $i"
if ! get_raw "$vermid"; then
echo "Unable to fetch snapshot email for: $i"
continue
fi fi


verifyfile "$verurl" "$i"
verifyfile "$vermid" "$i"
done done
elif [ x"$1" = x"find" ]; then elif [ x"$1" = x"find" ]; then
fetch "$currenturl" fetch "$currenturl"
@@ -235,7 +310,7 @@ BEGIN {
} }
' selection ' selection


read -p 'Select image, enter search term, reset, or quit: ' sel
read -p 'Select image #, enter search term, reset, or quit: ' sel
if [ x"$sel" = x"reset" ]; then if [ x"$sel" = x"reset" ]; then
xzcat "$STOREDIR"/snapshot.idx.xz | sort -r -k 5 > selection; xzcat "$STOREDIR"/snapshot.idx.xz | sort -r -k 5 > selection;
continue continue
@@ -249,7 +324,6 @@ BEGIN {
fi fi


if [ "$sel" -ge 1 -a "$sel" -le "$cnt" ] 2>/dev/null; then if [ "$sel" -ge 1 -a "$sel" -le "$cnt" ] 2>/dev/null; then
echo selected image $sel
echo $(tail -n +"$sel" selection | head -n 1) > sel echo $(tail -n +"$sel" selection | head -n 1) > sel
break break
else else
@@ -269,25 +343,62 @@ BEGIN {
exit 0 exit 0
fi fi


echo $sel
fname=$(cut -f 8 -d ' ' "$tmpdir"/sel)
dlurl=$(cut -f 9 -d ' ' "$tmpdir"/sel)
verurl=$(cut -f 10 -d ' ' "$tmpdir"/sel)
set -- ${sel}


# fetch link
$WGET -- "$dlurl"
echo selected image "$8"

dlverify ${sel}
elif [ x"$1" = x"test" ]; then
# Setup test environment
tmpdir=$(mktemp -d -t snapaid)

trap "rm -rf $tmpdir" 0

cd "$tmpdir"

STOREDIR="$tmpdir"/snapaid

# Make sure that the check keys function works.
echo 'Testing check_keys works...'

# Prime the custom keyring
GPG="gpg2 --no-default-keyring --keyring pubring.gpg"
for i in $KEY_URLS; do
$WGET -O - -- "$i" 2>/dev/null | $GPG --import 2>/dev/null
done


# verify image
fetch "$verurl"
if ! verifygpg "$verurl"; then
echo "Unable to verify: $fname"
if ! check_keys; then
echo failed
exit 1
fi fi


if ! verifyfile "$verurl" "$fname"; then
rm "$fname"
KEYS_orig="$KEYS"
KEYS="0x1384923867573928" # bogus key

if check_keys; then
echo failed
exit 1
fi fi
elif [ x"$1" = x"test" ]; then
# Run various tests

echo passed

# Test a bad download fails
echo 'Testing dlverify...'
WGET_orig="$WGET"
WGET=bad_file_dl

# if dlverify is successsful, then it's a failure
if dlverify iso 13.0-CURRENT sparc64 xxx 20181026 r339752 bootonly FreeBSD-13.0-CURRENT-sparc64-20181026-r339752-bootonly.iso.xz https://download.freebsd.org/ftp/snapshots/ISO-IMAGES/13.0/FreeBSD-13.0-CURRENT-sparc64-20181026-r339752-bootonly.iso.xz 20181026184443.GD75350@FreeBSD.org; then
echo 'failed'
exit 1
fi

# Make sure that a bad d/l was not left behind
if [ -e FreeBSD-13.0-CURRENT-sparc64-20181026-r339752-bootonly.iso.xz ]; then
echo failed
exit 1
fi
echo passed


# Test getting the raw file # Test getting the raw file
echo 'Testing get_raw success...' echo 'Testing get_raw success...'
@@ -333,6 +444,8 @@ elif [ x"$1" = x"test" ]; then
echo passed echo passed


setdefaults setdefaults

echo tests completed!!!
else else
echo "Unknown verb: $1" echo "Unknown verb: $1"
echo "Usage:" echo "Usage:"


Loading…
Cancel
Save