3 ### Fetch an archive, and unpack it into a directory in a safe manner.
7 ## Parse the command line.
10 *) echo >&2 "usage: $0 DIR LABEL URL"; exit 1 ;;
12 dir=$1 label=$2 url=$3
17 curl -s -o tmp/"$label.tar.gz" "$url"
19 ## Check the archive for unpleasantness. The GNU and FreeBSD versions of
20 ## tar(1) do something vaguely sensible with `..' components in the pathnames
21 ## of archive members. (Specifically, FreeBSD simply ignores the affected
22 ## members; GNU strips leading components in a bizarre way.) But OpenBSD
23 ## gets a special security award for cheerily following the `..' components.
24 ## So we have to do this complicated laundering thing.
26 ## The archive ought to unpack everything into a single directory and not
27 ## contain anythig weird. So check. Actually, this won't catch newlines in
28 ## member names, so we'll have to be careful about those. The regular
29 ## expression insists that everything be in a single directory identified by
30 ## the LABEL, and that the rest of the name contains no two adjacent dots.
31 ## We use the LABEL as part of an ERE, so it ought not contain bad things.
33 tar tzf tmp/"$label.tar.gz" |
34 grep -Ev "^$label/([^.]+|\.[^.])*$" >&2
36 echo >&2 "$0: archive has bad member pathnames"
40 ## Unpack the archive now that we know it's safe.
41 (cd tmp; tar xzf "$label.tar.gz")
43 ## Replace any existing tree with the new one.