summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtor-exit-ssl-check-many141
1 files changed, 141 insertions, 0 deletions
diff --git a/tor-exit-ssl-check-many b/tor-exit-ssl-check-many
new file mode 100755
index 0000000..0ca80c7
--- /dev/null
+++ b/tor-exit-ssl-check-many
@@ -0,0 +1,141 @@
+#!/bin/bash
+
+# Copyright (c) 2013 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 [<options>] <target> [<target>"
+ echo "Options:"
+ echo " -a <auth> use this authority [$AUTH]"
+ echo " -l <dir> log dir [$LOGDIR]"
+ echo " -m send mail when a certificate mismatch is found"
+ echo " -v be a bit verbose"
+ echo " -h print this help"
+}
+
+AUTH=tor.noreply.org
+PER_RUN=60
+DATADIR=$(mktemp -d "/tmp/tor-checks-XXXXXX")
+DUMPFILE=$(tempfile)
+DEFAULT_CHECKHOSTS="www.twitter.com www.facebook.com www.torproject.org db.torproject.org nagios.noreply.org www.gmx.net"
+LOGDIR="tor-exit-ssl-check-many.log"
+CACHEDIR="tor-exit-ssl-check-many.cache"
+MAIL=0
+
+trap "rm -rf '$DATADIR' '$DUMPFILE'" EXIT
+
+mkdir -vp "$LOGDIR"
+mkdir -vp "$CACHEDIR"
+
+LOG="$LOGDIR/log"
+CTR=0
+HOSTNAME=$(hostname)
+VERBOSE=0
+while getopts "vha:l:m" OPTION
+do
+ case "$OPTION" in
+ v)
+ VERBOSE=$((VERBOSE + 1))
+ ;;
+ h)
+ usage
+ exit 0
+ ;;
+ a)
+ AUTH="$OPTARG"
+ ;;
+ l)
+ LOGDIR="$OPTARG"
+ ;;
+ m)
+ MAIL=1
+ ;;
+ *)
+ usage >&2
+ exit 1
+ esac
+done
+shift $(($OPTIND - 1))
+
+if [ "${1:-}" = "--help" ]; then
+ usage
+ exit 0
+elif [ "$#" != 0 ]; then
+ usage >&2
+ exit 1
+fi
+
+declare -a CHECKHOSTS=("$@")
+if [ "${#CHECKHOSTS[@]}" = 0 ]; then
+ for i in $DEFAULT_CHECKHOSTS; do
+ CHECKHOSTS[${#CHECKHOSTS[@]}]="$i"
+ done
+fi
+
+run_some_checks() {
+ local idx=$(( RANDOM % ${#CHECKHOSTS[@]} ))
+ local host="${CHECKHOSTS[$idx]}"
+ wget -q -O - "http://$AUTH"/tor/status-vote/current/consensus | \
+ grep -v BadExit | grep '^s .*Exit' -B1 |\
+ awk '$1 == "r" {print $3}' |\
+ sort -R | \
+ head -n "$PER_RUN" | \
+ while read fpr; do
+ [ "$VERBOSE" = 0 ] || echo -n "Checking $host at $fpr..."
+ if tor-exit-ssl-check -c "$CACHEDIR" -d "$DATADIR" "$fpr" $host > "$DUMPFILE" 2>&1; then
+ ecode=0
+ else
+ ecode="$?"
+ fi
+ [ "$VERBOSE" = 0 ] || echo "$ecode"
+ prefix="[$(TZ=UTC date +%Y-%m-%dT%H:%M:%SZ)][$fpr][EC=$ecode]"
+ case "$ecode" in
+ 0) echo "$prefix OK" >> "$LOG";;
+ 2) echo "$prefix connect failed" >> "$LOG";;
+ 4) echo "$prefix handshake failed" >> "$LOG";;
+ 8) lf="$LOGDIR/$(date +%s).$HOSTNAME.$$.$CTR"
+ echo "$prefix differences - logged as $lf" >> "$LOG"
+ CTR=$((CTR + 1))
+ echo "$fpr" > "$lf"
+ echo >> "$lf"
+ cat "$DUMPFILE" >> "$lf"
+ echo >> "$lf"
+ wget -q -O - http://"$AUTH"/tor/server/fp/$(echo "$fpr" | perl -MMIME::Base64 -e "print unpack(\"H*\", decode_base64(<>)),\"\n\"") >> "$lf"
+ if [ "$MAIL" -gt 0 ]; then
+ (echo "Log file at $lf:"; echo; cat "$lf") | mail -s "certificate mismatch found for relay $fpr" "$USER"
+ fi
+ ;;
+ *)
+ echo "$prefix unknown exit code" >> "$LOG"
+ echo "$prefix unknown exit code" >&2
+ cp $DUMPFILE failed-output
+ exit 1
+ esac
+ done
+}
+
+while : ; do
+ run_some_checks
+ sleep 15
+done