tannhauser
A PoC Gemini proxy in Gopherspace
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