1#!/bin/bash
2
3#
4# This script uses cURL to verify that Jafar is able to produce a
5# bunch of censorship conditions. It should be noted that this script
6# only works on Linux and will never work on other systems.
7#
8
9set -e
10
11function execute() {
12  echo "+ $@" 1>&2
13  "$@"
14}
15
16function expectexitcode() {
17  local expect
18  local exitcode
19  expect=$1
20  shift
21  set +e
22  "$@"
23  exitcode=$?
24  set -e
25  echo "expected exitcode $expect, found $exitcode" 1>&2
26  if [ $exitcode != $expect ]; then
27    exit 1
28  fi
29}
30
31function runtest() {
32  echo "=== BEGIN $1 ==="
33  "$1"
34  echo "=== END $1 ==="
35}
36
37function http_got_nothing() {
38  expectexitcode 52 execute ./jafar -iptables-hijack-http-to 127.0.0.1:7117  \
39    -main-command 'curl -sm5 --connect-to ::example.com: http://ooni.io'
40}
41
42function http_recv_error() {
43  expectexitcode 56 execute ./jafar -iptables-reset-keyword ooni          \
44    -main-command 'curl -sm5 --connect-to ::example.com: http://ooni.io'
45}
46
47function http_operation_timedout() {
48  expectexitcode 28 execute ./jafar -iptables-drop-keyword ooni           \
49    -main-command 'curl -sm5 --connect-to ::example.com: http://ooni.io'
50}
51
52function http_couldnt_connect() {
53  local ip
54  ip=$(host -tA example.com|cut -f4 -d' ')
55  expectexitcode 7 execute ./jafar -iptables-reset-ip $ip                 \
56    -main-command 'curl -sm5 --connect-to ::example.com: http://ooni.io'
57}
58
59function http_blockpage() {
60  outfile=$(mktemp)
61  chown nobody $outfile  # curl runs as user nobody
62  expectexitcode 0 execute ./jafar -http-proxy-block ooni  \
63    -iptables-hijack-http-to 127.0.0.1:80                  \
64    -main-command "curl -so $outfile --connect-to ::example.com: http://ooni.io"
65  if ! grep -q '451 Unavailable For Legal Reasons' $outfile; then
66    echo "fatal: the blockpage does not contain the expected pattern" 1>&2
67    exit 1
68  fi
69}
70
71function dns_injection() {
72  output=$(expectexitcode 0 execute ./jafar                              \
73    -iptables-hijack-dns-to 127.0.0.1:53                                 \
74    -dns-proxy-hijack ooni                                               \
75    -main-command 'dig +time=2 +short @example.com ooni.io')
76  if [ "$output" != "127.0.0.1" ]; then
77    echo "fatal: the resulting IP is not the expected one" 1>&2
78    exit 1
79  fi
80}
81
82function dns_timeout() {
83  expectexitcode 9 execute ./jafar             \
84    -iptables-hijack-dns-to 127.0.0.1:53       \
85    -dns-proxy-ignore ooni                     \
86    -main-command 'dig +time=2 +short @example.com ooni.io'
87}
88
89function dns_nxdomain() {
90  output=$(expectexitcode 0 execute ./jafar                              \
91    -iptables-hijack-dns-to 127.0.0.1:53                                 \
92    -dns-proxy-block ooni                                                \
93    -main-command 'dig +time=2 +short @example.com ooni.io')
94  if [ "$output" != "" ]; then
95    echo "fatal: expected no output here" 1>&2
96    exit 1
97  fi
98}
99
100function sni_man_in_the_middle() {
101  expectexitcode 60 execute ./jafar -iptables-hijack-https-to 127.0.0.1:4114  \
102    -main-command 'curl -sm5 --connect-to ::example.com: https://ooni.io'
103}
104
105function sni_got_nothing() {
106  expectexitcode 52 execute ./jafar -iptables-hijack-https-to 127.0.0.1:4114  \
107    -main-command 'curl -sm5 --cacert badproxy.pem --connect-to ::example.com: https://ooni.io'
108}
109
110function sni_connect_error() {
111  expectexitcode 35 execute ./jafar -iptables-reset-keyword ooni           \
112    -main-command 'curl -sm5 --connect-to ::example.com: https://ooni.io'
113}
114
115function main() {
116  runtest http_got_nothing
117  runtest http_recv_error
118  runtest http_operation_timedout
119  runtest http_couldnt_connect
120  runtest http_blockpage
121  runtest dns_injection
122  runtest dns_timeout
123  runtest dns_nxdomain
124  runtest sni_man_in_the_middle
125  runtest sni_got_nothing
126  runtest sni_connect_error
127}
128
129main "$@"
130