summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2020-01-30 19:08:14 -0600
committerkali kaneko (leap communications) <kali@leap.se>2020-01-30 19:16:19 -0600
commit819adbbb708076bcf9d3ee6443c704303aad5a80 (patch)
tree53081f249aade5edc17f6a9a72f449414d881fdd
parent6ba23c4e3de16181857d5703198d2e817928f1ba (diff)
refactor auth middleware
-rw-r--r--Makefile4
-rw-r--r--go.mod2
-rw-r--r--go.sum88
-rw-r--r--main.go7
-rw-r--r--pkg/auth/anon/auth.go44
-rw-r--r--pkg/auth/creds/creds.go21
-rw-r--r--pkg/auth/interfaces.go26
-rw-r--r--pkg/auth/mechanism.go49
-rw-r--r--pkg/auth/mechanism_test.go47
-rw-r--r--pkg/auth/middleware.go65
-rw-r--r--pkg/auth/sip2/auth.go115
-rw-r--r--pkg/auth/sip2/client.go69
-rw-r--r--pkg/auth/sip2/spec.go15
-rw-r--r--pkg/auth/sip2/telnet.go15
-rw-r--r--pkg/config/main.go15
-rw-r--r--pkg/web/certs.go15
-rw-r--r--pkg/web/handlers.go15
-rw-r--r--pkg/web/middleware.go89
18 files changed, 551 insertions, 150 deletions
diff --git a/Makefile b/Makefile
index cc1ca07..680414d 100644
--- a/Makefile
+++ b/Makefile
@@ -5,9 +5,9 @@ PROVIDER_TEMPLATE=scripts/templates/provider.json.jinja
PROVIDER=deploy/public/provider.json
build:
- go build cmd/vpnweb/vpnweb.go
+ go build
demo-sip:
- . config/CONFIG && ./vpnweb -auth=sip
+ . config/CONFIG && ./vpnweb -auth=sip2
demo-anon:
. config/CONFIG && ./vpnweb -auth=anon
clean:
diff --git a/go.mod b/go.mod
index 55f4406..89224d7 100644
--- a/go.mod
+++ b/go.mod
@@ -3,6 +3,7 @@ module 0xacab.org/leap/vpnweb
go 1.12
require (
+ 0xacab.org/leap/bitmask-vpn v0.0.0-20191220193631-fc304c9181de // indirect
github.com/auth0/go-jwt-middleware v0.0.0-20190805220309-36081240882b
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible
@@ -10,5 +11,6 @@ require (
github.com/gorilla/mux v1.7.3 // indirect
github.com/reiver/go-oi v1.0.0 // indirect
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e
+ github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/urfave/negroni v1.0.0 // indirect
)
diff --git a/go.sum b/go.sum
index 6f0e519..48a5319 100644
--- a/go.sum
+++ b/go.sum
@@ -1,16 +1,104 @@
+0xacab.org/leap/bitmask-vpn v0.0.0-20191220193631-fc304c9181de h1:hLdOwRCCsT0DnYKpJ1kebV97hU4DNFi15347TXsRZZo=
+0xacab.org/leap/bitmask-vpn v0.0.0-20191220193631-fc304c9181de/go.mod h1:j1WslJ38fT1l9/3u56M09vedaRMwtEiSVlcD0RrA0bY=
+0xacab.org/leap/go-dialog v0.0.0-20181123042829-0ee8438431a0/go.mod h1:VZeIZ8qdzi4glGby9mBMNBMnvG2dV1A9nBpKy2d0JNA=
+0xacab.org/leap/shapeshifter v0.0.0-20191029173606-85d3e8ac43e2 h1:+IGQXhBErpPeZPbeQgmGZXbcCC39kJXwWC377r8cvkw=
+0xacab.org/leap/shapeshifter v0.0.0-20191029173606-85d3e8ac43e2/go.mod h1:TRHdLzHFv5wZnWXkuqpRzEdMFk9ICgvPXmcSupSfjk8=
+github.com/AllenDang/w32 v0.0.0-20180428130237-ad0a36d80adc/go.mod h1:1rHKulT5eD2DzdKxDXUZRKtBfkTzLmTL42ZmEmOfyrs=
+github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
+github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e/go.mod h1:uw9h2sd4WWHOPdJ13MQpwK5qYWKYDumDqxWWIknEQ+k=
+github.com/BurntSushi/xgbutil v0.0.0-20190907113008-ad855c713046/go.mod h1:uw9h2sd4WWHOPdJ13MQpwK5qYWKYDumDqxWWIknEQ+k=
+github.com/OperatorFoundation/obfs4 v0.0.0-20161108041644-17f2cb99c264 h1:8UbFvUSYrlcEU9W92tohq74kYvtXJo11WLI16TMi904=
+github.com/OperatorFoundation/obfs4 v0.0.0-20161108041644-17f2cb99c264/go.mod h1:oxwvRzQ4FDp7ysA1En4F/pyOh2Jfef4YTo1YhHUsBOA=
+github.com/OperatorFoundation/shapeshifter-ipc v0.0.0-20170814234159-11746ba927e0 h1:zDYt6FDJwDSX4woVFVK2EMt7fkxU5L5qDNLUjQwA+BQ=
+github.com/OperatorFoundation/shapeshifter-ipc v0.0.0-20170814234159-11746ba927e0/go.mod h1:kB00Ak8Dgn1uZlZHLc/WsUta58Jc+n/ZhCetcPkh42Q=
+github.com/OperatorFoundation/shapeshifter-transports v0.0.0-20191101030951-7a751b0500f4 h1:rav6TvUk8+Dr3AGtCnKP5VH/4yi42IHTkbqmVXZNIi0=
+github.com/OperatorFoundation/shapeshifter-transports v0.0.0-20191101030951-7a751b0500f4/go.mod h1:u3jvRgYV13oHabVAdXekh3yk9PHfpCKvB8uolQEs4jA=
+github.com/ProtonMail/go-autostart v0.0.0-20181114175602-c5272053443a h1:fXK2KsfnkBV9Nh+9SKzHchYjuE9s0vI20JG1mbtEAcc=
+github.com/ProtonMail/go-autostart v0.0.0-20181114175602-c5272053443a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4=
+github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf/go.mod h1:peYoMncQljjNS6tZwI9WVyQB3qZS6u79/N3mBOcnd3I=
+github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
+github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
+github.com/apparentlymart/go-openvpn-mgmt v0.0.0-20161009010951-9a305aecd7f2 h1:E7mgGSu7JSN+ELgOq2Pddy8fVfAbMN8u1jUvpKpHtXg=
+github.com/apparentlymart/go-openvpn-mgmt v0.0.0-20161009010951-9a305aecd7f2/go.mod h1:69IHK2p7ZvTuKqxDx3vRWZRyBhLh2rNJN3b6XnjCVhY=
github.com/auth0/go-jwt-middleware v0.0.0-20190805220309-36081240882b h1:CvoEHGmxWl5kONC5icxwqV899dkf4VjOScbxLpllEnw=
github.com/auth0/go-jwt-middleware v0.0.0-20190805220309-36081240882b/go.mod h1:LWMyo4iOLWXHGdBki7NIht1kHru/0wM179h+d3g8ATM=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dchest/siphash v1.2.1 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4=
+github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
+github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A=
+github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7/go.mod h1:zx/1xUUeYPy3Pcmet8OSXLbF47l+3y6hIPpyLWoR9oc=
+github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o=
+github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA=
+github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
+github.com/getlantern/systray v0.0.0-20191102120558-baeca33b8639/go.mod h1:7Splj4WBQSps8jODnMgrIV6goKL0N1HR+mhCAEVWlA0=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gotk3/gotk3 v0.0.0-20191027191019-60cba67d4ea4/go.mod h1:Eew3QBwAOBTrfFFDmsDE5wZWbcagBL1NUslj1GhRveo=
+github.com/jmshal/go-locale v0.0.0-20190124211249-eb00fb25cc61/go.mod h1:+Ny9b1U6p4zX0L9w+k3hSkz3puupLFP14Mion+rGNF8=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
+github.com/mattn/go-gtk v0.0.0-20180216084204-5a311a1830ab/go.mod h1:PwzwfeB5syFHXORC3MtPylVcjIoTDT/9cvkKpEndGVI=
+github.com/mattn/go-gtk v0.0.0-20191030024613-af2e013261f5/go.mod h1:PwzwfeB5syFHXORC3MtPylVcjIoTDT/9cvkKpEndGVI=
+github.com/mattn/go-pointer v0.0.0-20171114154726-1d30dc4b6f28/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
+github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
+github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b h1:9+ke9YJ9KGWw5ANXK6ozjoK47uI3uNbXv4YVINBnGm8=
+github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
+github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/reiver/go-oi v1.0.0 h1:nvECWD7LF+vOs8leNGV/ww+F2iZKf3EYjYZ527turzM=
github.com/reiver/go-oi v1.0.0/go.mod h1:RrDBct90BAhoDTxB1fenZwfykqeGvhI6LsNfStJoEkI=
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e h1:quuzZLi72kkJjl+f5AQ93FMcadG19WkS7MO6TXFOSas=
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e/go.mod h1:+5vNVvEWwEIx86DB9Ke/+a5wBI464eDRo3eF0LcfpWg=
+github.com/sevlyar/go-daemon v0.1.5/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
+github.com/skelterjohn/go.wde v0.0.0-20180104102407-a0324cbf3ffe/go.mod h1:zXxNsJHeUYIqpg890APBNEn9GoCbA4Cdnvuv3mx4fBk=
+github.com/skelterjohn/go.wde v0.0.0-20190318181201-adc3f78cdb45/go.mod h1:zXxNsJHeUYIqpg890APBNEn9GoCbA4Cdnvuv3mx4fBk=
+github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/sqweek/dialog v0.0.0-20190728103509-6254ed5b0d3c/go.mod h1:QSrNdZLZB8VoFPGlZ2vDuA2oNaVdhld3g0PZLc7soX8=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191105034135-c7e5f84aec59 h1:PyXRxSVbvzDGuqYXjHndV7xDzJ7w2K8KD9Ef8GB7KOE=
+golang.org/x/crypto v0.0.0-20191105034135-c7e5f84aec59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191105084925-a882066a44e0 h1:QPlSTtPE2k6PZPasQUbzuK3p9JbS+vMXYVto8g/yrsg=
+golang.org/x/net v0.0.0-20191105084925-a882066a44e0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191105142833-ac3223d80179/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20191104232314-dc038396d1f0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/main.go b/main.go
index d719149..48c3efa 100644
--- a/main.go
+++ b/main.go
@@ -12,6 +12,7 @@ import (
func main() {
opts := config.NewOpts()
ch := web.NewCertHandler(opts.CaCrt, opts.CaKey)
+ authenticator := auth.GetAuthenticator(opts, false)
/* protected routes */
@@ -19,8 +20,8 @@ func main() {
http.HandleFunc("/3/refresh-token", auth.RefreshAuthMiddleware(opts.Auth))
*/
- http.Handle("/3/cert", auth.RestrictedMiddleware(opts, ch))
- http.HandleFunc("/3/auth", auth.AuthenticatorMiddleware(opts))
+ http.HandleFunc("/3/auth", web.AuthMiddleware(authenticator.CheckCredentials, opts))
+ http.Handle("/3/cert", web.RestrictedMiddleware(authenticator.NeedsCredentials, ch.CertResponder, opts))
/* static files */
@@ -36,7 +37,7 @@ func main() {
pstr := ":" + opts.Port
log.Println("Listening in port", opts.Port)
- if opts.tls == true {
+ if opts.Tls == true {
log.Fatal(http.ListenAndServeTLS(pstr, opts.TlsCrt, opts.TlsKey, nil))
} else {
log.Fatal(http.ListenAndServe(pstr, nil))
diff --git a/pkg/auth/anon/auth.go b/pkg/auth/anon/auth.go
new file mode 100644
index 0000000..52d2827
--- /dev/null
+++ b/pkg/auth/anon/auth.go
@@ -0,0 +1,44 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package anon
+
+import (
+ "0xacab.org/leap/vpnweb/pkg/auth/creds"
+ "0xacab.org/leap/vpnweb/pkg/config"
+)
+
+const Label string = "anon"
+
+// AnonAuthenticator will allow anyone to get access to a protected resource (Like VPN certificates).
+// Used by RiseupVPN
+type Authenticator struct {
+}
+
+func (a *Authenticator) GetLabel() string {
+ return Label
+}
+
+func (a *Authenticator) CheckCredentials(cred *creds.Credentials) bool {
+ return true
+}
+
+func (a *Authenticator) NeedsCredentials() bool {
+ return false
+}
+
+func GetAuthenticator(opts *config.Opts, skipInit bool) *Authenticator {
+ return &Authenticator{}
+}
diff --git a/pkg/auth/creds/creds.go b/pkg/auth/creds/creds.go
new file mode 100644
index 0000000..65b3017
--- /dev/null
+++ b/pkg/auth/creds/creds.go
@@ -0,0 +1,21 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package creds
+
+type Credentials struct {
+ User string
+ Password string
+}
diff --git a/pkg/auth/interfaces.go b/pkg/auth/interfaces.go
new file mode 100644
index 0000000..619eff8
--- /dev/null
+++ b/pkg/auth/interfaces.go
@@ -0,0 +1,26 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package auth
+
+import (
+ "0xacab.org/leap/vpnweb/pkg/auth/creds"
+)
+
+type Authenticator interface {
+ GetLabel() string
+ NeedsCredentials() bool
+ CheckCredentials(*creds.Credentials) bool
+}
diff --git a/pkg/auth/mechanism.go b/pkg/auth/mechanism.go
new file mode 100644
index 0000000..8a28739
--- /dev/null
+++ b/pkg/auth/mechanism.go
@@ -0,0 +1,49 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package auth
+
+import (
+ "0xacab.org/leap/vpnweb/pkg/auth/anon"
+ "0xacab.org/leap/vpnweb/pkg/auth/sip2"
+ "0xacab.org/leap/vpnweb/pkg/config"
+ "log"
+)
+
+func GetAuthenticator(opts *config.Opts, skipConnect bool) Authenticator {
+ switch opts.Auth {
+ case anon.Label:
+ return anon.GetAuthenticator(opts, skipConnect)
+ case sip2.Label:
+ doAuthenticationChecks(opts)
+ return sip2.GetAuthenticator(opts, skipConnect)
+ default:
+ bailOnBadAuthModule(opts.Auth)
+ }
+ return nil
+}
+
+func doAuthenticationChecks(opts *config.Opts) {
+ if opts.AuthSecret == "" {
+ log.Fatal("Need to provide an AuthSecret value for SIP Authentication")
+ }
+ if len(opts.AuthSecret) < 20 {
+ log.Fatal("Please provider an AuthSecret longer than 20 chars")
+ }
+}
+
+func bailOnBadAuthModule(module string) {
+ log.Fatal("Unknown auth module: '", module, "'. Should be one of: ", sip2.Label, ", ", anon.Label, ".")
+}
diff --git a/pkg/auth/mechanism_test.go b/pkg/auth/mechanism_test.go
new file mode 100644
index 0000000..1a397b1
--- /dev/null
+++ b/pkg/auth/mechanism_test.go
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package auth
+
+import (
+ "0xacab.org/leap/vpnweb/pkg/config"
+ "os"
+ "testing"
+)
+
+func TestGetAuthenticator(t *testing.T) {
+ opts := &config.Opts{}
+ opts.Auth = "anon"
+
+ a := GetAuthenticator(opts, true)
+ if a.GetLabel() != "anon" {
+ t.Errorf("expected anon authenticator")
+ }
+
+ /* TODO test no secret */
+ /* TODO test short secret */
+ /* TODO refactor init to return proper errors */
+ /* TODO test invalid auth method */
+
+ os.Setenv("VPNWEB_SIP_USER", "user")
+ os.Setenv("VPNWEB_SIP_PASS", "pass")
+ os.Setenv("VPNWEB_SIP_LIBR_LOCATION", "test")
+ opts.Auth = "sip2"
+ opts.AuthSecret = "sikret000000000000000000000"
+ a = GetAuthenticator(opts, true)
+ if a.GetLabel() != "sip2" {
+ t.Errorf("expected sip authenticator")
+ }
+}
diff --git a/pkg/auth/middleware.go b/pkg/auth/middleware.go
deleted file mode 100644
index 280ceeb..0000000
--- a/pkg/auth/middleware.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package auth
-
-import (
- "0xacab.org/leap/vpnweb/pkg/auth/sip2"
- "0xacab.org/leap/vpnweb/pkg/config"
- "0xacab.org/leap/vpnweb/pkg/web"
- "github.com/auth0/go-jwt-middleware"
- "github.com/dgrijalva/jwt-go"
- "log"
- "net/http"
-)
-
-const (
- anonAuth = "anon"
- sip2Auth = "sip"
-)
-
-func bailOnBadAuthModule(module string) {
- log.Fatal("Unknown auth module: '", module, "'. Should be one of: ", anonAuth, ", ", sip2Auth, ".")
-}
-
-func checkForAuthSecret(opts *config.Opts) {
- if opts.AuthSecret == "" {
- log.Fatal("Need to provide a AuthSecret value for SIP Authentication")
- }
- if len(opts.AuthSecret) < 20 {
- log.Fatal("Please provider an AuthSecret longer than 20 chars")
- }
-}
-
-func AuthenticatorMiddleware(opts *config.Opts) http.HandlerFunc {
- switch opts.Auth {
- case anonAuth:
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- http.Error(w, "no authentication in anon mode", http.StatusBadRequest)
- })
- case sip2Auth:
- checkForAuthSecret(opts)
- return sip2.SipAuthenticator(opts)
- default:
- bailOnBadAuthModule(opts.Auth)
- }
- return nil
-}
-
-func RestrictedMiddleware(opts *config.Opts, ch web.CertHandler) http.Handler {
-
- jwtMiddleware := jwtmiddleware.New(jwtmiddleware.Options{
- ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
- return []byte(opts.AuthSecret), nil
- },
- SigningMethod: jwt.SigningMethodHS256,
- })
-
- switch opts.Auth {
- case anonAuth:
- return http.HandlerFunc(ch.CertResponder)
- case sip2Auth:
- checkForAuthSecret(opts)
- return jwtMiddleware.Handler(http.HandlerFunc(ch.CertResponder))
- default:
- bailOnBadAuthModule(opts.Auth)
- }
- return nil
-}
diff --git a/pkg/auth/sip2/auth.go b/pkg/auth/sip2/auth.go
index 9c01c28..47733c2 100644
--- a/pkg/auth/sip2/auth.go
+++ b/pkg/auth/sip2/auth.go
@@ -1,33 +1,46 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
package sip2
import (
- "encoding/json"
- "github.com/dgrijalva/jwt-go"
+ "errors"
"log"
- "net/http"
"os"
- "time"
"0xacab.org/leap/vpnweb/pkg/config"
)
-const sipUserVar string = "VPNWEB_SIP_USER"
-const sipPassVar string = "VPNWEB_SIP_PASS"
-const sipPortVar string = "VPNWEB_SIP_PORT"
-const sipHostVar string = "VPNWEB_SIP_HOST"
-const sipLibrLocVar string = "VPNWEB_SIP_LIBR_LOCATION"
-const sipTerminatorVar string = "VPNWEB_SIP_TERMINATOR"
-const sipDefaultTerminator string = "\r\n"
-
-type Credentials struct {
- User string
- Password string
-}
+const (
+ sipUserVar string = "VPNWEB_SIP_USER"
+ sipPassVar string = "VPNWEB_SIP_PASS"
+ sipPortVar string = "VPNWEB_SIP_PORT"
+ sipHostVar string = "VPNWEB_SIP_HOST"
+ sipLibrLocVar string = "VPNWEB_SIP_LIBR_LOCATION"
+ sipTerminatorVar string = "VPNWEB_SIP_TERMINATOR"
+ sipDefaultTerminator string = "\r\n"
+)
-func getConfigFromEnv(envVar string) string {
+func getConfigFromEnv(envVar, defaultVar string) string {
val, exists := os.LookupEnv(envVar)
if !exists {
- log.Fatal("Need to set required env var:", envVar)
+ if defaultVar == "" {
+ log.Fatal("Need to set required env var: ", envVar)
+ } else {
+ return defaultVar
+ }
}
return val
}
@@ -41,60 +54,40 @@ func setupTerminatorFromEnv() {
}
}
-func SipAuthenticator(opts *config.Opts) http.HandlerFunc {
-
+func initializeSipConnection(skipConnect bool) (sipClient, error) {
log.Println("Initializing SIP2 authenticator")
- SipUser := getConfigFromEnv(sipUserVar)
- SipPass := getConfigFromEnv(sipPassVar)
- SipHost := getConfigFromEnv(sipHostVar)
- SipPort := getConfigFromEnv(sipPortVar)
- SipLibrLoc := getConfigFromEnv(sipLibrLocVar)
+ user := getConfigFromEnv(sipUserVar, "")
+ pass := getConfigFromEnv(sipPassVar, "")
+ host := getConfigFromEnv(sipHostVar, "localhost")
+ port := getConfigFromEnv(sipPortVar, "6001")
+ loc := getConfigFromEnv(sipLibrLocVar, "")
setupTerminatorFromEnv()
- sip := NewClient(SipHost, SipPort, SipLibrLoc)
+ sip := newClient(host, port, loc)
+
+ if skipConnect {
+ // mainly for testing purposes at the moment
+ return sip, nil
+ }
ok, err := sip.Connect()
if err != nil {
- log.Fatal("Cannot connect sip client")
+ return sip, err
}
- ok = sip.Login(SipUser, SipPass)
+ ok = sip.Login(user, pass)
if !ok {
- log.Fatal("Error on SIP login")
- } else {
- log.Println("SIP login ok")
+ return sip, errors.New("SIP login error")
}
+ return sip, nil
+}
- var authTokenHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- var c Credentials
-
- err := json.NewDecoder(r.Body).Decode(&c)
- if err != nil {
- log.Println("Auth request did not send valid json")
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
-
- if c.User == "" || c.Password == "" {
- log.Println("Auth request did not include user or password")
- http.Error(w, "missing user and/or password", http.StatusBadRequest)
- return
- }
-
- valid := sip.CheckCredentials(c.User, c.Password)
- if !valid {
- log.Println("Wrong auth for user", c.User)
- http.Error(w, "wrong user and/or password", http.StatusUnauthorized)
- return
- }
+func GetAuthenticator(opts *config.Opts, skipConnect bool) *sipClient {
- log.Println("Valid auth for user", c.User)
- token := jwt.New(jwt.SigningMethodHS256)
- claims := token.Claims.(jwt.MapClaims)
- claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
- tokenString, _ := token.SignedString([]byte(opts.AuthSecret))
- w.Write([]byte(tokenString))
- })
- return authTokenHandler
+ sip, err := initializeSipConnection(skipConnect)
+ if err != nil {
+ log.Fatal("Cannot initialize sip:", err)
+ }
+ return &sip
}
diff --git a/pkg/auth/sip2/client.go b/pkg/auth/sip2/client.go
index 7116a84..9adf218 100644
--- a/pkg/auth/sip2/client.go
+++ b/pkg/auth/sip2/client.go
@@ -1,31 +1,50 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
package sip2
import (
+ "0xacab.org/leap/vpnweb/pkg/auth/creds"
"fmt"
"github.com/reiver/go-telnet"
"log"
"time"
)
-const loginRequestTemplate string = "9300CN%s|CO%s|CP%s|"
-const statusRequestTemplate string = "23000%s %sAO%s|AA%s|AD%s|"
+const (
+ Label string = "sip2"
+ loginRequestTemplate string = "9300CN%s|CO%s|CP%s|"
+ statusRequestTemplate string = "23000%s %sAO%s|AA%s|AD%s|"
+)
-type Client struct {
- Host string
- Port string
+type sipClient struct {
+ host string
+ port string
location string
conn *telnet.Conn
parser *Parser
}
-func NewClient(host, port, location string) Client {
- c := Client{host, port, location, nil, nil}
+func newClient(host, port, location string) sipClient {
+ c := sipClient{host, port, location, nil, nil}
c.parser = getParser()
return c
}
-func (c *Client) Connect() (bool, error) {
- conn, err := telnet.DialTo(c.Host + ":" + c.Port)
+func (c *sipClient) Connect() (bool, error) {
+ conn, err := telnet.DialTo(c.host + ":" + c.port)
if nil != err {
log.Println("error", err)
return false, err
@@ -34,7 +53,7 @@ func (c *Client) Connect() (bool, error) {
return true, nil
}
-func (c *Client) Login(user, pass string) bool {
+func (c *sipClient) Login(user, pass string) bool {
loginStr := fmt.Sprintf(loginRequestTemplate, user, pass, c.location)
if nil == c.conn {
fmt.Println("error! null connection")
@@ -42,14 +61,31 @@ func (c *Client) Login(user, pass string) bool {
telnetSend(c.conn, loginStr)
loginResp := telnetRead(c.conn)
msg := c.parseResponse(loginResp)
- if value, ok := c.parser.getFixedFieldValue(msg, Ok); ok && value == TRUE {
+ if value, ok := c.parser.getFixedFieldValue(msg, okVal); ok && value == trueVal {
return true
}
return false
}
-func (c *Client) CheckCredentials(user, passwd string) bool {
+func (c *sipClient) parseResponse(txt string) *message {
+ msg := c.parser.parseMessage(txt)
+ return msg
+}
+
+/* Authenticator interface */
+
+func (c *sipClient) GetLabel() string {
+ return Label
+}
+
+func (c *sipClient) NeedsCredentials() bool {
+ return true
+}
+
+func (c *sipClient) CheckCredentials(credentials *creds.Credentials) bool {
currentTime := time.Now()
+ user := credentials.User
+ passwd := credentials.Password
statusRequest := fmt.Sprintf(
statusRequestTemplate,
currentTime.Format("20060102"),
@@ -58,8 +94,8 @@ func (c *Client) CheckCredentials(user, passwd string) bool {
telnetSend(c.conn, statusRequest)
statusMsg := c.parseResponse(telnetRead(c.conn))
- if value, ok := c.parser.getFieldValue(statusMsg, ValidPatron); ok && value == YES {
- if value, ok := c.parser.getFieldValue(statusMsg, ValidPatronPassword); ok && value == YES {
+ if value, ok := c.parser.getFieldValue(statusMsg, validPatron); ok && value == yes {
+ if value, ok := c.parser.getFieldValue(statusMsg, validPatronPassword); ok && value == yes {
return true
}
}
@@ -67,8 +103,3 @@ func (c *Client) CheckCredentials(user, passwd string) bool {
// TODO log whatever error we can find (AF, Screen Message, for instance)
return false
}
-
-func (c *Client) parseResponse(txt string) *Message {
- msg := c.parser.parseMessage(txt)
- return msg
-}
diff --git a/pkg/auth/sip2/spec.go b/pkg/auth/sip2/spec.go
index af65b33..09561e6 100644
--- a/pkg/auth/sip2/spec.go
+++ b/pkg/auth/sip2/spec.go
@@ -1,3 +1,18 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
package sip2
import (
diff --git a/pkg/auth/sip2/telnet.go b/pkg/auth/sip2/telnet.go
index ae5004e..7d8c4fa 100644
--- a/pkg/auth/sip2/telnet.go
+++ b/pkg/auth/sip2/telnet.go
@@ -1,3 +1,18 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
package sip2
import (
diff --git a/pkg/config/main.go b/pkg/config/main.go
index c5b687e..1ce00aa 100644
--- a/pkg/config/main.go
+++ b/pkg/config/main.go
@@ -1,3 +1,18 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
package config
import (
diff --git a/pkg/web/certs.go b/pkg/web/certs.go
index 9cccc65..779bf72 100644
--- a/pkg/web/certs.go
+++ b/pkg/web/certs.go
@@ -1,3 +1,18 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
package web
import (
diff --git a/pkg/web/handlers.go b/pkg/web/handlers.go
index b7675f5..633ae95 100644
--- a/pkg/web/handlers.go
+++ b/pkg/web/handlers.go
@@ -1,3 +1,18 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
package web
import (
diff --git a/pkg/web/middleware.go b/pkg/web/middleware.go
new file mode 100644
index 0000000..3a74477
--- /dev/null
+++ b/pkg/web/middleware.go
@@ -0,0 +1,89 @@
+// Copyright (C) 2019 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package web
+
+import (
+ "0xacab.org/leap/vpnweb/pkg/auth/creds"
+ "0xacab.org/leap/vpnweb/pkg/config"
+ "encoding/json"
+ "github.com/auth0/go-jwt-middleware"
+ "github.com/dgrijalva/jwt-go"
+ "log"
+ "net/http"
+ "os"
+ "strings"
+ "time"
+)
+
+const debugAuth string = "VPNWEB_DEBUG_AUTH"
+
+func AuthMiddleware(authenticationFunc func(*creds.Credentials) bool, opts *config.Opts) http.HandlerFunc {
+ debugAuth, exists := os.LookupEnv(debugAuth)
+ if !exists {
+ debugAuth = "false"
+ }
+ var authHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ var c creds.Credentials
+ err := json.NewDecoder(r.Body).Decode(&c)
+ if err != nil {
+ log.Println("Auth request did not send valid json")
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ if c.User == "" || c.Password == "" {
+ log.Println("Auth request did not include user or password")
+ http.Error(w, "Missing user and/or password", http.StatusBadRequest)
+ return
+ }
+
+ valid := authenticationFunc(&c)
+
+ if !valid {
+ log.Println("Wrong auth for user", c.User)
+ http.Error(w, "Wrong user and/or password", http.StatusUnauthorized)
+ return
+ }
+
+ if strings.ToLower(debugAuth) == "yes" {
+ log.Println("Valid auth for user", c.User)
+ }
+ token := jwt.New(jwt.SigningMethodHS256)
+ claims := token.Claims.(jwt.MapClaims)
+ claims["expiration"] = time.Now().Add(time.Hour * 24).Unix()
+ tokenString, _ := token.SignedString([]byte(opts.AuthSecret))
+ w.Write([]byte(tokenString))
+ })
+ return authHandler
+}
+
+func RestrictedMiddleware(shouldProtect func() bool, handler func(w http.ResponseWriter, r *http.Request), opts *config.Opts) http.Handler {
+
+ jwtMiddleware := jwtmiddleware.New(jwtmiddleware.Options{
+ ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
+ return []byte(opts.AuthSecret), nil
+ },
+ SigningMethod: jwt.SigningMethodHS256,
+ })
+
+ switch shouldProtect() {
+ case false:
+ return http.HandlerFunc(handler)
+ case true:
+ return jwtMiddleware.Handler(http.HandlerFunc(handler))
+ }
+ return nil
+}