source: mod_gnutls/test/runtests @ c3ad933

debian/masterdebian/stretch-backportsupstream
Last change on this file since c3ad933 was 94cb972, checked in by Thomas Klute <thomas2.klute@…>, 4 years ago

Minimal OCSP stapling implementation using externally provided response

Works if the configured file contains a valid and current OCSP
response. Note that the module does not yet check those conditions,
the file is just read and forwarded to GnuTLS.

  • Property mode set to 100755
File size: 6.9 KB
Line 
1#!/bin/bash
2
3# Authors:
4# Daniel Kahn Gillmor <dkg@fifthhorseman.net>
5# Thomas Klute <thomas2.klute@uni-dortmund.de>
6
7set -e
8. ${srcdir}/common.bash
9netns_reexec ${@}
10
11testid="${1##t-}"
12
13if [ -z "$testid" ] ; then
14    echo -e "No test case selected.\nUsage: ${0} t-N" >&2
15    exit 1
16else
17    testid=${srcdir}/tests/"$(printf "%02d" "$testid")"_*
18fi
19
20BADVARS=0
21for v in APACHE2 TEST_HOST TEST_PORT TEST_QUERY_DELAY TEST_MSVA_WAIT \
22                 MSVA_PORT; do
23    if [ ! -v "$v" ]; then
24        printf "You need to set the %s environment variable\n" "$v" >&2
25        BADVARS=1
26    fi
27done
28
29if [ 0 != "$BADVARS" ]; then
30    exit 1
31fi
32
33# write script file and line to stderr on error
34function pinpoint_error()
35{
36    echo "${1} failed at line ${2}!" >&2
37}
38trap 'pinpoint_error ${BASH_SOURCE} ${LINENO}' ERR
39
40function stop_msva()
41{
42    kill_by_pidfile "${msva_pidfile}"
43    unset msva_pidfile
44}
45
46# Compare expected/actual outputs, filtering out headers from actual
47# output that are expected to change between runs or builds (currently
48# "Date" and "Server"). The headers must be excluded in the expected
49# output.
50#
51# Parameters:
52# $1: path to expected output
53# $2: path to actual output
54# $3: additional options for diff (optional)
55function diff_output_filter_headers()
56{
57    local expected="$1"
58    local actual="$2"
59    diff $3 -u "${expected}" <( cat "${actual}" | \
60        grep -v -P '^Date:\s.*GMT\s?$' | \
61        grep -v -P '^Server:\sApache'  | \
62        tail -n "$(wc -l < ${expected})" )
63}
64
65# Run a command, storing its PID in the given file
66# Usage: run_with_pidfile PIDFILE COMMAND [ARGS]
67function run_with_pidfile()
68{
69    local pidfile=$1
70    local cmd=$2
71    shift 2
72    echo $BASHPID >${pidfile}
73    exec ${cmd} $*
74}
75
76# Kills the process with the PID contained in a given file, then
77# deletes the file.
78# Usage: kill_by_pidfile PIDFILE
79function kill_by_pidfile()
80{
81    local pidfile="${1}"
82    # In some testcases with expected failure, gnutls-cli sometimes
83    # failed before the subshell in front of the pipe (see gnutls-cli
84    # call below) got so far as to write the PID, much less exec
85    # sleep. So we need to check if there actually is anything to
86    # kill.
87    if [ -n "${pidfile}" ]; then
88        local pid=$(cat "${pidfile}")
89        if [ -n "${pid}" ] && ps -p "${pid}"; then
90            kill "${pid}"
91        fi
92        rm "${pidfile}"
93    fi
94}
95
96function apache_down_err() {
97    printf "FAILURE: %s\n" "$TEST_NAME"
98    ${APACHE2} -f "${t}/apache.conf" -k stop || true
99    if [ -e output ]; then
100        printf "\ngnutls-cli outputs:\n"
101        diff_output_filter_headers "output" "$output" || true
102    fi
103
104    if [ -n "${sleep_pidfile}" ]; then
105        kill_by_pidfile "${sleep_pidfile}"
106    fi
107
108    local errlog="logs/${TEST_NAME}.error.log"
109    if [ -r "${errlog}" ]; then
110        printf "\nApache error logs:\n"
111        tail "${errlog}"
112    fi
113
114    if [ -n "${USE_MSVA}" ]; then
115        stop_msva
116    fi
117}
118
119if [ -n "${USE_MSVA}" ]; then
120    msva_pidfile="$(mktemp mod_gnutls_test-XXXXXX.pid)"
121    GNUPGHOME=msva.gnupghome MSVA_KEYSERVER_POLICY=never run_with_pidfile "${msva_pidfile}" monkeysphere-validation-agent &
122    trap stop_msva EXIT
123
124    printf "TESTING: initial MSVA verification\n"
125    # set to 0 if MSVA is up
126    ret=1
127    export MONKEYSPHERE_VALIDATION_AGENT_SOCKET="http://127.0.0.1:$MSVA_PORT"
128
129    # convert TEST_MSVA_WAIT to seconds because that's what "sleep" expects
130    TEST_MSVA_SLEEP="$((${TEST_MSVA_WAIT} / 1000)).$((${TEST_MSVA_WAIT} % 1000))"
131    # wait at most TEST_MSVA_MAX_WAIT milliseconds for MSVA to get ready
132    waited=0
133    until [ ${ret} -eq 0 ] \
134              || [ ${waited} -ge ${TEST_MSVA_MAX_WAIT} ]; do
135        if msva-query-agent https "$(cat client.uid)" x509pem client < client/x509.pem
136        then
137            ret=0
138        else
139            echo "MSVA not ready yet"
140        fi
141        sleep "${TEST_MSVA_SLEEP}"
142        waited=$((${waited} + ${TEST_MSVA_WAIT}))
143    done
144
145    # check if MSVA is up, fail if not
146    if [ ${ret} -eq 0 ]; then
147        printf "\nSUCCESS: initial MSVA verification\n"
148    else
149        printf "\nFAIL: initial MSVA verification\n"
150        exit 1
151    fi
152fi
153
154TEST_PID="apache2.pid"
155# configure locking for the Apache process
156if [ -n "${USE_TEST_NAMESPACE}" ]; then
157    echo "Using namespaces to isolate tests, no need for locking."
158    flock_cmd=""
159elif [ -n "${TEST_LOCK}" ]; then
160    flock_cmd="${FLOCK} -w ${TEST_LOCK_WAIT} $(realpath ${TEST_LOCK})"
161else
162    echo "Locking disabled, using wait based on Apache PID file."
163    wait_pid_gone "${TEST_PID}"
164    flock_cmd=""
165fi
166
167t="$(realpath ${testid})"
168export srcdir="$(realpath ${srcdir})"
169export TEST_NAME="$(basename "$t")"
170output="outputs/${TEST_NAME}.output"
171rm -f "$output"
172
173if [ -e ${t}/fail.* ]; then
174    EXPECTED_FAILURE="$(printf " (expected: %s)" fail.*)"
175else
176    unset EXPECTED_FAILURE
177fi
178printf "TESTING: %s%s\n" "$TEST_NAME" "$EXPECTED_FAILURE"
179trap apache_down_err EXIT
180if [ -n "${USE_MSVA}" ]; then
181    MONKEYSPHERE_VALIDATION_AGENT_SOCKET="http://127.0.0.1:$MSVA_PORT" \
182                                        ${flock_cmd} \
183                                        ${APACHE2} -f "${t}/apache.conf" -k start \
184        || [ -e "${t}/fail.server" ]
185else
186    ${flock_cmd} \
187        ${APACHE2} -f "${t}/apache.conf" -k start \
188        || [ -e "${t}/fail.server" ]
189fi
190
191# check OCSP server
192if [ -n "${CHECK_OCSP_SERVER}" ]; then
193    if [ -n "${OCSP_RESPONSE_FILE}" ]; then
194        store_ocsp="--outfile ${OCSP_RESPONSE_FILE}"
195    fi
196    echo "---- Testing OCSP server ----"
197    ocsptool --ask --nonce --load-issuer authority/x509.pem --load-cert server/x509.pem ${store_ocsp}
198    echo "---- OCSP test done ----"
199fi
200
201# PID file for sleep command (explanation below)
202sleep_pidfile="$(mktemp mod_gnutls_test-XXXXXX.pid)"
203
204# The sleep call keeps the pipe from the subshell to gnutls-cli
205# open. Without it gnutls-cli would terminate as soon as sed is
206# done, and not wait for a response from the server, leading to
207# failing tests. Sending sleep to the background allows the test
208# case to proceed instead of waiting for it to return. The sleep
209# process is stopped after gnutls-cli terminates.
210if (sed "s/__HOSTNAME__/${TEST_HOST}/" <${t}/input && \
211           run_with_pidfile "${sleep_pidfile}" sleep "${TEST_QUERY_DELAY}" &) | \
212       gnutls-cli -p "${TEST_PORT}" $(cat ${t}/gnutls-cli.args) "${TEST_HOST}" \
213       | tee "$output" && test "${PIPESTATUS[1]}" -eq 0;
214then
215    if [ -e ${t}/fail* ]; then
216        printf "%s should have failed but succeeded\n" "$(basename "$t")" >&2
217        exit 1
218    fi
219else
220    if [ ! -e ${t}/fail* ]; then
221        printf "%s should have succeeded but failed\n" "$(basename "$t")" >&2
222        exit 1
223    fi
224fi
225
226kill_by_pidfile "${sleep_pidfile}"
227unset sleep_pidfile
228
229if [ -e ${t}/output ] ; then
230    diff_output_filter_headers "${t}/output" "$output" >&2
231fi
232if [ -n "${USE_MSVA}" ]; then
233    trap stop_msva EXIT
234else
235    trap - EXIT
236fi
237${APACHE2} -f "${t}/apache.conf" -k stop || [ -e ${t}/fail.server ]
238printf "SUCCESS: %s\n" "$TEST_NAME"
239
240if [ -n "${USE_MSVA}" ]; then
241    stop_msva
242    # Without explicitly resetting the trap function, it would be
243    # called again on exit. Of course, we could just not stop MSVA and
244    # let the trap do the work, but I think the code is easier to
245    # understand like this.
246    trap - EXIT
247fi
Note: See TracBrowser for help on using the repository browser.