1#!/bin/sh
2# Get the online version of the GnuPG software version database
3# Copyright (C) 2014  Werner Koch
4#
5# This file is free software; as a special exception the author gives
6# unlimited permission to copy and/or distribute it, with or without
7# modifications, as long as this notice is preserved.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
11# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13# The URL of the file to retrieve.
14urlbase="https://versions.gnupg.org/"
15
16WGET=wget
17GPGV=gpgv
18
19srcdir=$(dirname "$0")
20distsigkey="$srcdir/../g10/distsigkey.gpg"
21
22# Convert a 3 part version number it a numeric value.
23cvtver () {
24  awk 'NR==1 {split($NF,A,".");X=1000000*A[1]+1000*A[2]+A[3];print X;exit 0}'
25}
26
27# Prints usage information.
28usage()
29{
30    cat <<EOF
31Usage: $(basename $0) [OPTIONS]
32Get the online version of the GnuPG software version database
33Options:
34    --skip-download    Assume download has already been done.
35    --skip-verify      Do not check signatures
36    --skip-selfcheck   Do not check GnuPG version
37    --find-sha1sum     Print the name of the sha1sum utility
38    --find-sha256sum   Print the name of the sha256sum utility
39    --help             Print this help.
40EOF
41    exit $1
42}
43
44#
45# Parse options
46#
47skip_download=no
48skip_verify=no
49skip_selfcheck=no
50find_sha1sum=no
51find_sha256sum=no
52while test $# -gt 0; do
53    case "$1" in
54	# Set up `optarg'.
55	--*=*)
56	    optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
57	    ;;
58	*)
59	    optarg=""
60	    ;;
61    esac
62
63    case $1 in
64        --help|-h)
65	    usage 0
66	    ;;
67        --skip-download)
68            skip_download=yes
69            ;;
70        --skip-verify)
71            skip_verify=yes
72            ;;
73        --skip-selfcheck)
74            skip_selfcheck=yes
75            ;;
76        --find-sha1sum)
77            find_sha1sum=yes
78            ;;
79        --find-sha256sum)
80            find_sha256sum=yes
81            ;;
82	*)
83	    usage 1 1>&2
84	    ;;
85    esac
86    shift
87done
88
89# Mac OSX has only a shasum and not sha1sum
90if [ ${find_sha1sum} = yes ]; then
91    for i in sha1sum shasum ; do
92       tmp=$($i </dev/null 2>/dev/null | cut -d ' ' -f1)
93       if [ x"$tmp" = x"da39a3ee5e6b4b0d3255bfef95601890afd80709" ]; then
94           echo "$i"
95           exit 0
96       fi
97    done
98    echo "false"
99    exit 1
100fi
101
102# Mac OSX has only a shasum and not sha256sum
103if [ ${find_sha256sum} = yes ]; then
104    for i in 'shasum -a 256' sha256sum ; do
105       tmp=$($i </dev/null 2>/dev/null | cut -d ' ' -f1)
106       tmp2="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
107       if [ x"$tmp" = x"$tmp2" ]; then
108           echo "$i"
109           exit 0
110       fi
111    done
112    echo "false"
113    exit 1
114fi
115
116
117# Get GnuPG version from VERSION file.  For a GIT checkout this means
118# that ./autogen.sh must have been run first.  For a regular tarball
119# VERSION is always available.
120if [ ! -f "$srcdir/../VERSION" ]; then
121    echo "VERSION file missing - run autogen.sh first." >&2
122    exit 1
123fi
124version=$(cat "$srcdir/../VERSION")
125version_num=$(echo "$version" | cvtver)
126
127if [ $skip_verify = no ]; then
128  if ! $GPGV --version >/dev/null 2>/dev/null ; then
129    echo "command \"gpgv\" is not installed" >&2
130    echo "(please install an older version of GnuPG)" >&2
131    exit 1
132  fi
133fi
134
135#
136# Download the list and verify.
137#
138if [ $skip_download = yes ]; then
139  if [ ! -f swdb.lst ]; then
140      echo "swdb.lst is missing." >&2
141      exit 1
142  fi
143  if [ $skip_verify = no ]; then
144    if [ ! -f swdb.lst.sig ]; then
145      echo "swdb.lst.sig is missing." >&2
146      exit 1
147    fi
148  fi
149else
150  if ! $WGET --version >/dev/null 2>/dev/null ; then
151      echo "command \"wget\" is not installed" >&2
152      exit 1
153  fi
154
155  if ! $WGET -q -O swdb.lst "$urlbase/swdb.lst" ; then
156      echo "download of swdb.lst failed." >&2
157      exit 1
158  fi
159  if [ $skip_verify = no ]; then
160    if ! $WGET -q -O swdb.lst.sig "$urlbase/swdb.lst.sig" ; then
161      echo "download of swdb.lst.sig failed." >&2
162      exit 1
163    fi
164  fi
165fi
166if [ $skip_verify = no ]; then
167  if ! $GPGV --keyring "$distsigkey" swdb.lst.sig swdb.lst; then
168    echo "list of software versions is not valid!" >&2
169    exit 1
170 fi
171fi
172
173#
174# Check that the online version of GnuPG is not less than this version
175# to help detect rollback attacks.
176#
177if [ $skip_selfcheck = no ]; then
178  gnupg_ver=$(awk '$1=="gnupg24_ver" {print $2;exit}' swdb.lst)
179  if [ -z "$gnupg_ver" ]; then
180      echo "GnuPG 2.4 version info missing in swdb.lst!" >&2
181      exit 1
182  fi
183  gnupg_ver_num=$(echo "$gnupg_ver" | cvtver)
184  if [ $(( $gnupg_ver_num >= $version_num )) = 0 ]; then
185      echo "GnuPG version in swdb.lst is less than this version!" >&2
186      echo "  This version: $version" >&2
187      echo "  SWDB version: $gnupg_ver" >&2
188      exit 1
189  fi
190fi
191