summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Palfrader <peter@palfrader.org>2012-12-10 15:07:57 +0000
committerweasel <weasel@bc3d92e2-beff-0310-a7cd-cc87d7ac0ede>2012-12-10 15:07:57 +0000
commit6a5f6f53f53d1b0715dbba7b43b0690ab854e4fd (patch)
treeb497087d1d016ca9dd3a20b105b5df102c769636
parentd678d35e6875b1ca3b8497029815ad4f8034544b (diff)
Add tor-exit-ssl-check
git-svn-id: svn+ssh://asteria.noreply.org/svn/weaselutils/trunk@560 bc3d92e2-beff-0310-a7cd-cc87d7ac0ede
-rwxr-xr-xtor-exit-ssl-check196
1 files changed, 196 insertions, 0 deletions
diff --git a/tor-exit-ssl-check b/tor-exit-ssl-check
new file mode 100755
index 0000000..823bb4f
--- /dev/null
+++ b/tor-exit-ssl-check
@@ -0,0 +1,196 @@
+#!/bin/bash
+
+# Copyright (c) 2012 Peter Palfrader <peter@palfrader.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+set -e
+set -u
+
+usage() {
+ echo "Usage: $0 [-v [-v]] [-d <datadir>] <torserver fpr> <targethost> [<targetport>]"
+ echo " If datadir is -, a list of fingerprints is read from stdin"
+}
+
+verbose=0
+datadir=""
+while getopts "vhd:" OPTION
+do
+ case "$OPTION" in
+ v)
+ verbose=$((verbose + 1))
+ ;;
+ h)
+ usage
+ exit 0
+ ;;
+ d)
+ datadir="$OPTARG"
+ ;;
+ *)
+ usage >&2
+ exit 1
+ esac
+done
+shift $(($OPTIND - 1))
+
+if [ "${1:-}" = "--help" ]; then
+ usage
+ exit 0
+elif [ "$#" -lt 2 ]; then
+ usage >&2
+ exit 1
+fi
+
+
+torserver="$1"; shift
+hostname="$1"; shift
+port="${1:-443}"
+
+socksport=$((RANDOM % 40000 + 20000))
+mapaddr="192.0.2.1"
+
+
+logpid=""
+torpid=""
+tmpdir=""
+
+cleanup() {
+ [ -z "$torpid" ] || kill "$torpid" || true
+ [ -z "$logpid" ] || kill "$logpid" || true
+ [ -z "$tmpdir" ] || rm -rf "$tmpdir" || true
+}
+
+tmpdir=$(mktemp -d "/tmp/cert-check-XXXXXX")
+trap 'cleanup' EXIT
+
+pidfile="$tmpdir/pid"
+torlog="$tmpdir/log"
+if [ "$verbose" -gt 0 ]; then
+ tail -F "$torlog" &
+ logpid=$!
+fi
+
+if command -v tor > /dev/null; then
+ tor="tor"
+elif [ -x /usr/sbin/tor ]; then
+ tor="/usr/sbin/tor"
+else
+ echo >&2 "Cannot find tor executable"
+ exit 1
+fi
+
+if [ "$verbose" -gt 1 ]; then
+ loglevel="info"
+else
+ loglevel="notice"
+fi
+
+datadir=${datadir:-$tmpdir/tor}
+cat > "$tmpdir/torrc" << EOF
+DataDirectory $datadir
+RunAsDaemon 1
+SocksPort $socksport
+PidFile $pidfile
+Log $loglevel file $torlog
+SafeLogging 0
+# MapAddress $mapaddr $hostname.\$$torserver.exit
+ControlSocket $tmpdir/sock
+StrictNodes 1
+EOF
+
+cat > "$tmpdir/torsocks.conf" << EOF
+server = 127.0.0.1
+server_port = $socksport
+EOF
+
+mkdir -p -m 0700 "$datadir"
+if [ "$verbose" -gt 0 ]; then hush=""; else hush="--hush"; fi
+"$tor" $hush -f "$tmpdir/torrc"
+torpid="$(cat $pidfile)"
+
+
+eatdata() {
+ local fn="$1"; shift
+ if [ "$verbose" -gt 0 ]; then
+ tee "$fn"
+ else
+ cat > "$fn"
+ fi
+}
+expect_ok() {
+ local line
+ read code line <&${COPROC[0]}
+ line=$(echo "$line" | tr -d '\r')
+ if ! [ "$code" = "250" ]; then
+ echo >&2 "Tor said '$code $line' - no idea what that means"
+ exit 1
+ fi
+}
+
+[ "$verbose" = 0 ] || echo "Directly:"
+openssl s_client -no_ticket -showcerts -connect "$hostname":"$port" < /dev/null 2>&1 | eatdata "$tmpdir/cert-direct"
+egrep -v '(Session-ID|Master-Key|Start Time):' < "$tmpdir/cert-direct" > "$tmpdir/cert-direct.filtered"
+[ "$verbose" = 0 ] || echo "===="
+
+
+coproc socat UNIX-CONNECT:"$tmpdir/sock" -
+echo 'AUTHENTICATE' >&${COPROC[1]}
+expect_ok
+
+errors=0
+while : ; do
+ if [ "$torserver" = "-" ]; then
+ read server
+ [ -n "$server" ] || break
+ else
+ server="$torserver"
+ fi
+
+ [ "$verbose" = 0 ] || echo "Setting ExitNodes $server"
+ echo "RESETCONF ExitNodes" >&${COPROC[1]}
+ expect_ok
+ echo "SETCONF ExitNodes=\$$server" >&${COPROC[1]}
+ expect_ok
+
+ rm -f "$tmpdir/cert-tor" "$tmpdir/cert-tor.filtered"
+
+ [ "$verbose" = 0 ] || echo "Via $server:"
+ TORSOCKS_CONF_FILE="$tmpdir/torsocks.conf" torify openssl s_client -no_ticket -showcerts -connect "$hostname":"$port" < /dev/null 2>&1 | eatdata "$tmpdir/cert-tor"
+
+ egrep -v '(Session-ID|Master-Key|Start Time):' < "$tmpdir/cert-tor" > "$tmpdir/cert-tor.filtered"
+
+ if diff "$tmpdir/cert-tor.filtered" "$tmpdir/cert-direct.filtered" > /dev/null; then
+ echo "RESULT: $server: No real differences."
+ [ "$verbose" = 0 ] || diff -U100 "$tmpdir/cert-tor" "$tmpdir/cert-direct" || true
+ elif egrep '^connect:errno=' "$tmpdir/cert-tor" > /dev/null; then
+ echo "RESULT: $server: Connect failed"
+ errors=1
+ else
+ echo "RESULT: $server: differences!"
+ [ "$verbose" = 0 ] || echo "===="
+ [ "$verbose" = 0 ] || echo "Diff:"
+ diff -U100 "$tmpdir/cert-tor" "$tmpdir/cert-direct" || true
+ errors=1
+ fi
+
+ [ "$torserver" = "-" ] || break
+done
+exit "$errors"