From d8b9a3d7c76d460f9735bb9229781cf4d5a8e6ed Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sat, 13 Aug 2011 20:02:26 +0100 Subject: [PATCH] fetch-unpack-archive: New program for the mix. --- fetch-unpack-archive | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100755 fetch-unpack-archive diff --git a/fetch-unpack-archive b/fetch-unpack-archive new file mode 100755 index 0000000..e9b3d3e --- /dev/null +++ b/fetch-unpack-archive @@ -0,0 +1,46 @@ +#! /bin/sh +### +### Fetch an archive, and unpack it into a directory in a safe manner. + +set -e + +## Parse the command line. +case $# in + 3) ;; + *) echo >&2 "usage: $0 DIR LABEL URL"; exit 1 ;; +esac +dir=$1 label=$2 url=$3 +cd "$dir" + +## Fetch the archive. +rm -rf tmp; mkdir tmp +curl -s -o tmp/"$label.tar.gz" "$url" + +## Check the archive for unpleasantness. The GNU and FreeBSD versions of +## tar(1) do something vaguely sensible with `..' components in the pathnames +## of archive members. (Specifically, FreeBSD simply ignores the affected +## members; GNU strips leading components in a bizarre way.) But OpenBSD +## gets a special security award for cheerily following the `..' components. +## So we have to do this complicated laundering thing. +## +## The archive ought to unpack everything into a single directory and not +## contain anythig weird. So check. Actually, this won't catch newlines in +## member names, so we'll have to be careful about those. The regular +## expression insists that everything be in a single directory identified by +## the LABEL, and that the rest of the name contains no two adjacent dots. +## We use the LABEL as part of an ERE, so it ought not contain bad things. +if + tar tzf tmp/"$label.tar.gz" | + grep -Ev "^$label/([^.]+|\.[^.])*$" >&2 +then + echo >&2 "$0: archive has bad member pathnames" + exit 1 +fi + +## Unpack the archive now that we know it's safe. +(cd tmp; tar xzf "$label.tar.gz") + +## Replace any existing tree with the new one. +rm -rf "$label" +mv tmp/"$label" . +rm -rf tmp -- 2.11.0