summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile11
-rw-r--r--basicauth.conf-sample20
-rw-r--r--httpconnectd.sh35
-rw-r--r--httpconnectd.sh.in103
-rw-r--r--httpconnectd@.service.in2
6 files changed, 133 insertions, 39 deletions
diff --git a/.gitignore b/.gitignore
index e00d49d..0e77e51 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
httpconnectd@.service
httpconnectd
+httpconnectd.sh
.var.*
.tmp.*
diff --git a/Makefile b/Makefile
index a740bd1..dad9c4a 100644
--- a/Makefile
+++ b/Makefile
@@ -4,6 +4,8 @@
prefix = /usr/local
bindir = $(prefix)/bin
systemddir = $(prefix)/lib/systemd/system
+sysconfdir = $(prefix)/etc
+pkgconfdir = $(sysconfdir)/httpconnectd
DESTDIR =
Q = @
@@ -11,19 +13,20 @@ Q = @
MAKEFLAGS += -r
vars = $(patsubst .var.%,%,$(filter .var.%,$^))
-build_targets = httpconnectd httpconnectd@.service httpconnectd.socket
-install_targets = $(DESTDIR)$(bindir)/httpconnectd $(DESTDIR)$(systemddir)/httpconnectd@.service $(DESTDIR)$(systemddir)/httpconnectd.socket
+build_targets = httpconnectd httpconnectd@.service httpconnectd.socket basicauth.conf-sample
+install_targets = $(DESTDIR)$(bindir)/httpconnectd $(DESTDIR)$(systemddir)/httpconnectd@.service $(DESTDIR)$(systemddir)/httpconnectd.socket $(DESTDIR)$(pkgconfdir)/basicauth.conf-sample
all: $(build_targets)
install: $(install_targets)
clean:
- rm -f -- httpconnectd httpconnectd@.service
+ rm -f -- httpconnectd httpconnectd.sh httpconnectd@.service
uninstall:
rm -f -- $(install_targets)
rmdir -p -- $(dir $(install_targets))
.PHONY: all install clean uninstall
httpconnectd@.service: .var.bindir
+httpconnectd.sh: .var.pkgconfdir
########################################################################
@@ -37,6 +40,8 @@ $(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; }
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 b/httpconnectd.sh
deleted file mode 100644
index 24edb68..0000000
--- a/httpconnectd.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2016 Luke Shumaker
-# License: WTFPLv2
-
-# Dependencies:
-# - bash
-# - socat
-# - date -R
-
-server='httpconnectd'
-
-MethodNotAllowed() {
- printf '%s\r\n' \
- 'HTTP/1.1 405 Method Not Allowed' \
- "Server: $server" \
- "Date: $(date -R)" \
- 'Allow: CONNECT' \
- ''
- exit 0
-}
-
-worker() {
- read -r method dest version
- if [[ "$method" != CONNECT ]]; then
- MethodNotAllowed
- fi
- while read -r line; do
- if [[ "$line" == $'\r' ]]; then
- break;
- fi
- done
- exec socat STDIO TCP-CONNECT:"$dest"
-}
-
-worker "$@"
diff --git a/httpconnectd.sh.in b/httpconnectd.sh.in
new file mode 100644
index 0000000..747fcea
--- /dev/null
+++ b/httpconnectd.sh.in
@@ -0,0 +1,103 @@
+#!/usr/bin/env bash
+# Copyright 2016 Luke Shumaker
+# License: WTFPLv2
+
+# Dependencies:
+# - bash
+# - sed
+# - socat
+# - date -R
+
+server="${0##*/}"
+
+NoContent() {
+ printf '%s\r\n' \
+ 'HTTP/1.1 204 No Content' \
+ "Server: $server" \
+ "Date: $(date -R)" \
+ ''
+}
+
+Forbidden() {
+ printf '%s\r\n' \
+ 'HTTP/1.1 403 Forbidden' \
+ "Server: $server" \
+ "Date: $(date -R)" \
+ 'Allow: CONNECT' \
+ ''
+}
+
+MethodNotAllowed() {
+ printf '%s\r\n' \
+ 'HTTP/1.1 405 Method Not Allowed' \
+ "Server: $server" \
+ "Date: $(date -R)" \
+ 'Allow: CONNECT' \
+ ''
+}
+
+ProxyAuthenticationRequired() {
+ 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')" \
+ ''
+}
+
+InternalServerError() {
+ printf '%s\r\n' \
+ 'HTTP/1.1 500 Internal Server Error' \
+ "Server: $server" \
+ "Date: $(date -R)" \
+ ''
+}
+
+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
+ NoContent
+ exec socat STDIO TCP-CONNECT:"$dest"
+ ;;
+ esac
+ done
+ exit 1
+}
+
+while worker "$@"; do :; done
diff --git a/httpconnectd@.service.in b/httpconnectd@.service.in
index a057c27..05bcff8 100644
--- a/httpconnectd@.service.in
+++ b/httpconnectd@.service.in
@@ -5,7 +5,7 @@ Description=An HTTP CONNECT connection
After=network.target
[Service]
-ExecStart=@bindir@/httpconnectd
+ExecStart=-@bindir@/httpconnectd
StandardInput=socket
StandardOutput=socket
StandardError=journal