From b3783dffb56a48ae936564f2a3d5763f15cd0529 Mon Sep 17 00:00:00 2001 From: Michael Aldridge Date: Fri, 21 Aug 2020 00:03:53 -0700 Subject: [PATCH] internal/ldap: Initial boilerplate --- go.mod | 11 ++++ go.sum | 138 ++++++++++++++++++++++++++++++++++++++++ internal/ldap/bind.go | 34 ++++++++++ internal/ldap/ldap.go | 81 +++++++++++++++++++++++ internal/ldap/search.go | 67 +++++++++++++++++++ internal/ldap/type.go | 19 ++++++ internal/ldap/util.go | 9 +++ main.go | 50 +++++++++++++++ 8 files changed, 409 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/ldap/bind.go create mode 100644 internal/ldap/ldap.go create mode 100644 internal/ldap/search.go create mode 100644 internal/ldap/type.go create mode 100644 internal/ldap/util.go create mode 100644 main.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..ff45457 --- /dev/null +++ b/go.mod @@ -0,0 +1,11 @@ +module github.com/netauth/ldap + +go 1.15 + +require ( + github.com/hashicorp/go-hclog v0.9.2 + github.com/netauth/netauth v0.3.4 + github.com/ps78674/goldap v0.0.0-20200721080011-cd2e7ee23841 + github.com/ps78674/ldapserver v0.0.0-20200521101606-2395f680392c + github.com/spf13/viper v1.3.2 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..86a8691 --- /dev/null +++ b/go.sum @@ -0,0 +1,138 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/RoaringBitmap/roaring v0.4.17/go.mod h1:D3qVegWTmfCaX4Bl5CrBE9hfrSrrXIr8KVNvRsDi1NI= +github.com/Smerity/govarint v0.0.0-20150407073650-7265e41f48f1/go.mod h1:o80NPAib/LOl8Eysqppjj7kkGkqz++eqzYGlvROpDcQ= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/blevesearch/bleve v0.7.0/go.mod h1:Y2lmIkzV6mcNfAnAdOd+ZxHkHchhBfU/xroGIp61wfw= +github.com/blevesearch/blevex v0.0.0-20180227211930-4b158bb555a3/go.mod h1:WH+MU2F4T0VmSdaPX+Wu5GYoZBrYWdOZWSjzvYcDmqQ= +github.com/blevesearch/go-porterstemmer v1.0.2/go.mod h1:haWQqFT3RdOGz7PJuM3or/pWNJS1pKkoZJWCkWu0DVA= +github.com/blevesearch/segment v0.0.0-20160915185041-762005e7a34f/go.mod h1:IInt5XRvpiGE09KOk9mmCMLjHhydIhNPKPPFLFBB7L8= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/couchbase/vellum v0.0.0-20190328134517-462e86d8716b/go.mod h1:prYTC8EgTu3gwbqJihkud9zRXISvyulAplQ6exdCo1g= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= +github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= +github.com/cznic/strutil v0.0.0-20181122101858-275e90344537/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= +github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= +github.com/netauth/netauth v0.3.4 h1:nAWT15xzGOtQ3TmuFgN0yYUleSzpDv09WKNj623+TCI= +github.com/netauth/netauth v0.3.4/go.mod h1:J72ArpIVnQDgBUv/e6iCjg9U6yOrpLOF4o4UKQd51pQ= +github.com/netauth/protocol v0.0.0-20191124005711-167b58b61c72 h1:TRWDX4YIgajtmV3DHPrj7J/mNcg1C0YiRNppdQACstg= +github.com/netauth/protocol v0.0.0-20191124005711-167b58b61c72/go.mod h1:xaNx5CDzZAIQf/05XC49krheuDM51d0ghkBw8liKAag= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/ps78674/goldap v0.0.0-20200721080011-cd2e7ee23841 h1:K8RUAFsylWykxjpgTU/oW4I7h7+W/zAcN16ZogFaOds= +github.com/ps78674/goldap v0.0.0-20200721080011-cd2e7ee23841/go.mod h1:1I9otN1F15q9oNDy1XDfWWCMl5qD2bUHG8OC+IwyDa0= +github.com/ps78674/ldapserver v0.0.0-20200521101606-2395f680392c h1:/zfKmv5fhYt0LzAQx04RVJ8p+v7ejfup1+Jt6S9ijYo= +github.com/ps78674/ldapserver v0.0.0-20200521101606-2395f680392c/go.mod h1:l2UBdoHdF4GrVGhunn7fxIdpTl7sTtvR67thWxhq+/k= +github.com/radovskyb/watcher v1.0.6/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg= +github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff/go.mod h1:KSQcGKpxUMHk3nbYzs/tIBAM2iDooCn0BmttHOJEbLs= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/steveyen/gtreap v0.0.0-20150807155958-0abe01ef9be2/go.mod h1:mjqs7N0Q6m5HpR7QfXVBZXZWSqTjQLeTujjA/xUp2uw= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/tecbot/gorocksdb v0.0.0-20181010114359-8752a9433481/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= +github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/ldap/bind.go b/internal/ldap/bind.go new file mode 100644 index 0000000..a76e15a --- /dev/null +++ b/internal/ldap/bind.go @@ -0,0 +1,34 @@ +package ldap + +import ( + "context" + + ldap "github.com/ps78674/ldapserver" +) + +func (s *server) handleBind(w ldap.ResponseWriter, m *ldap.Message) { + ctx := context.Background() + + r := m.GetBindRequest() + // The server only supports simple auth, no SASL or anything + // fancy because we are after all just fronting another + // protocol. + if r.AuthenticationChoice() != "simple" { + res := ldap.NewBindResponse(ldap.LDAPResultUnwillingToPerform) + res.SetDiagnosticMessage("Authentication choice not supported") + w.Write(res) + return + } + + s.l.Debug("Bind from dn", "dn", r.Name()) + + if err := s.c.AuthEntity(ctx, entityIDFromDN(r.Name()), string(r.AuthenticationSimple())); err != nil { + res := ldap.NewBindResponse(ldap.LDAPResultInvalidCredentials) + res.SetDiagnosticMessage("invalid credentials") + w.Write(res) + return + } + + res := ldap.NewBindResponse(ldap.LDAPResultSuccess) + w.Write(res) +} diff --git a/internal/ldap/ldap.go b/internal/ldap/ldap.go new file mode 100644 index 0000000..0bafc29 --- /dev/null +++ b/internal/ldap/ldap.go @@ -0,0 +1,81 @@ +package ldap + +import ( + "os" + "os/signal" + "syscall" + + "github.com/hashicorp/go-hclog" + ldap "github.com/ps78674/ldapserver" +) + +// New returns a new ldap server instance +func New(l hclog.Logger, nacl naClient) *server { + x := new(server) + x.l = l.Named("ldap") + x.c = nacl + x.Server = ldap.NewServer() + + routes := ldap.NewRouteMux() + routes.NotFound(x.handleNotFound) + routes.Abandon(x.handleAbandon) + routes.Bind(x.handleBind) + + routes.Search(x.handleSearchDSE). + BaseDn(""). + Scope(ldap.SearchRequestScopeBaseObject). + Filter("(objectclass=*)"). + Label("Search - ROOT DSE") + + routes.Search(x.handleSearchMyCompany). + BaseDn("o=My Company, c=US"). + Scope(ldap.SearchRequestScopeBaseObject). + Label("Search - Compagny Root") + + routes.Search(x.handleSearch).Label("Search - Generic") + + x.Handle(routes) + + return x +} + +// Serve serves a plaintext DSA on the provided bind string. +func (s *server) Serve(bind string) error { + chErr := make(chan error) + defer close(chErr) + go s.ListenAndServe(bind, chErr) + if err := <-chErr; err != nil { + s.l.Error("Error from main server thread", "error", err) + return err + } + + ch := make(chan os.Signal, 5) + signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) + <-ch + close(ch) + s.Stop() + return nil +} + +func (s *server) handleNotFound(w ldap.ResponseWriter, r *ldap.Message) { + switch r.ProtocolOpType() { + case ldap.ApplicationBindRequest: + res := ldap.NewBindResponse(ldap.LDAPResultSuccess) + res.SetDiagnosticMessage("Default binding behavior set to return Success") + + w.Write(res) + + default: + res := ldap.NewResponse(ldap.LDAPResultUnwillingToPerform) + res.SetDiagnosticMessage("Operation not implemented by server") + w.Write(res) + } +} + +func (s *server) handleAbandon(w ldap.ResponseWriter, m *ldap.Message) { + var req = m.GetAbandonRequest() + // retreive the request to abandon, and send a abort signal to it + if requestToAbandon, ok := m.Client.GetMessageByID(int(req)); ok { + requestToAbandon.Abandon() + } +} diff --git a/internal/ldap/search.go b/internal/ldap/search.go new file mode 100644 index 0000000..a3f5c50 --- /dev/null +++ b/internal/ldap/search.go @@ -0,0 +1,67 @@ +package ldap + +import ( + "log" + + ldap "github.com/ps78674/ldapserver" +) + +func (s *server) handleSearchDSE(w ldap.ResponseWriter, m *ldap.Message) { + e := ldap.NewSearchResultEntry("") + e.AddAttribute("vendorName", "NetAuth") + e.AddAttribute("vendorVersion", "1.0") + e.AddAttribute("objectClass", "top", "extensibleObject") + e.AddAttribute("supportedLDAPVersion", "3") + e.AddAttribute("namingContexts", "o=My Company, c=US") + w.Write(e) + + res := ldap.NewSearchResultDoneResponse(ldap.LDAPResultSuccess) + w.Write(res) +} + +func (s *server) handleSearchMyCompany(w ldap.ResponseWriter, m *ldap.Message) { + r := m.GetSearchRequest() + log.Printf("handleSearchMyCompany - Request BaseDn=%s", r.BaseObject()) + + e := ldap.NewSearchResultEntry(string(r.BaseObject())) + e.AddAttribute("objectClass", "top", "organizationalUnit") + w.Write(e) + + res := ldap.NewSearchResultDoneResponse(ldap.LDAPResultSuccess) + w.Write(res) +} + +func (s *server) handleSearch(w ldap.ResponseWriter, m *ldap.Message) { + r := m.GetSearchRequest() + log.Printf("Request BaseDn=%s", r.BaseObject()) + log.Printf("Request Filter=%s", r.Filter()) + log.Printf("Request FilterString=%s", r.FilterString()) + log.Printf("Request Attributes=%s", r.Attributes()) + log.Printf("Request TimeLimit=%d", r.TimeLimit().Int()) + + // Handle Stop Signal (server stop / client disconnected / Abandoned request....) + select { + case <-m.Done: + log.Print("Leaving handleSearch...") + return + default: + } + + e := ldap.NewSearchResultEntry("cn=Valere JEANTET, " + string(r.BaseObject())) + e.AddAttribute("mail", "valere.jeantet@gmail.com", "mail@vjeantet.fr") + e.AddAttribute("company", "SODADI") + e.AddAttribute("department", "DSI/SEC") + e.AddAttribute("l", "Ferrieres en brie") + e.AddAttribute("mobile", "0612324567") + e.AddAttribute("telephoneNumber", "0612324567") + e.AddAttribute("cn", "Valère JEANTET") + w.Write(e) + + e = ldap.NewSearchResultEntry("cn=Claire Thomas, " + string(r.BaseObject())) + e.AddAttribute("mail", "claire.thomas@gmail.com") + e.AddAttribute("cn", "Claire THOMAS") + w.Write(e) + + res := ldap.NewSearchResultDoneResponse(ldap.LDAPResultSuccess) + w.Write(res) +} diff --git a/internal/ldap/type.go b/internal/ldap/type.go new file mode 100644 index 0000000..9760744 --- /dev/null +++ b/internal/ldap/type.go @@ -0,0 +1,19 @@ +package ldap + +import ( + "context" + + "github.com/hashicorp/go-hclog" + ldap "github.com/ps78674/ldapserver" +) + +type naClient interface { + AuthEntity(context.Context, string, string) error +} + +type server struct { + *ldap.Server + + c naClient + l hclog.Logger +} diff --git a/internal/ldap/util.go b/internal/ldap/util.go new file mode 100644 index 0000000..475d263 --- /dev/null +++ b/internal/ldap/util.go @@ -0,0 +1,9 @@ +package ldap + +import ( + "github.com/ps78674/goldap/message" +) + +func entityIDFromDN(message.LDAPDN) string { + return "" +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..645e602 --- /dev/null +++ b/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "log" + "os" + + "github.com/hashicorp/go-hclog" + "github.com/netauth/ldap/internal/ldap" + "github.com/netauth/netauth/pkg/netauth" + "github.com/spf13/viper" +) + +func main() { + var appLogger hclog.Logger + + llevel := os.Getenv("NETAUTH_LOGLEVEL") + if llevel != "" { + appLogger = hclog.New(&hclog.LoggerOptions{ + Name: "ldap-proxy", + Level: hclog.LevelFromString(llevel), + }) + } else { + appLogger = hclog.NewNullLogger() + } + + log.SetOutput(appLogger.Named("ldap.protocol").StandardWriter(&hclog.StandardLoggerOptions{ForceLevel: hclog.Trace})) + log.SetPrefix("") + log.SetFlags(0) + + viper.SetConfigName("config") + viper.AddConfigPath("/etc/netauth/") + viper.AddConfigPath("$HOME/.netauth/") + viper.AddConfigPath(".") + if err := viper.ReadInConfig(); err != nil { + appLogger.Error("Error loading config", "error", err) + os.Exit(5) + } + + nacl, err := netauth.NewWithLog(appLogger.Named("netauth")) + if err != nil { + os.Exit(2) + } + + ls := ldap.New(appLogger, nacl) + if err := ls.Serve("localhost:10389"); err != nil { + appLogger.Error("Error serving", "error", err) + return + } + appLogger.Info("Goodbye!") +}