vanguards - Additional protections for Tor Onion Services

I was unsuccessful in finding any download errors using the script. Even after building tor with commit “7aa496a2e0” the tor version still shows as being 0.4.7.16-1. If anyone else has any luck please try to run the script on Whonix-Gateway and provide feedback. Patrick I assure you that there is no malware or spyware in the script. I encourage you to run the script. We are all trying to fix this issue. Also I’m not sure what you meant by your last comment.

#!/bin/bash

# Welcome to tor debugger. I have purposely not used git bisect because I feel it would be very easy to miss commits with issues.

TIME_WHEN_TOR_SOCKS_DOWNLOAD_RUNS_BINARY=""

TIME_WHEN_VANGUARDS_STATUS_RUNS=""

TIME_WHEN_VANGUARDS_STATUS_RUNS_BINARY=""

GET_TEXT_WHERE_THE_WARNING_OCCURS=""

WARNING_WHEN_CELLS_DROP="Possible Tor bug, or possible attack if very frequent"

ALTERNATE_WARNING_WHEN_CELLS_DROP="We force-closed circuit"

FIRST_COMMIT="7aa496a2e0"

#FIRST_COMMIT="a56350abc8"

#FIRST_COMMIT="d7f14a54fb"

CURRENT_COMMIT=""

LAST_COMMIT="364b8c2925"

TOR="tor"

STOP=0

COMMIT_BEFORE_LAST_COMMIT=""

COMMIT_BEFORE_LAST_COMMIT_TEMP=""

DIRECTORY="/home/user/Downloads/tor"

LAUNCH_DIR=$(pwd)

HERE="$(dirname "$(readlink -f "${0}")")"


LOG_DIR="${LAUNCH_DIR}/logs"
mkdir -p "${LOG_DIR}"
LOG_FILE="${LOG_DIR}/BuildTest.log"

exec > >(tee -a $LOG_FILE) 2>&1

# Logs a message in a standardized format to stdout
# $1 The message to log
log() {
    local MSG="${1}"
    local CMD="$(basename "${0}")"
    local TIMESTAMP=$(date -u --rfc-3339=seconds)

    echo "${TIMESTAMP} [BuildTest] [${CMD}] ${MSG}"
}

# Check if there is a tor directory and then navigate to it. If not clone and download from GitLab.
# Install all essential tools needed to build Tor
# Downgrade tor and tor-geoipdb to version 0.4.7.16-1
initialize(){
    sudo apt-get update
    sudo apt-get dist-upgrade -y
    sudo apt-get install tor=0.4.7.16-1 tor-geoipdb=0.4.7.16-1 --allow-downgrades -y
    if [ -d "$DIRECTORY" ]; then
        log "$DIRECTORY does exist."
    else
        git clone https://gitlab.com/torproject/tor.git
    fi
    cd tor
    git checkout $LAST_COMMIT
    log "Changed to Tor Directory:$HERE/$TOR"
    sudo apt-get install git build-essential automake libevent-dev libssl-dev zlib1g-dev pkg-config
    sudo service vanguards start
    COMMIT_BEFORE_LAST_COMMIT_TEMP=$(git rev-list $FIRST_COMMIT^...$LAST_COMMIT|grep -A 1 $LAST_COMMIT|head -1| cut -c1-10)
}

# Builds tor from local directory
# git checkout moves head to a particular commit
build_tor_from_source(){
    CURRENT_COMMIT="${1}"
    git checkout $CURRENT_COMMIT
    log "Building Tor with commit:$CURRENT_COMMIT"
    ./autogen.sh
    ./configure --disable-asciidoc
    make
    sudo make install
    run_tor_socks_download
    get_vanguards_status
    check_if_the_commit_causes_download_errors
}

# A test download is executed.
# The time when the download occured is captured and converted to binary.
run_tor_socks_download(){
    torsocks curl --fail --silent --show-error --output "/tmp/test.png" "https://onlinetestcase.com/wp-content/uploads/2023/06/1MB.png"
    TIME_WHEN_TOR_SOCKS_DOWNLOAD_RUNS_BINARY=$(echo "obase=2;$(date +%s)" |bc)
    log "Tor Socks curl Download has executed."
    log "Tor socks download time captured in binary."
}

# Gets vanguards status and then captures the line whichs shows the warning about cells dropped after the curl download.
# The time is converted to binary
get_vanguards_status(){
    GET_TEXT_WHERE_THE_WARNING_OCCURS=$(sudo service vanguards status| tail -n 1)
    TIME_WHEN_VANGUARDS_STATUS_RUNS=$(sudo service vanguards status| tail -n 1| cut -c1-15)
    TIME_WHEN_VANGUARDS_STATUS_RUNS_BINARY=$(echo "obase=2;$(date -d "$TIME_WHEN_VANGUARDS_STATUS_RUNS" +%s)" |bc)
    log "Vanguards status time captured in binary."
}
 

# Tor is built commit by commit to see where the download failures occur.
go_to_next_commit(){
    CURRENT_COMMIT="${1}"
    GREP_OUTPUT="$(git rev-list $FIRST_COMMIT^...$LAST_COMMIT|grep -B 1 $CURRENT_COMMIT|head -1)"
    NEXT_COMMIT="$(echo "$GREP_OUTPUT"| cut -c1-10)"
    CURRENT_COMMIT=$NEXT_COMMIT
    log "The latest or last commit to this repository was $LAST_COMMIT"
    GREP_OUTPUT1=$(git rev-list $FIRST_COMMIT^...$LAST_COMMIT|grep -A 1 $CURRENT_COMMIT| head -1)
    COMMIT_BEFORE_LAST_COMMIT=$(echo "$GREP_OUTPUT1"| cut -c1-10)
    if [[ "$COMMIT_BEFORE_LAST_COMMIT_TEMP" == $COMMIT_BEFORE_LAST_COMMIT ]]; then
        log "The commit before the last commit reached"
        STOP=1
        build_tor_from_source "$CURRENT_COMMIT"
    else
        build_tor_from_source "$CURRENT_COMMIT"
    fi
}

#  This section of the code checks if the commit causes download errors
check_if_the_commit_causes_download_errors(){
# See if the warnings occur when vanguards status is checked. If no warnings occur that means this commit is fine.
if [[ "$GET_TEXT_WHERE_THE_WARNING_OCCURS" =~ "$WARNING_WHEN_CELLS_DROP" ]] || [[ "$GET_TEXT_WHERE_THE_WARNING_OCCURS" =~ "$ALTERNATE_WARNING_WHEN_CELLS_DROP" ]]; then
    if [[ "$TIME_WHEN_VANGUARDS_STATUS_RUNS_BINARY" == "$TIME_WHEN_TOR_SOCKS_DOWNLOAD_RUNS_BINARY" ]]; then
        log "Download failures have been detected at this commit:$CURRENT_COMMIT"
        git checkout "$LAST_COMMIT"
        log "The head has been restored to it's original location"
        exit
    else
        log "Binary times are not matching. So else statement was executed"
        go_to_next_commit "$CURRENT_COMMIT"
    fi
else
    log "The commit:$CURRENT_COMMIT seems to be fine."

    if [[ $STOP == 1 ]]; then
        log "The build process has been terminated because the last commit has been reached."
        git checkout "$LAST_COMMIT"
        log "The head has been restored to it's original location"
        exit
    fi
    log "Moving on to the next commit"
    go_to_next_commit "$CURRENT_COMMIT"
fi
}

# Initialize then build tor from source.
initialize
build_tor_from_source "$FIRST_COMMIT"
````````````