mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	[Vendor] Update go-ldap to v3.2.4 (#13163)
* [Vendor] update go-ldap to v3.0.3 * update go-ldap to v3.2.4 Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
		
							
								
								
									
										3
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
									
									
									
									
								
							| @@ -39,6 +39,7 @@ require ( | ||||
| 	github.com/go-enry/go-enry/v2 v2.5.2 | ||||
| 	github.com/go-git/go-billy/v5 v5.0.0 | ||||
| 	github.com/go-git/go-git/v5 v5.1.0 | ||||
| 	github.com/go-ldap/ldap/v3 v3.2.4 | ||||
| 	github.com/go-redis/redis/v7 v7.4.0 | ||||
| 	github.com/go-sql-driver/mysql v1.5.0 | ||||
| 	github.com/go-swagger/go-swagger v0.25.0 | ||||
| @@ -112,10 +113,8 @@ require ( | ||||
| 	golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect | ||||
| 	golang.org/x/tools v0.0.0-20200921210052-fa0125251cc4 | ||||
| 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect | ||||
| 	gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 // indirect | ||||
| 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df | ||||
| 	gopkg.in/ini.v1 v1.61.0 | ||||
| 	gopkg.in/ldap.v3 v3.0.2 | ||||
| 	gopkg.in/yaml.v2 v2.3.0 | ||||
| 	mvdan.cc/xurls/v2 v2.1.0 | ||||
| 	strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 | ||||
|   | ||||
							
								
								
									
										11
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								go.sum
									
									
									
									
									
								
							| @@ -50,6 +50,8 @@ gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGq | ||||
| gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= | ||||
| github.com/6543/go-version v1.2.3 h1:uF30BawMhoQLzqBeCwhFcWM6HVxlzMHe/zXbzJeKP+o= | ||||
| github.com/6543/go-version v1.2.3/go.mod h1:fcfWh4zkneEgGXe8JJptiGwp8l6JgJJgS7oTw6P83So= | ||||
| github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28= | ||||
| github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= | ||||
| github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= | ||||
| github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||
| github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= | ||||
| @@ -242,6 +244,8 @@ github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a h1:FQqo | ||||
| github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= | ||||
| github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8= | ||||
| github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= | ||||
| github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8= | ||||
| github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= | ||||
| github.com/go-enry/go-enry/v2 v2.5.2 h1:3f3PFAO6JitWkPi1GQ5/m6Xu4gNL1U5soJ8QaYqJ0YQ= | ||||
| github.com/go-enry/go-enry/v2 v2.5.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= | ||||
| github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo= | ||||
| @@ -256,6 +260,8 @@ github.com/go-git/go-git/v5 v5.1.0 h1:HxJn9g/E7eYvKW3Fm7Jt4ee8LXfPOm/H1cdDu8vEss | ||||
| github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM= | ||||
| github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= | ||||
| github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= | ||||
| github.com/go-ldap/ldap/v3 v3.2.4 h1:PFavAq2xTgzo/loE8qNXcQaofAaqIpI4WgaLdv+1l3E= | ||||
| github.com/go-ldap/ldap/v3 v3.2.4/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg= | ||||
| github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= | ||||
| github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= | ||||
| github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= | ||||
| @@ -934,6 +940,7 @@ golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8U | ||||
| golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
| golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
| golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
| golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
| golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
| golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= | ||||
| @@ -1148,8 +1155,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba | ||||
| gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= | ||||
| gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= | ||||
| gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= | ||||
| gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 h1:nn6Zav2sOQHCFJHEspya8KqxhFwKci30UxHy3HXPTyQ= | ||||
| gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| @@ -1170,8 +1175,6 @@ gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= | ||||
| gopkg.in/ini.v1 v1.60.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= | ||||
| gopkg.in/ini.v1 v1.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10= | ||||
| gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= | ||||
| gopkg.in/ldap.v3 v3.0.2 h1:R6RBtabK6e1GO0eQKtkyOFbAHO73QesLzI2w2DZ6b9w= | ||||
| gopkg.in/ldap.v3 v3.0.2/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw= | ||||
| gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= | ||||
| gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= | ||||
| gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= | ||||
|   | ||||
| @@ -14,7 +14,7 @@ import ( | ||||
|  | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
|  | ||||
| 	"gopkg.in/ldap.v3" | ||||
| 	"github.com/go-ldap/ldap/v3" | ||||
| ) | ||||
|  | ||||
| // SecurityProtocol protocol type | ||||
|   | ||||
							
								
								
									
										17
									
								
								vendor/github.com/Azure/go-ntlmssp/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/Azure/go-ntlmssp/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| sudo: false | ||||
|  | ||||
| language: go | ||||
|  | ||||
| before_script: | ||||
|   - go get -u golang.org/x/lint/golint | ||||
|  | ||||
| go: | ||||
|   - 1.10.x | ||||
|   - master | ||||
|  | ||||
| script: | ||||
|   - test -z "$(gofmt -s -l . | tee /dev/stderr)" | ||||
|   - test -z "$(golint ./... |  tee /dev/stderr)" | ||||
|   - go vet ./... | ||||
|   - go build -v ./... | ||||
|   - go test -v ./... | ||||
							
								
								
									
										21
									
								
								vendor/github.com/Azure/go-ntlmssp/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/Azure/go-ntlmssp/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| The MIT License (MIT) | ||||
|  | ||||
| Copyright (c) 2016 Microsoft | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
							
								
								
									
										29
									
								
								vendor/github.com/Azure/go-ntlmssp/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/Azure/go-ntlmssp/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| # go-ntlmssp | ||||
| Golang package that provides NTLM/Negotiate authentication over HTTP | ||||
|  | ||||
| [](https://godoc.org/github.com/Azure/go-ntlmssp) [](https://travis-ci.org/Azure/go-ntlmssp) | ||||
|  | ||||
| Protocol details from https://msdn.microsoft.com/en-us/library/cc236621.aspx | ||||
| Implementation hints from http://davenport.sourceforge.net/ntlm.html | ||||
|  | ||||
| This package only implements authentication, no key exchange or encryption. It | ||||
| only supports Unicode (UTF16LE) encoding of protocol strings, no OEM encoding. | ||||
| This package implements NTLMv2. | ||||
|  | ||||
| # Usage | ||||
|  | ||||
| ``` | ||||
| url, user, password := "http://www.example.com/secrets", "robpike", "pw123" | ||||
| client := &http.Client{ | ||||
|   Transport: ntlmssp.Negotiator{ | ||||
|     RoundTripper:&http.Transport{}, | ||||
|   }, | ||||
| } | ||||
|  | ||||
| req, _ := http.NewRequest("GET", url, nil) | ||||
| req.SetBasicAuth(user, password) | ||||
| res, _ := client.Do(req) | ||||
| ``` | ||||
|  | ||||
| ----- | ||||
| This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. | ||||
							
								
								
									
										183
									
								
								vendor/github.com/Azure/go-ntlmssp/authenticate_message.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								vendor/github.com/Azure/go-ntlmssp/authenticate_message.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | ||||
| package ntlmssp | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto/rand" | ||||
| 	"encoding/binary" | ||||
| 	"encoding/hex" | ||||
| 	"errors" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| type authenicateMessage struct { | ||||
| 	LmChallengeResponse []byte | ||||
| 	NtChallengeResponse []byte | ||||
|  | ||||
| 	TargetName string | ||||
| 	UserName   string | ||||
|  | ||||
| 	// only set if negotiateFlag_NTLMSSP_NEGOTIATE_KEY_EXCH | ||||
| 	EncryptedRandomSessionKey []byte | ||||
|  | ||||
| 	NegotiateFlags negotiateFlags | ||||
|  | ||||
| 	MIC []byte | ||||
| } | ||||
|  | ||||
| type authenticateMessageFields struct { | ||||
| 	messageHeader | ||||
| 	LmChallengeResponse varField | ||||
| 	NtChallengeResponse varField | ||||
| 	TargetName          varField | ||||
| 	UserName            varField | ||||
| 	Workstation         varField | ||||
| 	_                   [8]byte | ||||
| 	NegotiateFlags      negotiateFlags | ||||
| } | ||||
|  | ||||
| func (m authenicateMessage) MarshalBinary() ([]byte, error) { | ||||
| 	if !m.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATEUNICODE) { | ||||
| 		return nil, errors.New("Only unicode is supported") | ||||
| 	} | ||||
|  | ||||
| 	target, user := toUnicode(m.TargetName), toUnicode(m.UserName) | ||||
| 	workstation := toUnicode("go-ntlmssp") | ||||
|  | ||||
| 	ptr := binary.Size(&authenticateMessageFields{}) | ||||
| 	f := authenticateMessageFields{ | ||||
| 		messageHeader:       newMessageHeader(3), | ||||
| 		NegotiateFlags:      m.NegotiateFlags, | ||||
| 		LmChallengeResponse: newVarField(&ptr, len(m.LmChallengeResponse)), | ||||
| 		NtChallengeResponse: newVarField(&ptr, len(m.NtChallengeResponse)), | ||||
| 		TargetName:          newVarField(&ptr, len(target)), | ||||
| 		UserName:            newVarField(&ptr, len(user)), | ||||
| 		Workstation:         newVarField(&ptr, len(workstation)), | ||||
| 	} | ||||
|  | ||||
| 	f.NegotiateFlags.Unset(negotiateFlagNTLMSSPNEGOTIATEVERSION) | ||||
|  | ||||
| 	b := bytes.Buffer{} | ||||
| 	if err := binary.Write(&b, binary.LittleEndian, &f); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := binary.Write(&b, binary.LittleEndian, &m.LmChallengeResponse); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := binary.Write(&b, binary.LittleEndian, &m.NtChallengeResponse); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := binary.Write(&b, binary.LittleEndian, &target); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := binary.Write(&b, binary.LittleEndian, &user); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := binary.Write(&b, binary.LittleEndian, &workstation); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return b.Bytes(), nil | ||||
| } | ||||
|  | ||||
| //ProcessChallenge crafts an AUTHENTICATE message in response to the CHALLENGE message | ||||
| //that was received from the server | ||||
| func ProcessChallenge(challengeMessageData []byte, user, password string) ([]byte, error) { | ||||
| 	if user == "" && password == "" { | ||||
| 		return nil, errors.New("Anonymous authentication not supported") | ||||
| 	} | ||||
|  | ||||
| 	var cm challengeMessage | ||||
| 	if err := cm.UnmarshalBinary(challengeMessageData); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if cm.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATELMKEY) { | ||||
| 		return nil, errors.New("Only NTLM v2 is supported, but server requested v1 (NTLMSSP_NEGOTIATE_LM_KEY)") | ||||
| 	} | ||||
| 	if cm.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATEKEYEXCH) { | ||||
| 		return nil, errors.New("Key exchange requested but not supported (NTLMSSP_NEGOTIATE_KEY_EXCH)") | ||||
| 	} | ||||
|  | ||||
| 	am := authenicateMessage{ | ||||
| 		UserName:       user, | ||||
| 		TargetName:     cm.TargetName, | ||||
| 		NegotiateFlags: cm.NegotiateFlags, | ||||
| 	} | ||||
|  | ||||
| 	timestamp := cm.TargetInfo[avIDMsvAvTimestamp] | ||||
| 	if timestamp == nil { // no time sent, take current time | ||||
| 		ft := uint64(time.Now().UnixNano()) / 100 | ||||
| 		ft += 116444736000000000 // add time between unix & windows offset | ||||
| 		timestamp = make([]byte, 8) | ||||
| 		binary.LittleEndian.PutUint64(timestamp, ft) | ||||
| 	} | ||||
|  | ||||
| 	clientChallenge := make([]byte, 8) | ||||
| 	rand.Reader.Read(clientChallenge) | ||||
|  | ||||
| 	ntlmV2Hash := getNtlmV2Hash(password, user, cm.TargetName) | ||||
|  | ||||
| 	am.NtChallengeResponse = computeNtlmV2Response(ntlmV2Hash, | ||||
| 		cm.ServerChallenge[:], clientChallenge, timestamp, cm.TargetInfoRaw) | ||||
|  | ||||
| 	if cm.TargetInfoRaw == nil { | ||||
| 		am.LmChallengeResponse = computeLmV2Response(ntlmV2Hash, | ||||
| 			cm.ServerChallenge[:], clientChallenge) | ||||
| 	} | ||||
| 	return am.MarshalBinary() | ||||
| } | ||||
|  | ||||
| func ProcessChallengeWithHash(challengeMessageData []byte, user, hash string) ([]byte, error) { | ||||
| 	if user == "" && hash == "" { | ||||
| 		return nil, errors.New("Anonymous authentication not supported") | ||||
| 	} | ||||
|  | ||||
| 	var cm challengeMessage | ||||
| 	if err := cm.UnmarshalBinary(challengeMessageData); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if cm.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATELMKEY) { | ||||
| 		return nil, errors.New("Only NTLM v2 is supported, but server requested v1 (NTLMSSP_NEGOTIATE_LM_KEY)") | ||||
| 	} | ||||
| 	if cm.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATEKEYEXCH) { | ||||
| 		return nil, errors.New("Key exchange requested but not supported (NTLMSSP_NEGOTIATE_KEY_EXCH)") | ||||
| 	} | ||||
|  | ||||
| 	am := authenicateMessage{ | ||||
| 		UserName:       user, | ||||
| 		TargetName:     cm.TargetName, | ||||
| 		NegotiateFlags: cm.NegotiateFlags, | ||||
| 	} | ||||
|  | ||||
| 	timestamp := cm.TargetInfo[avIDMsvAvTimestamp] | ||||
| 	if timestamp == nil { // no time sent, take current time | ||||
| 		ft := uint64(time.Now().UnixNano()) / 100 | ||||
| 		ft += 116444736000000000 // add time between unix & windows offset | ||||
| 		timestamp = make([]byte, 8) | ||||
| 		binary.LittleEndian.PutUint64(timestamp, ft) | ||||
| 	} | ||||
|  | ||||
| 	clientChallenge := make([]byte, 8) | ||||
| 	rand.Reader.Read(clientChallenge) | ||||
|  | ||||
| 	hashParts := strings.Split(hash, ":") | ||||
| 	if len(hashParts) > 1 { | ||||
| 		hash = hashParts[1] | ||||
| 	} | ||||
| 	hashBytes, err := hex.DecodeString(hash) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	ntlmV2Hash := hmacMd5(hashBytes, toUnicode(strings.ToUpper(user)+cm.TargetName)) | ||||
|  | ||||
| 	am.NtChallengeResponse = computeNtlmV2Response(ntlmV2Hash, | ||||
| 		cm.ServerChallenge[:], clientChallenge, timestamp, cm.TargetInfoRaw) | ||||
|  | ||||
| 	if cm.TargetInfoRaw == nil { | ||||
| 		am.LmChallengeResponse = computeLmV2Response(ntlmV2Hash, | ||||
| 			cm.ServerChallenge[:], clientChallenge) | ||||
| 	} | ||||
| 	return am.MarshalBinary() | ||||
| } | ||||
							
								
								
									
										37
									
								
								vendor/github.com/Azure/go-ntlmssp/authheader.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/Azure/go-ntlmssp/authheader.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| package ntlmssp | ||||
|  | ||||
| import ( | ||||
| 	"encoding/base64" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| type authheader string | ||||
|  | ||||
| func (h authheader) IsBasic() bool { | ||||
| 	return strings.HasPrefix(string(h), "Basic ") | ||||
| } | ||||
|  | ||||
| func (h authheader) IsNegotiate() bool { | ||||
| 	return strings.HasPrefix(string(h), "Negotiate") | ||||
| } | ||||
|  | ||||
| func (h authheader) IsNTLM() bool { | ||||
| 	return strings.HasPrefix(string(h), "NTLM") | ||||
| } | ||||
|  | ||||
| func (h authheader) GetData() ([]byte, error) { | ||||
| 	p := strings.Split(string(h), " ") | ||||
| 	if len(p) < 2 { | ||||
| 		return nil, nil | ||||
| 	} | ||||
| 	return base64.StdEncoding.DecodeString(string(p[1])) | ||||
| } | ||||
|  | ||||
| func (h authheader) GetBasicCreds() (username, password string, err error) { | ||||
| 	d, err := h.GetData() | ||||
| 	if err != nil { | ||||
| 		return "", "", err | ||||
| 	} | ||||
| 	parts := strings.SplitN(string(d), ":", 2) | ||||
| 	return parts[0], parts[1], nil | ||||
| } | ||||
							
								
								
									
										17
									
								
								vendor/github.com/Azure/go-ntlmssp/avids.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/Azure/go-ntlmssp/avids.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| package ntlmssp | ||||
|  | ||||
| type avID uint16 | ||||
|  | ||||
| const ( | ||||
| 	avIDMsvAvEOL avID = iota | ||||
| 	avIDMsvAvNbComputerName | ||||
| 	avIDMsvAvNbDomainName | ||||
| 	avIDMsvAvDNSComputerName | ||||
| 	avIDMsvAvDNSDomainName | ||||
| 	avIDMsvAvDNSTreeName | ||||
| 	avIDMsvAvFlags | ||||
| 	avIDMsvAvTimestamp | ||||
| 	avIDMsvAvSingleHost | ||||
| 	avIDMsvAvTargetName | ||||
| 	avIDMsvChannelBindings | ||||
| ) | ||||
							
								
								
									
										82
									
								
								vendor/github.com/Azure/go-ntlmssp/challenge_message.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								vendor/github.com/Azure/go-ntlmssp/challenge_message.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| package ntlmssp | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| type challengeMessageFields struct { | ||||
| 	messageHeader | ||||
| 	TargetName      varField | ||||
| 	NegotiateFlags  negotiateFlags | ||||
| 	ServerChallenge [8]byte | ||||
| 	_               [8]byte | ||||
| 	TargetInfo      varField | ||||
| } | ||||
|  | ||||
| func (m challengeMessageFields) IsValid() bool { | ||||
| 	return m.messageHeader.IsValid() && m.MessageType == 2 | ||||
| } | ||||
|  | ||||
| type challengeMessage struct { | ||||
| 	challengeMessageFields | ||||
| 	TargetName    string | ||||
| 	TargetInfo    map[avID][]byte | ||||
| 	TargetInfoRaw []byte | ||||
| } | ||||
|  | ||||
| func (m *challengeMessage) UnmarshalBinary(data []byte) error { | ||||
| 	r := bytes.NewReader(data) | ||||
| 	err := binary.Read(r, binary.LittleEndian, &m.challengeMessageFields) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if !m.challengeMessageFields.IsValid() { | ||||
| 		return fmt.Errorf("Message is not a valid challenge message: %+v", m.challengeMessageFields.messageHeader) | ||||
| 	} | ||||
|  | ||||
| 	if m.challengeMessageFields.TargetName.Len > 0 { | ||||
| 		m.TargetName, err = m.challengeMessageFields.TargetName.ReadStringFrom(data, m.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATEUNICODE)) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if m.challengeMessageFields.TargetInfo.Len > 0 { | ||||
| 		d, err := m.challengeMessageFields.TargetInfo.ReadFrom(data) | ||||
| 		m.TargetInfoRaw = d | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		m.TargetInfo = make(map[avID][]byte) | ||||
| 		r := bytes.NewReader(d) | ||||
| 		for { | ||||
| 			var id avID | ||||
| 			var l uint16 | ||||
| 			err = binary.Read(r, binary.LittleEndian, &id) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			if id == avIDMsvAvEOL { | ||||
| 				break | ||||
| 			} | ||||
|  | ||||
| 			err = binary.Read(r, binary.LittleEndian, &l) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			value := make([]byte, l) | ||||
| 			n, err := r.Read(value) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			if n != int(l) { | ||||
| 				return fmt.Errorf("Expected to read %d bytes, got only %d", l, n) | ||||
| 			} | ||||
| 			m.TargetInfo[id] = value | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										21
									
								
								vendor/github.com/Azure/go-ntlmssp/messageheader.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/Azure/go-ntlmssp/messageheader.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| package ntlmssp | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| ) | ||||
|  | ||||
| var signature = [8]byte{'N', 'T', 'L', 'M', 'S', 'S', 'P', 0} | ||||
|  | ||||
| type messageHeader struct { | ||||
| 	Signature   [8]byte | ||||
| 	MessageType uint32 | ||||
| } | ||||
|  | ||||
| func (h messageHeader) IsValid() bool { | ||||
| 	return bytes.Equal(h.Signature[:], signature[:]) && | ||||
| 		h.MessageType > 0 && h.MessageType < 4 | ||||
| } | ||||
|  | ||||
| func newMessageHeader(messageType uint32) messageHeader { | ||||
| 	return messageHeader{signature, messageType} | ||||
| } | ||||
							
								
								
									
										52
									
								
								vendor/github.com/Azure/go-ntlmssp/negotiate_flags.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/Azure/go-ntlmssp/negotiate_flags.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| package ntlmssp | ||||
|  | ||||
| type negotiateFlags uint32 | ||||
|  | ||||
| const ( | ||||
| 	/*A*/ negotiateFlagNTLMSSPNEGOTIATEUNICODE negotiateFlags = 1 << 0 | ||||
| 	/*B*/ negotiateFlagNTLMNEGOTIATEOEM = 1 << 1 | ||||
| 	/*C*/ negotiateFlagNTLMSSPREQUESTTARGET = 1 << 2 | ||||
|  | ||||
| 	/*D*/ | ||||
| 	negotiateFlagNTLMSSPNEGOTIATESIGN = 1 << 4 | ||||
| 	/*E*/ negotiateFlagNTLMSSPNEGOTIATESEAL = 1 << 5 | ||||
| 	/*F*/ negotiateFlagNTLMSSPNEGOTIATEDATAGRAM = 1 << 6 | ||||
| 	/*G*/ negotiateFlagNTLMSSPNEGOTIATELMKEY = 1 << 7 | ||||
|  | ||||
| 	/*H*/ | ||||
| 	negotiateFlagNTLMSSPNEGOTIATENTLM = 1 << 9 | ||||
|  | ||||
| 	/*J*/ | ||||
| 	negotiateFlagANONYMOUS = 1 << 11 | ||||
| 	/*K*/ negotiateFlagNTLMSSPNEGOTIATEOEMDOMAINSUPPLIED = 1 << 12 | ||||
| 	/*L*/ negotiateFlagNTLMSSPNEGOTIATEOEMWORKSTATIONSUPPLIED = 1 << 13 | ||||
|  | ||||
| 	/*M*/ | ||||
| 	negotiateFlagNTLMSSPNEGOTIATEALWAYSSIGN = 1 << 15 | ||||
| 	/*N*/ negotiateFlagNTLMSSPTARGETTYPEDOMAIN = 1 << 16 | ||||
| 	/*O*/ negotiateFlagNTLMSSPTARGETTYPESERVER = 1 << 17 | ||||
|  | ||||
| 	/*P*/ | ||||
| 	negotiateFlagNTLMSSPNEGOTIATEEXTENDEDSESSIONSECURITY = 1 << 19 | ||||
| 	/*Q*/ negotiateFlagNTLMSSPNEGOTIATEIDENTIFY = 1 << 20 | ||||
|  | ||||
| 	/*R*/ | ||||
| 	negotiateFlagNTLMSSPREQUESTNONNTSESSIONKEY = 1 << 22 | ||||
| 	/*S*/ negotiateFlagNTLMSSPNEGOTIATETARGETINFO = 1 << 23 | ||||
|  | ||||
| 	/*T*/ | ||||
| 	negotiateFlagNTLMSSPNEGOTIATEVERSION = 1 << 25 | ||||
|  | ||||
| 	/*U*/ | ||||
| 	negotiateFlagNTLMSSPNEGOTIATE128 = 1 << 29 | ||||
| 	/*V*/ negotiateFlagNTLMSSPNEGOTIATEKEYEXCH = 1 << 30 | ||||
| 	/*W*/ negotiateFlagNTLMSSPNEGOTIATE56 = 1 << 31 | ||||
| ) | ||||
|  | ||||
| func (field negotiateFlags) Has(flags negotiateFlags) bool { | ||||
| 	return field&flags == flags | ||||
| } | ||||
|  | ||||
| func (field *negotiateFlags) Unset(flags negotiateFlags) { | ||||
| 	*field = *field ^ (*field & flags) | ||||
| } | ||||
							
								
								
									
										64
									
								
								vendor/github.com/Azure/go-ntlmssp/negotiate_message.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/Azure/go-ntlmssp/negotiate_message.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| package ntlmssp | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"errors" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| const expMsgBodyLen = 40 | ||||
|  | ||||
| type negotiateMessageFields struct { | ||||
| 	messageHeader | ||||
| 	NegotiateFlags negotiateFlags | ||||
|  | ||||
| 	Domain      varField | ||||
| 	Workstation varField | ||||
|  | ||||
| 	Version | ||||
| } | ||||
|  | ||||
| var defaultFlags = negotiateFlagNTLMSSPNEGOTIATETARGETINFO | | ||||
| 	negotiateFlagNTLMSSPNEGOTIATE56 | | ||||
| 	negotiateFlagNTLMSSPNEGOTIATE128 | | ||||
| 	negotiateFlagNTLMSSPNEGOTIATEUNICODE | | ||||
| 	negotiateFlagNTLMSSPNEGOTIATEEXTENDEDSESSIONSECURITY | ||||
|  | ||||
| //NewNegotiateMessage creates a new NEGOTIATE message with the | ||||
| //flags that this package supports. | ||||
| func NewNegotiateMessage(domainName, workstationName string) ([]byte, error) { | ||||
| 	payloadOffset := expMsgBodyLen | ||||
| 	flags := defaultFlags | ||||
|  | ||||
| 	if domainName != "" { | ||||
| 		flags |= negotiateFlagNTLMSSPNEGOTIATEOEMDOMAINSUPPLIED | ||||
| 	} | ||||
|  | ||||
| 	if workstationName != "" { | ||||
| 		flags |= negotiateFlagNTLMSSPNEGOTIATEOEMWORKSTATIONSUPPLIED | ||||
| 	} | ||||
|  | ||||
| 	msg := negotiateMessageFields{ | ||||
| 		messageHeader:  newMessageHeader(1), | ||||
| 		NegotiateFlags: flags, | ||||
| 		Domain:         newVarField(&payloadOffset, len(domainName)), | ||||
| 		Workstation:    newVarField(&payloadOffset, len(workstationName)), | ||||
| 		Version:        DefaultVersion(), | ||||
| 	} | ||||
|  | ||||
| 	b := bytes.Buffer{} | ||||
| 	if err := binary.Write(&b, binary.LittleEndian, &msg); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if b.Len() != expMsgBodyLen { | ||||
| 		return nil, errors.New("incorrect body length") | ||||
| 	} | ||||
|  | ||||
| 	payload := strings.ToUpper(domainName + workstationName) | ||||
| 	if _, err := b.WriteString(payload); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return b.Bytes(), nil | ||||
| } | ||||
							
								
								
									
										144
									
								
								vendor/github.com/Azure/go-ntlmssp/negotiator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								vendor/github.com/Azure/go-ntlmssp/negotiator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
| package ntlmssp | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/base64" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // GetDomain : parse domain name from based on slashes in the input | ||||
| func GetDomain(user string) (string, string) { | ||||
| 	domain := "" | ||||
|  | ||||
| 	if strings.Contains(user, "\\") { | ||||
| 		ucomponents := strings.SplitN(user, "\\", 2) | ||||
| 		domain = ucomponents[0] | ||||
| 		user = ucomponents[1] | ||||
| 	} | ||||
| 	return user, domain | ||||
| } | ||||
|  | ||||
| //Negotiator is a http.Roundtripper decorator that automatically | ||||
| //converts basic authentication to NTLM/Negotiate authentication when appropriate. | ||||
| type Negotiator struct{ http.RoundTripper } | ||||
|  | ||||
| //RoundTrip sends the request to the server, handling any authentication | ||||
| //re-sends as needed. | ||||
| func (l Negotiator) RoundTrip(req *http.Request) (res *http.Response, err error) { | ||||
| 	// Use default round tripper if not provided | ||||
| 	rt := l.RoundTripper | ||||
| 	if rt == nil { | ||||
| 		rt = http.DefaultTransport | ||||
| 	} | ||||
| 	// If it is not basic auth, just round trip the request as usual | ||||
| 	reqauth := authheader(req.Header.Get("Authorization")) | ||||
| 	if !reqauth.IsBasic() { | ||||
| 		return rt.RoundTrip(req) | ||||
| 	} | ||||
| 	// Save request body | ||||
| 	body := bytes.Buffer{} | ||||
| 	if req.Body != nil { | ||||
| 		_, err = body.ReadFrom(req.Body) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		req.Body.Close() | ||||
| 		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes())) | ||||
| 	} | ||||
| 	// first try anonymous, in case the server still finds us | ||||
| 	// authenticated from previous traffic | ||||
| 	req.Header.Del("Authorization") | ||||
| 	res, err = rt.RoundTrip(req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if res.StatusCode != http.StatusUnauthorized { | ||||
| 		return res, err | ||||
| 	} | ||||
|  | ||||
| 	resauth := authheader(res.Header.Get("Www-Authenticate")) | ||||
| 	if !resauth.IsNegotiate() && !resauth.IsNTLM() { | ||||
| 		// Unauthorized, Negotiate not requested, let's try with basic auth | ||||
| 		req.Header.Set("Authorization", string(reqauth)) | ||||
| 		io.Copy(ioutil.Discard, res.Body) | ||||
| 		res.Body.Close() | ||||
| 		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes())) | ||||
|  | ||||
| 		res, err = rt.RoundTrip(req) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		if res.StatusCode != http.StatusUnauthorized { | ||||
| 			return res, err | ||||
| 		} | ||||
| 		resauth = authheader(res.Header.Get("Www-Authenticate")) | ||||
| 	} | ||||
|  | ||||
| 	if resauth.IsNegotiate() || resauth.IsNTLM() { | ||||
| 		// 401 with request:Basic and response:Negotiate | ||||
| 		io.Copy(ioutil.Discard, res.Body) | ||||
| 		res.Body.Close() | ||||
|  | ||||
| 		// recycle credentials | ||||
| 		u, p, err := reqauth.GetBasicCreds() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		// get domain from username | ||||
| 		domain := "" | ||||
| 		u, domain = GetDomain(u) | ||||
|  | ||||
| 		// send negotiate | ||||
| 		negotiateMessage, err := NewNegotiateMessage(domain, "") | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		if resauth.IsNTLM() { | ||||
| 			req.Header.Set("Authorization", "NTLM "+base64.StdEncoding.EncodeToString(negotiateMessage)) | ||||
| 		} else { | ||||
| 			req.Header.Set("Authorization", "Negotiate "+base64.StdEncoding.EncodeToString(negotiateMessage)) | ||||
| 		} | ||||
|  | ||||
| 		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes())) | ||||
|  | ||||
| 		res, err = rt.RoundTrip(req) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		// receive challenge? | ||||
| 		resauth = authheader(res.Header.Get("Www-Authenticate")) | ||||
| 		challengeMessage, err := resauth.GetData() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		if !(resauth.IsNegotiate() || resauth.IsNTLM()) || len(challengeMessage) == 0 { | ||||
| 			// Negotiation failed, let client deal with response | ||||
| 			return res, nil | ||||
| 		} | ||||
| 		io.Copy(ioutil.Discard, res.Body) | ||||
| 		res.Body.Close() | ||||
|  | ||||
| 		// send authenticate | ||||
| 		authenticateMessage, err := ProcessChallenge(challengeMessage, u, p) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		if resauth.IsNTLM() { | ||||
| 			req.Header.Set("Authorization", "NTLM "+base64.StdEncoding.EncodeToString(authenticateMessage)) | ||||
| 		} else { | ||||
| 			req.Header.Set("Authorization", "Negotiate "+base64.StdEncoding.EncodeToString(authenticateMessage)) | ||||
| 		} | ||||
|  | ||||
| 		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes())) | ||||
|  | ||||
| 		return rt.RoundTrip(req) | ||||
| 	} | ||||
|  | ||||
| 	return res, err | ||||
| } | ||||
							
								
								
									
										51
									
								
								vendor/github.com/Azure/go-ntlmssp/nlmp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								vendor/github.com/Azure/go-ntlmssp/nlmp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| // Package ntlmssp provides NTLM/Negotiate authentication over HTTP | ||||
| // | ||||
| // Protocol details from https://msdn.microsoft.com/en-us/library/cc236621.aspx, | ||||
| // implementation hints from http://davenport.sourceforge.net/ntlm.html . | ||||
| // This package only implements authentication, no key exchange or encryption. It | ||||
| // only supports Unicode (UTF16LE) encoding of protocol strings, no OEM encoding. | ||||
| // This package implements NTLMv2. | ||||
| package ntlmssp | ||||
|  | ||||
| import ( | ||||
| 	"crypto/hmac" | ||||
| 	"crypto/md5" | ||||
| 	"golang.org/x/crypto/md4" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| func getNtlmV2Hash(password, username, target string) []byte { | ||||
| 	return hmacMd5(getNtlmHash(password), toUnicode(strings.ToUpper(username)+target)) | ||||
| } | ||||
|  | ||||
| func getNtlmHash(password string) []byte { | ||||
| 	hash := md4.New() | ||||
| 	hash.Write(toUnicode(password)) | ||||
| 	return hash.Sum(nil) | ||||
| } | ||||
|  | ||||
| func computeNtlmV2Response(ntlmV2Hash, serverChallenge, clientChallenge, | ||||
| 	timestamp, targetInfo []byte) []byte { | ||||
|  | ||||
| 	temp := []byte{1, 1, 0, 0, 0, 0, 0, 0} | ||||
| 	temp = append(temp, timestamp...) | ||||
| 	temp = append(temp, clientChallenge...) | ||||
| 	temp = append(temp, 0, 0, 0, 0) | ||||
| 	temp = append(temp, targetInfo...) | ||||
| 	temp = append(temp, 0, 0, 0, 0) | ||||
|  | ||||
| 	NTProofStr := hmacMd5(ntlmV2Hash, serverChallenge, temp) | ||||
| 	return append(NTProofStr, temp...) | ||||
| } | ||||
|  | ||||
| func computeLmV2Response(ntlmV2Hash, serverChallenge, clientChallenge []byte) []byte { | ||||
| 	return append(hmacMd5(ntlmV2Hash, serverChallenge, clientChallenge), clientChallenge...) | ||||
| } | ||||
|  | ||||
| func hmacMd5(key []byte, data ...[]byte) []byte { | ||||
| 	mac := hmac.New(md5.New, key) | ||||
| 	for _, d := range data { | ||||
| 		mac.Write(d) | ||||
| 	} | ||||
| 	return mac.Sum(nil) | ||||
| } | ||||
							
								
								
									
										29
									
								
								vendor/github.com/Azure/go-ntlmssp/unicode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/Azure/go-ntlmssp/unicode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| package ntlmssp | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"errors" | ||||
| 	"unicode/utf16" | ||||
| ) | ||||
|  | ||||
| // helper func's for dealing with Windows Unicode (UTF16LE) | ||||
|  | ||||
| func fromUnicode(d []byte) (string, error) { | ||||
| 	if len(d)%2 > 0 { | ||||
| 		return "", errors.New("Unicode (UTF 16 LE) specified, but uneven data length") | ||||
| 	} | ||||
| 	s := make([]uint16, len(d)/2) | ||||
| 	err := binary.Read(bytes.NewReader(d), binary.LittleEndian, &s) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return string(utf16.Decode(s)), nil | ||||
| } | ||||
|  | ||||
| func toUnicode(s string) []byte { | ||||
| 	uints := utf16.Encode([]rune(s)) | ||||
| 	b := bytes.Buffer{} | ||||
| 	binary.Write(&b, binary.LittleEndian, &uints) | ||||
| 	return b.Bytes() | ||||
| } | ||||
							
								
								
									
										40
									
								
								vendor/github.com/Azure/go-ntlmssp/varfield.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/Azure/go-ntlmssp/varfield.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| package ntlmssp | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| ) | ||||
|  | ||||
| type varField struct { | ||||
| 	Len          uint16 | ||||
| 	MaxLen       uint16 | ||||
| 	BufferOffset uint32 | ||||
| } | ||||
|  | ||||
| func (f varField) ReadFrom(buffer []byte) ([]byte, error) { | ||||
| 	if len(buffer) < int(f.BufferOffset+uint32(f.Len)) { | ||||
| 		return nil, errors.New("Error reading data, varField extends beyond buffer") | ||||
| 	} | ||||
| 	return buffer[f.BufferOffset : f.BufferOffset+uint32(f.Len)], nil | ||||
| } | ||||
|  | ||||
| func (f varField) ReadStringFrom(buffer []byte, unicode bool) (string, error) { | ||||
| 	d, err := f.ReadFrom(buffer) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	if unicode { // UTF-16LE encoding scheme | ||||
| 		return fromUnicode(d) | ||||
| 	} | ||||
| 	// OEM encoding, close enough to ASCII, since no code page is specified | ||||
| 	return string(d), err | ||||
| } | ||||
|  | ||||
| func newVarField(ptr *int, fieldsize int) varField { | ||||
| 	f := varField{ | ||||
| 		Len:          uint16(fieldsize), | ||||
| 		MaxLen:       uint16(fieldsize), | ||||
| 		BufferOffset: uint32(*ptr), | ||||
| 	} | ||||
| 	*ptr += fieldsize | ||||
| 	return f | ||||
| } | ||||
							
								
								
									
										20
									
								
								vendor/github.com/Azure/go-ntlmssp/version.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/Azure/go-ntlmssp/version.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| package ntlmssp | ||||
|  | ||||
| // Version is a struct representing https://msdn.microsoft.com/en-us/library/cc236654.aspx | ||||
| type Version struct { | ||||
| 	ProductMajorVersion uint8 | ||||
| 	ProductMinorVersion uint8 | ||||
| 	ProductBuild        uint16 | ||||
| 	_                   [3]byte | ||||
| 	NTLMRevisionCurrent uint8 | ||||
| } | ||||
|  | ||||
| // DefaultVersion returns a Version with "sensible" defaults (Windows 7) | ||||
| func DefaultVersion() Version { | ||||
| 	return Version{ | ||||
| 		ProductMajorVersion: 6, | ||||
| 		ProductMinorVersion: 1, | ||||
| 		ProductBuild:        7601, | ||||
| 		NTLMRevisionCurrent: 15, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										39
									
								
								vendor/github.com/go-asn1-ber/asn1-ber/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/go-asn1-ber/asn1-ber/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| language: go | ||||
|  | ||||
| go: | ||||
|   - 1.2.x | ||||
|   - 1.6.x | ||||
|   - 1.9.x | ||||
|   - 1.10.x | ||||
|   - 1.11.x | ||||
|   - 1.12.x | ||||
|   - 1.14.x | ||||
|   - tip | ||||
|  | ||||
| os: | ||||
|   - linux | ||||
|  | ||||
| arch: | ||||
|   - amd64 | ||||
|  | ||||
| dist: xenial | ||||
|  | ||||
| env: | ||||
|   - GOARCH=amd64 | ||||
|  | ||||
| jobs: | ||||
|   include: | ||||
|     - os: windows | ||||
|       go: 1.14.x | ||||
|     - os: osx | ||||
|       go: 1.14.x | ||||
|     - os: linux | ||||
|       go: 1.14.x | ||||
|       arch: arm64 | ||||
|     - os: linux | ||||
|       go: 1.14.x | ||||
|       env: | ||||
|         - GOARCH=386 | ||||
|  | ||||
| script: | ||||
|   - go test -v -cover ./... || go test -v ./... | ||||
							
								
								
									
										22
									
								
								vendor/github.com/go-asn1-ber/asn1-ber/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/go-asn1-ber/asn1-ber/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| The MIT License (MIT) | ||||
|  | ||||
| Copyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com) | ||||
| Portions copyright (c) 2015-2016 go-asn1-ber Authors | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
							
								
								
									
										224
									
								
								vendor/gopkg.in/asn1-ber.v1/ber.go → vendor/github.com/go-asn1-ber/asn1-ber/ber.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										224
									
								
								vendor/gopkg.in/asn1-ber.v1/ber.go → vendor/github.com/go-asn1-ber/asn1-ber/ber.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -5,10 +5,17 @@ import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"math" | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| 	"time" | ||||
| 	"unicode/utf8" | ||||
| ) | ||||
| 
 | ||||
| // MaxPacketLengthBytes specifies the maximum allowed packet size when calling ReadPacket or DecodePacket. Set to 0 for | ||||
| // no limit. | ||||
| var MaxPacketLengthBytes int64 = math.MaxInt32 | ||||
| 
 | ||||
| type Packet struct { | ||||
| 	Identifier | ||||
| 	Value       interface{} | ||||
| @@ -138,42 +145,46 @@ var TypeMap = map[Type]string{ | ||||
| 	TypeConstructed: "Constructed", | ||||
| } | ||||
| 
 | ||||
| var Debug bool = false | ||||
| var Debug = false | ||||
| 
 | ||||
| func PrintBytes(out io.Writer, buf []byte, indent string) { | ||||
| 	data_lines := make([]string, (len(buf)/30)+1) | ||||
| 	num_lines := make([]string, (len(buf)/30)+1) | ||||
| 	dataLines := make([]string, (len(buf)/30)+1) | ||||
| 	numLines := make([]string, (len(buf)/30)+1) | ||||
| 
 | ||||
| 	for i, b := range buf { | ||||
| 		data_lines[i/30] += fmt.Sprintf("%02x ", b) | ||||
| 		num_lines[i/30] += fmt.Sprintf("%02d ", (i+1)%100) | ||||
| 		dataLines[i/30] += fmt.Sprintf("%02x ", b) | ||||
| 		numLines[i/30] += fmt.Sprintf("%02d ", (i+1)%100) | ||||
| 	} | ||||
| 
 | ||||
| 	for i := 0; i < len(data_lines); i++ { | ||||
| 		out.Write([]byte(indent + data_lines[i] + "\n")) | ||||
| 		out.Write([]byte(indent + num_lines[i] + "\n\n")) | ||||
| 	for i := 0; i < len(dataLines); i++ { | ||||
| 		_, _ = out.Write([]byte(indent + dataLines[i] + "\n")) | ||||
| 		_, _ = out.Write([]byte(indent + numLines[i] + "\n\n")) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func WritePacket(out io.Writer, p *Packet) { | ||||
| 	printPacket(out, p, 0, false) | ||||
| } | ||||
| 
 | ||||
| func PrintPacket(p *Packet) { | ||||
| 	printPacket(os.Stdout, p, 0, false) | ||||
| } | ||||
| 
 | ||||
| func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) { | ||||
| 	indent_str := "" | ||||
| 	indentStr := "" | ||||
| 
 | ||||
| 	for len(indent_str) != indent { | ||||
| 		indent_str += " " | ||||
| 	for len(indentStr) != indent { | ||||
| 		indentStr += " " | ||||
| 	} | ||||
| 
 | ||||
| 	class_str := ClassMap[p.ClassType] | ||||
| 	classStr := ClassMap[p.ClassType] | ||||
| 
 | ||||
| 	tagtype_str := TypeMap[p.TagType] | ||||
| 	tagTypeStr := TypeMap[p.TagType] | ||||
| 
 | ||||
| 	tag_str := fmt.Sprintf("0x%02X", p.Tag) | ||||
| 	tagStr := fmt.Sprintf("0x%02X", p.Tag) | ||||
| 
 | ||||
| 	if p.ClassType == ClassUniversal { | ||||
| 		tag_str = tagMap[p.Tag] | ||||
| 		tagStr = tagMap[p.Tag] | ||||
| 	} | ||||
| 
 | ||||
| 	value := fmt.Sprint(p.Value) | ||||
| @@ -183,10 +194,10 @@ func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) { | ||||
| 		description = p.Description + ": " | ||||
| 	} | ||||
| 
 | ||||
| 	fmt.Fprintf(out, "%s%s(%s, %s, %s) Len=%d %q\n", indent_str, description, class_str, tagtype_str, tag_str, p.Data.Len(), value) | ||||
| 	_, _ = fmt.Fprintf(out, "%s%s(%s, %s, %s) Len=%d %q\n", indentStr, description, classStr, tagTypeStr, tagStr, p.Data.Len(), value) | ||||
| 
 | ||||
| 	if printBytes { | ||||
| 		PrintBytes(out, p.Bytes(), indent_str) | ||||
| 		PrintBytes(out, p.Bytes(), indentStr) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, child := range p.Children { | ||||
| @@ -194,7 +205,7 @@ func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ReadPacket reads a single Packet from the reader | ||||
| // ReadPacket reads a single Packet from the reader. | ||||
| func ReadPacket(reader io.Reader) (*Packet, error) { | ||||
| 	p, _, err := readPacket(reader) | ||||
| 	if err != nil { | ||||
| @@ -207,7 +218,7 @@ func DecodeString(data []byte) string { | ||||
| 	return string(data) | ||||
| } | ||||
| 
 | ||||
| func parseInt64(bytes []byte) (ret int64, err error) { | ||||
| func ParseInt64(bytes []byte) (ret int64, err error) { | ||||
| 	if len(bytes) > 8 { | ||||
| 		// We'll overflow an int64 in this case. | ||||
| 		err = fmt.Errorf("integer too large") | ||||
| @@ -230,7 +241,7 @@ func encodeInteger(i int64) []byte { | ||||
| 
 | ||||
| 	var j int | ||||
| 	for ; n > 0; n-- { | ||||
| 		out[j] = (byte(i >> uint((n-1)*8))) | ||||
| 		out[j] = byte(i >> uint((n-1)*8)) | ||||
| 		j++ | ||||
| 	} | ||||
| 
 | ||||
| @@ -262,7 +273,7 @@ func DecodePacket(data []byte) *Packet { | ||||
| } | ||||
| 
 | ||||
| // DecodePacketErr decodes the given bytes into a single Packet | ||||
| // If a decode error is encountered, nil is returned | ||||
| // If a decode error is encountered, nil is returned. | ||||
| func DecodePacketErr(data []byte) (*Packet, error) { | ||||
| 	p, _, err := readPacket(bytes.NewBuffer(data)) | ||||
| 	if err != nil { | ||||
| @@ -271,7 +282,7 @@ func DecodePacketErr(data []byte) (*Packet, error) { | ||||
| 	return p, nil | ||||
| } | ||||
| 
 | ||||
| // readPacket reads a single Packet from the reader, returning the number of bytes read | ||||
| // readPacket reads a single Packet from the reader, returning the number of bytes read. | ||||
| func readPacket(reader io.Reader) (*Packet, int, error) { | ||||
| 	identifier, length, read, err := readHeader(reader) | ||||
| 	if err != nil { | ||||
| @@ -330,7 +341,10 @@ func readPacket(reader io.Reader) (*Packet, int, error) { | ||||
| 	} | ||||
| 
 | ||||
| 	// Read definite-length content | ||||
| 	content := make([]byte, length, length) | ||||
| 	if MaxPacketLengthBytes > 0 && int64(length) > MaxPacketLengthBytes { | ||||
| 		return nil, read, fmt.Errorf("length %d greater than maximum %d", length, MaxPacketLengthBytes) | ||||
| 	} | ||||
| 	content := make([]byte, length) | ||||
| 	if length > 0 { | ||||
| 		_, err := io.ReadFull(reader, content) | ||||
| 		if err != nil { | ||||
| @@ -349,11 +363,11 @@ func readPacket(reader io.Reader) (*Packet, int, error) { | ||||
| 		switch p.Tag { | ||||
| 		case TagEOC: | ||||
| 		case TagBoolean: | ||||
| 			val, _ := parseInt64(content) | ||||
| 			val, _ := ParseInt64(content) | ||||
| 
 | ||||
| 			p.Value = val != 0 | ||||
| 		case TagInteger: | ||||
| 			p.Value, _ = parseInt64(content) | ||||
| 			p.Value, _ = ParseInt64(content) | ||||
| 		case TagBitString: | ||||
| 		case TagOctetString: | ||||
| 			// the actual string encoding is not known here | ||||
| @@ -365,22 +379,42 @@ func readPacket(reader io.Reader) (*Packet, int, error) { | ||||
| 		case TagObjectDescriptor: | ||||
| 		case TagExternal: | ||||
| 		case TagRealFloat: | ||||
| 			p.Value, err = ParseReal(content) | ||||
| 		case TagEnumerated: | ||||
| 			p.Value, _ = parseInt64(content) | ||||
| 			p.Value, _ = ParseInt64(content) | ||||
| 		case TagEmbeddedPDV: | ||||
| 		case TagUTF8String: | ||||
| 			p.Value = DecodeString(content) | ||||
| 			val := DecodeString(content) | ||||
| 			if !utf8.Valid([]byte(val)) { | ||||
| 				err = errors.New("invalid UTF-8 string") | ||||
| 			} else { | ||||
| 				p.Value = val | ||||
| 			} | ||||
| 		case TagRelativeOID: | ||||
| 		case TagSequence: | ||||
| 		case TagSet: | ||||
| 		case TagNumericString: | ||||
| 		case TagPrintableString: | ||||
| 			p.Value = DecodeString(content) | ||||
| 			val := DecodeString(content) | ||||
| 			if err = isPrintableString(val); err == nil { | ||||
| 				p.Value = val | ||||
| 			} | ||||
| 		case TagT61String: | ||||
| 		case TagVideotexString: | ||||
| 		case TagIA5String: | ||||
| 			val := DecodeString(content) | ||||
| 			for i, c := range val { | ||||
| 				if c >= 0x7F { | ||||
| 					err = fmt.Errorf("invalid character for IA5String at pos %d: %c", i, c) | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if err == nil { | ||||
| 				p.Value = val | ||||
| 			} | ||||
| 		case TagUTCTime: | ||||
| 		case TagGeneralizedTime: | ||||
| 			p.Value, err = ParseGeneralizedTime(content) | ||||
| 		case TagGraphicString: | ||||
| 		case TagVisibleString: | ||||
| 		case TagGeneralString: | ||||
| @@ -392,7 +426,24 @@ func readPacket(reader io.Reader) (*Packet, int, error) { | ||||
| 		p.Data.Write(content) | ||||
| 	} | ||||
| 
 | ||||
| 	return p, read, nil | ||||
| 	return p, read, err | ||||
| } | ||||
| 
 | ||||
| func isPrintableString(val string) error { | ||||
| 	for i, c := range val { | ||||
| 		switch { | ||||
| 		case c >= 'a' && c <= 'z': | ||||
| 		case c >= 'A' && c <= 'Z': | ||||
| 		case c >= '0' && c <= '9': | ||||
| 		default: | ||||
| 			switch c { | ||||
| 			case '\'', '(', ')', '+', ',', '-', '.', '=', '/', ':', '?', ' ': | ||||
| 			default: | ||||
| 				return fmt.Errorf("invalid character in position %d", i) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *Packet) Bytes() []byte { | ||||
| @@ -410,61 +461,99 @@ func (p *Packet) AppendChild(child *Packet) { | ||||
| 	p.Children = append(p.Children, child) | ||||
| } | ||||
| 
 | ||||
| func Encode(ClassType Class, TagType Type, Tag Tag, Value interface{}, Description string) *Packet { | ||||
| func Encode(classType Class, tagType Type, tag Tag, value interface{}, description string) *Packet { | ||||
| 	p := new(Packet) | ||||
| 
 | ||||
| 	p.ClassType = ClassType | ||||
| 	p.TagType = TagType | ||||
| 	p.Tag = Tag | ||||
| 	p.ClassType = classType | ||||
| 	p.TagType = tagType | ||||
| 	p.Tag = tag | ||||
| 	p.Data = new(bytes.Buffer) | ||||
| 
 | ||||
| 	p.Children = make([]*Packet, 0, 2) | ||||
| 
 | ||||
| 	p.Value = Value | ||||
| 	p.Description = Description | ||||
| 	p.Value = value | ||||
| 	p.Description = description | ||||
| 
 | ||||
| 	if Value != nil { | ||||
| 		v := reflect.ValueOf(Value) | ||||
| 	if value != nil { | ||||
| 		v := reflect.ValueOf(value) | ||||
| 
 | ||||
| 		if ClassType == ClassUniversal { | ||||
| 			switch Tag { | ||||
| 		if classType == ClassUniversal { | ||||
| 			switch tag { | ||||
| 			case TagOctetString: | ||||
| 				sv, ok := v.Interface().(string) | ||||
| 
 | ||||
| 				if ok { | ||||
| 					p.Data.Write([]byte(sv)) | ||||
| 				} | ||||
| 			case TagEnumerated: | ||||
| 				bv, ok := v.Interface().([]byte) | ||||
| 				if ok { | ||||
| 					p.Data.Write(bv) | ||||
| 				} | ||||
| 			case TagEmbeddedPDV: | ||||
| 				bv, ok := v.Interface().([]byte) | ||||
| 				if ok { | ||||
| 					p.Data.Write(bv) | ||||
| 				} | ||||
| 			} | ||||
| 		} else if classType == ClassContext { | ||||
| 			switch tag { | ||||
| 			case TagEnumerated: | ||||
| 				bv, ok := v.Interface().([]byte) | ||||
| 				if ok { | ||||
| 					p.Data.Write(bv) | ||||
| 				} | ||||
| 			case TagEmbeddedPDV: | ||||
| 				bv, ok := v.Interface().([]byte) | ||||
| 				if ok { | ||||
| 					p.Data.Write(bv) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return p | ||||
| } | ||||
| 
 | ||||
| func NewSequence(Description string) *Packet { | ||||
| 	return Encode(ClassUniversal, TypeConstructed, TagSequence, nil, Description) | ||||
| func NewSequence(description string) *Packet { | ||||
| 	return Encode(ClassUniversal, TypeConstructed, TagSequence, nil, description) | ||||
| } | ||||
| 
 | ||||
| func NewBoolean(ClassType Class, TagType Type, Tag Tag, Value bool, Description string) *Packet { | ||||
| func NewBoolean(classType Class, tagType Type, tag Tag, value bool, description string) *Packet { | ||||
| 	intValue := int64(0) | ||||
| 
 | ||||
| 	if Value { | ||||
| 	if value { | ||||
| 		intValue = 1 | ||||
| 	} | ||||
| 
 | ||||
| 	p := Encode(ClassType, TagType, Tag, nil, Description) | ||||
| 	p := Encode(classType, tagType, tag, nil, description) | ||||
| 
 | ||||
| 	p.Value = Value | ||||
| 	p.Value = value | ||||
| 	p.Data.Write(encodeInteger(intValue)) | ||||
| 
 | ||||
| 	return p | ||||
| } | ||||
| 
 | ||||
| func NewInteger(ClassType Class, TagType Type, Tag Tag, Value interface{}, Description string) *Packet { | ||||
| 	p := Encode(ClassType, TagType, Tag, nil, Description) | ||||
| // NewLDAPBoolean returns a RFC 4511-compliant Boolean packet. | ||||
| func NewLDAPBoolean(classType Class, tagType Type, tag Tag, value bool, description string) *Packet { | ||||
| 	intValue := int64(0) | ||||
| 
 | ||||
| 	p.Value = Value | ||||
| 	switch v := Value.(type) { | ||||
| 	if value { | ||||
| 		intValue = 255 | ||||
| 	} | ||||
| 
 | ||||
| 	p := Encode(classType, tagType, tag, nil, description) | ||||
| 
 | ||||
| 	p.Value = value | ||||
| 	p.Data.Write(encodeInteger(intValue)) | ||||
| 
 | ||||
| 	return p | ||||
| } | ||||
| 
 | ||||
| func NewInteger(classType Class, tagType Type, tag Tag, value interface{}, description string) *Packet { | ||||
| 	p := Encode(classType, tagType, tag, nil, description) | ||||
| 
 | ||||
| 	p.Value = value | ||||
| 	switch v := value.(type) { | ||||
| 	case int: | ||||
| 		p.Data.Write(encodeInteger(int64(v))) | ||||
| 	case uint: | ||||
| @@ -494,11 +583,38 @@ func NewInteger(ClassType Class, TagType Type, Tag Tag, Value interface{}, Descr | ||||
| 	return p | ||||
| } | ||||
| 
 | ||||
| func NewString(ClassType Class, TagType Type, Tag Tag, Value, Description string) *Packet { | ||||
| 	p := Encode(ClassType, TagType, Tag, nil, Description) | ||||
| func NewString(classType Class, tagType Type, tag Tag, value, description string) *Packet { | ||||
| 	p := Encode(classType, tagType, tag, nil, description) | ||||
| 
 | ||||
| 	p.Value = Value | ||||
| 	p.Data.Write([]byte(Value)) | ||||
| 	p.Value = value | ||||
| 	p.Data.Write([]byte(value)) | ||||
| 
 | ||||
| 	return p | ||||
| } | ||||
| 
 | ||||
| func NewGeneralizedTime(classType Class, tagType Type, tag Tag, value time.Time, description string) *Packet { | ||||
| 	p := Encode(classType, tagType, tag, nil, description) | ||||
| 	var s string | ||||
| 	if value.Nanosecond() != 0 { | ||||
| 		s = value.Format(`20060102150405.000000000Z`) | ||||
| 	} else { | ||||
| 		s = value.Format(`20060102150405Z`) | ||||
| 	} | ||||
| 	p.Value = s | ||||
| 	p.Data.Write([]byte(s)) | ||||
| 	return p | ||||
| } | ||||
| 
 | ||||
| func NewReal(classType Class, tagType Type, tag Tag, value interface{}, description string) *Packet { | ||||
| 	p := Encode(classType, tagType, tag, nil, description) | ||||
| 
 | ||||
| 	switch v := value.(type) { | ||||
| 	case float64: | ||||
| 		p.Data.Write(encodeFloat(v)) | ||||
| 	case float32: | ||||
| 		p.Data.Write(encodeFloat(float64(v))) | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("Invalid type %T, expected float{64|32}", v)) | ||||
| 	} | ||||
| 	return p | ||||
| } | ||||
| @@ -6,7 +6,7 @@ func encodeUnsignedInteger(i uint64) []byte { | ||||
| 
 | ||||
| 	var j int | ||||
| 	for ; n > 0; n-- { | ||||
| 		out[j] = (byte(i >> uint((n-1)*8))) | ||||
| 		out[j] = byte(i >> uint((n-1)*8)) | ||||
| 		j++ | ||||
| 	} | ||||
| 
 | ||||
							
								
								
									
										105
									
								
								vendor/github.com/go-asn1-ber/asn1-ber/generalizedTime.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/go-asn1-ber/asn1-ber/generalizedTime.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| package ber | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // ErrInvalidTimeFormat is returned when the generalizedTime string was not correct. | ||||
| var ErrInvalidTimeFormat = errors.New("invalid time format") | ||||
|  | ||||
| var zeroTime = time.Time{} | ||||
|  | ||||
| // ParseGeneralizedTime parses a string value and if it conforms to | ||||
| // GeneralizedTime[^0] format, will return a time.Time for that value. | ||||
| // | ||||
| // [^0]: https://www.itu.int/rec/T-REC-X.690-201508-I/en Section 11.7 | ||||
| func ParseGeneralizedTime(v []byte) (time.Time, error) { | ||||
| 	var format string | ||||
| 	var fract time.Duration | ||||
|  | ||||
| 	str := []byte(DecodeString(v)) | ||||
| 	tzIndex := bytes.IndexAny(str, "Z+-") | ||||
| 	if tzIndex < 0 { | ||||
| 		return zeroTime, ErrInvalidTimeFormat | ||||
| 	} | ||||
|  | ||||
| 	dot := bytes.IndexAny(str, ".,") | ||||
| 	switch dot { | ||||
| 	case -1: | ||||
| 		switch tzIndex { | ||||
| 		case 10: | ||||
| 			format = `2006010215Z` | ||||
| 		case 12: | ||||
| 			format = `200601021504Z` | ||||
| 		case 14: | ||||
| 			format = `20060102150405Z` | ||||
| 		default: | ||||
| 			return zeroTime, ErrInvalidTimeFormat | ||||
| 		} | ||||
|  | ||||
| 	case 10, 12: | ||||
| 		if tzIndex < dot { | ||||
| 			return zeroTime, ErrInvalidTimeFormat | ||||
| 		} | ||||
| 		// a "," is also allowed, but would not be parsed by time.Parse(): | ||||
| 		str[dot] = '.' | ||||
|  | ||||
| 		// If <minute> is omitted, then <fraction> represents a fraction of an | ||||
| 		// hour; otherwise, if <second> and <leap-second> are omitted, then | ||||
| 		// <fraction> represents a fraction of a minute; otherwise, <fraction> | ||||
| 		// represents a fraction of a second. | ||||
|  | ||||
| 		// parse as float from dot to timezone | ||||
| 		f, err := strconv.ParseFloat(string(str[dot:tzIndex]), 64) | ||||
| 		if err != nil { | ||||
| 			return zeroTime, fmt.Errorf("failed to parse float: %s", err) | ||||
| 		} | ||||
| 		// ...and strip that part | ||||
| 		str = append(str[:dot], str[tzIndex:]...) | ||||
| 		tzIndex = dot | ||||
|  | ||||
| 		if dot == 10 { | ||||
| 			fract = time.Duration(int64(f * float64(time.Hour))) | ||||
| 			format = `2006010215Z` | ||||
| 		} else { | ||||
| 			fract = time.Duration(int64(f * float64(time.Minute))) | ||||
| 			format = `200601021504Z` | ||||
| 		} | ||||
|  | ||||
| 	case 14: | ||||
| 		if tzIndex < dot { | ||||
| 			return zeroTime, ErrInvalidTimeFormat | ||||
| 		} | ||||
| 		str[dot] = '.' | ||||
| 		// no need for fractional seconds, time.Parse() handles that | ||||
| 		format = `20060102150405Z` | ||||
|  | ||||
| 	default: | ||||
| 		return zeroTime, ErrInvalidTimeFormat | ||||
| 	} | ||||
|  | ||||
| 	l := len(str) | ||||
| 	switch l - tzIndex { | ||||
| 	case 1: | ||||
| 		if str[l-1] != 'Z' { | ||||
| 			return zeroTime, ErrInvalidTimeFormat | ||||
| 		} | ||||
| 	case 3: | ||||
| 		format += `0700` | ||||
| 		str = append(str, []byte("00")...) | ||||
| 	case 5: | ||||
| 		format += `0700` | ||||
| 	default: | ||||
| 		return zeroTime, ErrInvalidTimeFormat | ||||
| 	} | ||||
|  | ||||
| 	t, err := time.Parse(format, string(str)) | ||||
| 	if err != nil { | ||||
| 		return zeroTime, fmt.Errorf("%s: %s", ErrInvalidTimeFormat, err) | ||||
| 	} | ||||
| 	return t.Add(fract), nil | ||||
| } | ||||
							
								
								
									
										3
									
								
								vendor/github.com/go-asn1-ber/asn1-ber/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/go-asn1-ber/asn1-ber/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| module github.com/go-asn1-ber/asn1-ber | ||||
|  | ||||
| go 1.13 | ||||
							
								
								
									
										29
									
								
								vendor/gopkg.in/asn1-ber.v1/header.go → vendor/github.com/go-asn1-ber/asn1-ber/header.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/gopkg.in/asn1-ber.v1/header.go → vendor/github.com/go-asn1-ber/asn1-ber/header.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -2,28 +2,37 @@ package ber | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| ) | ||||
| 
 | ||||
| func readHeader(reader io.Reader) (identifier Identifier, length int, read int, err error) { | ||||
| 	if i, c, err := readIdentifier(reader); err != nil { | ||||
| 		return Identifier{}, 0, read, err | ||||
| 	} else { | ||||
| 		identifier = i | ||||
| 		read += c | ||||
| 	} | ||||
| 	var ( | ||||
| 		c, l int | ||||
| 		i    Identifier | ||||
| 	) | ||||
| 
 | ||||
| 	if l, c, err := readLength(reader); err != nil { | ||||
| 	if i, c, err = readIdentifier(reader); err != nil { | ||||
| 		return Identifier{}, 0, read, err | ||||
| 	} else { | ||||
| 		length = l | ||||
| 		read += c | ||||
| 	} | ||||
| 	identifier = i | ||||
| 	read += c | ||||
| 
 | ||||
| 	if l, c, err = readLength(reader); err != nil { | ||||
| 		return Identifier{}, 0, read, err | ||||
| 	} | ||||
| 	length = l | ||||
| 	read += c | ||||
| 
 | ||||
| 	// Validate length type with identifier (x.600, 8.1.3.2.a) | ||||
| 	if length == LengthIndefinite && identifier.TagType == TypePrimitive { | ||||
| 		return Identifier{}, 0, read, errors.New("indefinite length used with primitive type") | ||||
| 	} | ||||
| 
 | ||||
| 	if length < LengthIndefinite { | ||||
| 		err = fmt.Errorf("length cannot be less than %d", LengthIndefinite) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	return identifier, length, read, nil | ||||
| } | ||||
| @@ -4,7 +4,6 @@ import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"math" | ||||
| ) | ||||
| 
 | ||||
| func readIdentifier(reader io.Reader) (Identifier, int, error) { | ||||
| @@ -80,24 +79,34 @@ func encodeIdentifier(identifier Identifier) []byte { | ||||
| 
 | ||||
| 		tag := identifier.Tag | ||||
| 
 | ||||
| 		highBit := uint(63) | ||||
| 		for { | ||||
| 			if tag&(1<<highBit) != 0 { | ||||
| 				break | ||||
| 			} | ||||
| 			highBit-- | ||||
| 		} | ||||
| 
 | ||||
| 		tagBytes := int(math.Ceil(float64(highBit) / 7.0)) | ||||
| 		for i := tagBytes - 1; i >= 0; i-- { | ||||
| 			offset := uint(i) * 7 | ||||
| 			mask := Tag(0x7f) << offset | ||||
| 			tagByte := (tag & mask) >> offset | ||||
| 			if i != 0 { | ||||
| 				tagByte |= 0x80 | ||||
| 			} | ||||
| 			b = append(b, byte(tagByte)) | ||||
| 		} | ||||
| 		b = append(b, encodeHighTag(tag)...) | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
| 
 | ||||
| func encodeHighTag(tag Tag) []byte { | ||||
| 	// set cap=4 to hopefully avoid additional allocations | ||||
| 	b := make([]byte, 0, 4) | ||||
| 	for tag != 0 { | ||||
| 		// t := last 7 bits of tag (HighTagValueBitmask = 0x7F) | ||||
| 		t := tag & HighTagValueBitmask | ||||
| 
 | ||||
| 		// right shift tag 7 to remove what was just pulled off | ||||
| 		tag >>= 7 | ||||
| 
 | ||||
| 		// if b already has entries this entry needs a continuation bit (0x80) | ||||
| 		if len(b) != 0 { | ||||
| 			t |= HighTagContinueBitmask | ||||
| 		} | ||||
| 
 | ||||
| 		b = append(b, byte(t)) | ||||
| 	} | ||||
| 	// reverse | ||||
| 	// since bits were pulled off 'tag' small to high the byte slice is in reverse order. | ||||
| 	// example: tag = 0xFF results in {0x7F, 0x01 + 0x80 (continuation bit)} | ||||
| 	// this needs to be reversed into 0x81 0x7F | ||||
| 	for i, j := 0, len(b)-1; i < len(b)/2; i++ { | ||||
| 		b[i], b[j-i] = b[j-i], b[i] | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
							
								
								
									
										26
									
								
								vendor/gopkg.in/asn1-ber.v1/length.go → vendor/github.com/go-asn1-ber/asn1-ber/length.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/gopkg.in/asn1-ber.v1/length.go → vendor/github.com/go-asn1-ber/asn1-ber/length.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -38,6 +38,9 @@ func readLength(reader io.Reader) (length int, read int, err error) { | ||||
| 		if lengthBytes > 8 { | ||||
| 			return 0, read, errors.New("long-form length overflow") | ||||
| 		} | ||||
| 
 | ||||
| 		// Accumulate into a 64-bit variable | ||||
| 		var length64 int64 | ||||
| 		for i := 0; i < lengthBytes; i++ { | ||||
| 			b, err = readByte(reader) | ||||
| 			if err != nil { | ||||
| @@ -49,8 +52,15 @@ func readLength(reader io.Reader) (length int, read int, err error) { | ||||
| 			read++ | ||||
| 
 | ||||
| 			// x.600, 8.1.3.5 | ||||
| 			length <<= 8 | ||||
| 			length |= int(b) | ||||
| 			length64 <<= 8 | ||||
| 			length64 |= int64(b) | ||||
| 		} | ||||
| 
 | ||||
| 		// Cast to a platform-specific integer | ||||
| 		length = int(length64) | ||||
| 		// Ensure we didn't overflow | ||||
| 		if int64(length) != length64 { | ||||
| 			return 0, read, errors.New("long-form length overflow") | ||||
| 		} | ||||
| 
 | ||||
| 	default: | ||||
| @@ -61,11 +71,11 @@ func readLength(reader io.Reader) (length int, read int, err error) { | ||||
| } | ||||
| 
 | ||||
| func encodeLength(length int) []byte { | ||||
| 	length_bytes := encodeUnsignedInteger(uint64(length)) | ||||
| 	if length > 127 || len(length_bytes) > 1 { | ||||
| 		longFormBytes := []byte{(LengthLongFormBitmask | byte(len(length_bytes)))} | ||||
| 		longFormBytes = append(longFormBytes, length_bytes...) | ||||
| 		length_bytes = longFormBytes | ||||
| 	lengthBytes := encodeUnsignedInteger(uint64(length)) | ||||
| 	if length > 127 || len(lengthBytes) > 1 { | ||||
| 		longFormBytes := []byte{LengthLongFormBitmask | byte(len(lengthBytes))} | ||||
| 		longFormBytes = append(longFormBytes, lengthBytes...) | ||||
| 		lengthBytes = longFormBytes | ||||
| 	} | ||||
| 	return length_bytes | ||||
| 	return lengthBytes | ||||
| } | ||||
							
								
								
									
										157
									
								
								vendor/github.com/go-asn1-ber/asn1-ber/real.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								vendor/github.com/go-asn1-ber/asn1-ber/real.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | ||||
| package ber | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| func encodeFloat(v float64) []byte { | ||||
| 	switch { | ||||
| 	case math.IsInf(v, 1): | ||||
| 		return []byte{0x40} | ||||
| 	case math.IsInf(v, -1): | ||||
| 		return []byte{0x41} | ||||
| 	case math.IsNaN(v): | ||||
| 		return []byte{0x42} | ||||
| 	case v == 0.0: | ||||
| 		if math.Signbit(v) { | ||||
| 			return []byte{0x43} | ||||
| 		} | ||||
| 		return []byte{} | ||||
| 	default: | ||||
| 		// we take the easy part ;-) | ||||
| 		value := []byte(strconv.FormatFloat(v, 'G', -1, 64)) | ||||
| 		var ret []byte | ||||
| 		if bytes.Contains(value, []byte{'E'}) { | ||||
| 			ret = []byte{0x03} | ||||
| 		} else { | ||||
| 			ret = []byte{0x02} | ||||
| 		} | ||||
| 		ret = append(ret, value...) | ||||
| 		return ret | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func ParseReal(v []byte) (val float64, err error) { | ||||
| 	if len(v) == 0 { | ||||
| 		return 0.0, nil | ||||
| 	} | ||||
| 	switch { | ||||
| 	case v[0]&0x80 == 0x80: | ||||
| 		val, err = parseBinaryFloat(v) | ||||
| 	case v[0]&0xC0 == 0x40: | ||||
| 		val, err = parseSpecialFloat(v) | ||||
| 	case v[0]&0xC0 == 0x0: | ||||
| 		val, err = parseDecimalFloat(v) | ||||
| 	default: | ||||
| 		return 0.0, fmt.Errorf("invalid info block") | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return 0.0, err | ||||
| 	} | ||||
|  | ||||
| 	if val == 0.0 && !math.Signbit(val) { | ||||
| 		return 0.0, errors.New("REAL value +0 must be encoded with zero-length value block") | ||||
| 	} | ||||
| 	return val, nil | ||||
| } | ||||
|  | ||||
| func parseBinaryFloat(v []byte) (float64, error) { | ||||
| 	var info byte | ||||
| 	var buf []byte | ||||
|  | ||||
| 	info, v = v[0], v[1:] | ||||
|  | ||||
| 	var base int | ||||
| 	switch info & 0x30 { | ||||
| 	case 0x00: | ||||
| 		base = 2 | ||||
| 	case 0x10: | ||||
| 		base = 8 | ||||
| 	case 0x20: | ||||
| 		base = 16 | ||||
| 	case 0x30: | ||||
| 		return 0.0, errors.New("bits 6 and 5 of information octet for REAL are equal to 11") | ||||
| 	} | ||||
|  | ||||
| 	scale := uint((info & 0x0c) >> 2) | ||||
|  | ||||
| 	var expLen int | ||||
| 	switch info & 0x03 { | ||||
| 	case 0x00: | ||||
| 		expLen = 1 | ||||
| 	case 0x01: | ||||
| 		expLen = 2 | ||||
| 	case 0x02: | ||||
| 		expLen = 3 | ||||
| 	case 0x03: | ||||
| 		expLen = int(v[0]) | ||||
| 		if expLen > 8 { | ||||
| 			return 0.0, errors.New("too big value of exponent") | ||||
| 		} | ||||
| 		v = v[1:] | ||||
| 	} | ||||
| 	buf, v = v[:expLen], v[expLen:] | ||||
| 	exponent, err := ParseInt64(buf) | ||||
| 	if err != nil { | ||||
| 		return 0.0, err | ||||
| 	} | ||||
|  | ||||
| 	if len(v) > 8 { | ||||
| 		return 0.0, errors.New("too big value of mantissa") | ||||
| 	} | ||||
|  | ||||
| 	mant, err := ParseInt64(v) | ||||
| 	if err != nil { | ||||
| 		return 0.0, err | ||||
| 	} | ||||
| 	mantissa := mant << scale | ||||
|  | ||||
| 	if info&0x40 == 0x40 { | ||||
| 		mantissa = -mantissa | ||||
| 	} | ||||
|  | ||||
| 	return float64(mantissa) * math.Pow(float64(base), float64(exponent)), nil | ||||
| } | ||||
|  | ||||
| func parseDecimalFloat(v []byte) (val float64, err error) { | ||||
| 	switch v[0] & 0x3F { | ||||
| 	case 0x01: // NR form 1 | ||||
| 		var iVal int64 | ||||
| 		iVal, err = strconv.ParseInt(strings.TrimLeft(string(v[1:]), " "), 10, 64) | ||||
| 		val = float64(iVal) | ||||
| 	case 0x02, 0x03: // NR form 2, 3 | ||||
| 		val, err = strconv.ParseFloat(strings.Replace(strings.TrimLeft(string(v[1:]), " "), ",", ".", -1), 64) | ||||
| 	default: | ||||
| 		err = errors.New("incorrect NR form") | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return 0.0, err | ||||
| 	} | ||||
|  | ||||
| 	if val == 0.0 && math.Signbit(val) { | ||||
| 		return 0.0, errors.New("REAL value -0 must be encoded as a special value") | ||||
| 	} | ||||
| 	return val, nil | ||||
| } | ||||
|  | ||||
| func parseSpecialFloat(v []byte) (float64, error) { | ||||
| 	if len(v) != 1 { | ||||
| 		return 0.0, errors.New(`encoding of "special value" must not contain exponent and mantissa`) | ||||
| 	} | ||||
| 	switch v[0] { | ||||
| 	case 0x40: | ||||
| 		return math.Inf(1), nil | ||||
| 	case 0x41: | ||||
| 		return math.Inf(-1), nil | ||||
| 	case 0x42: | ||||
| 		return math.NaN(), nil | ||||
| 	case 0x43: | ||||
| 		return math.Copysign(0, -1), nil | ||||
| 	} | ||||
| 	return 0.0, errors.New(`encoding of "special value" not from ASN.1 standard`) | ||||
| } | ||||
							
								
								
									
										2
									
								
								vendor/gopkg.in/asn1-ber.v1/util.go → vendor/github.com/go-asn1-ber/asn1-ber/util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/gopkg.in/asn1-ber.v1/util.go → vendor/github.com/go-asn1-ber/asn1-ber/util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,7 +3,7 @@ package ber | ||||
| import "io" | ||||
| 
 | ||||
| func readByte(reader io.Reader) (byte, error) { | ||||
| 	bytes := make([]byte, 1, 1) | ||||
| 	bytes := make([]byte, 1) | ||||
| 	_, err := io.ReadFull(reader, bytes) | ||||
| 	if err != nil { | ||||
| 		if err == io.EOF { | ||||
							
								
								
									
										0
									
								
								vendor/gopkg.in/ldap.v3/LICENSE → vendor/github.com/go-ldap/ldap/v3/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								vendor/gopkg.in/ldap.v3/LICENSE → vendor/github.com/go-ldap/ldap/v3/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
									
										62
									
								
								vendor/gopkg.in/ldap.v3/add.go → vendor/github.com/go-ldap/ldap/v3/add.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										62
									
								
								vendor/gopkg.in/ldap.v3/add.go → vendor/github.com/go-ldap/ldap/v3/add.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,19 +1,9 @@ | ||||
| // | ||||
| // https://tools.ietf.org/html/rfc4511 | ||||
| // | ||||
| // AddRequest ::= [APPLICATION 8] SEQUENCE { | ||||
| //      entry           LDAPDN, | ||||
| //      attributes      AttributeList } | ||||
| // | ||||
| // AttributeList ::= SEQUENCE OF attribute Attribute | ||||
| 
 | ||||
| package ldap | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"log" | ||||
| 
 | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
| 
 | ||||
| // Attribute represents an LDAP attribute | ||||
| @@ -45,20 +35,26 @@ type AddRequest struct { | ||||
| 	Controls []Control | ||||
| } | ||||
| 
 | ||||
| func (a AddRequest) encode() *ber.Packet { | ||||
| 	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationAddRequest, nil, "Add Request") | ||||
| 	request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.DN, "DN")) | ||||
| func (req *AddRequest) appendTo(envelope *ber.Packet) error { | ||||
| 	pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationAddRequest, nil, "Add Request") | ||||
| 	pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.DN, "DN")) | ||||
| 	attributes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes") | ||||
| 	for _, attribute := range a.Attributes { | ||||
| 	for _, attribute := range req.Attributes { | ||||
| 		attributes.AppendChild(attribute.encode()) | ||||
| 	} | ||||
| 	request.AppendChild(attributes) | ||||
| 	return request | ||||
| 	pkt.AppendChild(attributes) | ||||
| 
 | ||||
| 	envelope.AppendChild(pkt) | ||||
| 	if len(req.Controls) > 0 { | ||||
| 		envelope.AppendChild(encodeControls(req.Controls)) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Attribute adds an attribute with the given type and values | ||||
| func (a *AddRequest) Attribute(attrType string, attrVals []string) { | ||||
| 	a.Attributes = append(a.Attributes, Attribute{Type: attrType, Vals: attrVals}) | ||||
| func (req *AddRequest) Attribute(attrType string, attrVals []string) { | ||||
| 	req.Attributes = append(req.Attributes, Attribute{Type: attrType, Vals: attrVals}) | ||||
| } | ||||
| 
 | ||||
| // NewAddRequest returns an AddRequest for the given DN, with no attributes | ||||
| @@ -72,39 +68,17 @@ func NewAddRequest(dn string, controls []Control) *AddRequest { | ||||
| 
 | ||||
| // Add performs the given AddRequest | ||||
| func (l *Conn) Add(addRequest *AddRequest) error { | ||||
| 	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") | ||||
| 	packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) | ||||
| 	packet.AppendChild(addRequest.encode()) | ||||
| 	if len(addRequest.Controls) > 0 { | ||||
| 		packet.AppendChild(encodeControls(addRequest.Controls)) | ||||
| 	} | ||||
| 
 | ||||
| 	l.Debug.PrintPacket(packet) | ||||
| 
 | ||||
| 	msgCtx, err := l.sendMessage(packet) | ||||
| 	msgCtx, err := l.doRequest(addRequest) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
| 
 | ||||
| 	l.Debug.Printf("%d: waiting for response", msgCtx.id) | ||||
| 	packetResponse, ok := <-msgCtx.responses | ||||
| 	if !ok { | ||||
| 		return NewError(ErrorNetwork, errors.New("ldap: response channel closed")) | ||||
| 	} | ||||
| 	packet, err = packetResponse.ReadPacket() | ||||
| 	l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 	packet, err := l.readPacket(msgCtx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if l.Debug { | ||||
| 		if err := addLDAPDescriptions(packet); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		ber.PrintPacket(packet) | ||||
| 	} | ||||
| 
 | ||||
| 	if packet.Children[1].Tag == ApplicationAddResponse { | ||||
| 		err := GetLDAPError(packet) | ||||
| 		if err != nil { | ||||
| @@ -113,7 +87,5 @@ func (l *Conn) Add(addRequest *AddRequest) error { | ||||
| 	} else { | ||||
| 		log.Printf("Unexpected Response: %d", packet.Children[1].Tag) | ||||
| 	} | ||||
| 
 | ||||
| 	l.Debug.Printf("%d: returning", msgCtx.id) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										540
									
								
								vendor/github.com/go-ldap/ldap/v3/bind.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										540
									
								
								vendor/github.com/go-ldap/ldap/v3/bind.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,540 @@ | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto/md5" | ||||
| 	enchex "encoding/hex" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"math/rand" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/Azure/go-ntlmssp" | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
|  | ||||
| // SimpleBindRequest represents a username/password bind operation | ||||
| type SimpleBindRequest struct { | ||||
| 	// Username is the name of the Directory object that the client wishes to bind as | ||||
| 	Username string | ||||
| 	// Password is the credentials to bind with | ||||
| 	Password string | ||||
| 	// Controls are optional controls to send with the bind request | ||||
| 	Controls []Control | ||||
| 	// AllowEmptyPassword sets whether the client allows binding with an empty password | ||||
| 	// (normally used for unauthenticated bind). | ||||
| 	AllowEmptyPassword bool | ||||
| } | ||||
|  | ||||
| // SimpleBindResult contains the response from the server | ||||
| type SimpleBindResult struct { | ||||
| 	Controls []Control | ||||
| } | ||||
|  | ||||
| // NewSimpleBindRequest returns a bind request | ||||
| func NewSimpleBindRequest(username string, password string, controls []Control) *SimpleBindRequest { | ||||
| 	return &SimpleBindRequest{ | ||||
| 		Username:           username, | ||||
| 		Password:           password, | ||||
| 		Controls:           controls, | ||||
| 		AllowEmptyPassword: false, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (req *SimpleBindRequest) appendTo(envelope *ber.Packet) error { | ||||
| 	pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") | ||||
| 	pkt.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) | ||||
| 	pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.Username, "User Name")) | ||||
| 	pkt.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, req.Password, "Password")) | ||||
|  | ||||
| 	envelope.AppendChild(pkt) | ||||
| 	if len(req.Controls) > 0 { | ||||
| 		envelope.AppendChild(encodeControls(req.Controls)) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // SimpleBind performs the simple bind operation defined in the given request | ||||
| func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) { | ||||
| 	if simpleBindRequest.Password == "" && !simpleBindRequest.AllowEmptyPassword { | ||||
| 		return nil, NewError(ErrorEmptyPassword, errors.New("ldap: empty password not allowed by the client")) | ||||
| 	} | ||||
|  | ||||
| 	msgCtx, err := l.doRequest(simpleBindRequest) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	packet, err := l.readPacket(msgCtx) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	result := &SimpleBindResult{ | ||||
| 		Controls: make([]Control, 0), | ||||
| 	} | ||||
|  | ||||
| 	if len(packet.Children) == 3 { | ||||
| 		for _, child := range packet.Children[2].Children { | ||||
| 			decodedChild, decodeErr := DecodeControl(child) | ||||
| 			if decodeErr != nil { | ||||
| 				return nil, fmt.Errorf("failed to decode child control: %s", decodeErr) | ||||
| 			} | ||||
| 			result.Controls = append(result.Controls, decodedChild) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	err = GetLDAPError(packet) | ||||
| 	return result, err | ||||
| } | ||||
|  | ||||
| // Bind performs a bind with the given username and password. | ||||
| // | ||||
| // It does not allow unauthenticated bind (i.e. empty password). Use the UnauthenticatedBind method | ||||
| // for that. | ||||
| func (l *Conn) Bind(username, password string) error { | ||||
| 	req := &SimpleBindRequest{ | ||||
| 		Username:           username, | ||||
| 		Password:           password, | ||||
| 		AllowEmptyPassword: false, | ||||
| 	} | ||||
| 	_, err := l.SimpleBind(req) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // UnauthenticatedBind performs an unauthenticated bind. | ||||
| // | ||||
| // A username may be provided for trace (e.g. logging) purpose only, but it is normally not | ||||
| // authenticated or otherwise validated by the LDAP server. | ||||
| // | ||||
| // See https://tools.ietf.org/html/rfc4513#section-5.1.2 . | ||||
| // See https://tools.ietf.org/html/rfc4513#section-6.3.1 . | ||||
| func (l *Conn) UnauthenticatedBind(username string) error { | ||||
| 	req := &SimpleBindRequest{ | ||||
| 		Username:           username, | ||||
| 		Password:           "", | ||||
| 		AllowEmptyPassword: true, | ||||
| 	} | ||||
| 	_, err := l.SimpleBind(req) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // DigestMD5BindRequest represents a digest-md5 bind operation | ||||
| type DigestMD5BindRequest struct { | ||||
| 	Host string | ||||
| 	// Username is the name of the Directory object that the client wishes to bind as | ||||
| 	Username string | ||||
| 	// Password is the credentials to bind with | ||||
| 	Password string | ||||
| 	// Controls are optional controls to send with the bind request | ||||
| 	Controls []Control | ||||
| } | ||||
|  | ||||
| func (req *DigestMD5BindRequest) appendTo(envelope *ber.Packet) error { | ||||
| 	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") | ||||
| 	request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) | ||||
| 	request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "User Name")) | ||||
|  | ||||
| 	auth := ber.Encode(ber.ClassContext, ber.TypeConstructed, 3, "", "authentication") | ||||
| 	auth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "DIGEST-MD5", "SASL Mech")) | ||||
| 	request.AppendChild(auth) | ||||
| 	envelope.AppendChild(request) | ||||
| 	if len(req.Controls) > 0 { | ||||
| 		envelope.AppendChild(encodeControls(req.Controls)) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // DigestMD5BindResult contains the response from the server | ||||
| type DigestMD5BindResult struct { | ||||
| 	Controls []Control | ||||
| } | ||||
|  | ||||
| // MD5Bind performs a digest-md5 bind with the given host, username and password. | ||||
| func (l *Conn) MD5Bind(host, username, password string) error { | ||||
| 	req := &DigestMD5BindRequest{ | ||||
| 		Host:     host, | ||||
| 		Username: username, | ||||
| 		Password: password, | ||||
| 	} | ||||
| 	_, err := l.DigestMD5Bind(req) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // DigestMD5Bind performs the digest-md5 bind operation defined in the given request | ||||
| func (l *Conn) DigestMD5Bind(digestMD5BindRequest *DigestMD5BindRequest) (*DigestMD5BindResult, error) { | ||||
| 	if digestMD5BindRequest.Password == "" { | ||||
| 		return nil, NewError(ErrorEmptyPassword, errors.New("ldap: empty password not allowed by the client")) | ||||
| 	} | ||||
|  | ||||
| 	msgCtx, err := l.doRequest(digestMD5BindRequest) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	packet, err := l.readPacket(msgCtx) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 	if l.Debug { | ||||
| 		if err = addLDAPDescriptions(packet); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		ber.PrintPacket(packet) | ||||
| 	} | ||||
|  | ||||
| 	result := &DigestMD5BindResult{ | ||||
| 		Controls: make([]Control, 0), | ||||
| 	} | ||||
| 	var params map[string]string | ||||
| 	if len(packet.Children) == 2 { | ||||
| 		if len(packet.Children[1].Children) == 4 { | ||||
| 			child := packet.Children[1].Children[0] | ||||
| 			if child.Tag != ber.TagEnumerated { | ||||
| 				return result, GetLDAPError(packet) | ||||
| 			} | ||||
| 			if child.Value.(int64) != 14 { | ||||
| 				return result, GetLDAPError(packet) | ||||
| 			} | ||||
| 			child = packet.Children[1].Children[3] | ||||
| 			if child.Tag != ber.TagObjectDescriptor { | ||||
| 				return result, GetLDAPError(packet) | ||||
| 			} | ||||
| 			if child.Data == nil { | ||||
| 				return result, GetLDAPError(packet) | ||||
| 			} | ||||
| 			data, _ := ioutil.ReadAll(child.Data) | ||||
| 			params, err = parseParams(string(data)) | ||||
| 			if err != nil { | ||||
| 				return result, fmt.Errorf("parsing digest-challenge: %s", err) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if params != nil { | ||||
| 		resp := computeResponse( | ||||
| 			params, | ||||
| 			"ldap/"+strings.ToLower(digestMD5BindRequest.Host), | ||||
| 			digestMD5BindRequest.Username, | ||||
| 			digestMD5BindRequest.Password, | ||||
| 		) | ||||
| 		packet = ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") | ||||
| 		packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) | ||||
|  | ||||
| 		request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") | ||||
| 		request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) | ||||
| 		request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "User Name")) | ||||
|  | ||||
| 		auth := ber.Encode(ber.ClassContext, ber.TypeConstructed, 3, "", "authentication") | ||||
| 		auth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "DIGEST-MD5", "SASL Mech")) | ||||
| 		auth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, resp, "Credentials")) | ||||
| 		request.AppendChild(auth) | ||||
| 		packet.AppendChild(request) | ||||
| 		msgCtx, err = l.sendMessage(packet) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("send message: %s", err) | ||||
| 		} | ||||
| 		defer l.finishMessage(msgCtx) | ||||
| 		packetResponse, ok := <-msgCtx.responses | ||||
| 		if !ok { | ||||
| 			return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed")) | ||||
| 		} | ||||
| 		packet, err = packetResponse.ReadPacket() | ||||
| 		l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("read packet: %s", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	err = GetLDAPError(packet) | ||||
| 	return result, err | ||||
| } | ||||
|  | ||||
| func parseParams(str string) (map[string]string, error) { | ||||
| 	m := make(map[string]string) | ||||
| 	var key, value string | ||||
| 	var state int | ||||
| 	for i := 0; i <= len(str); i++ { | ||||
| 		switch state { | ||||
| 		case 0: //reading key | ||||
| 			if i == len(str) { | ||||
| 				return nil, fmt.Errorf("syntax error on %d", i) | ||||
| 			} | ||||
| 			if str[i] != '=' { | ||||
| 				key += string(str[i]) | ||||
| 				continue | ||||
| 			} | ||||
| 			state = 1 | ||||
| 		case 1: //reading value | ||||
| 			if i == len(str) { | ||||
| 				m[key] = value | ||||
| 				break | ||||
| 			} | ||||
| 			switch str[i] { | ||||
| 			case ',': | ||||
| 				m[key] = value | ||||
| 				state = 0 | ||||
| 				key = "" | ||||
| 				value = "" | ||||
| 			case '"': | ||||
| 				if value != "" { | ||||
| 					return nil, fmt.Errorf("syntax error on %d", i) | ||||
| 				} | ||||
| 				state = 2 | ||||
| 			default: | ||||
| 				value += string(str[i]) | ||||
| 			} | ||||
| 		case 2: //inside quotes | ||||
| 			if i == len(str) { | ||||
| 				return nil, fmt.Errorf("syntax error on %d", i) | ||||
| 			} | ||||
| 			if str[i] != '"' { | ||||
| 				value += string(str[i]) | ||||
| 			} else { | ||||
| 				state = 1 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return m, nil | ||||
| } | ||||
|  | ||||
| func computeResponse(params map[string]string, uri, username, password string) string { | ||||
| 	nc := "00000001" | ||||
| 	qop := "auth" | ||||
| 	cnonce := enchex.EncodeToString(randomBytes(16)) | ||||
| 	x := username + ":" + params["realm"] + ":" + password | ||||
| 	y := md5Hash([]byte(x)) | ||||
|  | ||||
| 	a1 := bytes.NewBuffer(y) | ||||
| 	a1.WriteString(":" + params["nonce"] + ":" + cnonce) | ||||
| 	if len(params["authzid"]) > 0 { | ||||
| 		a1.WriteString(":" + params["authzid"]) | ||||
| 	} | ||||
| 	a2 := bytes.NewBuffer([]byte("AUTHENTICATE")) | ||||
| 	a2.WriteString(":" + uri) | ||||
| 	ha1 := enchex.EncodeToString(md5Hash(a1.Bytes())) | ||||
| 	ha2 := enchex.EncodeToString(md5Hash(a2.Bytes())) | ||||
|  | ||||
| 	kd := ha1 | ||||
| 	kd += ":" + params["nonce"] | ||||
| 	kd += ":" + nc | ||||
| 	kd += ":" + cnonce | ||||
| 	kd += ":" + qop | ||||
| 	kd += ":" + ha2 | ||||
| 	resp := enchex.EncodeToString(md5Hash([]byte(kd))) | ||||
| 	return fmt.Sprintf( | ||||
| 		`username="%s",realm="%s",nonce="%s",cnonce="%s",nc=00000001,qop=%s,digest-uri="%s",response=%s`, | ||||
| 		username, | ||||
| 		params["realm"], | ||||
| 		params["nonce"], | ||||
| 		cnonce, | ||||
| 		qop, | ||||
| 		uri, | ||||
| 		resp, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| func md5Hash(b []byte) []byte { | ||||
| 	hasher := md5.New() | ||||
| 	hasher.Write(b) | ||||
| 	return hasher.Sum(nil) | ||||
| } | ||||
|  | ||||
| func randomBytes(len int) []byte { | ||||
| 	b := make([]byte, len) | ||||
| 	for i := 0; i < len; i++ { | ||||
| 		b[i] = byte(rand.Intn(256)) | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| var externalBindRequest = requestFunc(func(envelope *ber.Packet) error { | ||||
| 	pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") | ||||
| 	pkt.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) | ||||
| 	pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "User Name")) | ||||
|  | ||||
| 	saslAuth := ber.Encode(ber.ClassContext, ber.TypeConstructed, 3, "", "authentication") | ||||
| 	saslAuth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "EXTERNAL", "SASL Mech")) | ||||
| 	saslAuth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "SASL Cred")) | ||||
|  | ||||
| 	pkt.AppendChild(saslAuth) | ||||
|  | ||||
| 	envelope.AppendChild(pkt) | ||||
|  | ||||
| 	return nil | ||||
| }) | ||||
|  | ||||
| // ExternalBind performs SASL/EXTERNAL authentication. | ||||
| // | ||||
| // Use ldap.DialURL("ldapi://") to connect to the Unix socket before ExternalBind. | ||||
| // | ||||
| // See https://tools.ietf.org/html/rfc4422#appendix-A | ||||
| func (l *Conn) ExternalBind() error { | ||||
| 	msgCtx, err := l.doRequest(externalBindRequest) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	packet, err := l.readPacket(msgCtx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	return GetLDAPError(packet) | ||||
| } | ||||
|  | ||||
| // NTLMBind performs an NTLMSSP bind leveraging https://github.com/Azure/go-ntlmssp | ||||
|  | ||||
| // NTLMBindRequest represents an NTLMSSP bind operation | ||||
| type NTLMBindRequest struct { | ||||
| 	// Domain is the AD Domain to authenticate too. If not specified, it will be grabbed from the NTLMSSP Challenge | ||||
| 	Domain string | ||||
| 	// Username is the name of the Directory object that the client wishes to bind as | ||||
| 	Username string | ||||
| 	// Password is the credentials to bind with | ||||
| 	Password string | ||||
| 	// Hash is the hex NTLM hash to bind with. Password or hash must be provided | ||||
| 	Hash string | ||||
| 	// Controls are optional controls to send with the bind request | ||||
| 	Controls []Control | ||||
| } | ||||
|  | ||||
| func (req *NTLMBindRequest) appendTo(envelope *ber.Packet) error { | ||||
| 	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") | ||||
| 	request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) | ||||
| 	request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "User Name")) | ||||
|  | ||||
| 	// generate an NTLMSSP Negotiation message for the  specified domain (it can be blank) | ||||
| 	negMessage, err := ntlmssp.NewNegotiateMessage(req.Domain, "") | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("err creating negmessage: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	// append the generated NTLMSSP message as a TagEnumerated BER value | ||||
| 	auth := ber.Encode(ber.ClassContext, ber.TypePrimitive, ber.TagEnumerated, negMessage, "authentication") | ||||
| 	request.AppendChild(auth) | ||||
| 	envelope.AppendChild(request) | ||||
| 	if len(req.Controls) > 0 { | ||||
| 		envelope.AppendChild(encodeControls(req.Controls)) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // NTLMBindResult contains the response from the server | ||||
| type NTLMBindResult struct { | ||||
| 	Controls []Control | ||||
| } | ||||
|  | ||||
| // NTLMBind performs an NTLMSSP Bind with the given domain, username and password | ||||
| func (l *Conn) NTLMBind(domain, username, password string) error { | ||||
| 	req := &NTLMBindRequest{ | ||||
| 		Domain:   domain, | ||||
| 		Username: username, | ||||
| 		Password: password, | ||||
| 	} | ||||
| 	_, err := l.NTLMChallengeBind(req) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // NTLMBindWithHash performs an NTLM Bind with an NTLM hash instead of plaintext password (pass-the-hash) | ||||
| func (l *Conn) NTLMBindWithHash(domain, username, hash string) error { | ||||
| 	req := &NTLMBindRequest{ | ||||
| 		Domain:   domain, | ||||
| 		Username: username, | ||||
| 		Hash:     hash, | ||||
| 	} | ||||
| 	_, err := l.NTLMChallengeBind(req) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // NTLMChallengeBind performs the NTLMSSP bind operation defined in the given request | ||||
| func (l *Conn) NTLMChallengeBind(ntlmBindRequest *NTLMBindRequest) (*NTLMBindResult, error) { | ||||
| 	if ntlmBindRequest.Password == "" && ntlmBindRequest.Hash == "" { | ||||
| 		return nil, NewError(ErrorEmptyPassword, errors.New("ldap: empty password not allowed by the client")) | ||||
| 	} | ||||
|  | ||||
| 	msgCtx, err := l.doRequest(ntlmBindRequest) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
| 	packet, err := l.readPacket(msgCtx) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 	if l.Debug { | ||||
| 		if err = addLDAPDescriptions(packet); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		ber.PrintPacket(packet) | ||||
| 	} | ||||
| 	result := &NTLMBindResult{ | ||||
| 		Controls: make([]Control, 0), | ||||
| 	} | ||||
| 	var ntlmsspChallenge []byte | ||||
|  | ||||
| 	// now find the NTLM Response Message | ||||
| 	if len(packet.Children) == 2 { | ||||
| 		if len(packet.Children[1].Children) == 3 { | ||||
| 			child := packet.Children[1].Children[1] | ||||
| 			ntlmsspChallenge = child.ByteValue | ||||
| 			// Check to make sure we got the right message. It will always start with NTLMSSP | ||||
| 			if !bytes.Equal(ntlmsspChallenge[:7], []byte("NTLMSSP")) { | ||||
| 				return result, GetLDAPError(packet) | ||||
| 			} | ||||
| 			l.Debug.Printf("%d: found ntlmssp challenge", msgCtx.id) | ||||
| 		} | ||||
| 	} | ||||
| 	if ntlmsspChallenge != nil { | ||||
| 		var err error | ||||
| 		var responseMessage []byte | ||||
| 		// generate a response message to the challenge with the given Username/Password if password is provided | ||||
| 		if ntlmBindRequest.Password != "" { | ||||
| 			responseMessage, err = ntlmssp.ProcessChallenge(ntlmsspChallenge, ntlmBindRequest.Username, ntlmBindRequest.Password) | ||||
| 		} else if ntlmBindRequest.Hash != "" { | ||||
| 			responseMessage, err = ntlmssp.ProcessChallengeWithHash(ntlmsspChallenge, ntlmBindRequest.Username, ntlmBindRequest.Hash) | ||||
| 		} else { | ||||
| 			err = fmt.Errorf("need a password or hash to generate reply") | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			return result, fmt.Errorf("parsing ntlm-challenge: %s", err) | ||||
| 		} | ||||
| 		packet = ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") | ||||
| 		packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) | ||||
|  | ||||
| 		request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") | ||||
| 		request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) | ||||
| 		request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "User Name")) | ||||
|  | ||||
| 		// append the challenge response message as a TagEmbeddedPDV BER value | ||||
| 		auth := ber.Encode(ber.ClassContext, ber.TypePrimitive, ber.TagEmbeddedPDV, responseMessage, "authentication") | ||||
|  | ||||
| 		request.AppendChild(auth) | ||||
| 		packet.AppendChild(request) | ||||
| 		msgCtx, err = l.sendMessage(packet) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("send message: %s", err) | ||||
| 		} | ||||
| 		defer l.finishMessage(msgCtx) | ||||
| 		packetResponse, ok := <-msgCtx.responses | ||||
| 		if !ok { | ||||
| 			return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed")) | ||||
| 		} | ||||
| 		packet, err = packetResponse.ReadPacket() | ||||
| 		l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("read packet: %s", err) | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	err = GetLDAPError(packet) | ||||
| 	return result, err | ||||
| } | ||||
							
								
								
									
										30
									
								
								vendor/github.com/go-ldap/ldap/v3/client.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/go-ldap/ldap/v3/client.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"crypto/tls" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // Client knows how to interact with an LDAP server | ||||
| type Client interface { | ||||
| 	Start() | ||||
| 	StartTLS(*tls.Config) error | ||||
| 	Close() | ||||
| 	SetTimeout(time.Duration) | ||||
|  | ||||
| 	Bind(username, password string) error | ||||
| 	UnauthenticatedBind(username string) error | ||||
| 	SimpleBind(*SimpleBindRequest) (*SimpleBindResult, error) | ||||
| 	ExternalBind() error | ||||
|  | ||||
| 	Add(*AddRequest) error | ||||
| 	Del(*DelRequest) error | ||||
| 	Modify(*ModifyRequest) error | ||||
| 	ModifyDN(*ModifyDNRequest) error | ||||
|  | ||||
| 	Compare(dn, attribute, value string) (bool, error) | ||||
| 	PasswordModify(*PasswordModifyRequest) (*PasswordModifyResult, error) | ||||
|  | ||||
| 	Search(*SearchRequest) (*SearchResult, error) | ||||
| 	SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error) | ||||
| } | ||||
							
								
								
									
										61
									
								
								vendor/github.com/go-ldap/ldap/v3/compare.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/go-ldap/ldap/v3/compare.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
|  | ||||
| // CompareRequest represents an LDAP CompareRequest operation. | ||||
| type CompareRequest struct { | ||||
| 	DN        string | ||||
| 	Attribute string | ||||
| 	Value     string | ||||
| } | ||||
|  | ||||
| func (req *CompareRequest) appendTo(envelope *ber.Packet) error { | ||||
| 	pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationCompareRequest, nil, "Compare Request") | ||||
| 	pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.DN, "DN")) | ||||
|  | ||||
| 	ava := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "AttributeValueAssertion") | ||||
| 	ava.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.Attribute, "AttributeDesc")) | ||||
| 	ava.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.Value, "AssertionValue")) | ||||
|  | ||||
| 	pkt.AppendChild(ava) | ||||
|  | ||||
| 	envelope.AppendChild(pkt) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Compare checks to see if the attribute of the dn matches value. Returns true if it does otherwise | ||||
| // false with any error that occurs if any. | ||||
| func (l *Conn) Compare(dn, attribute, value string) (bool, error) { | ||||
| 	msgCtx, err := l.doRequest(&CompareRequest{ | ||||
| 		DN:        dn, | ||||
| 		Attribute: attribute, | ||||
| 		Value:     value}) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	packet, err := l.readPacket(msgCtx) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
|  | ||||
| 	if packet.Children[1].Tag == ApplicationCompareResponse { | ||||
| 		err := GetLDAPError(packet) | ||||
|  | ||||
| 		switch { | ||||
| 		case IsErrorWithCode(err, LDAPResultCompareTrue): | ||||
| 			return true, nil | ||||
| 		case IsErrorWithCode(err, LDAPResultCompareFalse): | ||||
| 			return false, nil | ||||
| 		default: | ||||
| 			return false, err | ||||
| 		} | ||||
| 	} | ||||
| 	return false, fmt.Errorf("unexpected Response: %d", packet.Children[1].Tag) | ||||
| } | ||||
							
								
								
									
										122
									
								
								vendor/gopkg.in/ldap.v3/conn.go → vendor/github.com/go-ldap/ldap/v3/conn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										122
									
								
								vendor/gopkg.in/ldap.v3/conn.go → vendor/github.com/go-ldap/ldap/v3/conn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -11,7 +11,7 @@ import ( | ||||
| 	"sync/atomic" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| @@ -112,8 +112,63 @@ var _ Client = &Conn{} | ||||
| // multiple places will probably result in undesired behaviour. | ||||
| var DefaultTimeout = 60 * time.Second | ||||
| 
 | ||||
| // DialOpt configures DialContext. | ||||
| type DialOpt func(*DialContext) | ||||
| 
 | ||||
| // DialWithDialer updates net.Dialer in DialContext. | ||||
| func DialWithDialer(d *net.Dialer) DialOpt { | ||||
| 	return func(dc *DialContext) { | ||||
| 		dc.d = d | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // DialWithTLSConfig updates tls.Config in DialContext. | ||||
| func DialWithTLSConfig(tc *tls.Config) DialOpt { | ||||
| 	return func(dc *DialContext) { | ||||
| 		dc.tc = tc | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // DialContext contains necessary parameters to dial the given ldap URL. | ||||
| type DialContext struct { | ||||
| 	d  *net.Dialer | ||||
| 	tc *tls.Config | ||||
| } | ||||
| 
 | ||||
| func (dc *DialContext) dial(u *url.URL) (net.Conn, error) { | ||||
| 	if u.Scheme == "ldapi" { | ||||
| 		if u.Path == "" || u.Path == "/" { | ||||
| 			u.Path = "/var/run/slapd/ldapi" | ||||
| 		} | ||||
| 		return dc.d.Dial("unix", u.Path) | ||||
| 	} | ||||
| 
 | ||||
| 	host, port, err := net.SplitHostPort(u.Host) | ||||
| 	if err != nil { | ||||
| 		// we assume that error is due to missing port | ||||
| 		host = u.Host | ||||
| 		port = "" | ||||
| 	} | ||||
| 
 | ||||
| 	switch u.Scheme { | ||||
| 	case "ldap": | ||||
| 		if port == "" { | ||||
| 			port = DefaultLdapPort | ||||
| 		} | ||||
| 		return dc.d.Dial("tcp", net.JoinHostPort(host, port)) | ||||
| 	case "ldaps": | ||||
| 		if port == "" { | ||||
| 			port = DefaultLdapsPort | ||||
| 		} | ||||
| 		return tls.DialWithDialer(dc.d, "tcp", net.JoinHostPort(host, port), dc.tc) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil, fmt.Errorf("Unknown scheme '%s'", u.Scheme) | ||||
| } | ||||
| 
 | ||||
| // Dial connects to the given address on the given network using net.Dial | ||||
| // and then returns a new Conn for the connection. | ||||
| // @deprecated Use DialURL instead. | ||||
| func Dial(network, addr string) (*Conn, error) { | ||||
| 	c, err := net.DialTimeout(network, addr, DefaultTimeout) | ||||
| 	if err != nil { | ||||
| @@ -126,6 +181,7 @@ func Dial(network, addr string) (*Conn, error) { | ||||
| 
 | ||||
| // DialTLS connects to the given address on the given network using tls.Dial | ||||
| // and then returns a new Conn for the connection. | ||||
| // @deprecated Use DialURL instead. | ||||
| func DialTLS(network, addr string, config *tls.Config) (*Conn, error) { | ||||
| 	c, err := tls.DialWithDialer(&net.Dialer{Timeout: DefaultTimeout}, network, addr, config) | ||||
| 	if err != nil { | ||||
| @@ -136,40 +192,31 @@ func DialTLS(network, addr string, config *tls.Config) (*Conn, error) { | ||||
| 	return conn, nil | ||||
| } | ||||
| 
 | ||||
| // DialURL connects to the given ldap URL vie TCP using tls.Dial or net.Dial if ldaps:// | ||||
| // or ldap:// specified as protocol. On success a new Conn for the connection | ||||
| // is returned. | ||||
| func DialURL(addr string) (*Conn, error) { | ||||
| 
 | ||||
| 	lurl, err := url.Parse(addr) | ||||
| // DialURL connects to the given ldap URL. | ||||
| // The following schemas are supported: ldap://, ldaps://, ldapi://. | ||||
| // On success a new Conn for the connection is returned. | ||||
| func DialURL(addr string, opts ...DialOpt) (*Conn, error) { | ||||
| 	u, err := url.Parse(addr) | ||||
| 	if err != nil { | ||||
| 		return nil, NewError(ErrorNetwork, err) | ||||
| 	} | ||||
| 
 | ||||
| 	host, port, err := net.SplitHostPort(lurl.Host) | ||||
| 	var dc DialContext | ||||
| 	for _, opt := range opts { | ||||
| 		opt(&dc) | ||||
| 	} | ||||
| 	if dc.d == nil { | ||||
| 		dc.d = &net.Dialer{Timeout: DefaultTimeout} | ||||
| 	} | ||||
| 
 | ||||
| 	c, err := dc.dial(u) | ||||
| 	if err != nil { | ||||
| 		// we asume that error is due to missing port | ||||
| 		host = lurl.Host | ||||
| 		port = "" | ||||
| 		return nil, NewError(ErrorNetwork, err) | ||||
| 	} | ||||
| 
 | ||||
| 	switch lurl.Scheme { | ||||
| 	case "ldap": | ||||
| 		if port == "" { | ||||
| 			port = DefaultLdapPort | ||||
| 		} | ||||
| 		return Dial("tcp", net.JoinHostPort(host, port)) | ||||
| 	case "ldaps": | ||||
| 		if port == "" { | ||||
| 			port = DefaultLdapsPort | ||||
| 		} | ||||
| 		tlsConf := &tls.Config{ | ||||
| 			ServerName: host, | ||||
| 		} | ||||
| 		return DialTLS("tcp", net.JoinHostPort(host, port), tlsConf) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil, NewError(ErrorNetwork, fmt.Errorf("Unknown scheme '%s'", lurl.Scheme)) | ||||
| 	conn := NewConn(c, u.Scheme == "ldaps") | ||||
| 	conn.Start() | ||||
| 	return conn, nil | ||||
| } | ||||
| 
 | ||||
| // NewConn returns a new Conn using conn for network I/O. | ||||
| @@ -187,9 +234,9 @@ func NewConn(conn net.Conn, isTLS bool) *Conn { | ||||
| 
 | ||||
| // Start initializes goroutines to read responses and process messages | ||||
| func (l *Conn) Start() { | ||||
| 	l.wgClose.Add(1) | ||||
| 	go l.reader() | ||||
| 	go l.processMessages() | ||||
| 	l.wgClose.Add(1) | ||||
| } | ||||
| 
 | ||||
| // IsClosing returns whether or not we're currently closing. | ||||
| @@ -274,7 +321,7 @@ func (l *Conn) StartTLS(config *tls.Config) error { | ||||
| 			l.Close() | ||||
| 			return err | ||||
| 		} | ||||
| 		ber.PrintPacket(packet) | ||||
| 		l.Debug.PrintPacket(packet) | ||||
| 	} | ||||
| 
 | ||||
| 	if err := GetLDAPError(packet); err == nil { | ||||
| @@ -343,7 +390,12 @@ func (l *Conn) sendMessageWithFlags(packet *ber.Packet, flags sendMessageFlags) | ||||
| 			responses: responses, | ||||
| 		}, | ||||
| 	} | ||||
| 	l.sendProcessMessage(message) | ||||
| 	if !l.sendProcessMessage(message) { | ||||
| 		if l.IsClosing() { | ||||
| 			return nil, NewError(ErrorNetwork, errors.New("ldap: connection closed")) | ||||
| 		} | ||||
| 		return nil, NewError(ErrorNetwork, errors.New("ldap: could not send message for unknown reason")) | ||||
| 	} | ||||
| 	return message.Context, nil | ||||
| } | ||||
| 
 | ||||
| @@ -447,7 +499,7 @@ func (l *Conn) processMessages() { | ||||
| 					msgCtx.sendResponse(&PacketResponse{message.Packet, nil}) | ||||
| 				} else { | ||||
| 					log.Printf("Received unexpected message %d, %v", message.MessageID, l.IsClosing()) | ||||
| 					ber.PrintPacket(message.Packet) | ||||
| 					l.Debug.PrintPacket(message.Packet) | ||||
| 				} | ||||
| 			case MessageTimeout: | ||||
| 				// Handle the timeout by closing the channel | ||||
| @@ -490,11 +542,13 @@ func (l *Conn) reader() { | ||||
| 			// A read error is expected here if we are closing the connection... | ||||
| 			if !l.IsClosing() { | ||||
| 				l.closeErr.Store(fmt.Errorf("unable to read LDAP response packet: %s", err)) | ||||
| 				l.Debug.Printf("reader error: %s", err.Error()) | ||||
| 				l.Debug.Printf("reader error: %s", err) | ||||
| 			} | ||||
| 			return | ||||
| 		} | ||||
| 		addLDAPDescriptions(packet) | ||||
| 		if err := addLDAPDescriptions(packet); err != nil { | ||||
| 			l.Debug.Printf("descriptions error: %s", err) | ||||
| 		} | ||||
| 		if len(packet.Children) == 0 { | ||||
| 			l.Debug.Printf("Received bad ldap packet") | ||||
| 			continue | ||||
							
								
								
									
										39
									
								
								vendor/gopkg.in/ldap.v3/control.go → vendor/github.com/go-ldap/ldap/v3/control.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/gopkg.in/ldap.v3/control.go → vendor/github.com/go-ldap/ldap/v3/control.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,7 +4,7 @@ import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 
 | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| @@ -63,7 +63,9 @@ func (c *ControlString) Encode() *ber.Packet { | ||||
| 	if c.Criticality { | ||||
| 		packet.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.Criticality, "Criticality")) | ||||
| 	} | ||||
| 	packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, string(c.ControlValue), "Control Value")) | ||||
| 	if c.ControlValue != "" { | ||||
| 		packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, string(c.ControlValue), "Control Value")) | ||||
| 	} | ||||
| 	return packet | ||||
| } | ||||
| 
 | ||||
| @@ -402,33 +404,26 @@ func DecodeControl(packet *ber.Packet) (Control, error) { | ||||
| 			if child.Tag == 0 { | ||||
| 				//Warning | ||||
| 				warningPacket := child.Children[0] | ||||
| 				packet, err := ber.DecodePacketErr(warningPacket.Data.Bytes()) | ||||
| 				val, err := ber.ParseInt64(warningPacket.Data.Bytes()) | ||||
| 				if err != nil { | ||||
| 					return nil, fmt.Errorf("failed to decode data bytes: %s", err) | ||||
| 				} | ||||
| 				val, ok := packet.Value.(int64) | ||||
| 				if ok { | ||||
| 					if warningPacket.Tag == 0 { | ||||
| 						//timeBeforeExpiration | ||||
| 						c.Expire = val | ||||
| 						warningPacket.Value = c.Expire | ||||
| 					} else if warningPacket.Tag == 1 { | ||||
| 						//graceAuthNsRemaining | ||||
| 						c.Grace = val | ||||
| 						warningPacket.Value = c.Grace | ||||
| 					} | ||||
| 				if warningPacket.Tag == 0 { | ||||
| 					//timeBeforeExpiration | ||||
| 					c.Expire = val | ||||
| 					warningPacket.Value = c.Expire | ||||
| 				} else if warningPacket.Tag == 1 { | ||||
| 					//graceAuthNsRemaining | ||||
| 					c.Grace = val | ||||
| 					warningPacket.Value = c.Grace | ||||
| 				} | ||||
| 			} else if child.Tag == 1 { | ||||
| 				// Error | ||||
| 				packet, err := ber.DecodePacketErr(child.Data.Bytes()) | ||||
| 				if err != nil { | ||||
| 					return nil, fmt.Errorf("failed to decode data bytes: %s", err) | ||||
| 				} | ||||
| 				val, ok := packet.Value.(int8) | ||||
| 				if !ok { | ||||
| 					// what to do? | ||||
| 					val = -1 | ||||
| 				bs := child.Data.Bytes() | ||||
| 				if len(bs) != 1 || bs[0] > 8 { | ||||
| 					return nil, fmt.Errorf("failed to decode data bytes: %s", "invalid PasswordPolicyResponse enum value") | ||||
| 				} | ||||
| 				val := int8(bs[0]) | ||||
| 				c.Error = val | ||||
| 				child.Value = c.Error | ||||
| 				c.ErrorString = BeheraPasswordPolicyErrorMap[c.Error] | ||||
							
								
								
									
										10
									
								
								vendor/gopkg.in/ldap.v3/debug.go → vendor/github.com/go-ldap/ldap/v3/debug.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/gopkg.in/ldap.v3/debug.go → vendor/github.com/go-ldap/ldap/v3/debug.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,20 +3,26 @@ package ldap | ||||
| import ( | ||||
| 	"log" | ||||
| 
 | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
| 
 | ||||
| // debugging type | ||||
| //     - has a Printf method to write the debug output | ||||
| type debugging bool | ||||
| 
 | ||||
| // write debug output | ||||
| // Enable controls debugging mode. | ||||
| func (debug *debugging) Enable(b bool) { | ||||
| 	*debug = debugging(b) | ||||
| } | ||||
| 
 | ||||
| // Printf writes debug output. | ||||
| func (debug debugging) Printf(format string, args ...interface{}) { | ||||
| 	if debug { | ||||
| 		log.Printf(format, args...) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // PrintPacket dumps a packet. | ||||
| func (debug debugging) PrintPacket(packet *ber.Packet) { | ||||
| 	if debug { | ||||
| 		ber.PrintPacket(packet) | ||||
							
								
								
									
										59
									
								
								vendor/github.com/go-ldap/ldap/v3/del.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vendor/github.com/go-ldap/ldap/v3/del.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"log" | ||||
|  | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
|  | ||||
| // DelRequest implements an LDAP deletion request | ||||
| type DelRequest struct { | ||||
| 	// DN is the name of the directory entry to delete | ||||
| 	DN string | ||||
| 	// Controls hold optional controls to send with the request | ||||
| 	Controls []Control | ||||
| } | ||||
|  | ||||
| func (req *DelRequest) appendTo(envelope *ber.Packet) error { | ||||
| 	pkt := ber.Encode(ber.ClassApplication, ber.TypePrimitive, ApplicationDelRequest, req.DN, "Del Request") | ||||
| 	pkt.Data.Write([]byte(req.DN)) | ||||
|  | ||||
| 	envelope.AppendChild(pkt) | ||||
| 	if len(req.Controls) > 0 { | ||||
| 		envelope.AppendChild(encodeControls(req.Controls)) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // NewDelRequest creates a delete request for the given DN and controls | ||||
| func NewDelRequest(DN string, Controls []Control) *DelRequest { | ||||
| 	return &DelRequest{ | ||||
| 		DN:       DN, | ||||
| 		Controls: Controls, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Del executes the given delete request | ||||
| func (l *Conn) Del(delRequest *DelRequest) error { | ||||
| 	msgCtx, err := l.doRequest(delRequest) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	packet, err := l.readPacket(msgCtx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if packet.Children[1].Tag == ApplicationDelResponse { | ||||
| 		err := GetLDAPError(packet) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else { | ||||
| 		log.Printf("Unexpected Response: %d", packet.Children[1].Tag) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										46
									
								
								vendor/gopkg.in/ldap.v3/dn.go → vendor/github.com/go-ldap/ldap/v3/dn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/gopkg.in/ldap.v3/dn.go → vendor/github.com/go-ldap/ldap/v3/dn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,44 +1,3 @@ | ||||
| // File contains DN parsing functionality | ||||
| // | ||||
| // https://tools.ietf.org/html/rfc4514 | ||||
| // | ||||
| //   distinguishedName = [ relativeDistinguishedName | ||||
| //         *( COMMA relativeDistinguishedName ) ] | ||||
| //     relativeDistinguishedName = attributeTypeAndValue | ||||
| //         *( PLUS attributeTypeAndValue ) | ||||
| //     attributeTypeAndValue = attributeType EQUALS attributeValue | ||||
| //     attributeType = descr / numericoid | ||||
| //     attributeValue = string / hexstring | ||||
| // | ||||
| //     ; The following characters are to be escaped when they appear | ||||
| //     ; in the value to be encoded: ESC, one of <escaped>, leading | ||||
| //     ; SHARP or SPACE, trailing SPACE, and NULL. | ||||
| //     string =   [ ( leadchar / pair ) [ *( stringchar / pair ) | ||||
| //        ( trailchar / pair ) ] ] | ||||
| // | ||||
| //     leadchar = LUTF1 / UTFMB | ||||
| //     LUTF1 = %x01-1F / %x21 / %x24-2A / %x2D-3A / | ||||
| //        %x3D / %x3F-5B / %x5D-7F | ||||
| // | ||||
| //     trailchar  = TUTF1 / UTFMB | ||||
| //     TUTF1 = %x01-1F / %x21 / %x23-2A / %x2D-3A / | ||||
| //        %x3D / %x3F-5B / %x5D-7F | ||||
| // | ||||
| //     stringchar = SUTF1 / UTFMB | ||||
| //     SUTF1 = %x01-21 / %x23-2A / %x2D-3A / | ||||
| //        %x3D / %x3F-5B / %x5D-7F | ||||
| // | ||||
| //     pair = ESC ( ESC / special / hexpair ) | ||||
| //     special = escaped / SPACE / SHARP / EQUALS | ||||
| //     escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE | ||||
| //     hexstring = SHARP 1*hexpair | ||||
| //     hexpair = HEX HEX | ||||
| // | ||||
| //  where the productions <descr>, <numericoid>, <COMMA>, <DQUOTE>, | ||||
| //  <EQUALS>, <ESC>, <HEX>, <LANGLE>, <NULL>, <PLUS>, <RANGLE>, <SEMI>, | ||||
| //  <SPACE>, <SHARP>, and <UTFMB> are defined in [RFC4512]. | ||||
| // | ||||
| 
 | ||||
| package ldap | ||||
| 
 | ||||
| import ( | ||||
| @@ -48,7 +7,7 @@ import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
| 
 | ||||
| // AttributeTypeAndValue represents an attributeTypeAndValue from https://tools.ietf.org/html/rfc4514 | ||||
| @@ -69,7 +28,8 @@ type DN struct { | ||||
| 	RDNs []*RelativeDN | ||||
| } | ||||
| 
 | ||||
| // ParseDN returns a distinguishedName or an error | ||||
| // ParseDN returns a distinguishedName or an error. | ||||
| // The function respects https://tools.ietf.org/html/rfc4514 | ||||
| func ParseDN(str string) (*DN, error) { | ||||
| 	dn := new(DN) | ||||
| 	dn.RDNs = make([]*RelativeDN, 0) | ||||
							
								
								
									
										0
									
								
								vendor/gopkg.in/ldap.v3/doc.go → vendor/github.com/go-ldap/ldap/v3/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								vendor/gopkg.in/ldap.v3/doc.go → vendor/github.com/go-ldap/ldap/v3/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
									
										37
									
								
								vendor/gopkg.in/ldap.v3/error.go → vendor/github.com/go-ldap/ldap/v3/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/gopkg.in/ldap.v3/error.go → vendor/github.com/go-ldap/ldap/v3/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,7 +3,7 @@ package ldap | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
| 
 | ||||
| // LDAP Result Codes | ||||
| @@ -184,6 +184,8 @@ type Error struct { | ||||
| 	ResultCode uint16 | ||||
| 	// MatchedDN is the matchedDN returned if any | ||||
| 	MatchedDN string | ||||
| 	// Packet is the returned packet if any | ||||
| 	Packet *ber.Packet | ||||
| } | ||||
| 
 | ||||
| func (e *Error) Error() string { | ||||
| @@ -196,22 +198,28 @@ func (e *Error) Error() string { | ||||
| func GetLDAPError(packet *ber.Packet) error { | ||||
| 	if packet == nil { | ||||
| 		return &Error{ResultCode: ErrorUnexpectedResponse, Err: fmt.Errorf("Empty packet")} | ||||
| 	} else if len(packet.Children) >= 2 { | ||||
| 	} | ||||
| 
 | ||||
| 	if len(packet.Children) >= 2 { | ||||
| 		response := packet.Children[1] | ||||
| 		if response == nil { | ||||
| 			return &Error{ResultCode: ErrorUnexpectedResponse, Err: fmt.Errorf("Empty response in packet")} | ||||
| 			return &Error{ResultCode: ErrorUnexpectedResponse, Err: fmt.Errorf("Empty response in packet"), Packet: packet} | ||||
| 		} | ||||
| 		if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 { | ||||
| 			resultCode := uint16(response.Children[0].Value.(int64)) | ||||
| 			if resultCode == 0 { // No error | ||||
| 				return nil | ||||
| 			} | ||||
| 			return &Error{ResultCode: resultCode, MatchedDN: response.Children[1].Value.(string), | ||||
| 				Err: fmt.Errorf("%s", response.Children[2].Value.(string))} | ||||
| 			return &Error{ | ||||
| 				ResultCode: resultCode, | ||||
| 				MatchedDN:  response.Children[1].Value.(string), | ||||
| 				Err:        fmt.Errorf("%s", response.Children[2].Value.(string)), | ||||
| 				Packet:     packet, | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &Error{ResultCode: ErrorNetwork, Err: fmt.Errorf("Invalid packet format")} | ||||
| 	return &Error{ResultCode: ErrorNetwork, Err: fmt.Errorf("Invalid packet format"), Packet: packet} | ||||
| } | ||||
| 
 | ||||
| // NewError creates an LDAP error with the given code and underlying error | ||||
| @@ -219,8 +227,8 @@ func NewError(resultCode uint16, err error) error { | ||||
| 	return &Error{ResultCode: resultCode, Err: err} | ||||
| } | ||||
| 
 | ||||
| // IsErrorWithCode returns true if the given error is an LDAP error with the given result code | ||||
| func IsErrorWithCode(err error, desiredResultCode uint16) bool { | ||||
| // IsErrorAnyOf returns true if the given error is an LDAP error with any one of the given result codes | ||||
| func IsErrorAnyOf(err error, codes ...uint16) bool { | ||||
| 	if err == nil { | ||||
| 		return false | ||||
| 	} | ||||
| @@ -230,5 +238,16 @@ func IsErrorWithCode(err error, desiredResultCode uint16) bool { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	return serverError.ResultCode == desiredResultCode | ||||
| 	for _, code := range codes { | ||||
| 		if serverError.ResultCode == code { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // IsErrorWithCode returns true if the given error is an LDAP error with the given result code | ||||
| func IsErrorWithCode(err error, desiredResultCode uint16) bool { | ||||
| 	return IsErrorAnyOf(err, desiredResultCode) | ||||
| } | ||||
							
								
								
									
										176
									
								
								vendor/gopkg.in/ldap.v3/filter.go → vendor/github.com/go-ldap/ldap/v3/filter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										176
									
								
								vendor/gopkg.in/ldap.v3/filter.go → vendor/github.com/go-ldap/ldap/v3/filter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -5,10 +5,12 @@ import ( | ||||
| 	hexpac "encoding/hex" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"strings" | ||||
| 	"unicode" | ||||
| 	"unicode/utf8" | ||||
| 
 | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
| 
 | ||||
| // Filter choices | ||||
| @@ -69,6 +71,8 @@ var MatchingRuleAssertionMap = map[uint64]string{ | ||||
| 	MatchingRuleAssertionDNAttributes: "Matching Rule Assertion DN Attributes", | ||||
| } | ||||
| 
 | ||||
| var _SymbolAny = []byte{'*'} | ||||
| 
 | ||||
| // CompileFilter converts a string representation of a filter into a BER-encoded packet | ||||
| func CompileFilter(filter string) (*ber.Packet, error) { | ||||
| 	if len(filter) == 0 || filter[0] != '(' { | ||||
| @@ -88,74 +92,75 @@ func CompileFilter(filter string) (*ber.Packet, error) { | ||||
| } | ||||
| 
 | ||||
| // DecompileFilter converts a packet representation of a filter into a string representation | ||||
| func DecompileFilter(packet *ber.Packet) (ret string, err error) { | ||||
| func DecompileFilter(packet *ber.Packet) (_ string, err error) { | ||||
| 	defer func() { | ||||
| 		if r := recover(); r != nil { | ||||
| 			err = NewError(ErrorFilterDecompile, errors.New("ldap: error decompiling filter")) | ||||
| 		} | ||||
| 	}() | ||||
| 	ret = "(" | ||||
| 	err = nil | ||||
| 
 | ||||
| 	buf := bytes.NewBuffer(nil) | ||||
| 	buf.WriteByte('(') | ||||
| 	childStr := "" | ||||
| 
 | ||||
| 	switch packet.Tag { | ||||
| 	case FilterAnd: | ||||
| 		ret += "&" | ||||
| 		buf.WriteByte('&') | ||||
| 		for _, child := range packet.Children { | ||||
| 			childStr, err = DecompileFilter(child) | ||||
| 			if err != nil { | ||||
| 				return | ||||
| 			} | ||||
| 			ret += childStr | ||||
| 			buf.WriteString(childStr) | ||||
| 		} | ||||
| 	case FilterOr: | ||||
| 		ret += "|" | ||||
| 		buf.WriteByte('|') | ||||
| 		for _, child := range packet.Children { | ||||
| 			childStr, err = DecompileFilter(child) | ||||
| 			if err != nil { | ||||
| 				return | ||||
| 			} | ||||
| 			ret += childStr | ||||
| 			buf.WriteString(childStr) | ||||
| 		} | ||||
| 	case FilterNot: | ||||
| 		ret += "!" | ||||
| 		buf.WriteByte('!') | ||||
| 		childStr, err = DecompileFilter(packet.Children[0]) | ||||
| 		if err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 		ret += childStr | ||||
| 		buf.WriteString(childStr) | ||||
| 
 | ||||
| 	case FilterSubstrings: | ||||
| 		ret += ber.DecodeString(packet.Children[0].Data.Bytes()) | ||||
| 		ret += "=" | ||||
| 		buf.WriteString(ber.DecodeString(packet.Children[0].Data.Bytes())) | ||||
| 		buf.WriteByte('=') | ||||
| 		for i, child := range packet.Children[1].Children { | ||||
| 			if i == 0 && child.Tag != FilterSubstringsInitial { | ||||
| 				ret += "*" | ||||
| 				buf.Write(_SymbolAny) | ||||
| 			} | ||||
| 			ret += EscapeFilter(ber.DecodeString(child.Data.Bytes())) | ||||
| 			buf.WriteString(EscapeFilter(ber.DecodeString(child.Data.Bytes()))) | ||||
| 			if child.Tag != FilterSubstringsFinal { | ||||
| 				ret += "*" | ||||
| 				buf.Write(_SymbolAny) | ||||
| 			} | ||||
| 		} | ||||
| 	case FilterEqualityMatch: | ||||
| 		ret += ber.DecodeString(packet.Children[0].Data.Bytes()) | ||||
| 		ret += "=" | ||||
| 		ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes())) | ||||
| 		buf.WriteString(ber.DecodeString(packet.Children[0].Data.Bytes())) | ||||
| 		buf.WriteByte('=') | ||||
| 		buf.WriteString(EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))) | ||||
| 	case FilterGreaterOrEqual: | ||||
| 		ret += ber.DecodeString(packet.Children[0].Data.Bytes()) | ||||
| 		ret += ">=" | ||||
| 		ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes())) | ||||
| 		buf.WriteString(ber.DecodeString(packet.Children[0].Data.Bytes())) | ||||
| 		buf.WriteString(">=") | ||||
| 		buf.WriteString(EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))) | ||||
| 	case FilterLessOrEqual: | ||||
| 		ret += ber.DecodeString(packet.Children[0].Data.Bytes()) | ||||
| 		ret += "<=" | ||||
| 		ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes())) | ||||
| 		buf.WriteString(ber.DecodeString(packet.Children[0].Data.Bytes())) | ||||
| 		buf.WriteString("<=") | ||||
| 		buf.WriteString(EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))) | ||||
| 	case FilterPresent: | ||||
| 		ret += ber.DecodeString(packet.Data.Bytes()) | ||||
| 		ret += "=*" | ||||
| 		buf.WriteString(ber.DecodeString(packet.Data.Bytes())) | ||||
| 		buf.WriteString("=*") | ||||
| 	case FilterApproxMatch: | ||||
| 		ret += ber.DecodeString(packet.Children[0].Data.Bytes()) | ||||
| 		ret += "~=" | ||||
| 		ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes())) | ||||
| 		buf.WriteString(ber.DecodeString(packet.Children[0].Data.Bytes())) | ||||
| 		buf.WriteString("~=") | ||||
| 		buf.WriteString(EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))) | ||||
| 	case FilterExtensibleMatch: | ||||
| 		attr := "" | ||||
| 		dnAttributes := false | ||||
| @@ -176,21 +181,22 @@ func DecompileFilter(packet *ber.Packet) (ret string, err error) { | ||||
| 		} | ||||
| 
 | ||||
| 		if len(attr) > 0 { | ||||
| 			ret += attr | ||||
| 			buf.WriteString(attr) | ||||
| 		} | ||||
| 		if dnAttributes { | ||||
| 			ret += ":dn" | ||||
| 			buf.WriteString(":dn") | ||||
| 		} | ||||
| 		if len(matchingRule) > 0 { | ||||
| 			ret += ":" | ||||
| 			ret += matchingRule | ||||
| 			buf.WriteString(":") | ||||
| 			buf.WriteString(matchingRule) | ||||
| 		} | ||||
| 		ret += ":=" | ||||
| 		ret += EscapeFilter(value) | ||||
| 		buf.WriteString(":=") | ||||
| 		buf.WriteString(EscapeFilter(value)) | ||||
| 	} | ||||
| 
 | ||||
| 	ret += ")" | ||||
| 	return | ||||
| 	buf.WriteByte(')') | ||||
| 
 | ||||
| 	return buf.String(), nil | ||||
| } | ||||
| 
 | ||||
| func compileFilterSet(filter string, pos int, parent *ber.Packet) (int, error) { | ||||
| @@ -253,11 +259,10 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) { | ||||
| 		) | ||||
| 
 | ||||
| 		state := stateReadingAttr | ||||
| 
 | ||||
| 		attribute := "" | ||||
| 		attribute := bytes.NewBuffer(nil) | ||||
| 		extensibleDNAttributes := false | ||||
| 		extensibleMatchingRule := "" | ||||
| 		condition := "" | ||||
| 		extensibleMatchingRule := bytes.NewBuffer(nil) | ||||
| 		condition := bytes.NewBuffer(nil) | ||||
| 
 | ||||
| 		for newPos < len(filter) { | ||||
| 			remainingFilter := filter[newPos:] | ||||
| @@ -324,7 +329,7 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) { | ||||
| 
 | ||||
| 				// Still reading the attribute name | ||||
| 				default: | ||||
| 					attribute += fmt.Sprintf("%c", currentRune) | ||||
| 					attribute.WriteRune(currentRune) | ||||
| 					newPos += currentWidth | ||||
| 				} | ||||
| 
 | ||||
| @@ -338,13 +343,13 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) { | ||||
| 
 | ||||
| 				// Still reading the matching rule oid | ||||
| 				default: | ||||
| 					extensibleMatchingRule += fmt.Sprintf("%c", currentRune) | ||||
| 					extensibleMatchingRule.WriteRune(currentRune) | ||||
| 					newPos += currentWidth | ||||
| 				} | ||||
| 
 | ||||
| 			case stateReadingCondition: | ||||
| 				// append to the condition | ||||
| 				condition += fmt.Sprintf("%c", currentRune) | ||||
| 				condition.WriteRune(currentRune) | ||||
| 				newPos += currentWidth | ||||
| 			} | ||||
| 		} | ||||
| @@ -368,17 +373,17 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) { | ||||
| 			// } | ||||
| 
 | ||||
| 			// Include the matching rule oid, if specified | ||||
| 			if len(extensibleMatchingRule) > 0 { | ||||
| 				packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionMatchingRule, extensibleMatchingRule, MatchingRuleAssertionMap[MatchingRuleAssertionMatchingRule])) | ||||
| 			if extensibleMatchingRule.Len() > 0 { | ||||
| 				packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionMatchingRule, extensibleMatchingRule.String(), MatchingRuleAssertionMap[MatchingRuleAssertionMatchingRule])) | ||||
| 			} | ||||
| 
 | ||||
| 			// Include the attribute, if specified | ||||
| 			if len(attribute) > 0 { | ||||
| 				packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionType, attribute, MatchingRuleAssertionMap[MatchingRuleAssertionType])) | ||||
| 			if attribute.Len() > 0 { | ||||
| 				packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionType, attribute.String(), MatchingRuleAssertionMap[MatchingRuleAssertionType])) | ||||
| 			} | ||||
| 
 | ||||
| 			// Add the value (only required child) | ||||
| 			encodedString, encodeErr := escapedStringToEncodedBytes(condition) | ||||
| 			encodedString, encodeErr := decodeEscapedSymbols(condition.Bytes()) | ||||
| 			if encodeErr != nil { | ||||
| 				return packet, newPos, encodeErr | ||||
| 			} | ||||
| @@ -389,16 +394,16 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) { | ||||
| 				packet.AppendChild(ber.NewBoolean(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionDNAttributes, extensibleDNAttributes, MatchingRuleAssertionMap[MatchingRuleAssertionDNAttributes])) | ||||
| 			} | ||||
| 
 | ||||
| 		case packet.Tag == FilterEqualityMatch && condition == "*": | ||||
| 			packet = ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterPresent, attribute, FilterMap[FilterPresent]) | ||||
| 		case packet.Tag == FilterEqualityMatch && strings.Contains(condition, "*"): | ||||
| 			packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute")) | ||||
| 		case packet.Tag == FilterEqualityMatch && bytes.Equal(condition.Bytes(), _SymbolAny): | ||||
| 			packet = ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterPresent, attribute.String(), FilterMap[FilterPresent]) | ||||
| 		case packet.Tag == FilterEqualityMatch && bytes.Index(condition.Bytes(), _SymbolAny) > -1: | ||||
| 			packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute.String(), "Attribute")) | ||||
| 			packet.Tag = FilterSubstrings | ||||
| 			packet.Description = FilterMap[uint64(packet.Tag)] | ||||
| 			seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings") | ||||
| 			parts := strings.Split(condition, "*") | ||||
| 			parts := bytes.Split(condition.Bytes(), _SymbolAny) | ||||
| 			for i, part := range parts { | ||||
| 				if part == "" { | ||||
| 				if len(part) == 0 { | ||||
| 					continue | ||||
| 				} | ||||
| 				var tag ber.Tag | ||||
| @@ -410,7 +415,7 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) { | ||||
| 				default: | ||||
| 					tag = FilterSubstringsAny | ||||
| 				} | ||||
| 				encodedString, encodeErr := escapedStringToEncodedBytes(part) | ||||
| 				encodedString, encodeErr := decodeEscapedSymbols(part) | ||||
| 				if encodeErr != nil { | ||||
| 					return packet, newPos, encodeErr | ||||
| 				} | ||||
| @@ -418,11 +423,11 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) { | ||||
| 			} | ||||
| 			packet.AppendChild(seq) | ||||
| 		default: | ||||
| 			encodedString, encodeErr := escapedStringToEncodedBytes(condition) | ||||
| 			encodedString, encodeErr := decodeEscapedSymbols(condition.Bytes()) | ||||
| 			if encodeErr != nil { | ||||
| 				return packet, newPos, encodeErr | ||||
| 			} | ||||
| 			packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute")) | ||||
| 			packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute.String(), "Attribute")) | ||||
| 			packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, encodedString, "Condition")) | ||||
| 		} | ||||
| 
 | ||||
| @@ -432,34 +437,51 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) { | ||||
| } | ||||
| 
 | ||||
| // Convert from "ABC\xx\xx\xx" form to literal bytes for transport | ||||
| func escapedStringToEncodedBytes(escapedString string) (string, error) { | ||||
| 	var buffer bytes.Buffer | ||||
| 	i := 0 | ||||
| 	for i < len(escapedString) { | ||||
| 		currentRune, currentWidth := utf8.DecodeRuneInString(escapedString[i:]) | ||||
| 		if currentRune == utf8.RuneError { | ||||
| 			return "", NewError(ErrorFilterCompile, fmt.Errorf("ldap: error reading rune at position %d", i)) | ||||
| func decodeEscapedSymbols(src []byte) (string, error) { | ||||
| 
 | ||||
| 	var ( | ||||
| 		buffer  bytes.Buffer | ||||
| 		offset  int | ||||
| 		reader  = bytes.NewReader(src) | ||||
| 		byteHex []byte | ||||
| 		byteVal []byte | ||||
| 	) | ||||
| 
 | ||||
| 	for { | ||||
| 		runeVal, runeSize, err := reader.ReadRune() | ||||
| 		if err == io.EOF { | ||||
| 			return buffer.String(), nil | ||||
| 		} else if err != nil { | ||||
| 			return "", NewError(ErrorFilterCompile, fmt.Errorf("ldap: failed to read filter: %v", err)) | ||||
| 		} else if runeVal == unicode.ReplacementChar { | ||||
| 			return "", NewError(ErrorFilterCompile, fmt.Errorf("ldap: error reading rune at position %d", offset)) | ||||
| 		} | ||||
| 
 | ||||
| 		// Check for escaped hex characters and convert them to their literal value for transport. | ||||
| 		if currentRune == '\\' { | ||||
| 		if runeVal == '\\' { | ||||
| 			// http://tools.ietf.org/search/rfc4515 | ||||
| 			// \ (%x5C) is not a valid character unless it is followed by two HEX characters due to not | ||||
| 			// being a member of UTF1SUBSET. | ||||
| 			if i+2 > len(escapedString) { | ||||
| 				return "", NewError(ErrorFilterCompile, errors.New("ldap: missing characters for escape in filter")) | ||||
| 			if byteHex == nil { | ||||
| 				byteHex = make([]byte, 2) | ||||
| 				byteVal = make([]byte, 1) | ||||
| 			} | ||||
| 			escByte, decodeErr := hexpac.DecodeString(escapedString[i+1 : i+3]) | ||||
| 			if decodeErr != nil { | ||||
| 				return "", NewError(ErrorFilterCompile, errors.New("ldap: invalid characters for escape in filter")) | ||||
| 
 | ||||
| 			if _, err := io.ReadFull(reader, byteHex); err != nil { | ||||
| 				if err == io.ErrUnexpectedEOF { | ||||
| 					return "", NewError(ErrorFilterCompile, errors.New("ldap: missing characters for escape in filter")) | ||||
| 				} | ||||
| 				return "", NewError(ErrorFilterCompile, fmt.Errorf("ldap: invalid characters for escape in filter: %v", err)) | ||||
| 			} | ||||
| 			buffer.WriteByte(escByte[0]) | ||||
| 			i += 2 // +1 from end of loop, so 3 total for \xx. | ||||
| 
 | ||||
| 			if _, err := hexpac.Decode(byteVal, byteHex); err != nil { | ||||
| 				return "", NewError(ErrorFilterCompile, fmt.Errorf("ldap: invalid characters for escape in filter: %v", err)) | ||||
| 			} | ||||
| 
 | ||||
| 			buffer.Write(byteVal) | ||||
| 		} else { | ||||
| 			buffer.WriteRune(currentRune) | ||||
| 			buffer.WriteRune(runeVal) | ||||
| 		} | ||||
| 
 | ||||
| 		i += currentWidth | ||||
| 		offset += runeSize | ||||
| 	} | ||||
| 	return buffer.String(), nil | ||||
| } | ||||
							
								
								
									
										9
									
								
								vendor/github.com/go-ldap/ldap/v3/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/go-ldap/ldap/v3/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| module github.com/go-ldap/ldap/v3 | ||||
|  | ||||
| go 1.13 | ||||
|  | ||||
| require ( | ||||
| 	github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c | ||||
| 	github.com/go-asn1-ber/asn1-ber v1.5.1 | ||||
| 	golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 // indirect | ||||
| ) | ||||
							
								
								
									
										11
									
								
								vendor/github.com/go-ldap/ldap/v3/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/go-ldap/ldap/v3/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28= | ||||
| github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= | ||||
| github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8= | ||||
| github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM= | ||||
| golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| 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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
							
								
								
									
										53
									
								
								vendor/gopkg.in/ldap.v3/ldap.go → vendor/github.com/go-ldap/ldap/v3/ldap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								vendor/gopkg.in/ldap.v3/ldap.go → vendor/github.com/go-ldap/ldap/v3/ldap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,12 +1,11 @@ | ||||
| package ldap | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 
 | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
| 
 | ||||
| // LDAP Application Codes | ||||
| @@ -87,7 +86,7 @@ var BeheraPasswordPolicyErrorMap = map[int8]string{ | ||||
| func addLDAPDescriptions(packet *ber.Packet) (err error) { | ||||
| 	defer func() { | ||||
| 		if r := recover(); r != nil { | ||||
| 			err = NewError(ErrorDebugging, errors.New("ldap: cannot process packet to add descriptions")) | ||||
| 			err = NewError(ErrorDebugging, fmt.Errorf("ldap: cannot process packet to add descriptions: %s", r)) | ||||
| 		} | ||||
| 	}() | ||||
| 	packet.Description = "LDAP Response" | ||||
| @@ -224,32 +223,26 @@ func addControlDescriptions(packet *ber.Packet) error { | ||||
| 				if child.Tag == 0 { | ||||
| 					//Warning | ||||
| 					warningPacket := child.Children[0] | ||||
| 					packet, err := ber.DecodePacketErr(warningPacket.Data.Bytes()) | ||||
| 					val, err := ber.ParseInt64(warningPacket.Data.Bytes()) | ||||
| 					if err != nil { | ||||
| 						return fmt.Errorf("failed to decode data bytes: %s", err) | ||||
| 					} | ||||
| 					val, ok := packet.Value.(int64) | ||||
| 					if ok { | ||||
| 						if warningPacket.Tag == 0 { | ||||
| 							//timeBeforeExpiration | ||||
| 							value.Description += " (TimeBeforeExpiration)" | ||||
| 							warningPacket.Value = val | ||||
| 						} else if warningPacket.Tag == 1 { | ||||
| 							//graceAuthNsRemaining | ||||
| 							value.Description += " (GraceAuthNsRemaining)" | ||||
| 							warningPacket.Value = val | ||||
| 						} | ||||
| 					if warningPacket.Tag == 0 { | ||||
| 						//timeBeforeExpiration | ||||
| 						value.Description += " (TimeBeforeExpiration)" | ||||
| 						warningPacket.Value = val | ||||
| 					} else if warningPacket.Tag == 1 { | ||||
| 						//graceAuthNsRemaining | ||||
| 						value.Description += " (GraceAuthNsRemaining)" | ||||
| 						warningPacket.Value = val | ||||
| 					} | ||||
| 				} else if child.Tag == 1 { | ||||
| 					// Error | ||||
| 					packet, err := ber.DecodePacketErr(child.Data.Bytes()) | ||||
| 					if err != nil { | ||||
| 						return fmt.Errorf("failed to decode data bytes: %s", err) | ||||
| 					} | ||||
| 					val, ok := packet.Value.(int8) | ||||
| 					if !ok { | ||||
| 						val = -1 | ||||
| 					bs := child.Data.Bytes() | ||||
| 					if len(bs) != 1 || bs[0] > 8 { | ||||
| 						return fmt.Errorf("failed to decode data bytes: %s", "invalid PasswordPolicyResponse enum value") | ||||
| 					} | ||||
| 					val := int8(bs[0]) | ||||
| 					child.Description = "Error" | ||||
| 					child.Value = val | ||||
| 				} | ||||
| @@ -270,10 +263,18 @@ func addRequestDescriptions(packet *ber.Packet) error { | ||||
| } | ||||
| 
 | ||||
| func addDefaultLDAPResponseDescriptions(packet *ber.Packet) error { | ||||
| 	err := GetLDAPError(packet) | ||||
| 	packet.Children[1].Children[0].Description = "Result Code (" + LDAPResultCodeMap[err.(*Error).ResultCode] + ")" | ||||
| 	packet.Children[1].Children[1].Description = "Matched DN (" + err.(*Error).MatchedDN + ")" | ||||
| 	packet.Children[1].Children[2].Description = "Error Message" | ||||
| 	resultCode := uint16(LDAPResultSuccess) | ||||
| 	matchedDN := "" | ||||
| 	description := "Success" | ||||
| 	if err := GetLDAPError(packet); err != nil { | ||||
| 		resultCode = err.(*Error).ResultCode | ||||
| 		matchedDN = err.(*Error).MatchedDN | ||||
| 		description = "Error Message" | ||||
| 	} | ||||
| 
 | ||||
| 	packet.Children[1].Children[0].Description = "Result Code (" + LDAPResultCodeMap[resultCode] + ")" | ||||
| 	packet.Children[1].Children[1].Description = "Matched DN (" + matchedDN + ")" | ||||
| 	packet.Children[1].Children[2].Description = description | ||||
| 	if len(packet.Children[1].Children) > 3 { | ||||
| 		packet.Children[1].Children[3].Description = "Referral" | ||||
| 	} | ||||
							
								
								
									
										80
									
								
								vendor/github.com/go-ldap/ldap/v3/moddn.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								vendor/github.com/go-ldap/ldap/v3/moddn.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"log" | ||||
|  | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
|  | ||||
| // ModifyDNRequest holds the request to modify a DN | ||||
| type ModifyDNRequest struct { | ||||
| 	DN           string | ||||
| 	NewRDN       string | ||||
| 	DeleteOldRDN bool | ||||
| 	NewSuperior  string | ||||
| } | ||||
|  | ||||
| // NewModifyDNRequest creates a new request which can be passed to ModifyDN(). | ||||
| // | ||||
| // To move an object in the tree, set the "newSup" to the new parent entry DN. Use an | ||||
| // empty string for just changing the object's RDN. | ||||
| // | ||||
| // For moving the object without renaming, the "rdn" must be the first | ||||
| // RDN of the given DN. | ||||
| // | ||||
| // A call like | ||||
| //   mdnReq := NewModifyDNRequest("uid=someone,dc=example,dc=org", "uid=newname", true, "") | ||||
| // will setup the request to just rename uid=someone,dc=example,dc=org to | ||||
| // uid=newname,dc=example,dc=org. | ||||
| func NewModifyDNRequest(dn string, rdn string, delOld bool, newSup string) *ModifyDNRequest { | ||||
| 	return &ModifyDNRequest{ | ||||
| 		DN:           dn, | ||||
| 		NewRDN:       rdn, | ||||
| 		DeleteOldRDN: delOld, | ||||
| 		NewSuperior:  newSup, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (req *ModifyDNRequest) appendTo(envelope *ber.Packet) error { | ||||
| 	pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyDNRequest, nil, "Modify DN Request") | ||||
| 	pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.DN, "DN")) | ||||
| 	pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.NewRDN, "New RDN")) | ||||
| 	if req.DeleteOldRDN { | ||||
| 		buf := []byte{0xff} | ||||
| 		pkt.AppendChild(ber.NewString(ber.ClassUniversal,ber.TypePrimitive,ber.TagBoolean, string(buf),"Delete old RDN")) | ||||
| 	}else{ | ||||
| 		pkt.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, req.DeleteOldRDN, "Delete old RDN")) | ||||
| 	}   | ||||
| 	if req.NewSuperior != "" { | ||||
| 		pkt.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, req.NewSuperior, "New Superior")) | ||||
| 	} | ||||
|  | ||||
| 	envelope.AppendChild(pkt) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // ModifyDN renames the given DN and optionally move to another base (when the "newSup" argument | ||||
| // to NewModifyDNRequest() is not ""). | ||||
| func (l *Conn) ModifyDN(m *ModifyDNRequest) error { | ||||
| 	msgCtx, err := l.doRequest(m) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	packet, err := l.readPacket(msgCtx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if packet.Children[1].Tag == ApplicationModifyDNResponse { | ||||
| 		err := GetLDAPError(packet) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else { | ||||
| 		log.Printf("Unexpected Response: %d", packet.Children[1].Tag) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										132
									
								
								vendor/github.com/go-ldap/ldap/v3/modify.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								vendor/github.com/go-ldap/ldap/v3/modify.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"log" | ||||
|  | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
|  | ||||
| // Change operation choices | ||||
| const ( | ||||
| 	AddAttribute       = 0 | ||||
| 	DeleteAttribute    = 1 | ||||
| 	ReplaceAttribute   = 2 | ||||
| 	IncrementAttribute = 3 // (https://tools.ietf.org/html/rfc4525) | ||||
| ) | ||||
|  | ||||
| // PartialAttribute for a ModifyRequest as defined in https://tools.ietf.org/html/rfc4511 | ||||
| type PartialAttribute struct { | ||||
| 	// Type is the type of the partial attribute | ||||
| 	Type string | ||||
| 	// Vals are the values of the partial attribute | ||||
| 	Vals []string | ||||
| } | ||||
|  | ||||
| func (p *PartialAttribute) encode() *ber.Packet { | ||||
| 	seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "PartialAttribute") | ||||
| 	seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, p.Type, "Type")) | ||||
| 	set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue") | ||||
| 	for _, value := range p.Vals { | ||||
| 		set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals")) | ||||
| 	} | ||||
| 	seq.AppendChild(set) | ||||
| 	return seq | ||||
| } | ||||
|  | ||||
| // Change for a ModifyRequest as defined in https://tools.ietf.org/html/rfc4511 | ||||
| type Change struct { | ||||
| 	// Operation is the type of change to be made | ||||
| 	Operation uint | ||||
| 	// Modification is the attribute to be modified | ||||
| 	Modification PartialAttribute | ||||
| } | ||||
|  | ||||
| func (c *Change) encode() *ber.Packet { | ||||
| 	change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change") | ||||
| 	change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(c.Operation), "Operation")) | ||||
| 	change.AppendChild(c.Modification.encode()) | ||||
| 	return change | ||||
| } | ||||
|  | ||||
| // ModifyRequest as defined in https://tools.ietf.org/html/rfc4511 | ||||
| type ModifyRequest struct { | ||||
| 	// DN is the distinguishedName of the directory entry to modify | ||||
| 	DN string | ||||
| 	// Changes contain the attributes to modify | ||||
| 	Changes []Change | ||||
| 	// Controls hold optional controls to send with the request | ||||
| 	Controls []Control | ||||
| } | ||||
|  | ||||
| // Add appends the given attribute to the list of changes to be made | ||||
| func (req *ModifyRequest) Add(attrType string, attrVals []string) { | ||||
| 	req.appendChange(AddAttribute, attrType, attrVals) | ||||
| } | ||||
|  | ||||
| // Delete appends the given attribute to the list of changes to be made | ||||
| func (req *ModifyRequest) Delete(attrType string, attrVals []string) { | ||||
| 	req.appendChange(DeleteAttribute, attrType, attrVals) | ||||
| } | ||||
|  | ||||
| // Replace appends the given attribute to the list of changes to be made | ||||
| func (req *ModifyRequest) Replace(attrType string, attrVals []string) { | ||||
| 	req.appendChange(ReplaceAttribute, attrType, attrVals) | ||||
| } | ||||
|  | ||||
| // Increment appends the given attribute to the list of changes to be made | ||||
| func (req *ModifyRequest) Increment(attrType string, attrVal string) { | ||||
| 	req.appendChange(IncrementAttribute, attrType, []string{attrVal}) | ||||
| } | ||||
|  | ||||
| func (req *ModifyRequest) appendChange(operation uint, attrType string, attrVals []string) { | ||||
| 	req.Changes = append(req.Changes, Change{operation, PartialAttribute{Type: attrType, Vals: attrVals}}) | ||||
| } | ||||
|  | ||||
| func (req *ModifyRequest) appendTo(envelope *ber.Packet) error { | ||||
| 	pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyRequest, nil, "Modify Request") | ||||
| 	pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.DN, "DN")) | ||||
| 	changes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Changes") | ||||
| 	for _, change := range req.Changes { | ||||
| 		changes.AppendChild(change.encode()) | ||||
| 	} | ||||
| 	pkt.AppendChild(changes) | ||||
|  | ||||
| 	envelope.AppendChild(pkt) | ||||
| 	if len(req.Controls) > 0 { | ||||
| 		envelope.AppendChild(encodeControls(req.Controls)) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // NewModifyRequest creates a modify request for the given DN | ||||
| func NewModifyRequest(dn string, controls []Control) *ModifyRequest { | ||||
| 	return &ModifyRequest{ | ||||
| 		DN:       dn, | ||||
| 		Controls: controls, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Modify performs the ModifyRequest | ||||
| func (l *Conn) Modify(modifyRequest *ModifyRequest) error { | ||||
| 	msgCtx, err := l.doRequest(modifyRequest) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	packet, err := l.readPacket(msgCtx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if packet.Children[1].Tag == ApplicationModifyResponse { | ||||
| 		err := GetLDAPError(packet) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else { | ||||
| 		log.Printf("Unexpected Response: %d", packet.Children[1].Tag) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @@ -1,15 +1,9 @@ | ||||
| // This file contains the password modify extended operation as specified in rfc 3062 | ||||
| // | ||||
| // https://tools.ietf.org/html/rfc3062 | ||||
| // | ||||
| 
 | ||||
| package ldap | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| @@ -36,30 +30,33 @@ type PasswordModifyResult struct { | ||||
| 	Referral string | ||||
| } | ||||
| 
 | ||||
| func (r *PasswordModifyRequest) encode() (*ber.Packet, error) { | ||||
| 	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationExtendedRequest, nil, "Password Modify Extended Operation") | ||||
| 	request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, passwordModifyOID, "Extended Request Name: Password Modify OID")) | ||||
| func (req *PasswordModifyRequest) appendTo(envelope *ber.Packet) error { | ||||
| 	pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationExtendedRequest, nil, "Password Modify Extended Operation") | ||||
| 	pkt.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, passwordModifyOID, "Extended Request Name: Password Modify OID")) | ||||
| 
 | ||||
| 	extendedRequestValue := ber.Encode(ber.ClassContext, ber.TypePrimitive, 1, nil, "Extended Request Value: Password Modify Request") | ||||
| 	passwordModifyRequestValue := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Password Modify Request") | ||||
| 	if r.UserIdentity != "" { | ||||
| 		passwordModifyRequestValue.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, r.UserIdentity, "User Identity")) | ||||
| 	if req.UserIdentity != "" { | ||||
| 		passwordModifyRequestValue.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, req.UserIdentity, "User Identity")) | ||||
| 	} | ||||
| 	if r.OldPassword != "" { | ||||
| 		passwordModifyRequestValue.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 1, r.OldPassword, "Old Password")) | ||||
| 	if req.OldPassword != "" { | ||||
| 		passwordModifyRequestValue.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 1, req.OldPassword, "Old Password")) | ||||
| 	} | ||||
| 	if r.NewPassword != "" { | ||||
| 		passwordModifyRequestValue.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 2, r.NewPassword, "New Password")) | ||||
| 	if req.NewPassword != "" { | ||||
| 		passwordModifyRequestValue.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 2, req.NewPassword, "New Password")) | ||||
| 	} | ||||
| 
 | ||||
| 	extendedRequestValue.AppendChild(passwordModifyRequestValue) | ||||
| 	request.AppendChild(extendedRequestValue) | ||||
| 
 | ||||
| 	return request, nil | ||||
| 	pkt.AppendChild(extendedRequestValue) | ||||
| 
 | ||||
| 	envelope.AppendChild(pkt) | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // NewPasswordModifyRequest creates a new PasswordModifyRequest | ||||
| // | ||||
| // According to the RFC 3602: | ||||
| // According to the RFC 3602 (https://tools.ietf.org/html/rfc3062): | ||||
| // userIdentity is a string representing the user associated with the request. | ||||
| // This string may or may not be an LDAPDN (RFC 2253). | ||||
| // If userIdentity is empty then the operation will act on the user associated | ||||
| @@ -84,46 +81,18 @@ func NewPasswordModifyRequest(userIdentity string, oldPassword string, newPasswo | ||||
| 
 | ||||
| // PasswordModify performs the modification request | ||||
| func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error) { | ||||
| 	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") | ||||
| 	packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) | ||||
| 
 | ||||
| 	encodedPasswordModifyRequest, err := passwordModifyRequest.encode() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	packet.AppendChild(encodedPasswordModifyRequest) | ||||
| 
 | ||||
| 	l.Debug.PrintPacket(packet) | ||||
| 
 | ||||
| 	msgCtx, err := l.sendMessage(packet) | ||||
| 	msgCtx, err := l.doRequest(passwordModifyRequest) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
| 
 | ||||
| 	result := &PasswordModifyResult{} | ||||
| 
 | ||||
| 	l.Debug.Printf("%d: waiting for response", msgCtx.id) | ||||
| 	packetResponse, ok := <-msgCtx.responses | ||||
| 	if !ok { | ||||
| 		return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed")) | ||||
| 	} | ||||
| 	packet, err = packetResponse.ReadPacket() | ||||
| 	l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 	packet, err := l.readPacket(msgCtx) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	if packet == nil { | ||||
| 		return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve message")) | ||||
| 	} | ||||
| 
 | ||||
| 	if l.Debug { | ||||
| 		if err := addLDAPDescriptions(packet); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		ber.PrintPacket(packet) | ||||
| 	} | ||||
| 	result := &PasswordModifyResult{} | ||||
| 
 | ||||
| 	if packet.Children[1].Tag == ApplicationExtendedResponse { | ||||
| 		err := GetLDAPError(packet) | ||||
							
								
								
									
										66
									
								
								vendor/github.com/go-ldap/ldap/v3/request.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								vendor/github.com/go-ldap/ldap/v3/request.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
|  | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	errRespChanClosed = errors.New("ldap: response channel closed") | ||||
| 	errCouldNotRetMsg = errors.New("ldap: could not retrieve message") | ||||
| ) | ||||
|  | ||||
| type request interface { | ||||
| 	appendTo(*ber.Packet) error | ||||
| } | ||||
|  | ||||
| type requestFunc func(*ber.Packet) error | ||||
|  | ||||
| func (f requestFunc) appendTo(p *ber.Packet) error { | ||||
| 	return f(p) | ||||
| } | ||||
|  | ||||
| func (l *Conn) doRequest(req request) (*messageContext, error) { | ||||
| 	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") | ||||
| 	packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) | ||||
| 	if err := req.appendTo(packet); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if l.Debug { | ||||
| 		l.Debug.PrintPacket(packet) | ||||
| 	} | ||||
|  | ||||
| 	msgCtx, err := l.sendMessage(packet) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	l.Debug.Printf("%d: returning", msgCtx.id) | ||||
| 	return msgCtx, nil | ||||
| } | ||||
|  | ||||
| func (l *Conn) readPacket(msgCtx *messageContext) (*ber.Packet, error) { | ||||
| 	l.Debug.Printf("%d: waiting for response", msgCtx.id) | ||||
| 	packetResponse, ok := <-msgCtx.responses | ||||
| 	if !ok { | ||||
| 		return nil, NewError(ErrorNetwork, errRespChanClosed) | ||||
| 	} | ||||
| 	packet, err := packetResponse.ReadPacket() | ||||
| 	l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if packet == nil { | ||||
| 		return nil, NewError(ErrorNetwork, errCouldNotRetMsg) | ||||
| 	} | ||||
|  | ||||
| 	if l.Debug { | ||||
| 		if err = addLDAPDescriptions(packet); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		l.Debug.PrintPacket(packet) | ||||
| 	} | ||||
| 	return packet, nil | ||||
| } | ||||
							
								
								
									
										176
									
								
								vendor/gopkg.in/ldap.v3/search.go → vendor/github.com/go-ldap/ldap/v3/search.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										176
									
								
								vendor/gopkg.in/ldap.v3/search.go → vendor/github.com/go-ldap/ldap/v3/search.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,58 +1,3 @@ | ||||
| // File contains Search functionality | ||||
| // | ||||
| // https://tools.ietf.org/html/rfc4511 | ||||
| // | ||||
| //         SearchRequest ::= [APPLICATION 3] SEQUENCE { | ||||
| //              baseObject      LDAPDN, | ||||
| //              scope           ENUMERATED { | ||||
| //                   baseObject              (0), | ||||
| //                   singleLevel             (1), | ||||
| //                   wholeSubtree            (2), | ||||
| //                   ...  }, | ||||
| //              derefAliases    ENUMERATED { | ||||
| //                   neverDerefAliases       (0), | ||||
| //                   derefInSearching        (1), | ||||
| //                   derefFindingBaseObj     (2), | ||||
| //                   derefAlways             (3) }, | ||||
| //              sizeLimit       INTEGER (0 ..  maxInt), | ||||
| //              timeLimit       INTEGER (0 ..  maxInt), | ||||
| //              typesOnly       BOOLEAN, | ||||
| //              filter          Filter, | ||||
| //              attributes      AttributeSelection } | ||||
| // | ||||
| //         AttributeSelection ::= SEQUENCE OF selector LDAPString | ||||
| //                         -- The LDAPString is constrained to | ||||
| //                         -- <attributeSelector> in Section 4.5.1.8 | ||||
| // | ||||
| //         Filter ::= CHOICE { | ||||
| //              and             [0] SET SIZE (1..MAX) OF filter Filter, | ||||
| //              or              [1] SET SIZE (1..MAX) OF filter Filter, | ||||
| //              not             [2] Filter, | ||||
| //              equalityMatch   [3] AttributeValueAssertion, | ||||
| //              substrings      [4] SubstringFilter, | ||||
| //              greaterOrEqual  [5] AttributeValueAssertion, | ||||
| //              lessOrEqual     [6] AttributeValueAssertion, | ||||
| //              present         [7] AttributeDescription, | ||||
| //              approxMatch     [8] AttributeValueAssertion, | ||||
| //              extensibleMatch [9] MatchingRuleAssertion, | ||||
| //              ...  } | ||||
| // | ||||
| //         SubstringFilter ::= SEQUENCE { | ||||
| //              type           AttributeDescription, | ||||
| //              substrings     SEQUENCE SIZE (1..MAX) OF substring CHOICE { | ||||
| //                   initial [0] AssertionValue,  -- can occur at most once | ||||
| //                   any     [1] AssertionValue, | ||||
| //                   final   [2] AssertionValue } -- can occur at most once | ||||
| //              } | ||||
| // | ||||
| //         MatchingRuleAssertion ::= SEQUENCE { | ||||
| //              matchingRule    [1] MatchingRuleId OPTIONAL, | ||||
| //              type            [2] AttributeDescription OPTIONAL, | ||||
| //              matchValue      [3] AssertionValue, | ||||
| //              dnAttributes    [4] BOOLEAN DEFAULT FALSE } | ||||
| // | ||||
| // | ||||
| 
 | ||||
| package ldap | ||||
| 
 | ||||
| import ( | ||||
| @@ -61,7 +6,7 @@ import ( | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| 	ber "github.com/go-asn1-ber/asn1-ber" | ||||
| ) | ||||
| 
 | ||||
| // scope choices | ||||
| @@ -132,6 +77,17 @@ func (e *Entry) GetAttributeValues(attribute string) []string { | ||||
| 	return []string{} | ||||
| } | ||||
| 
 | ||||
| // GetEqualFoldAttributeValues returns the values for the named attribute, or an | ||||
| // empty list. Attribute matching is done with strings.EqualFold. | ||||
| func (e *Entry) GetEqualFoldAttributeValues(attribute string) []string { | ||||
| 	for _, attr := range e.Attributes { | ||||
| 		if strings.EqualFold(attribute, attr.Name) { | ||||
| 			return attr.Values | ||||
| 		} | ||||
| 	} | ||||
| 	return []string{} | ||||
| } | ||||
| 
 | ||||
| // GetRawAttributeValues returns the byte values for the named attribute, or an empty list | ||||
| func (e *Entry) GetRawAttributeValues(attribute string) [][]byte { | ||||
| 	for _, attr := range e.Attributes { | ||||
| @@ -142,6 +98,16 @@ func (e *Entry) GetRawAttributeValues(attribute string) [][]byte { | ||||
| 	return [][]byte{} | ||||
| } | ||||
| 
 | ||||
| // GetEqualFoldRawAttributeValues returns the byte values for the named attribute, or an empty list | ||||
| func (e *Entry) GetEqualFoldRawAttributeValues(attribute string) [][]byte { | ||||
| 	for _, attr := range e.Attributes { | ||||
| 		if strings.EqualFold(attr.Name, attribute) { | ||||
| 			return attr.ByteValues | ||||
| 		} | ||||
| 	} | ||||
| 	return [][]byte{} | ||||
| } | ||||
| 
 | ||||
| // GetAttributeValue returns the first value for the named attribute, or "" | ||||
| func (e *Entry) GetAttributeValue(attribute string) string { | ||||
| 	values := e.GetAttributeValues(attribute) | ||||
| @@ -151,6 +117,16 @@ func (e *Entry) GetAttributeValue(attribute string) string { | ||||
| 	return values[0] | ||||
| } | ||||
| 
 | ||||
| // GetEqualFoldAttributeValue returns the first value for the named attribute, or "". | ||||
| // Attribute comparison is done with strings.EqualFold. | ||||
| func (e *Entry) GetEqualFoldAttributeValue(attribute string) string { | ||||
| 	values := e.GetEqualFoldAttributeValues(attribute) | ||||
| 	if len(values) == 0 { | ||||
| 		return "" | ||||
| 	} | ||||
| 	return values[0] | ||||
| } | ||||
| 
 | ||||
| // GetRawAttributeValue returns the first value for the named attribute, or an empty slice | ||||
| func (e *Entry) GetRawAttributeValue(attribute string) []byte { | ||||
| 	values := e.GetRawAttributeValues(attribute) | ||||
| @@ -160,6 +136,15 @@ func (e *Entry) GetRawAttributeValue(attribute string) []byte { | ||||
| 	return values[0] | ||||
| } | ||||
| 
 | ||||
| // GetEqualFoldRawAttributeValue returns the first value for the named attribute, or an empty slice | ||||
| func (e *Entry) GetEqualFoldRawAttributeValue(attribute string) []byte { | ||||
| 	values := e.GetEqualFoldRawAttributeValues(attribute) | ||||
| 	if len(values) == 0 { | ||||
| 		return []byte{} | ||||
| 	} | ||||
| 	return values[0] | ||||
| } | ||||
| 
 | ||||
| // Print outputs a human-readable description | ||||
| func (e *Entry) Print() { | ||||
| 	fmt.Printf("DN: %s\n", e.DN) | ||||
| @@ -246,27 +231,33 @@ type SearchRequest struct { | ||||
| 	Controls     []Control | ||||
| } | ||||
| 
 | ||||
| func (s *SearchRequest) encode() (*ber.Packet, error) { | ||||
| 	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationSearchRequest, nil, "Search Request") | ||||
| 	request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, s.BaseDN, "Base DN")) | ||||
| 	request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(s.Scope), "Scope")) | ||||
| 	request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(s.DerefAliases), "Deref Aliases")) | ||||
| 	request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(s.SizeLimit), "Size Limit")) | ||||
| 	request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(s.TimeLimit), "Time Limit")) | ||||
| 	request.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, s.TypesOnly, "Types Only")) | ||||
| func (req *SearchRequest) appendTo(envelope *ber.Packet) error { | ||||
| 	pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationSearchRequest, nil, "Search Request") | ||||
| 	pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.BaseDN, "Base DN")) | ||||
| 	pkt.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(req.Scope), "Scope")) | ||||
| 	pkt.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(req.DerefAliases), "Deref Aliases")) | ||||
| 	pkt.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(req.SizeLimit), "Size Limit")) | ||||
| 	pkt.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(req.TimeLimit), "Time Limit")) | ||||
| 	pkt.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, req.TypesOnly, "Types Only")) | ||||
| 	// compile and encode filter | ||||
| 	filterPacket, err := CompileFilter(s.Filter) | ||||
| 	filterPacket, err := CompileFilter(req.Filter) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 		return err | ||||
| 	} | ||||
| 	request.AppendChild(filterPacket) | ||||
| 	pkt.AppendChild(filterPacket) | ||||
| 	// encode attributes | ||||
| 	attributesPacket := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes") | ||||
| 	for _, attribute := range s.Attributes { | ||||
| 	for _, attribute := range req.Attributes { | ||||
| 		attributesPacket.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute")) | ||||
| 	} | ||||
| 	request.AppendChild(attributesPacket) | ||||
| 	return request, nil | ||||
| 	pkt.AppendChild(attributesPacket) | ||||
| 
 | ||||
| 	envelope.AppendChild(pkt) | ||||
| 	if len(req.Controls) > 0 { | ||||
| 		envelope.AppendChild(encodeControls(req.Controls)) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // NewSearchRequest creates a new search request | ||||
| @@ -366,22 +357,7 @@ func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) | ||||
| 
 | ||||
| // Search performs the given search request | ||||
| func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) { | ||||
| 	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") | ||||
| 	packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) | ||||
| 	// encode search request | ||||
| 	encodedSearchRequest, err := searchRequest.encode() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	packet.AppendChild(encodedSearchRequest) | ||||
| 	// encode search controls | ||||
| 	if len(searchRequest.Controls) > 0 { | ||||
| 		packet.AppendChild(encodeControls(searchRequest.Controls)) | ||||
| 	} | ||||
| 
 | ||||
| 	l.Debug.PrintPacket(packet) | ||||
| 
 | ||||
| 	msgCtx, err := l.sendMessage(packet) | ||||
| 	msgCtx, err := l.doRequest(searchRequest) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -392,24 +368,10 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) { | ||||
| 		Referrals: make([]string, 0), | ||||
| 		Controls:  make([]Control, 0)} | ||||
| 
 | ||||
| 	foundSearchResultDone := false | ||||
| 	for !foundSearchResultDone { | ||||
| 		l.Debug.Printf("%d: waiting for response", msgCtx.id) | ||||
| 		packetResponse, ok := <-msgCtx.responses | ||||
| 		if !ok { | ||||
| 			return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed")) | ||||
| 		} | ||||
| 		packet, err = packetResponse.ReadPacket() | ||||
| 		l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 	for { | ||||
| 		packet, err := l.readPacket(msgCtx) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 
 | ||||
| 		if l.Debug { | ||||
| 			if err := addLDAPDescriptions(packet); err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			ber.PrintPacket(packet) | ||||
| 			return result, err | ||||
| 		} | ||||
| 
 | ||||
| 		switch packet.Children[1].Tag { | ||||
| @@ -429,22 +391,20 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) { | ||||
| 		case 5: | ||||
| 			err := GetLDAPError(packet) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 				return result, err | ||||
| 			} | ||||
| 			if len(packet.Children) == 3 { | ||||
| 				for _, child := range packet.Children[2].Children { | ||||
| 					decodedChild, err := DecodeControl(child) | ||||
| 					if err != nil { | ||||
| 						return nil, fmt.Errorf("failed to decode child control: %s", err) | ||||
| 						return result, fmt.Errorf("failed to decode child control: %s", err) | ||||
| 					} | ||||
| 					result.Controls = append(result.Controls, decodedChild) | ||||
| 				} | ||||
| 			} | ||||
| 			foundSearchResultDone = true | ||||
| 			return result, nil | ||||
| 		case 19: | ||||
| 			result.Referrals = append(result.Referrals, packet.Children[1].Children[0].Value.(string)) | ||||
| 		} | ||||
| 	} | ||||
| 	l.Debug.Printf("%d: returning", msgCtx.id) | ||||
| 	return result, nil | ||||
| } | ||||
							
								
								
									
										15
									
								
								vendor/gopkg.in/asn1-ber.v1/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/gopkg.in/asn1-ber.v1/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,15 +0,0 @@ | ||||
| language: go | ||||
| go: | ||||
|     - 1.2 | ||||
|     - 1.3 | ||||
|     - 1.4 | ||||
|     - 1.5 | ||||
|     - tip | ||||
| go_import_path: gopkg.in/asn-ber.v1 | ||||
| install: | ||||
|     - go list -f '{{range .Imports}}{{.}} {{end}}' ./... | xargs go get -v | ||||
|     - go list -f '{{range .TestImports}}{{.}} {{end}}' ./... | xargs go get -v | ||||
|     - go get code.google.com/p/go.tools/cmd/cover || go get golang.org/x/tools/cmd/cover | ||||
|     - go build -v ./... | ||||
| script: | ||||
|     - go test -v -cover ./... | ||||
							
								
								
									
										27
									
								
								vendor/gopkg.in/asn1-ber.v1/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/gopkg.in/asn1-ber.v1/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,27 +0,0 @@ | ||||
| Copyright (c) 2012 The Go Authors. All rights reserved. | ||||
|  | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
|  | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
|  | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										0
									
								
								vendor/gopkg.in/ldap.v3/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								vendor/gopkg.in/ldap.v3/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
									
										32
									
								
								vendor/gopkg.in/ldap.v3/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/gopkg.in/ldap.v3/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,32 +0,0 @@ | ||||
| sudo: false | ||||
| language: go | ||||
| go: | ||||
|     - "1.4.x" | ||||
|     - "1.5.x" | ||||
|     - "1.6.x" | ||||
|     - "1.7.x" | ||||
|     - "1.8.x" | ||||
|     - "1.9.x" | ||||
|     - "1.10.x" | ||||
|     - "1.11.x" | ||||
|     - "1.12.x" | ||||
|     - tip | ||||
|  | ||||
| git: | ||||
|   depth: 1 | ||||
|  | ||||
| matrix: | ||||
|     fast_finish: true | ||||
|     allow_failures: | ||||
|         - go: tip | ||||
| go_import_path: gopkg.in/ldap.v3 | ||||
| install: | ||||
|     - go get gopkg.in/asn1-ber.v1 | ||||
|     - go get code.google.com/p/go.tools/cmd/cover || go get golang.org/x/tools/cmd/cover | ||||
|     - go get github.com/golang/lint/golint || go get golang.org/x/lint/golint || true | ||||
|     - go build -v ./... | ||||
| script: | ||||
|     - make test | ||||
|     - make fmt | ||||
|     - make vet | ||||
|     - make lint | ||||
							
								
								
									
										12
									
								
								vendor/gopkg.in/ldap.v3/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/gopkg.in/ldap.v3/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,12 +0,0 @@ | ||||
| # Contribution Guidelines | ||||
|  | ||||
| We welcome contribution and improvements. | ||||
|  | ||||
| ## Guiding Principles | ||||
|  | ||||
| To begin with here is a draft from an email exchange: | ||||
|  | ||||
|  * take compatibility seriously (our semvers, compatibility with older go versions, etc) | ||||
|  * don't tag untested code for release | ||||
|  * beware of baking in implicit behavior based on other libraries/tools choices | ||||
|  * be as high-fidelity as possible in plumbing through LDAP data (don't mask errors or reduce power of someone using the library) | ||||
							
								
								
									
										82
									
								
								vendor/gopkg.in/ldap.v3/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										82
									
								
								vendor/gopkg.in/ldap.v3/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,82 +0,0 @@ | ||||
| .PHONY: default install build test quicktest fmt vet lint  | ||||
|  | ||||
| # List of all release tags "supported" by our current Go version | ||||
| # E.g. ":go1.1:go1.2:go1.3:go1.4:go1.5:go1.6:go1.7:go1.8:go1.9:go1.10:go1.11:go1.12:" | ||||
| GO_RELEASE_TAGS := $(shell go list -f ':{{join (context.ReleaseTags) ":"}}:' runtime) | ||||
|  | ||||
| # Only use the `-race` flag on newer versions of Go (version 1.3 and newer) | ||||
| ifeq (,$(findstring :go1.3:,$(GO_RELEASE_TAGS))) | ||||
| 	RACE_FLAG := | ||||
| else | ||||
| 	RACE_FLAG := -race -cpu 1,2,4 | ||||
| endif | ||||
|  | ||||
| # Run `go vet` on Go 1.12 and newer. For Go 1.5-1.11, use `go tool vet` | ||||
| ifneq (,$(findstring :go1.12:,$(GO_RELEASE_TAGS))) | ||||
| 	GO_VET := go vet \ | ||||
| 		-atomic \ | ||||
| 		-bool \ | ||||
| 		-copylocks \ | ||||
| 		-nilfunc \ | ||||
| 		-printf \ | ||||
| 		-rangeloops \ | ||||
| 		-unreachable \ | ||||
| 		-unsafeptr \ | ||||
| 		-unusedresult \ | ||||
| 		. | ||||
| else ifneq (,$(findstring :go1.5:,$(GO_RELEASE_TAGS))) | ||||
| 	GO_VET := go tool vet \ | ||||
| 		-atomic \ | ||||
| 		-bool \ | ||||
| 		-copylocks \ | ||||
| 		-nilfunc \ | ||||
| 		-printf \ | ||||
| 		-shadow \ | ||||
| 		-rangeloops \ | ||||
| 		-unreachable \ | ||||
| 		-unsafeptr \ | ||||
| 		-unusedresult \ | ||||
| 		. | ||||
| else | ||||
| 	GO_VET := @echo "go vet skipped -- not supported on this version of Go" | ||||
| endif | ||||
|  | ||||
| default: fmt vet lint build quicktest | ||||
|  | ||||
| install: | ||||
| 	go get -t -v ./... | ||||
|  | ||||
| build: | ||||
| 	go build -v ./... | ||||
|  | ||||
| test: | ||||
| 	go test -v $(RACE_FLAG) -cover ./... | ||||
|  | ||||
| quicktest: | ||||
| 	go test ./... | ||||
|  | ||||
| # Capture output and force failure when there is non-empty output | ||||
| fmt: | ||||
| 	@echo gofmt -l . | ||||
| 	@OUTPUT=`gofmt -l . 2>&1`; \ | ||||
| 	if [ "$$OUTPUT" ]; then \ | ||||
| 		echo "gofmt must be run on the following files:"; \ | ||||
| 		echo "$$OUTPUT"; \ | ||||
| 		exit 1; \ | ||||
| 	fi | ||||
|  | ||||
| vet: | ||||
| 	$(GO_VET) | ||||
|  | ||||
| # https://github.com/golang/lint | ||||
| # go get github.com/golang/lint/golint | ||||
| # Capture output and force failure when there is non-empty output | ||||
| # Only run on go1.5+ | ||||
| lint: | ||||
| 	@echo golint ./... | ||||
| 	@OUTPUT=`command -v golint >/dev/null 2>&1 && golint ./... 2>&1`; \ | ||||
| 	if [ "$$OUTPUT" ]; then \ | ||||
| 		echo "golint errors:"; \ | ||||
| 		echo "$$OUTPUT"; \ | ||||
| 		exit 1; \ | ||||
| 	fi | ||||
							
								
								
									
										54
									
								
								vendor/gopkg.in/ldap.v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/gopkg.in/ldap.v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,54 +0,0 @@ | ||||
| [](https://godoc.org/gopkg.in/ldap.v3) | ||||
| [](https://travis-ci.org/go-ldap/ldap) | ||||
|  | ||||
| # Basic LDAP v3 functionality for the GO programming language. | ||||
|  | ||||
| ## Install | ||||
|  | ||||
| For the latest version use: | ||||
|  | ||||
|     go get gopkg.in/ldap.v3 | ||||
|  | ||||
| Import the latest version with: | ||||
|  | ||||
|     import "gopkg.in/ldap.v3" | ||||
|  | ||||
| ## Required Libraries: | ||||
|  | ||||
|  - gopkg.in/asn1-ber.v1 | ||||
|  | ||||
| ## Features: | ||||
|  | ||||
|  - Connecting to LDAP server (non-TLS, TLS, STARTTLS) | ||||
|  - Binding to LDAP server | ||||
|  - Searching for entries | ||||
|  - Filter Compile / Decompile | ||||
|  - Paging Search Results | ||||
|  - Modify Requests / Responses | ||||
|  - Add Requests / Responses | ||||
|  - Delete Requests / Responses | ||||
|  - Modify DN Requests / Responses | ||||
|  | ||||
| ## Examples: | ||||
|  | ||||
|  - search | ||||
|  - modify | ||||
|  | ||||
| ## Contributing: | ||||
|  | ||||
| Bug reports and pull requests are welcome! | ||||
|  | ||||
| Before submitting a pull request, please make sure tests and verification scripts pass: | ||||
| ``` | ||||
| make all | ||||
| ``` | ||||
|  | ||||
| To set up a pre-push hook to run the tests and verify scripts before pushing: | ||||
| ``` | ||||
| ln -s ../../.githooks/pre-push .git/hooks/pre-push | ||||
| ``` | ||||
|  | ||||
| --- | ||||
| The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/) | ||||
| The design is licensed under the Creative Commons 3.0 Attributions license. | ||||
| Read this article for more details: http://blog.golang.org/gopher | ||||
							
								
								
									
										135
									
								
								vendor/gopkg.in/ldap.v3/bind.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										135
									
								
								vendor/gopkg.in/ldap.v3/bind.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,135 +0,0 @@ | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| ) | ||||
|  | ||||
| // SimpleBindRequest represents a username/password bind operation | ||||
| type SimpleBindRequest struct { | ||||
| 	// Username is the name of the Directory object that the client wishes to bind as | ||||
| 	Username string | ||||
| 	// Password is the credentials to bind with | ||||
| 	Password string | ||||
| 	// Controls are optional controls to send with the bind request | ||||
| 	Controls []Control | ||||
| 	// AllowEmptyPassword sets whether the client allows binding with an empty password | ||||
| 	// (normally used for unauthenticated bind). | ||||
| 	AllowEmptyPassword bool | ||||
| } | ||||
|  | ||||
| // SimpleBindResult contains the response from the server | ||||
| type SimpleBindResult struct { | ||||
| 	Controls []Control | ||||
| } | ||||
|  | ||||
| // NewSimpleBindRequest returns a bind request | ||||
| func NewSimpleBindRequest(username string, password string, controls []Control) *SimpleBindRequest { | ||||
| 	return &SimpleBindRequest{ | ||||
| 		Username:           username, | ||||
| 		Password:           password, | ||||
| 		Controls:           controls, | ||||
| 		AllowEmptyPassword: false, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (bindRequest *SimpleBindRequest) encode() *ber.Packet { | ||||
| 	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") | ||||
| 	request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) | ||||
| 	request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, bindRequest.Username, "User Name")) | ||||
| 	request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, bindRequest.Password, "Password")) | ||||
|  | ||||
| 	return request | ||||
| } | ||||
|  | ||||
| // SimpleBind performs the simple bind operation defined in the given request | ||||
| func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) { | ||||
| 	if simpleBindRequest.Password == "" && !simpleBindRequest.AllowEmptyPassword { | ||||
| 		return nil, NewError(ErrorEmptyPassword, errors.New("ldap: empty password not allowed by the client")) | ||||
| 	} | ||||
|  | ||||
| 	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") | ||||
| 	packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) | ||||
| 	encodedBindRequest := simpleBindRequest.encode() | ||||
| 	packet.AppendChild(encodedBindRequest) | ||||
| 	if len(simpleBindRequest.Controls) > 0 { | ||||
| 		packet.AppendChild(encodeControls(simpleBindRequest.Controls)) | ||||
| 	} | ||||
|  | ||||
| 	if l.Debug { | ||||
| 		ber.PrintPacket(packet) | ||||
| 	} | ||||
|  | ||||
| 	msgCtx, err := l.sendMessage(packet) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	packetResponse, ok := <-msgCtx.responses | ||||
| 	if !ok { | ||||
| 		return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed")) | ||||
| 	} | ||||
| 	packet, err = packetResponse.ReadPacket() | ||||
| 	l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if l.Debug { | ||||
| 		if err = addLDAPDescriptions(packet); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		ber.PrintPacket(packet) | ||||
| 	} | ||||
|  | ||||
| 	result := &SimpleBindResult{ | ||||
| 		Controls: make([]Control, 0), | ||||
| 	} | ||||
|  | ||||
| 	if len(packet.Children) == 3 { | ||||
| 		for _, child := range packet.Children[2].Children { | ||||
| 			decodedChild, decodeErr := DecodeControl(child) | ||||
| 			if decodeErr != nil { | ||||
| 				return nil, fmt.Errorf("failed to decode child control: %s", decodeErr) | ||||
| 			} | ||||
| 			result.Controls = append(result.Controls, decodedChild) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	err = GetLDAPError(packet) | ||||
| 	return result, err | ||||
| } | ||||
|  | ||||
| // Bind performs a bind with the given username and password. | ||||
| // | ||||
| // It does not allow unauthenticated bind (i.e. empty password). Use the UnauthenticatedBind method | ||||
| // for that. | ||||
| func (l *Conn) Bind(username, password string) error { | ||||
| 	req := &SimpleBindRequest{ | ||||
| 		Username:           username, | ||||
| 		Password:           password, | ||||
| 		AllowEmptyPassword: false, | ||||
| 	} | ||||
| 	_, err := l.SimpleBind(req) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // UnauthenticatedBind performs an unauthenticated bind. | ||||
| // | ||||
| // A username may be provided for trace (e.g. logging) purpose only, but it is normally not | ||||
| // authenticated or otherwise validated by the LDAP server. | ||||
| // | ||||
| // See https://tools.ietf.org/html/rfc4513#section-5.1.2 . | ||||
| // See https://tools.ietf.org/html/rfc4513#section-6.3.1 . | ||||
| func (l *Conn) UnauthenticatedBind(username string) error { | ||||
| 	req := &SimpleBindRequest{ | ||||
| 		Username:           username, | ||||
| 		Password:           "", | ||||
| 		AllowEmptyPassword: true, | ||||
| 	} | ||||
| 	_, err := l.SimpleBind(req) | ||||
| 	return err | ||||
| } | ||||
							
								
								
									
										28
									
								
								vendor/gopkg.in/ldap.v3/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								vendor/gopkg.in/ldap.v3/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,28 +0,0 @@ | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"crypto/tls" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // Client knows how to interact with an LDAP server | ||||
| type Client interface { | ||||
| 	Start() | ||||
| 	StartTLS(config *tls.Config) error | ||||
| 	Close() | ||||
| 	SetTimeout(time.Duration) | ||||
|  | ||||
| 	Bind(username, password string) error | ||||
| 	SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) | ||||
|  | ||||
| 	Add(addRequest *AddRequest) error | ||||
| 	Del(delRequest *DelRequest) error | ||||
| 	Modify(modifyRequest *ModifyRequest) error | ||||
| 	ModifyDN(modifyDNRequest *ModifyDNRequest) error | ||||
|  | ||||
| 	Compare(dn, attribute, value string) (bool, error) | ||||
| 	PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error) | ||||
|  | ||||
| 	Search(searchRequest *SearchRequest) (*SearchResult, error) | ||||
| 	SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error) | ||||
| } | ||||
							
								
								
									
										83
									
								
								vendor/gopkg.in/ldap.v3/compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										83
									
								
								vendor/gopkg.in/ldap.v3/compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,83 +0,0 @@ | ||||
| // File contains Compare functionality | ||||
| // | ||||
| // https://tools.ietf.org/html/rfc4511 | ||||
| // | ||||
| // CompareRequest ::= [APPLICATION 14] SEQUENCE { | ||||
| //              entry           LDAPDN, | ||||
| //              ava             AttributeValueAssertion } | ||||
| // | ||||
| // AttributeValueAssertion ::= SEQUENCE { | ||||
| //              attributeDesc   AttributeDescription, | ||||
| //              assertionValue  AssertionValue } | ||||
| // | ||||
| // AttributeDescription ::= LDAPString | ||||
| //                         -- Constrained to <attributedescription> | ||||
| //                         -- [RFC4512] | ||||
| // | ||||
| // AttributeValue ::= OCTET STRING | ||||
| // | ||||
|  | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| ) | ||||
|  | ||||
| // Compare checks to see if the attribute of the dn matches value. Returns true if it does otherwise | ||||
| // false with any error that occurs if any. | ||||
| func (l *Conn) Compare(dn, attribute, value string) (bool, error) { | ||||
| 	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") | ||||
| 	packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) | ||||
|  | ||||
| 	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationCompareRequest, nil, "Compare Request") | ||||
| 	request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, dn, "DN")) | ||||
|  | ||||
| 	ava := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "AttributeValueAssertion") | ||||
| 	ava.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "AttributeDesc")) | ||||
| 	ava.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "AssertionValue")) | ||||
| 	request.AppendChild(ava) | ||||
| 	packet.AppendChild(request) | ||||
|  | ||||
| 	l.Debug.PrintPacket(packet) | ||||
|  | ||||
| 	msgCtx, err := l.sendMessage(packet) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	l.Debug.Printf("%d: waiting for response", msgCtx.id) | ||||
| 	packetResponse, ok := <-msgCtx.responses | ||||
| 	if !ok { | ||||
| 		return false, NewError(ErrorNetwork, errors.New("ldap: response channel closed")) | ||||
| 	} | ||||
| 	packet, err = packetResponse.ReadPacket() | ||||
| 	l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
|  | ||||
| 	if l.Debug { | ||||
| 		if err := addLDAPDescriptions(packet); err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
| 		ber.PrintPacket(packet) | ||||
| 	} | ||||
|  | ||||
| 	if packet.Children[1].Tag == ApplicationCompareResponse { | ||||
| 		err := GetLDAPError(packet) | ||||
|  | ||||
| 		switch { | ||||
| 		case IsErrorWithCode(err, LDAPResultCompareTrue): | ||||
| 			return true, nil | ||||
| 		case IsErrorWithCode(err, LDAPResultCompareFalse): | ||||
| 			return false, nil | ||||
| 		default: | ||||
| 			return false, err | ||||
| 		} | ||||
| 	} | ||||
| 	return false, fmt.Errorf("unexpected Response: %d", packet.Children[1].Tag) | ||||
| } | ||||
							
								
								
									
										84
									
								
								vendor/gopkg.in/ldap.v3/del.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										84
									
								
								vendor/gopkg.in/ldap.v3/del.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,84 +0,0 @@ | ||||
| // | ||||
| // https://tools.ietf.org/html/rfc4511 | ||||
| // | ||||
| // DelRequest ::= [APPLICATION 10] LDAPDN | ||||
|  | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"log" | ||||
|  | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| ) | ||||
|  | ||||
| // DelRequest implements an LDAP deletion request | ||||
| type DelRequest struct { | ||||
| 	// DN is the name of the directory entry to delete | ||||
| 	DN string | ||||
| 	// Controls hold optional controls to send with the request | ||||
| 	Controls []Control | ||||
| } | ||||
|  | ||||
| func (d DelRequest) encode() *ber.Packet { | ||||
| 	request := ber.Encode(ber.ClassApplication, ber.TypePrimitive, ApplicationDelRequest, d.DN, "Del Request") | ||||
| 	request.Data.Write([]byte(d.DN)) | ||||
| 	return request | ||||
| } | ||||
|  | ||||
| // NewDelRequest creates a delete request for the given DN and controls | ||||
| func NewDelRequest(DN string, | ||||
| 	Controls []Control) *DelRequest { | ||||
| 	return &DelRequest{ | ||||
| 		DN:       DN, | ||||
| 		Controls: Controls, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Del executes the given delete request | ||||
| func (l *Conn) Del(delRequest *DelRequest) error { | ||||
| 	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") | ||||
| 	packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) | ||||
| 	packet.AppendChild(delRequest.encode()) | ||||
| 	if len(delRequest.Controls) > 0 { | ||||
| 		packet.AppendChild(encodeControls(delRequest.Controls)) | ||||
| 	} | ||||
|  | ||||
| 	l.Debug.PrintPacket(packet) | ||||
|  | ||||
| 	msgCtx, err := l.sendMessage(packet) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	l.Debug.Printf("%d: waiting for response", msgCtx.id) | ||||
| 	packetResponse, ok := <-msgCtx.responses | ||||
| 	if !ok { | ||||
| 		return NewError(ErrorNetwork, errors.New("ldap: response channel closed")) | ||||
| 	} | ||||
| 	packet, err = packetResponse.ReadPacket() | ||||
| 	l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if l.Debug { | ||||
| 		if err := addLDAPDescriptions(packet); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		ber.PrintPacket(packet) | ||||
| 	} | ||||
|  | ||||
| 	if packet.Children[1].Tag == ApplicationDelResponse { | ||||
| 		err := GetLDAPError(packet) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else { | ||||
| 		log.Printf("Unexpected Response: %d", packet.Children[1].Tag) | ||||
| 	} | ||||
|  | ||||
| 	l.Debug.Printf("%d: returning", msgCtx.id) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										104
									
								
								vendor/gopkg.in/ldap.v3/moddn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										104
									
								
								vendor/gopkg.in/ldap.v3/moddn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,104 +0,0 @@ | ||||
| // Package ldap - moddn.go contains ModifyDN functionality | ||||
| // | ||||
| // https://tools.ietf.org/html/rfc4511 | ||||
| // ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { | ||||
| //      entry           LDAPDN, | ||||
| //      newrdn          RelativeLDAPDN, | ||||
| //      deleteoldrdn    BOOLEAN, | ||||
| //      newSuperior     [0] LDAPDN OPTIONAL } | ||||
| // | ||||
| // | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"log" | ||||
|  | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| ) | ||||
|  | ||||
| // ModifyDNRequest holds the request to modify a DN | ||||
| type ModifyDNRequest struct { | ||||
| 	DN           string | ||||
| 	NewRDN       string | ||||
| 	DeleteOldRDN bool | ||||
| 	NewSuperior  string | ||||
| } | ||||
|  | ||||
| // NewModifyDNRequest creates a new request which can be passed to ModifyDN(). | ||||
| // | ||||
| // To move an object in the tree, set the "newSup" to the new parent entry DN. Use an | ||||
| // empty string for just changing the object's RDN. | ||||
| // | ||||
| // For moving the object without renaming, the "rdn" must be the first | ||||
| // RDN of the given DN. | ||||
| // | ||||
| // A call like | ||||
| //   mdnReq := NewModifyDNRequest("uid=someone,dc=example,dc=org", "uid=newname", true, "") | ||||
| // will setup the request to just rename uid=someone,dc=example,dc=org to | ||||
| // uid=newname,dc=example,dc=org. | ||||
| func NewModifyDNRequest(dn string, rdn string, delOld bool, newSup string) *ModifyDNRequest { | ||||
| 	return &ModifyDNRequest{ | ||||
| 		DN:           dn, | ||||
| 		NewRDN:       rdn, | ||||
| 		DeleteOldRDN: delOld, | ||||
| 		NewSuperior:  newSup, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (m ModifyDNRequest) encode() *ber.Packet { | ||||
| 	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyDNRequest, nil, "Modify DN Request") | ||||
| 	request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.DN, "DN")) | ||||
| 	request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.NewRDN, "New RDN")) | ||||
| 	request.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, m.DeleteOldRDN, "Delete old RDN")) | ||||
| 	if m.NewSuperior != "" { | ||||
| 		request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, m.NewSuperior, "New Superior")) | ||||
| 	} | ||||
| 	return request | ||||
| } | ||||
|  | ||||
| // ModifyDN renames the given DN and optionally move to another base (when the "newSup" argument | ||||
| // to NewModifyDNRequest() is not ""). | ||||
| func (l *Conn) ModifyDN(m *ModifyDNRequest) error { | ||||
| 	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") | ||||
| 	packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) | ||||
| 	packet.AppendChild(m.encode()) | ||||
|  | ||||
| 	l.Debug.PrintPacket(packet) | ||||
|  | ||||
| 	msgCtx, err := l.sendMessage(packet) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	l.Debug.Printf("%d: waiting for response", msgCtx.id) | ||||
| 	packetResponse, ok := <-msgCtx.responses | ||||
| 	if !ok { | ||||
| 		return NewError(ErrorNetwork, errors.New("ldap: channel closed")) | ||||
| 	} | ||||
| 	packet, err = packetResponse.ReadPacket() | ||||
| 	l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if l.Debug { | ||||
| 		if err := addLDAPDescriptions(packet); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		ber.PrintPacket(packet) | ||||
| 	} | ||||
|  | ||||
| 	if packet.Children[1].Tag == ApplicationModifyDNResponse { | ||||
| 		err := GetLDAPError(packet) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else { | ||||
| 		log.Printf("Unexpected Response: %d", packet.Children[1].Tag) | ||||
| 	} | ||||
|  | ||||
| 	l.Debug.Printf("%d: returning", msgCtx.id) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										173
									
								
								vendor/gopkg.in/ldap.v3/modify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										173
									
								
								vendor/gopkg.in/ldap.v3/modify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,173 +0,0 @@ | ||||
| // File contains Modify functionality | ||||
| // | ||||
| // https://tools.ietf.org/html/rfc4511 | ||||
| // | ||||
| // ModifyRequest ::= [APPLICATION 6] SEQUENCE { | ||||
| //      object          LDAPDN, | ||||
| //      changes         SEQUENCE OF change SEQUENCE { | ||||
| //           operation       ENUMERATED { | ||||
| //                add     (0), | ||||
| //                delete  (1), | ||||
| //                replace (2), | ||||
| //                ...  }, | ||||
| //           modification    PartialAttribute } } | ||||
| // | ||||
| // PartialAttribute ::= SEQUENCE { | ||||
| //      type       AttributeDescription, | ||||
| //      vals       SET OF value AttributeValue } | ||||
| // | ||||
| // AttributeDescription ::= LDAPString | ||||
| //                         -- Constrained to <attributedescription> | ||||
| //                         -- [RFC4512] | ||||
| // | ||||
| // AttributeValue ::= OCTET STRING | ||||
| // | ||||
|  | ||||
| package ldap | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"log" | ||||
|  | ||||
| 	"gopkg.in/asn1-ber.v1" | ||||
| ) | ||||
|  | ||||
| // Change operation choices | ||||
| const ( | ||||
| 	AddAttribute     = 0 | ||||
| 	DeleteAttribute  = 1 | ||||
| 	ReplaceAttribute = 2 | ||||
| ) | ||||
|  | ||||
| // PartialAttribute for a ModifyRequest as defined in https://tools.ietf.org/html/rfc4511 | ||||
| type PartialAttribute struct { | ||||
| 	// Type is the type of the partial attribute | ||||
| 	Type string | ||||
| 	// Vals are the values of the partial attribute | ||||
| 	Vals []string | ||||
| } | ||||
|  | ||||
| func (p *PartialAttribute) encode() *ber.Packet { | ||||
| 	seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "PartialAttribute") | ||||
| 	seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, p.Type, "Type")) | ||||
| 	set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue") | ||||
| 	for _, value := range p.Vals { | ||||
| 		set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals")) | ||||
| 	} | ||||
| 	seq.AppendChild(set) | ||||
| 	return seq | ||||
| } | ||||
|  | ||||
| // Change for a ModifyRequest as defined in https://tools.ietf.org/html/rfc4511 | ||||
| type Change struct { | ||||
| 	// Operation is the type of change to be made | ||||
| 	Operation uint | ||||
| 	// Modification is the attribute to be modified | ||||
| 	Modification PartialAttribute | ||||
| } | ||||
|  | ||||
| func (c *Change) encode() *ber.Packet { | ||||
| 	change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change") | ||||
| 	change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(c.Operation), "Operation")) | ||||
| 	change.AppendChild(c.Modification.encode()) | ||||
| 	return change | ||||
| } | ||||
|  | ||||
| // ModifyRequest as defined in https://tools.ietf.org/html/rfc4511 | ||||
| type ModifyRequest struct { | ||||
| 	// DN is the distinguishedName of the directory entry to modify | ||||
| 	DN string | ||||
| 	// Changes contain the attributes to modify | ||||
| 	Changes []Change | ||||
| 	// Controls hold optional controls to send with the request | ||||
| 	Controls []Control | ||||
| } | ||||
|  | ||||
| // Add appends the given attribute to the list of changes to be made | ||||
| func (m *ModifyRequest) Add(attrType string, attrVals []string) { | ||||
| 	m.appendChange(AddAttribute, attrType, attrVals) | ||||
| } | ||||
|  | ||||
| // Delete appends the given attribute to the list of changes to be made | ||||
| func (m *ModifyRequest) Delete(attrType string, attrVals []string) { | ||||
| 	m.appendChange(DeleteAttribute, attrType, attrVals) | ||||
| } | ||||
|  | ||||
| // Replace appends the given attribute to the list of changes to be made | ||||
| func (m *ModifyRequest) Replace(attrType string, attrVals []string) { | ||||
| 	m.appendChange(ReplaceAttribute, attrType, attrVals) | ||||
| } | ||||
|  | ||||
| func (m *ModifyRequest) appendChange(operation uint, attrType string, attrVals []string) { | ||||
| 	m.Changes = append(m.Changes, Change{operation, PartialAttribute{Type: attrType, Vals: attrVals}}) | ||||
| } | ||||
|  | ||||
| func (m ModifyRequest) encode() *ber.Packet { | ||||
| 	request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyRequest, nil, "Modify Request") | ||||
| 	request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.DN, "DN")) | ||||
| 	changes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Changes") | ||||
| 	for _, change := range m.Changes { | ||||
| 		changes.AppendChild(change.encode()) | ||||
| 	} | ||||
| 	request.AppendChild(changes) | ||||
| 	return request | ||||
| } | ||||
|  | ||||
| // NewModifyRequest creates a modify request for the given DN | ||||
| func NewModifyRequest( | ||||
| 	dn string, | ||||
| 	controls []Control, | ||||
| ) *ModifyRequest { | ||||
| 	return &ModifyRequest{ | ||||
| 		DN:       dn, | ||||
| 		Controls: controls, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Modify performs the ModifyRequest | ||||
| func (l *Conn) Modify(modifyRequest *ModifyRequest) error { | ||||
| 	packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") | ||||
| 	packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) | ||||
| 	packet.AppendChild(modifyRequest.encode()) | ||||
| 	if len(modifyRequest.Controls) > 0 { | ||||
| 		packet.AppendChild(encodeControls(modifyRequest.Controls)) | ||||
| 	} | ||||
|  | ||||
| 	l.Debug.PrintPacket(packet) | ||||
|  | ||||
| 	msgCtx, err := l.sendMessage(packet) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer l.finishMessage(msgCtx) | ||||
|  | ||||
| 	l.Debug.Printf("%d: waiting for response", msgCtx.id) | ||||
| 	packetResponse, ok := <-msgCtx.responses | ||||
| 	if !ok { | ||||
| 		return NewError(ErrorNetwork, errors.New("ldap: response channel closed")) | ||||
| 	} | ||||
| 	packet, err = packetResponse.ReadPacket() | ||||
| 	l.Debug.Printf("%d: got response %p", msgCtx.id, packet) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if l.Debug { | ||||
| 		if err := addLDAPDescriptions(packet); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		ber.PrintPacket(packet) | ||||
| 	} | ||||
|  | ||||
| 	if packet.Children[1].Tag == ApplicationModifyResponse { | ||||
| 		err := GetLDAPError(packet) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else { | ||||
| 		log.Printf("Unexpected Response: %d", packet.Children[1].Tag) | ||||
| 	} | ||||
|  | ||||
| 	l.Debug.Printf("%d: returning", msgCtx.id) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										13
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							| @@ -49,6 +49,8 @@ gitea.com/macaron/session/postgres | ||||
| # gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7 | ||||
| ## explicit | ||||
| gitea.com/macaron/toolbox | ||||
| # github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c | ||||
| github.com/Azure/go-ntlmssp | ||||
| # github.com/BurntSushi/toml v0.3.1 | ||||
| github.com/BurntSushi/toml | ||||
| # github.com/PuerkitoBio/goquery v1.5.1 | ||||
| @@ -250,6 +252,8 @@ github.com/gliderlabs/ssh | ||||
| # github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a | ||||
| ## explicit | ||||
| github.com/glycerine/go-unsnap-stream | ||||
| # github.com/go-asn1-ber/asn1-ber v1.5.1 | ||||
| github.com/go-asn1-ber/asn1-ber | ||||
| # github.com/go-enry/go-enry/v2 v2.5.2 | ||||
| ## explicit | ||||
| github.com/go-enry/go-enry/v2 | ||||
| @@ -318,6 +322,9 @@ github.com/go-git/go-git/v5/utils/merkletrie/filesystem | ||||
| github.com/go-git/go-git/v5/utils/merkletrie/index | ||||
| github.com/go-git/go-git/v5/utils/merkletrie/internal/frame | ||||
| github.com/go-git/go-git/v5/utils/merkletrie/noder | ||||
| # github.com/go-ldap/ldap/v3 v3.2.4 | ||||
| ## explicit | ||||
| github.com/go-ldap/ldap/v3 | ||||
| # github.com/go-openapi/analysis v0.19.10 | ||||
| github.com/go-openapi/analysis | ||||
| github.com/go-openapi/analysis/internal | ||||
| @@ -935,18 +942,12 @@ google.golang.org/protobuf/runtime/protoimpl | ||||
| # gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc | ||||
| ## explicit | ||||
| gopkg.in/alexcesaro/quotedprintable.v3 | ||||
| # gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 | ||||
| ## explicit | ||||
| gopkg.in/asn1-ber.v1 | ||||
| # gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df | ||||
| ## explicit | ||||
| gopkg.in/gomail.v2 | ||||
| # gopkg.in/ini.v1 v1.61.0 | ||||
| ## explicit | ||||
| gopkg.in/ini.v1 | ||||
| # gopkg.in/ldap.v3 v3.0.2 | ||||
| ## explicit | ||||
| gopkg.in/ldap.v3 | ||||
| # gopkg.in/warnings.v0 v0.1.2 | ||||
| gopkg.in/warnings.v0 | ||||
| # gopkg.in/yaml.v2 v2.3.0 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 6543
					6543