summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore8
-rw-r--r--COPYING14
-rw-r--r--[l---------]Makefile60
-rw-r--r--basicauth.conf-sample20
-rw-r--r--httpconnectd.sh.in115
-rw-r--r--httpconnectd.socket11
-rw-r--r--httpconnectd@.service.in13
-rw-r--r--https.conf12
-rw-r--r--httpsconnectd.service.in12
-rw-r--r--httpsconnectd.sh.in13
10 files changed, 277 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 30be33f..0224fd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,11 @@
+httpconnectd@.service
+httpconnectd
+httpconnectd.sh
+
+httpsconnectd.service
+httpsconnectd
+httpsconnectd.sh
+
.tmp.*
.var.*
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..ee7d6a5
--- /dev/null
+++ b/COPYING
@@ -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.
+
diff --git a/Makefile b/Makefile
index 4ecdba5..a745ecf 120000..100644
--- a/Makefile
+++ b/Makefile
@@ -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