From 819adbbb708076bcf9d3ee6443c704303aad5a80 Mon Sep 17 00:00:00 2001 From: "kali kaneko (leap communications)" Date: Thu, 30 Jan 2020 19:08:14 -0600 Subject: refactor auth middleware --- Makefile | 4 +- go.mod | 2 + go.sum | 88 ++++++++++++++++++++++++++++++++++ main.go | 7 +-- pkg/auth/anon/auth.go | 44 +++++++++++++++++ pkg/auth/creds/creds.go | 21 +++++++++ pkg/auth/interfaces.go | 26 ++++++++++ pkg/auth/mechanism.go | 49 +++++++++++++++++++ pkg/auth/mechanism_test.go | 47 ++++++++++++++++++ pkg/auth/middleware.go | 65 ------------------------- pkg/auth/sip2/auth.go | 115 +++++++++++++++++++++------------------------ pkg/auth/sip2/client.go | 69 +++++++++++++++++++-------- pkg/auth/sip2/spec.go | 15 ++++++ pkg/auth/sip2/telnet.go | 15 ++++++ pkg/config/main.go | 15 ++++++ pkg/web/certs.go | 15 ++++++ pkg/web/handlers.go | 15 ++++++ pkg/web/middleware.go | 89 +++++++++++++++++++++++++++++++++++ 18 files changed, 551 insertions(+), 150 deletions(-) create mode 100644 pkg/auth/anon/auth.go create mode 100644 pkg/auth/creds/creds.go create mode 100644 pkg/auth/interfaces.go create mode 100644 pkg/auth/mechanism.go create mode 100644 pkg/auth/mechanism_test.go delete mode 100644 pkg/auth/middleware.go create mode 100644 pkg/web/middleware.go 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 . + +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 . + +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 . + +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 . + +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 . + +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 . + 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 . + 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 . + 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 . + 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 . + 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 . + 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 . + 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 . + +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 +} -- cgit v1.2.3