diff options
Diffstat (limited to 'httpconnectd.sh.in')
-rw-r--r-- | httpconnectd.sh.in | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/httpconnectd.sh.in b/httpconnectd.sh.in new file mode 100644 index 0000000..bcbdb1d --- /dev/null +++ b/httpconnectd.sh.in @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +# Copyright 2016 Luke Shumaker +# License: WTFPLv2 + +# Dependencies: +# - bash +# - sed +# - socat +# - date -R + +server="${0##*/}" + +OK() { + printf '%s\r\n' \ + 'HTTP/1.1 200 OK' \ + "Server: $server" \ + "Date: $(date -R)" \ + '' +} + +Forbidden() { + body='403 Forbidden' + printf '%s\r\n' \ + 'HTTP/1.1 403 Forbidden' \ + "Server: $server" \ + "Date: $(date -R)" \ + 'Allow: CONNECT' \ + "Content-Length: ${#body}" \ + '' + printf '%s' "$body" +} + +MethodNotAllowed() { + body='405 Method Not Allowed' + printf '%s\r\n' \ + 'HTTP/1.1 405 Method Not Allowed' \ + "Server: $server" \ + "Date: $(date -R)" \ + 'Allow: CONNECT' \ + "Content-Length: ${#body}" \ + '' + printf '%s' "$body" +} + +ProxyAuthenticationRequired() { + body='407 Proxy Authentication Required' + printf '%s\r\n' \ + 'HTTP/1.1 407 Proxy Authentication Required' \ + "Server: $server" \ + "Date: $(date -R)" \ + "Proxy-Authenticate: $(echo $(declare -F|sed -n 's/^declare -f authenticate_//p')|sed 's/ /, /g')" \ + "Content-Length: ${#body}" \ + '' + printf '%s' "$body" +} + +InternalServerError() { + body='500 Internal Server Error' + printf '%s\r\n' \ + 'HTTP/1.1 500 Internal Server Error' \ + "Server: $server" \ + "Date: $(date -R)" \ + "Content-Length: ${#body}" \ + '' + printf '%s' "$body" +} + +checkdest() { + true +} + +worker() { + local conffile + for conffile in @pkgconfdir@/*.conf; do + if ! source "$conffile"; then + InternalServerError + fi + done + local method dest version + read -r method dest version || exit 1 + if [[ "$method" != CONNECT ]]; then + MethodNotAllowed + return 0 + fi + local authenticated=false + local line + while read -r line; do + line="${line%$'\r'}" + case "${line,,}" in + proxy-authorization:*) + local scheme authparams + read -r scheme authparams <<<"${line#*:}" + scheme=${scheme,,} + if authenticate_${scheme} "$authparams" 1>&2; then + authenticated=true + fi + ;; + '') + if ! $authenticated; then + ProxyAuthenticationRequired + return 0 + fi + if ! checkdest "$dest"; then + Forbidden + return 0 + fi + OK + exec socat STDIO TCP-CONNECT:"$dest" + ;; + esac + done + exit 1 +} + +while worker "$@"; do :; done |