ulthar.xyz > Repos

tannhauser

A PoC Gemini proxy in Gopherspace
About Files Commits git clone https://ulthar.xyz/repos/tannhauser/tannhauser.git

tannhauser/tannhauser.dcgi

Download raw file: tannhauser.dcgi

#!/bin/sh
# A basic gopher-gemini gateway
# Dependencies:
# - nmap: ncat, to make a Gemini request. There should be a way to do this
#         with open/libre ssl and ordinary netcat.
# - Geomyidae: A Gopher server. I don't know whether or not its CGI system
#              is standard.

print_debug() {
    printf "+----------------+-----------------------------------------+\n"
    [ -n "$cgisearch" ] && printf "| (1) \$cgisearch : %s\n" "$cgisearch"
    [ -n "$cgiargs" ]   && printf "| (2) \$cgiargs   : %s\n" "$cgiargs"
    [ -n "$cgihost" ]   && printf "| (3) \$cgihost   : %s\n" "$cgihost"
    [ -n "$cgiport" ]   && printf "| (4) \$cgiport   : %s\n" "$cgiport"
    printf "+----------------+\n"
    [ -n "$url" ]       && printf "| \$url           : %s\n" "$url"
    [ -n "$host" ]      && printf "| \$host          : %s\n" "$host"
    [ -n "$gatepath" ]  && printf "| \$gatepath      : %s\n" "$gatepath"
    printf "+----------------+\n"
    [ -n "$status" ]    && printf "| \$status        : %s\n" "$status"
    [ -n "$code" ]      && printf "| \$code          : %s\n" "$code"
    [ -n "$mime" ]      && printf "| \$mime          : %s\n" "$mime"
    printf "+----------------+-----------------------------------------+\n"
}

# Geomyidae CGI command line
cgisearch="$1"
cgiargs="$2"
cgihost="$3"
cgiport="$4"

# Needed to send the request and assemble working links
if [ -n "$cgiargs" ]; then      # We're following a link through the proxy
    url="gemini://$cgiargs"
    host="$(echo "$cgiargs" | cut -d '/' -f1)"
    gatepath="$cgiargs"
elif [ -n "$cgisearch" ]; then  # Process user input
    if [ "$(echo "$cgisearch" | cut -d '/' -f1)" = "gemini:" ]; then
        # gemini://host.tld/path
        url="$cgisearch"
        host="$(echo "$cgisearch" | cut -d '/' -f3)"
        gatepath="${cgisearch%%gemini://}"
    else
        url="gemini://$cgisearch"
        host="$(echo "$cgisearch" | cut -d '/' -f1)"
        gatepath="$cgisearch"
    fi
else
    printf "CGI Error: \$cgisearch and \$cgiargs are empty\n"
    print_debug
fi

# Make sure there's a trailing slash on naked domains
[ ! "$(echo "$url" | cut -d '/' -f4)" ] && url="$url/"

# ncat doesn't like host:port URIs
host="${host%%:*}"

if [ -n "$url" ] && [ -n "$host" ] ; then
    printf "%s\r\n\r\n" "$url" |  ncat --ssl "$host" 1965 >/tmp/astrogate || {
        printf "Request Error: Failed to reach remote host\n"
        print_debug
        rm -f /tmp/astrogate
    }

    status="$(head -1 /tmp/astrogate)"
    code="$(echo "$status" | cut -d ' ' -f1)"
    mime="$(echo "$status" | cut -d ' ' -f2 | tr -d ';')"

    [ -z "$status" ] && {
        printf "CGI Error: gemini response (\$status line) is empty\n"
        print_debug
        rm -f /tmp/astrogate
        exit 1
    }

    print_debug

    if [ "$code" = "20" ] ; then  # Everything is okay
        case "$mime" in
            "text/gemini")
                sed "s/\t/ /g; 1 d" /tmp/astrogate \
                    | awk -v path="$gatepath" -v host="$host" -f ./gmi2gph.awk
            ;;
            "text/plain")
                sed "s/\t/ /g; 1 d" /tmp/astrogate
            ;;
            *)
                # TODO: differentiate between text for display and binary to dl
                printf "WARNING: \$mime (%s) is something else\n" "$mime"
                sed "s/\t/ /g; 1 d" /tmp/astrogate \
                    | awk -v path="$gatepath" -v host="$host" -f ./gmi2gph.awk
            ;;
        esac
    else
        printf "Gemini Error: %s\n" "$status"
        print_debug
        rm -f /tmp/astrogate
        exit 1
    fi

    rm -f /tmp/astrogate
else
    printf "CGI error: \$url and/or \$host are empty\n"
    print_debug
    exit 1
fi

exit 0
Generated 2024-06-10 19:24:14 -0700 by RepoRat