diff options
-rw-r--r-- | .gitignore | 8 | ||||
-rw-r--r-- | COPYING | 14 | ||||
-rw-r--r--[l---------] | Makefile | 60 | ||||
-rw-r--r-- | basicauth.conf-sample | 20 | ||||
-rw-r--r-- | httpconnectd.sh.in | 115 | ||||
-rw-r--r-- | httpconnectd.socket | 11 | ||||
-rw-r--r-- | httpconnectd@.service.in | 13 | ||||
-rw-r--r-- | https.conf | 12 | ||||
-rw-r--r-- | httpsconnectd.service.in | 12 | ||||
-rw-r--r-- | httpsconnectd.sh.in | 13 |
10 files changed, 277 insertions, 1 deletions
@@ -1,3 +1,11 @@ +httpconnectd@.service +httpconnectd +httpconnectd.sh + +httpsconnectd.service +httpsconnectd +httpsconnectd.sh + .tmp.* .var.* @@ -0,0 +1,14 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
+
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
+
@@ -1 +1,59 @@ -build-aux/Makefile.README.mk
\ No newline at end of file +# Copyright 2016 Luke Shumaker +# License: WTFPLv2 + +prefix = /usr/local +bindir = $(prefix)/bin +systemddir = $(prefix)/lib/systemd/system +sysconfdir = $(prefix)/etc +pkgconfdir = $(sysconfdir)/httpconnectd +DESTDIR = +Q = @ + +######################################################################## + +MAKEFLAGS += -r +vars = $(patsubst .var.%,%,$(filter .var.%,$^)) +build_targets += httpconnectd httpconnectd@.service httpconnectd.socket +build_targets += httpsconnectd httpsconnectd.service +build_targets += basicauth.conf-sample +install_targets += $(DESTDIR)$(bindir)/httpconnectd $(DESTDIR)$(systemddir)/httpconnectd@.service $(DESTDIR)$(systemddir)/httpconnectd.socket +install_targets += $(DESTDIR)$(bindir)/httpsconnectd $(DESTDIR)$(systemddir)/httpsconnectd.service $(DESTDIR)$(pkgconfdir)/https.conf +install_targets += $(DESTDIR)$(pkgconfdir)/basicauth.conf-sample + +all: $(build_targets) +install: $(install_targets) +clean: + rm -f -- httpconnectd httpconnectd.sh httpconnectd@.service + rm -f -- httpsconnectd httpsconnectd.sh httpsconnectd.service +uninstall: + rm -f -- $(install_targets) + rmdir -p -- $(dir $(install_targets)) +.PHONY: all install clean uninstall + +httpconnectd@.service: .var.bindir +httpconnectd.sh: .var.pkgconfdir + +httpsconnectd.service: .var.bindir +httpsconnectd.sh: .var.pkgconfdir + +######################################################################## + +%: %.sh + install -m755 $< $@ + +%: %.in + $(if $(Q),$(Q)echo 'EDIT < $< > $@';)$(if $(vars),sed $(foreach v,$(vars), -e 's|@$(v)@|$($(v))|g' ),cat) < $< > $@ + +$(DESTDIR)$(bindir)/%: % + install -Dm755 $< $@ +$(DESTDIR)$(systemddir)/%: % + install -Dm644 $< $@ +$(DESTDIR)$(pkgconfdir)/%: % + install -Dm644 $< $@ + +.var.%: FORCE + $(Q)printf '%s' '$($*)' > .tmp$@ && { cmp -s .tmp$@ $@ && rm -f -- .tmp$@ || mv -Tf .tmp$@ $@; } || { rm -f -- .tmp$@; false; } + +.DELETE_ON_ERROR: +.SECONDARY: +.PHONY: FORCE diff --git a/basicauth.conf-sample b/basicauth.conf-sample new file mode 100644 index 0000000..11048fc --- /dev/null +++ b/basicauth.conf-sample @@ -0,0 +1,20 @@ +#!/hint/bash +# Copyright 2016 Luke Shumaker +# License: WTFPLv2 + +# Dependencies: +# - bash +# - base64 -d + +authenticate_basic() { + local authparams="$*" + local pair + pair=$(base64 -d <<<"$authparams") + if [[ "$pair" != *:* ]]; then + return 1; + fi + local username="${pair%%:*}" + local password="${pair#*:}" + + # TODO: check username and password against some DB +} 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 diff --git a/httpconnectd.socket b/httpconnectd.socket new file mode 100644 index 0000000..38cefd8 --- /dev/null +++ b/httpconnectd.socket @@ -0,0 +1,11 @@ +# Copyright 2016 Luke Shumaker +# License: WTFPLv2 +[Unit] +Description=HTTP CONNECT server + +[Socket] +ListenStream=8080 +Accept=true + +[Install] +WantedBy=sockets.target diff --git a/httpconnectd@.service.in b/httpconnectd@.service.in new file mode 100644 index 0000000..05bcff8 --- /dev/null +++ b/httpconnectd@.service.in @@ -0,0 +1,13 @@ +# Copyright 2016 Luke Shumaker +# License: WTFPLv2 +[Unit] +Description=An HTTP CONNECT connection +After=network.target + +[Service] +ExecStart=-@bindir@/httpconnectd +StandardInput=socket +StandardOutput=socket +StandardError=journal +User=nobody +Group=nobody diff --git a/https.conf b/https.conf new file mode 100644 index 0000000..14cfaec --- /dev/null +++ b/https.conf @@ -0,0 +1,12 @@ +#!/hint/bash +# Copyright 2016 Luke Shumaker +# License: WTFPLv2 + +port=8443 +ssl_options=( + cert=/etc/ssl/private/myhostname/fullchain.pem + key=/etc/ssl/private/myhostname/privkey.pem + dhparam=/etc/ssl/private/dhparam-2048.pem + + verify=0 +) diff --git a/httpsconnectd.service.in b/httpsconnectd.service.in new file mode 100644 index 0000000..379dc59 --- /dev/null +++ b/httpsconnectd.service.in @@ -0,0 +1,12 @@ +# Copyright 2016 Luke Shumaker +# License: WTFPLv2 +[Unit] +Description=HTTPS CONNECT server + +[Service] +ExecStart=@bindir@/httpsconnectd +User=nobody +Group=keys + +[Install] +WantedBy=multi-user.target diff --git a/httpsconnectd.sh.in b/httpsconnectd.sh.in new file mode 100644 index 0000000..6dd9f54 --- /dev/null +++ b/httpsconnectd.sh.in @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# Copyright 2016 Luke Shumaker +# License: WTFPLv2 + +# Dependencies: +# - bash +# - socat (with OpenSSL support) +# - httpconnectd + +set -e +source @pkgconfdir@/https.conf +IFS=, +socat OPENSSL-LISTEN:"${port},${ssl_options[*]},reuseaddr,fork" EXEC:httpconnectd |