updated dependencies
This commit is contained in:
parent
4ed08230a5
commit
891373a25e
62
ci-build.sh
Executable file
62
ci-build.sh
Executable file
@ -0,0 +1,62 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
PROJECTNAME=adradius
|
||||||
|
RELEASENAME=${PROJECTNAME}
|
||||||
|
VERSION="0"
|
||||||
|
|
||||||
|
GOOPTIONS="-mod=vendor"
|
||||||
|
SRCFILES=cmd/adradius/*.go
|
||||||
|
|
||||||
|
build() {
|
||||||
|
echo "Begin of build"
|
||||||
|
if [[ ! -z $DRONE_TAG ]]
|
||||||
|
then
|
||||||
|
echo "Drone tag set, let's do a release"
|
||||||
|
VERSION=$DRONE_TAG
|
||||||
|
echo "${PROJECTNAME} ${VERSION}" > /build/VERSION
|
||||||
|
elif [[ ! -z $DRONE_TAG ]]
|
||||||
|
then
|
||||||
|
echo "Drone not set, let's only do a build"
|
||||||
|
VERSION=$DRONE_COMMIT
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -z $VERSION && ! -z $GOOS && ! -z $GOARCH ]]
|
||||||
|
then
|
||||||
|
echo "Let's set a release name"
|
||||||
|
RELEASENAME=${PROJECTNAME}-${VERSION}-${GOOS}-${GOARCH}
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Building project"
|
||||||
|
go build -o ${PROJECTNAME} ${GOOPTIONS} ${SRCFILES}
|
||||||
|
|
||||||
|
if [[ ! -z $DRONE_TAG ]]
|
||||||
|
then
|
||||||
|
echo "Let's make archives"
|
||||||
|
mkdir -p /build
|
||||||
|
tar -czvf /build/${RELEASENAME}.tar.gz ${PROJECTNAME}
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Removing binary file"
|
||||||
|
rm ${PROJECTNAME}
|
||||||
|
|
||||||
|
echo "End of build"
|
||||||
|
}
|
||||||
|
|
||||||
|
clean() {
|
||||||
|
rm -rf $RELEASEDIR
|
||||||
|
}
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
"build")
|
||||||
|
build
|
||||||
|
;;
|
||||||
|
"clean")
|
||||||
|
clean
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "No options choosen"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
13
go.mod
13
go.mod
@ -1,13 +1,16 @@
|
|||||||
module git.paulbsd.com/paulbsd/adradius
|
module git.paulbsd.com/paulbsd/adradius
|
||||||
|
|
||||||
go 1.13
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/go-asn1-ber/asn1-ber v1.5.3 // indirect
|
||||||
|
github.com/go-ldap/ldap/v3 v3.2.4
|
||||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||||
github.com/sevlyar/go-daemon v0.1.5
|
github.com/sevlyar/go-daemon v0.1.5
|
||||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||||
golang.org/x/text v0.3.2
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
|
||||||
gopkg.in/ini.v1 v1.52.0
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect
|
||||||
gopkg.in/ldap.v3 v3.1.0
|
golang.org/x/text v0.3.5
|
||||||
layeh.com/radius v0.0.0-20190322222518-890bc1058917
|
gopkg.in/ini.v1 v1.62.0
|
||||||
|
layeh.com/radius v0.0.0-20201203135236-838e26d0c9be
|
||||||
)
|
)
|
||||||
|
37
go.sum
37
go.sum
@ -1,3 +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=
|
||||||
|
github.com/go-asn1-ber/asn1-ber v1.5.3 h1:u7utq56RUFiynqUzgVMFDymapcOtQ/MZkh3H4QYkxag=
|
||||||
|
github.com/go-asn1-ber/asn1-ber v1.5.3/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||||
|
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/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
@ -11,19 +19,28 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
|
|||||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
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/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||||
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||||
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||||
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
|
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.52.0 h1:j+Lt/M1oPPejkniCg1TkWE2J3Eh1oZTsHSXzMTzUXn4=
|
layeh.com/radius v0.0.0-20201203135236-838e26d0c9be h1:4YeDNYYOf9Pnn3pWEktFE+ZCZ5qX5ZVMaw3VAtfoXPk=
|
||||||
gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
layeh.com/radius v0.0.0-20201203135236-838e26d0c9be/go.mod h1:pFWM9De99EY9TPVyHIyA56QmoRViVck/x41WFkUlc9A=
|
||||||
gopkg.in/ldap.v3 v3.1.0 h1:DIDWEjI7vQWREh0S8X5/NFPCZ3MCVd55LmXKPW4XLGE=
|
|
||||||
gopkg.in/ldap.v3 v3.1.0/go.mod h1:dQjCc0R0kfyFjIlWNMH1DORwUASZyDxo2Ry1B51dXaQ=
|
|
||||||
layeh.com/radius v0.0.0-20190322222518-890bc1058917 h1:BDXFaFzUt5EIqe/4wrTc4AcYZWP6iC6Ult+jQWLh5eU=
|
|
||||||
layeh.com/radius v0.0.0-20190322222518-890bc1058917/go.mod h1:fywZKyu//X7iRzaxLgPWsvc0L26IUpVvE/aeIL2JtIQ=
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import ldap "gopkg.in/ldap.v3"
|
import ldap "github.com/go-ldap/ldap/v3"
|
||||||
|
|
||||||
//Authenticate checks if the given credentials are valid, or returns an error if one occurred.
|
//Authenticate checks if the given credentials are valid, or returns an error if one occurred.
|
||||||
//username may be either the sAMAccountName or the userPrincipalName.
|
//username may be either the sAMAccountName or the userPrincipalName.
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
ldap "gopkg.in/ldap.v3"
|
ldap "github.com/go-ldap/ldap/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Conn represents an Active Directory connection.
|
//Conn represents an Active Directory connection.
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
ldap "github.com/go-ldap/ldap/v3"
|
||||||
"golang.org/x/text/encoding/unicode"
|
"golang.org/x/text/encoding/unicode"
|
||||||
ldap "gopkg.in/ldap.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//ModifyDNPassword sets a new password for the given user or returns an error if one occurred.
|
//ModifyDNPassword sets a new password for the given user or returns an error if one occurred.
|
||||||
|
@ -3,7 +3,7 @@ package auth
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
ldap "gopkg.in/ldap.v3"
|
ldap "github.com/go-ldap/ldap/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Search returns the entries for the given search criteria or an error if one occurred.
|
//Search returns the entries for the given search criteria or an error if one occurred.
|
||||||
|
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
|
||||||
|
|
||||||
|
[![GoDoc](https://godoc.org/github.com/Azure/go-ntlmssp?status.svg)](https://godoc.org/github.com/Azure/go-ntlmssp) [![Build Status](https://travis-ci.org/Azure/go-ntlmssp.svg?branch=dev)](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,
|
||||||
|
}
|
||||||
|
}
|
43
vendor/github.com/go-asn1-ber/asn1-ber/.travis.yml
generated
vendored
Normal file
43
vendor/github.com/go-asn1-ber/asn1-ber/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
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
|
||||||
|
- ppc64le
|
||||||
|
|
||||||
|
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 ./...
|
||||||
|
matrix:
|
||||||
|
allowfailures:
|
||||||
|
go: 1.2.x
|
0
vendor/gopkg.in/asn1-ber.v1/LICENSE → vendor/github.com/go-asn1-ber/asn1-ber/LICENSE
generated
vendored
0
vendor/gopkg.in/asn1-ber.v1/LICENSE → vendor/github.com/go-asn1-ber/asn1-ber/LICENSE
generated
vendored
208
vendor/gopkg.in/asn1-ber.v1/ber.go → vendor/github.com/go-asn1-ber/asn1-ber/ber.go
generated
vendored
208
vendor/gopkg.in/asn1-ber.v1/ber.go → vendor/github.com/go-asn1-ber/asn1-ber/ber.go
generated
vendored
@ -8,6 +8,8 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MaxPacketLengthBytes specifies the maximum allowed packet size when calling ReadPacket or DecodePacket. Set to 0 for
|
// MaxPacketLengthBytes specifies the maximum allowed packet size when calling ReadPacket or DecodePacket. Set to 0 for
|
||||||
@ -143,42 +145,46 @@ var TypeMap = map[Type]string{
|
|||||||
TypeConstructed: "Constructed",
|
TypeConstructed: "Constructed",
|
||||||
}
|
}
|
||||||
|
|
||||||
var Debug bool = false
|
var Debug = false
|
||||||
|
|
||||||
func PrintBytes(out io.Writer, buf []byte, indent string) {
|
func PrintBytes(out io.Writer, buf []byte, indent string) {
|
||||||
data_lines := make([]string, (len(buf)/30)+1)
|
dataLines := make([]string, (len(buf)/30)+1)
|
||||||
num_lines := make([]string, (len(buf)/30)+1)
|
numLines := make([]string, (len(buf)/30)+1)
|
||||||
|
|
||||||
for i, b := range buf {
|
for i, b := range buf {
|
||||||
data_lines[i/30] += fmt.Sprintf("%02x ", b)
|
dataLines[i/30] += fmt.Sprintf("%02x ", b)
|
||||||
num_lines[i/30] += fmt.Sprintf("%02d ", (i+1)%100)
|
numLines[i/30] += fmt.Sprintf("%02d ", (i+1)%100)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(data_lines); i++ {
|
for i := 0; i < len(dataLines); i++ {
|
||||||
out.Write([]byte(indent + data_lines[i] + "\n"))
|
_, _ = out.Write([]byte(indent + dataLines[i] + "\n"))
|
||||||
out.Write([]byte(indent + num_lines[i] + "\n\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) {
|
func PrintPacket(p *Packet) {
|
||||||
printPacket(os.Stdout, p, 0, false)
|
printPacket(os.Stdout, p, 0, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) {
|
func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) {
|
||||||
indent_str := ""
|
indentStr := ""
|
||||||
|
|
||||||
for len(indent_str) != indent {
|
for len(indentStr) != indent {
|
||||||
indent_str += " "
|
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 {
|
if p.ClassType == ClassUniversal {
|
||||||
tag_str = tagMap[p.Tag]
|
tagStr = tagMap[p.Tag]
|
||||||
}
|
}
|
||||||
|
|
||||||
value := fmt.Sprint(p.Value)
|
value := fmt.Sprint(p.Value)
|
||||||
@ -188,10 +194,10 @@ func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) {
|
|||||||
description = p.Description + ": "
|
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 {
|
if printBytes {
|
||||||
PrintBytes(out, p.Bytes(), indent_str)
|
PrintBytes(out, p.Bytes(), indentStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, child := range p.Children {
|
for _, child := range p.Children {
|
||||||
@ -199,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) {
|
func ReadPacket(reader io.Reader) (*Packet, error) {
|
||||||
p, _, err := readPacket(reader)
|
p, _, err := readPacket(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -235,7 +241,7 @@ func encodeInteger(i int64) []byte {
|
|||||||
|
|
||||||
var j int
|
var j int
|
||||||
for ; n > 0; n-- {
|
for ; n > 0; n-- {
|
||||||
out[j] = (byte(i >> uint((n-1)*8)))
|
out[j] = byte(i >> uint((n-1)*8))
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +273,7 @@ func DecodePacket(data []byte) *Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DecodePacketErr decodes the given bytes into a single 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) {
|
func DecodePacketErr(data []byte) (*Packet, error) {
|
||||||
p, _, err := readPacket(bytes.NewBuffer(data))
|
p, _, err := readPacket(bytes.NewBuffer(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -276,7 +282,7 @@ func DecodePacketErr(data []byte) (*Packet, error) {
|
|||||||
return p, nil
|
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) {
|
func readPacket(reader io.Reader) (*Packet, int, error) {
|
||||||
identifier, length, read, err := readHeader(reader)
|
identifier, length, read, err := readHeader(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -338,7 +344,7 @@ func readPacket(reader io.Reader) (*Packet, int, error) {
|
|||||||
if MaxPacketLengthBytes > 0 && int64(length) > MaxPacketLengthBytes {
|
if MaxPacketLengthBytes > 0 && int64(length) > MaxPacketLengthBytes {
|
||||||
return nil, read, fmt.Errorf("length %d greater than maximum %d", length, MaxPacketLengthBytes)
|
return nil, read, fmt.Errorf("length %d greater than maximum %d", length, MaxPacketLengthBytes)
|
||||||
}
|
}
|
||||||
content := make([]byte, length, length)
|
content := make([]byte, length)
|
||||||
if length > 0 {
|
if length > 0 {
|
||||||
_, err := io.ReadFull(reader, content)
|
_, err := io.ReadFull(reader, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -373,22 +379,42 @@ func readPacket(reader io.Reader) (*Packet, int, error) {
|
|||||||
case TagObjectDescriptor:
|
case TagObjectDescriptor:
|
||||||
case TagExternal:
|
case TagExternal:
|
||||||
case TagRealFloat:
|
case TagRealFloat:
|
||||||
|
p.Value, err = ParseReal(content)
|
||||||
case TagEnumerated:
|
case TagEnumerated:
|
||||||
p.Value, _ = ParseInt64(content)
|
p.Value, _ = ParseInt64(content)
|
||||||
case TagEmbeddedPDV:
|
case TagEmbeddedPDV:
|
||||||
case TagUTF8String:
|
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 TagRelativeOID:
|
||||||
case TagSequence:
|
case TagSequence:
|
||||||
case TagSet:
|
case TagSet:
|
||||||
case TagNumericString:
|
case TagNumericString:
|
||||||
case TagPrintableString:
|
case TagPrintableString:
|
||||||
p.Value = DecodeString(content)
|
val := DecodeString(content)
|
||||||
|
if err = isPrintableString(val); err == nil {
|
||||||
|
p.Value = val
|
||||||
|
}
|
||||||
case TagT61String:
|
case TagT61String:
|
||||||
case TagVideotexString:
|
case TagVideotexString:
|
||||||
case TagIA5String:
|
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 TagUTCTime:
|
||||||
case TagGeneralizedTime:
|
case TagGeneralizedTime:
|
||||||
|
p.Value, err = ParseGeneralizedTime(content)
|
||||||
case TagGraphicString:
|
case TagGraphicString:
|
||||||
case TagVisibleString:
|
case TagVisibleString:
|
||||||
case TagGeneralString:
|
case TagGeneralString:
|
||||||
@ -400,7 +426,24 @@ func readPacket(reader io.Reader) (*Packet, int, error) {
|
|||||||
p.Data.Write(content)
|
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 {
|
func (p *Packet) Bytes() []byte {
|
||||||
@ -418,61 +461,99 @@ func (p *Packet) AppendChild(child *Packet) {
|
|||||||
p.Children = append(p.Children, child)
|
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 := new(Packet)
|
||||||
|
|
||||||
p.ClassType = ClassType
|
p.ClassType = classType
|
||||||
p.TagType = TagType
|
p.TagType = tagType
|
||||||
p.Tag = Tag
|
p.Tag = tag
|
||||||
p.Data = new(bytes.Buffer)
|
p.Data = new(bytes.Buffer)
|
||||||
|
|
||||||
p.Children = make([]*Packet, 0, 2)
|
p.Children = make([]*Packet, 0, 2)
|
||||||
|
|
||||||
p.Value = Value
|
p.Value = value
|
||||||
p.Description = Description
|
p.Description = description
|
||||||
|
|
||||||
if Value != nil {
|
if value != nil {
|
||||||
v := reflect.ValueOf(Value)
|
v := reflect.ValueOf(value)
|
||||||
|
|
||||||
if ClassType == ClassUniversal {
|
if classType == ClassUniversal {
|
||||||
switch Tag {
|
switch tag {
|
||||||
case TagOctetString:
|
case TagOctetString:
|
||||||
sv, ok := v.Interface().(string)
|
sv, ok := v.Interface().(string)
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
p.Data.Write([]byte(sv))
|
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
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSequence(Description string) *Packet {
|
func NewSequence(description string) *Packet {
|
||||||
return Encode(ClassUniversal, TypeConstructed, TagSequence, nil, Description)
|
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)
|
intValue := int64(0)
|
||||||
|
|
||||||
if Value {
|
if value {
|
||||||
intValue = 1
|
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))
|
p.Data.Write(encodeInteger(intValue))
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInteger(ClassType Class, TagType Type, Tag Tag, Value interface{}, Description string) *Packet {
|
// NewLDAPBoolean returns a RFC 4511-compliant Boolean packet.
|
||||||
p := Encode(ClassType, TagType, Tag, nil, Description)
|
func NewLDAPBoolean(classType Class, tagType Type, tag Tag, value bool, description string) *Packet {
|
||||||
|
intValue := int64(0)
|
||||||
|
|
||||||
p.Value = Value
|
if value {
|
||||||
switch v := Value.(type) {
|
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:
|
case int:
|
||||||
p.Data.Write(encodeInteger(int64(v)))
|
p.Data.Write(encodeInteger(int64(v)))
|
||||||
case uint:
|
case uint:
|
||||||
@ -502,11 +583,38 @@ func NewInteger(ClassType Class, TagType Type, Tag Tag, Value interface{}, Descr
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewString(ClassType Class, TagType Type, Tag Tag, Value, Description string) *Packet {
|
func NewString(classType Class, tagType Type, tag Tag, value, description string) *Packet {
|
||||||
p := Encode(ClassType, TagType, Tag, nil, Description)
|
p := Encode(classType, tagType, tag, nil, description)
|
||||||
|
|
||||||
p.Value = Value
|
p.Value = value
|
||||||
p.Data.Write([]byte(Value))
|
p.Data.Write([]byte(value))
|
||||||
|
|
||||||
return p
|
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
|
var j int
|
||||||
for ; n > 0; n-- {
|
for ; n > 0; n-- {
|
||||||
out[j] = (byte(i >> uint((n-1)*8)))
|
out[j] = byte(i >> uint((n-1)*8))
|
||||||
j++
|
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
|
23
vendor/gopkg.in/asn1-ber.v1/header.go → vendor/github.com/go-asn1-ber/asn1-ber/header.go
generated
vendored
23
vendor/gopkg.in/asn1-ber.v1/header.go → vendor/github.com/go-asn1-ber/asn1-ber/header.go
generated
vendored
@ -7,19 +7,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func readHeader(reader io.Reader) (identifier Identifier, length int, read int, err error) {
|
func readHeader(reader io.Reader) (identifier Identifier, length int, read int, err error) {
|
||||||
if i, c, err := readIdentifier(reader); err != nil {
|
var (
|
||||||
return Identifier{}, 0, read, err
|
c, l int
|
||||||
} else {
|
i Identifier
|
||||||
identifier = i
|
)
|
||||||
read += c
|
|
||||||
}
|
|
||||||
|
|
||||||
if l, c, err := readLength(reader); err != nil {
|
if i, c, err = readIdentifier(reader); err != nil {
|
||||||
return Identifier{}, 0, read, err
|
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)
|
// Validate length type with identifier (x.600, 8.1.3.2.a)
|
||||||
if length == LengthIndefinite && identifier.TagType == TypePrimitive {
|
if length == LengthIndefinite && identifier.TagType == TypePrimitive {
|
12
vendor/gopkg.in/asn1-ber.v1/length.go → vendor/github.com/go-asn1-ber/asn1-ber/length.go
generated
vendored
12
vendor/gopkg.in/asn1-ber.v1/length.go → vendor/github.com/go-asn1-ber/asn1-ber/length.go
generated
vendored
@ -71,11 +71,11 @@ func readLength(reader io.Reader) (length int, read int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func encodeLength(length int) []byte {
|
func encodeLength(length int) []byte {
|
||||||
length_bytes := encodeUnsignedInteger(uint64(length))
|
lengthBytes := encodeUnsignedInteger(uint64(length))
|
||||||
if length > 127 || len(length_bytes) > 1 {
|
if length > 127 || len(lengthBytes) > 1 {
|
||||||
longFormBytes := []byte{(LengthLongFormBitmask | byte(len(length_bytes)))}
|
longFormBytes := []byte{LengthLongFormBitmask | byte(len(lengthBytes))}
|
||||||
longFormBytes = append(longFormBytes, length_bytes...)
|
longFormBytes = append(longFormBytes, lengthBytes...)
|
||||||
length_bytes = longFormBytes
|
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"
|
import "io"
|
||||||
|
|
||||||
func readByte(reader io.Reader) (byte, error) {
|
func readByte(reader io.Reader) (byte, error) {
|
||||||
bytes := make([]byte, 1, 1)
|
bytes := make([]byte, 1)
|
||||||
_, err := io.ReadFull(reader, bytes)
|
_, err := io.ReadFull(reader, bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
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
11
vendor/gopkg.in/ldap.v3/add.go → vendor/github.com/go-ldap/ldap/v3/add.go
generated
vendored
11
vendor/gopkg.in/ldap.v3/add.go → vendor/github.com/go-ldap/ldap/v3/add.go
generated
vendored
@ -1,18 +1,9 @@
|
|||||||
//
|
|
||||||
// https://tools.ietf.org/html/rfc4511
|
|
||||||
//
|
|
||||||
// AddRequest ::= [APPLICATION 8] SEQUENCE {
|
|
||||||
// entry LDAPDN,
|
|
||||||
// attributes AttributeList }
|
|
||||||
//
|
|
||||||
// AttributeList ::= SEQUENCE OF attribute Attribute
|
|
||||||
|
|
||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Attribute represents an LDAP attribute
|
// Attribute represents an LDAP attribute
|
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
|
||||||
|
}
|
0
vendor/gopkg.in/ldap.v3/client.go → vendor/github.com/go-ldap/ldap/v3/client.go
generated
vendored
0
vendor/gopkg.in/ldap.v3/client.go → vendor/github.com/go-ldap/ldap/v3/client.go
generated
vendored
21
vendor/gopkg.in/ldap.v3/compare.go → vendor/github.com/go-ldap/ldap/v3/compare.go
generated
vendored
21
vendor/gopkg.in/ldap.v3/compare.go → vendor/github.com/go-ldap/ldap/v3/compare.go
generated
vendored
@ -1,28 +1,9 @@
|
|||||||
// 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
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompareRequest represents an LDAP CompareRequest operation.
|
// CompareRequest represents an LDAP CompareRequest operation.
|
120
vendor/gopkg.in/ldap.v3/conn.go → vendor/github.com/go-ldap/ldap/v3/conn.go
generated
vendored
120
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"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -112,8 +112,63 @@ var _ Client = &Conn{}
|
|||||||
// multiple places will probably result in undesired behaviour.
|
// multiple places will probably result in undesired behaviour.
|
||||||
var DefaultTimeout = 60 * time.Second
|
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
|
// Dial connects to the given address on the given network using net.Dial
|
||||||
// and then returns a new Conn for the connection.
|
// and then returns a new Conn for the connection.
|
||||||
|
// @deprecated Use DialURL instead.
|
||||||
func Dial(network, addr string) (*Conn, error) {
|
func Dial(network, addr string) (*Conn, error) {
|
||||||
c, err := net.DialTimeout(network, addr, DefaultTimeout)
|
c, err := net.DialTimeout(network, addr, DefaultTimeout)
|
||||||
if err != nil {
|
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
|
// DialTLS connects to the given address on the given network using tls.Dial
|
||||||
// and then returns a new Conn for the connection.
|
// and then returns a new Conn for the connection.
|
||||||
|
// @deprecated Use DialURL instead.
|
||||||
func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
|
func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
|
||||||
c, err := tls.DialWithDialer(&net.Dialer{Timeout: DefaultTimeout}, network, addr, config)
|
c, err := tls.DialWithDialer(&net.Dialer{Timeout: DefaultTimeout}, network, addr, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -136,44 +192,31 @@ func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
|
|||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialURL connects to the given ldap URL vie TCP using tls.Dial or net.Dial if ldaps://
|
// DialURL connects to the given ldap URL.
|
||||||
// or ldap:// specified as protocol. On success a new Conn for the connection
|
// The following schemas are supported: ldap://, ldaps://, ldapi://.
|
||||||
// is returned.
|
// On success a new Conn for the connection is returned.
|
||||||
func DialURL(addr string) (*Conn, error) {
|
func DialURL(addr string, opts ...DialOpt) (*Conn, error) {
|
||||||
lurl, err := url.Parse(addr)
|
u, err := url.Parse(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, NewError(ErrorNetwork, err)
|
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 {
|
if err != nil {
|
||||||
// we asume that error is due to missing port
|
return nil, NewError(ErrorNetwork, err)
|
||||||
host = lurl.Host
|
|
||||||
port = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch lurl.Scheme {
|
conn := NewConn(c, u.Scheme == "ldaps")
|
||||||
case "ldapi":
|
conn.Start()
|
||||||
if lurl.Path == "" || lurl.Path == "/" {
|
return conn, nil
|
||||||
lurl.Path = "/var/run/slapd/ldapi"
|
|
||||||
}
|
|
||||||
return Dial("unix", lurl.Path)
|
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConn returns a new Conn using conn for network I/O.
|
// NewConn returns a new Conn using conn for network I/O.
|
||||||
@ -191,9 +234,9 @@ func NewConn(conn net.Conn, isTLS bool) *Conn {
|
|||||||
|
|
||||||
// Start initializes goroutines to read responses and process messages
|
// Start initializes goroutines to read responses and process messages
|
||||||
func (l *Conn) Start() {
|
func (l *Conn) Start() {
|
||||||
|
l.wgClose.Add(1)
|
||||||
go l.reader()
|
go l.reader()
|
||||||
go l.processMessages()
|
go l.processMessages()
|
||||||
l.wgClose.Add(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsClosing returns whether or not we're currently closing.
|
// IsClosing returns whether or not we're currently closing.
|
||||||
@ -278,7 +321,7 @@ func (l *Conn) StartTLS(config *tls.Config) error {
|
|||||||
l.Close()
|
l.Close()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ber.PrintPacket(packet)
|
l.Debug.PrintPacket(packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := GetLDAPError(packet); err == nil {
|
if err := GetLDAPError(packet); err == nil {
|
||||||
@ -347,7 +390,12 @@ func (l *Conn) sendMessageWithFlags(packet *ber.Packet, flags sendMessageFlags)
|
|||||||
responses: responses,
|
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
|
return message.Context, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,7 +499,7 @@ func (l *Conn) processMessages() {
|
|||||||
msgCtx.sendResponse(&PacketResponse{message.Packet, nil})
|
msgCtx.sendResponse(&PacketResponse{message.Packet, nil})
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Received unexpected message %d, %v", message.MessageID, l.IsClosing())
|
log.Printf("Received unexpected message %d, %v", message.MessageID, l.IsClosing())
|
||||||
ber.PrintPacket(message.Packet)
|
l.Debug.PrintPacket(message.Packet)
|
||||||
}
|
}
|
||||||
case MessageTimeout:
|
case MessageTimeout:
|
||||||
// Handle the timeout by closing the channel
|
// Handle the timeout by closing the channel
|
35
vendor/gopkg.in/ldap.v3/control.go → vendor/github.com/go-ldap/ldap/v3/control.go
generated
vendored
35
vendor/gopkg.in/ldap.v3/control.go → vendor/github.com/go-ldap/ldap/v3/control.go
generated
vendored
@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -404,33 +404,26 @@ func DecodeControl(packet *ber.Packet) (Control, error) {
|
|||||||
if child.Tag == 0 {
|
if child.Tag == 0 {
|
||||||
//Warning
|
//Warning
|
||||||
warningPacket := child.Children[0]
|
warningPacket := child.Children[0]
|
||||||
packet, err := ber.DecodePacketErr(warningPacket.Data.Bytes())
|
val, err := ber.ParseInt64(warningPacket.Data.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to decode data bytes: %s", err)
|
return nil, fmt.Errorf("failed to decode data bytes: %s", err)
|
||||||
}
|
}
|
||||||
val, ok := packet.Value.(int64)
|
if warningPacket.Tag == 0 {
|
||||||
if ok {
|
//timeBeforeExpiration
|
||||||
if warningPacket.Tag == 0 {
|
c.Expire = val
|
||||||
//timeBeforeExpiration
|
warningPacket.Value = c.Expire
|
||||||
c.Expire = val
|
} else if warningPacket.Tag == 1 {
|
||||||
warningPacket.Value = c.Expire
|
//graceAuthNsRemaining
|
||||||
} else if warningPacket.Tag == 1 {
|
c.Grace = val
|
||||||
//graceAuthNsRemaining
|
warningPacket.Value = c.Grace
|
||||||
c.Grace = val
|
|
||||||
warningPacket.Value = c.Grace
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if child.Tag == 1 {
|
} else if child.Tag == 1 {
|
||||||
// Error
|
// Error
|
||||||
packet, err := ber.DecodePacketErr(child.Data.Bytes())
|
bs := child.Data.Bytes()
|
||||||
if err != nil {
|
if len(bs) != 1 || bs[0] > 8 {
|
||||||
return nil, fmt.Errorf("failed to decode data bytes: %s", err)
|
return nil, fmt.Errorf("failed to decode data bytes: %s", "invalid PasswordPolicyResponse enum value")
|
||||||
}
|
|
||||||
val, ok := packet.Value.(int8)
|
|
||||||
if !ok {
|
|
||||||
// what to do?
|
|
||||||
val = -1
|
|
||||||
}
|
}
|
||||||
|
val := int8(bs[0])
|
||||||
c.Error = val
|
c.Error = val
|
||||||
child.Value = c.Error
|
child.Value = c.Error
|
||||||
c.ErrorString = BeheraPasswordPolicyErrorMap[c.Error]
|
c.ErrorString = BeheraPasswordPolicyErrorMap[c.Error]
|
2
vendor/gopkg.in/ldap.v3/debug.go → vendor/github.com/go-ldap/ldap/v3/debug.go
generated
vendored
2
vendor/gopkg.in/ldap.v3/debug.go → vendor/github.com/go-ldap/ldap/v3/debug.go
generated
vendored
@ -3,7 +3,7 @@ package ldap
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
// debugging type
|
// debugging type
|
7
vendor/gopkg.in/ldap.v3/del.go → vendor/github.com/go-ldap/ldap/v3/del.go
generated
vendored
7
vendor/gopkg.in/ldap.v3/del.go → vendor/github.com/go-ldap/ldap/v3/del.go
generated
vendored
@ -1,14 +1,9 @@
|
|||||||
//
|
|
||||||
// https://tools.ietf.org/html/rfc4511
|
|
||||||
//
|
|
||||||
// DelRequest ::= [APPLICATION 10] LDAPDN
|
|
||||||
|
|
||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DelRequest implements an LDAP deletion request
|
// DelRequest implements an LDAP deletion request
|
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
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -48,7 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"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
|
// AttributeTypeAndValue represents an attributeTypeAndValue from https://tools.ietf.org/html/rfc4514
|
||||||
@ -69,7 +28,8 @@ type DN struct {
|
|||||||
RDNs []*RelativeDN
|
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) {
|
func ParseDN(str string) (*DN, error) {
|
||||||
dn := new(DN)
|
dn := new(DN)
|
||||||
dn.RDNs = make([]*RelativeDN, 0)
|
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
33
vendor/gopkg.in/ldap.v3/error.go → vendor/github.com/go-ldap/ldap/v3/error.go
generated
vendored
33
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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LDAP Result Codes
|
// LDAP Result Codes
|
||||||
@ -184,6 +184,8 @@ type Error struct {
|
|||||||
ResultCode uint16
|
ResultCode uint16
|
||||||
// MatchedDN is the matchedDN returned if any
|
// MatchedDN is the matchedDN returned if any
|
||||||
MatchedDN string
|
MatchedDN string
|
||||||
|
// Packet is the returned packet if any
|
||||||
|
Packet *ber.Packet
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
func (e *Error) Error() string {
|
||||||
@ -201,19 +203,23 @@ func GetLDAPError(packet *ber.Packet) error {
|
|||||||
if len(packet.Children) >= 2 {
|
if len(packet.Children) >= 2 {
|
||||||
response := packet.Children[1]
|
response := packet.Children[1]
|
||||||
if response == nil {
|
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 {
|
if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 {
|
||||||
resultCode := uint16(response.Children[0].Value.(int64))
|
resultCode := uint16(response.Children[0].Value.(int64))
|
||||||
if resultCode == 0 { // No error
|
if resultCode == 0 { // No error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &Error{ResultCode: resultCode, MatchedDN: response.Children[1].Value.(string),
|
return &Error{
|
||||||
Err: fmt.Errorf("%s", response.Children[2].Value.(string))}
|
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
|
// NewError creates an LDAP error with the given code and underlying error
|
||||||
@ -221,8 +227,8 @@ func NewError(resultCode uint16, err error) error {
|
|||||||
return &Error{ResultCode: resultCode, Err: err}
|
return &Error{ResultCode: resultCode, Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsErrorWithCode returns true if the given error is an LDAP error with the given result code
|
// IsErrorAnyOf returns true if the given error is an LDAP error with any one of the given result codes
|
||||||
func IsErrorWithCode(err error, desiredResultCode uint16) bool {
|
func IsErrorAnyOf(err error, codes ...uint16) bool {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -232,5 +238,16 @@ func IsErrorWithCode(err error, desiredResultCode uint16) bool {
|
|||||||
return false
|
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"
|
hexpac "encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Filter choices
|
// Filter choices
|
||||||
@ -69,6 +71,8 @@ var MatchingRuleAssertionMap = map[uint64]string{
|
|||||||
MatchingRuleAssertionDNAttributes: "Matching Rule Assertion DN Attributes",
|
MatchingRuleAssertionDNAttributes: "Matching Rule Assertion DN Attributes",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _SymbolAny = []byte{'*'}
|
||||||
|
|
||||||
// CompileFilter converts a string representation of a filter into a BER-encoded packet
|
// CompileFilter converts a string representation of a filter into a BER-encoded packet
|
||||||
func CompileFilter(filter string) (*ber.Packet, error) {
|
func CompileFilter(filter string) (*ber.Packet, error) {
|
||||||
if len(filter) == 0 || filter[0] != '(' {
|
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
|
// 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() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
err = NewError(ErrorFilterDecompile, errors.New("ldap: error decompiling filter"))
|
err = NewError(ErrorFilterDecompile, errors.New("ldap: error decompiling filter"))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ret = "("
|
|
||||||
err = nil
|
buf := bytes.NewBuffer(nil)
|
||||||
|
buf.WriteByte('(')
|
||||||
childStr := ""
|
childStr := ""
|
||||||
|
|
||||||
switch packet.Tag {
|
switch packet.Tag {
|
||||||
case FilterAnd:
|
case FilterAnd:
|
||||||
ret += "&"
|
buf.WriteByte('&')
|
||||||
for _, child := range packet.Children {
|
for _, child := range packet.Children {
|
||||||
childStr, err = DecompileFilter(child)
|
childStr, err = DecompileFilter(child)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ret += childStr
|
buf.WriteString(childStr)
|
||||||
}
|
}
|
||||||
case FilterOr:
|
case FilterOr:
|
||||||
ret += "|"
|
buf.WriteByte('|')
|
||||||
for _, child := range packet.Children {
|
for _, child := range packet.Children {
|
||||||
childStr, err = DecompileFilter(child)
|
childStr, err = DecompileFilter(child)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ret += childStr
|
buf.WriteString(childStr)
|
||||||
}
|
}
|
||||||
case FilterNot:
|
case FilterNot:
|
||||||
ret += "!"
|
buf.WriteByte('!')
|
||||||
childStr, err = DecompileFilter(packet.Children[0])
|
childStr, err = DecompileFilter(packet.Children[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ret += childStr
|
buf.WriteString(childStr)
|
||||||
|
|
||||||
case FilterSubstrings:
|
case FilterSubstrings:
|
||||||
ret += ber.DecodeString(packet.Children[0].Data.Bytes())
|
buf.WriteString(ber.DecodeString(packet.Children[0].Data.Bytes()))
|
||||||
ret += "="
|
buf.WriteByte('=')
|
||||||
for i, child := range packet.Children[1].Children {
|
for i, child := range packet.Children[1].Children {
|
||||||
if i == 0 && child.Tag != FilterSubstringsInitial {
|
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 {
|
if child.Tag != FilterSubstringsFinal {
|
||||||
ret += "*"
|
buf.Write(_SymbolAny)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case FilterEqualityMatch:
|
case FilterEqualityMatch:
|
||||||
ret += ber.DecodeString(packet.Children[0].Data.Bytes())
|
buf.WriteString(ber.DecodeString(packet.Children[0].Data.Bytes()))
|
||||||
ret += "="
|
buf.WriteByte('=')
|
||||||
ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))
|
buf.WriteString(EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes())))
|
||||||
case FilterGreaterOrEqual:
|
case FilterGreaterOrEqual:
|
||||||
ret += ber.DecodeString(packet.Children[0].Data.Bytes())
|
buf.WriteString(ber.DecodeString(packet.Children[0].Data.Bytes()))
|
||||||
ret += ">="
|
buf.WriteString(">=")
|
||||||
ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))
|
buf.WriteString(EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes())))
|
||||||
case FilterLessOrEqual:
|
case FilterLessOrEqual:
|
||||||
ret += ber.DecodeString(packet.Children[0].Data.Bytes())
|
buf.WriteString(ber.DecodeString(packet.Children[0].Data.Bytes()))
|
||||||
ret += "<="
|
buf.WriteString("<=")
|
||||||
ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))
|
buf.WriteString(EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes())))
|
||||||
case FilterPresent:
|
case FilterPresent:
|
||||||
ret += ber.DecodeString(packet.Data.Bytes())
|
buf.WriteString(ber.DecodeString(packet.Data.Bytes()))
|
||||||
ret += "=*"
|
buf.WriteString("=*")
|
||||||
case FilterApproxMatch:
|
case FilterApproxMatch:
|
||||||
ret += ber.DecodeString(packet.Children[0].Data.Bytes())
|
buf.WriteString(ber.DecodeString(packet.Children[0].Data.Bytes()))
|
||||||
ret += "~="
|
buf.WriteString("~=")
|
||||||
ret += EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes()))
|
buf.WriteString(EscapeFilter(ber.DecodeString(packet.Children[1].Data.Bytes())))
|
||||||
case FilterExtensibleMatch:
|
case FilterExtensibleMatch:
|
||||||
attr := ""
|
attr := ""
|
||||||
dnAttributes := false
|
dnAttributes := false
|
||||||
@ -176,21 +181,22 @@ func DecompileFilter(packet *ber.Packet) (ret string, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(attr) > 0 {
|
if len(attr) > 0 {
|
||||||
ret += attr
|
buf.WriteString(attr)
|
||||||
}
|
}
|
||||||
if dnAttributes {
|
if dnAttributes {
|
||||||
ret += ":dn"
|
buf.WriteString(":dn")
|
||||||
}
|
}
|
||||||
if len(matchingRule) > 0 {
|
if len(matchingRule) > 0 {
|
||||||
ret += ":"
|
buf.WriteString(":")
|
||||||
ret += matchingRule
|
buf.WriteString(matchingRule)
|
||||||
}
|
}
|
||||||
ret += ":="
|
buf.WriteString(":=")
|
||||||
ret += EscapeFilter(value)
|
buf.WriteString(EscapeFilter(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
ret += ")"
|
buf.WriteByte(')')
|
||||||
return
|
|
||||||
|
return buf.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileFilterSet(filter string, pos int, parent *ber.Packet) (int, error) {
|
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
|
state := stateReadingAttr
|
||||||
|
attribute := bytes.NewBuffer(nil)
|
||||||
attribute := ""
|
|
||||||
extensibleDNAttributes := false
|
extensibleDNAttributes := false
|
||||||
extensibleMatchingRule := ""
|
extensibleMatchingRule := bytes.NewBuffer(nil)
|
||||||
condition := ""
|
condition := bytes.NewBuffer(nil)
|
||||||
|
|
||||||
for newPos < len(filter) {
|
for newPos < len(filter) {
|
||||||
remainingFilter := filter[newPos:]
|
remainingFilter := filter[newPos:]
|
||||||
@ -324,7 +329,7 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
|
|||||||
|
|
||||||
// Still reading the attribute name
|
// Still reading the attribute name
|
||||||
default:
|
default:
|
||||||
attribute += fmt.Sprintf("%c", currentRune)
|
attribute.WriteRune(currentRune)
|
||||||
newPos += currentWidth
|
newPos += currentWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,13 +343,13 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
|
|||||||
|
|
||||||
// Still reading the matching rule oid
|
// Still reading the matching rule oid
|
||||||
default:
|
default:
|
||||||
extensibleMatchingRule += fmt.Sprintf("%c", currentRune)
|
extensibleMatchingRule.WriteRune(currentRune)
|
||||||
newPos += currentWidth
|
newPos += currentWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
case stateReadingCondition:
|
case stateReadingCondition:
|
||||||
// append to the condition
|
// append to the condition
|
||||||
condition += fmt.Sprintf("%c", currentRune)
|
condition.WriteRune(currentRune)
|
||||||
newPos += currentWidth
|
newPos += currentWidth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -368,17 +373,17 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// Include the matching rule oid, if specified
|
// Include the matching rule oid, if specified
|
||||||
if len(extensibleMatchingRule) > 0 {
|
if extensibleMatchingRule.Len() > 0 {
|
||||||
packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionMatchingRule, extensibleMatchingRule, MatchingRuleAssertionMap[MatchingRuleAssertionMatchingRule]))
|
packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionMatchingRule, extensibleMatchingRule.String(), MatchingRuleAssertionMap[MatchingRuleAssertionMatchingRule]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include the attribute, if specified
|
// Include the attribute, if specified
|
||||||
if len(attribute) > 0 {
|
if attribute.Len() > 0 {
|
||||||
packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionType, attribute, MatchingRuleAssertionMap[MatchingRuleAssertionType]))
|
packet.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionType, attribute.String(), MatchingRuleAssertionMap[MatchingRuleAssertionType]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the value (only required child)
|
// Add the value (only required child)
|
||||||
encodedString, encodeErr := escapedStringToEncodedBytes(condition)
|
encodedString, encodeErr := decodeEscapedSymbols(condition.Bytes())
|
||||||
if encodeErr != nil {
|
if encodeErr != nil {
|
||||||
return packet, newPos, encodeErr
|
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]))
|
packet.AppendChild(ber.NewBoolean(ber.ClassContext, ber.TypePrimitive, MatchingRuleAssertionDNAttributes, extensibleDNAttributes, MatchingRuleAssertionMap[MatchingRuleAssertionDNAttributes]))
|
||||||
}
|
}
|
||||||
|
|
||||||
case packet.Tag == FilterEqualityMatch && condition == "*":
|
case packet.Tag == FilterEqualityMatch && bytes.Equal(condition.Bytes(), _SymbolAny):
|
||||||
packet = ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterPresent, attribute, FilterMap[FilterPresent])
|
packet = ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterPresent, attribute.String(), FilterMap[FilterPresent])
|
||||||
case packet.Tag == FilterEqualityMatch && strings.Contains(condition, "*"):
|
case packet.Tag == FilterEqualityMatch && bytes.Index(condition.Bytes(), _SymbolAny) > -1:
|
||||||
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.Tag = FilterSubstrings
|
packet.Tag = FilterSubstrings
|
||||||
packet.Description = FilterMap[uint64(packet.Tag)]
|
packet.Description = FilterMap[uint64(packet.Tag)]
|
||||||
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings")
|
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 {
|
for i, part := range parts {
|
||||||
if part == "" {
|
if len(part) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var tag ber.Tag
|
var tag ber.Tag
|
||||||
@ -410,7 +415,7 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
|
|||||||
default:
|
default:
|
||||||
tag = FilterSubstringsAny
|
tag = FilterSubstringsAny
|
||||||
}
|
}
|
||||||
encodedString, encodeErr := escapedStringToEncodedBytes(part)
|
encodedString, encodeErr := decodeEscapedSymbols(part)
|
||||||
if encodeErr != nil {
|
if encodeErr != nil {
|
||||||
return packet, newPos, encodeErr
|
return packet, newPos, encodeErr
|
||||||
}
|
}
|
||||||
@ -418,11 +423,11 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) {
|
|||||||
}
|
}
|
||||||
packet.AppendChild(seq)
|
packet.AppendChild(seq)
|
||||||
default:
|
default:
|
||||||
encodedString, encodeErr := escapedStringToEncodedBytes(condition)
|
encodedString, encodeErr := decodeEscapedSymbols(condition.Bytes())
|
||||||
if encodeErr != nil {
|
if encodeErr != nil {
|
||||||
return packet, newPos, encodeErr
|
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"))
|
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
|
// Convert from "ABC\xx\xx\xx" form to literal bytes for transport
|
||||||
func escapedStringToEncodedBytes(escapedString string) (string, error) {
|
func decodeEscapedSymbols(src []byte) (string, error) {
|
||||||
var buffer bytes.Buffer
|
|
||||||
i := 0
|
var (
|
||||||
for i < len(escapedString) {
|
buffer bytes.Buffer
|
||||||
currentRune, currentWidth := utf8.DecodeRuneInString(escapedString[i:])
|
offset int
|
||||||
if currentRune == utf8.RuneError {
|
reader = bytes.NewReader(src)
|
||||||
return "", NewError(ErrorFilterCompile, fmt.Errorf("ldap: error reading rune at position %d", i))
|
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 runeVal == '\\' {
|
||||||
if currentRune == '\\' {
|
|
||||||
// http://tools.ietf.org/search/rfc4515
|
// http://tools.ietf.org/search/rfc4515
|
||||||
// \ (%x5C) is not a valid character unless it is followed by two HEX characters due to not
|
// \ (%x5C) is not a valid character unless it is followed by two HEX characters due to not
|
||||||
// being a member of UTF1SUBSET.
|
// being a member of UTF1SUBSET.
|
||||||
if i+2 > len(escapedString) {
|
if byteHex == nil {
|
||||||
return "", NewError(ErrorFilterCompile, errors.New("ldap: missing characters for escape in filter"))
|
byteHex = make([]byte, 2)
|
||||||
|
byteVal = make([]byte, 1)
|
||||||
}
|
}
|
||||||
escByte, decodeErr := hexpac.DecodeString(escapedString[i+1 : i+3])
|
|
||||||
if decodeErr != nil {
|
if _, err := io.ReadFull(reader, byteHex); err != nil {
|
||||||
return "", NewError(ErrorFilterCompile, errors.New("ldap: invalid characters for escape in filter"))
|
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 {
|
} 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=
|
51
vendor/gopkg.in/ldap.v3/ldap.go → vendor/github.com/go-ldap/ldap/v3/ldap.go
generated
vendored
51
vendor/gopkg.in/ldap.v3/ldap.go → vendor/github.com/go-ldap/ldap/v3/ldap.go
generated
vendored
@ -5,7 +5,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LDAP Application Codes
|
// LDAP Application Codes
|
||||||
@ -223,32 +223,26 @@ func addControlDescriptions(packet *ber.Packet) error {
|
|||||||
if child.Tag == 0 {
|
if child.Tag == 0 {
|
||||||
//Warning
|
//Warning
|
||||||
warningPacket := child.Children[0]
|
warningPacket := child.Children[0]
|
||||||
packet, err := ber.DecodePacketErr(warningPacket.Data.Bytes())
|
val, err := ber.ParseInt64(warningPacket.Data.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to decode data bytes: %s", err)
|
return fmt.Errorf("failed to decode data bytes: %s", err)
|
||||||
}
|
}
|
||||||
val, ok := packet.Value.(int64)
|
if warningPacket.Tag == 0 {
|
||||||
if ok {
|
//timeBeforeExpiration
|
||||||
if warningPacket.Tag == 0 {
|
value.Description += " (TimeBeforeExpiration)"
|
||||||
//timeBeforeExpiration
|
warningPacket.Value = val
|
||||||
value.Description += " (TimeBeforeExpiration)"
|
} else if warningPacket.Tag == 1 {
|
||||||
warningPacket.Value = val
|
//graceAuthNsRemaining
|
||||||
} else if warningPacket.Tag == 1 {
|
value.Description += " (GraceAuthNsRemaining)"
|
||||||
//graceAuthNsRemaining
|
warningPacket.Value = val
|
||||||
value.Description += " (GraceAuthNsRemaining)"
|
|
||||||
warningPacket.Value = val
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if child.Tag == 1 {
|
} else if child.Tag == 1 {
|
||||||
// Error
|
// Error
|
||||||
packet, err := ber.DecodePacketErr(child.Data.Bytes())
|
bs := child.Data.Bytes()
|
||||||
if err != nil {
|
if len(bs) != 1 || bs[0] > 8 {
|
||||||
return fmt.Errorf("failed to decode data bytes: %s", err)
|
return fmt.Errorf("failed to decode data bytes: %s", "invalid PasswordPolicyResponse enum value")
|
||||||
}
|
|
||||||
val, ok := packet.Value.(int8)
|
|
||||||
if !ok {
|
|
||||||
val = -1
|
|
||||||
}
|
}
|
||||||
|
val := int8(bs[0])
|
||||||
child.Description = "Error"
|
child.Description = "Error"
|
||||||
child.Value = val
|
child.Value = val
|
||||||
}
|
}
|
||||||
@ -269,13 +263,18 @@ func addRequestDescriptions(packet *ber.Packet) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func addDefaultLDAPResponseDescriptions(packet *ber.Packet) error {
|
func addDefaultLDAPResponseDescriptions(packet *ber.Packet) error {
|
||||||
err := GetLDAPError(packet)
|
resultCode := uint16(LDAPResultSuccess)
|
||||||
if err == nil {
|
matchedDN := ""
|
||||||
return nil
|
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[err.(*Error).ResultCode] + ")"
|
|
||||||
packet.Children[1].Children[1].Description = "Matched DN (" + err.(*Error).MatchedDN + ")"
|
packet.Children[1].Children[0].Description = "Result Code (" + LDAPResultCodeMap[resultCode] + ")"
|
||||||
packet.Children[1].Children[2].Description = "Error Message"
|
packet.Children[1].Children[1].Description = "Matched DN (" + matchedDN + ")"
|
||||||
|
packet.Children[1].Children[2].Description = description
|
||||||
if len(packet.Children[1].Children) > 3 {
|
if len(packet.Children[1].Children) > 3 {
|
||||||
packet.Children[1].Children[3].Description = "Referral"
|
packet.Children[1].Children[3].Description = "Referral"
|
||||||
}
|
}
|
19
vendor/gopkg.in/ldap.v3/moddn.go → vendor/github.com/go-ldap/ldap/v3/moddn.go
generated
vendored
19
vendor/gopkg.in/ldap.v3/moddn.go → vendor/github.com/go-ldap/ldap/v3/moddn.go
generated
vendored
@ -1,19 +1,9 @@
|
|||||||
// 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
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ModifyDNRequest holds the request to modify a DN
|
// ModifyDNRequest holds the request to modify a DN
|
||||||
@ -49,7 +39,12 @@ func (req *ModifyDNRequest) appendTo(envelope *ber.Packet) error {
|
|||||||
pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyDNRequest, nil, "Modify DN Request")
|
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.DN, "DN"))
|
||||||
pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.NewRDN, "New RDN"))
|
pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.NewRDN, "New RDN"))
|
||||||
pkt.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, req.DeleteOldRDN, "Delete old 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 != "" {
|
if req.NewSuperior != "" {
|
||||||
pkt.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, req.NewSuperior, "New Superior"))
|
pkt.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, req.NewSuperior, "New Superior"))
|
||||||
}
|
}
|
39
vendor/gopkg.in/ldap.v3/modify.go → vendor/github.com/go-ldap/ldap/v3/modify.go
generated
vendored
39
vendor/gopkg.in/ldap.v3/modify.go → vendor/github.com/go-ldap/ldap/v3/modify.go
generated
vendored
@ -1,41 +1,17 @@
|
|||||||
// 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
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Change operation choices
|
// Change operation choices
|
||||||
const (
|
const (
|
||||||
AddAttribute = 0
|
AddAttribute = 0
|
||||||
DeleteAttribute = 1
|
DeleteAttribute = 1
|
||||||
ReplaceAttribute = 2
|
ReplaceAttribute = 2
|
||||||
|
IncrementAttribute = 3 // (https://tools.ietf.org/html/rfc4525)
|
||||||
)
|
)
|
||||||
|
|
||||||
// PartialAttribute for a ModifyRequest as defined in https://tools.ietf.org/html/rfc4511
|
// PartialAttribute for a ModifyRequest as defined in https://tools.ietf.org/html/rfc4511
|
||||||
@ -97,6 +73,11 @@ func (req *ModifyRequest) Replace(attrType string, attrVals []string) {
|
|||||||
req.appendChange(ReplaceAttribute, attrType, attrVals)
|
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) {
|
func (req *ModifyRequest) appendChange(operation uint, attrType string, attrVals []string) {
|
||||||
req.Changes = append(req.Changes, Change{operation, PartialAttribute{Type: attrType, Vals: attrVals}})
|
req.Changes = append(req.Changes, Change{operation, PartialAttribute{Type: attrType, Vals: attrVals}})
|
||||||
}
|
}
|
@ -1,14 +1,9 @@
|
|||||||
// This file contains the password modify extended operation as specified in rfc 3062
|
|
||||||
//
|
|
||||||
// https://tools.ietf.org/html/rfc3062
|
|
||||||
//
|
|
||||||
|
|
||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -61,7 +56,7 @@ func (req *PasswordModifyRequest) appendTo(envelope *ber.Packet) error {
|
|||||||
|
|
||||||
// NewPasswordModifyRequest creates a new PasswordModifyRequest
|
// 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.
|
// userIdentity is a string representing the user associated with the request.
|
||||||
// This string may or may not be an LDAPDN (RFC 2253).
|
// This string may or may not be an LDAPDN (RFC 2253).
|
||||||
// If userIdentity is empty then the operation will act on the user associated
|
// If userIdentity is empty then the operation will act on the user associated
|
6
vendor/gopkg.in/ldap.v3/request.go → vendor/github.com/go-ldap/ldap/v3/request.go
generated
vendored
6
vendor/gopkg.in/ldap.v3/request.go → vendor/github.com/go-ldap/ldap/v3/request.go
generated
vendored
@ -3,7 +3,7 @@ package ldap
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -29,7 +29,7 @@ func (l *Conn) doRequest(req request) (*messageContext, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if l.Debug {
|
if l.Debug {
|
||||||
ber.PrintPacket(packet)
|
l.Debug.PrintPacket(packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
msgCtx, err := l.sendMessage(packet)
|
msgCtx, err := l.sendMessage(packet)
|
||||||
@ -60,7 +60,7 @@ func (l *Conn) readPacket(msgCtx *messageContext) (*ber.Packet, error) {
|
|||||||
if err = addLDAPDescriptions(packet); err != nil {
|
if err = addLDAPDescriptions(packet); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ber.PrintPacket(packet)
|
l.Debug.PrintPacket(packet)
|
||||||
}
|
}
|
||||||
return packet, nil
|
return packet, nil
|
||||||
}
|
}
|
103
vendor/gopkg.in/ldap.v3/search.go → vendor/github.com/go-ldap/ldap/v3/search.go
generated
vendored
103
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
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -61,7 +6,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
ber "gopkg.in/asn1-ber.v1"
|
ber "github.com/go-asn1-ber/asn1-ber"
|
||||||
)
|
)
|
||||||
|
|
||||||
// scope choices
|
// scope choices
|
||||||
@ -132,6 +77,17 @@ func (e *Entry) GetAttributeValues(attribute string) []string {
|
|||||||
return []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
|
// GetRawAttributeValues returns the byte values for the named attribute, or an empty list
|
||||||
func (e *Entry) GetRawAttributeValues(attribute string) [][]byte {
|
func (e *Entry) GetRawAttributeValues(attribute string) [][]byte {
|
||||||
for _, attr := range e.Attributes {
|
for _, attr := range e.Attributes {
|
||||||
@ -142,6 +98,16 @@ func (e *Entry) GetRawAttributeValues(attribute string) [][]byte {
|
|||||||
return [][]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 ""
|
// GetAttributeValue returns the first value for the named attribute, or ""
|
||||||
func (e *Entry) GetAttributeValue(attribute string) string {
|
func (e *Entry) GetAttributeValue(attribute string) string {
|
||||||
values := e.GetAttributeValues(attribute)
|
values := e.GetAttributeValues(attribute)
|
||||||
@ -151,6 +117,16 @@ func (e *Entry) GetAttributeValue(attribute string) string {
|
|||||||
return values[0]
|
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
|
// GetRawAttributeValue returns the first value for the named attribute, or an empty slice
|
||||||
func (e *Entry) GetRawAttributeValue(attribute string) []byte {
|
func (e *Entry) GetRawAttributeValue(attribute string) []byte {
|
||||||
values := e.GetRawAttributeValues(attribute)
|
values := e.GetRawAttributeValues(attribute)
|
||||||
@ -160,6 +136,15 @@ func (e *Entry) GetRawAttributeValue(attribute string) []byte {
|
|||||||
return values[0]
|
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
|
// Print outputs a human-readable description
|
||||||
func (e *Entry) Print() {
|
func (e *Entry) Print() {
|
||||||
fmt.Printf("DN: %s\n", e.DN)
|
fmt.Printf("DN: %s\n", e.DN)
|
||||||
@ -386,7 +371,7 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) {
|
|||||||
for {
|
for {
|
||||||
packet, err := l.readPacket(msgCtx)
|
packet, err := l.readPacket(msgCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch packet.Children[1].Tag {
|
switch packet.Children[1].Tag {
|
||||||
@ -406,13 +391,13 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) {
|
|||||||
case 5:
|
case 5:
|
||||||
err := GetLDAPError(packet)
|
err := GetLDAPError(packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return result, err
|
||||||
}
|
}
|
||||||
if len(packet.Children) == 3 {
|
if len(packet.Children) == 3 {
|
||||||
for _, child := range packet.Children[2].Children {
|
for _, child := range packet.Children[2].Children {
|
||||||
decodedChild, err := DecodeControl(child)
|
decodedChild, err := DecodeControl(child)
|
||||||
if err != nil {
|
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)
|
result.Controls = append(result.Controls, decodedChild)
|
||||||
}
|
}
|
3
vendor/golang.org/x/crypto/AUTHORS
generated
vendored
Normal file
3
vendor/golang.org/x/crypto/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code refers to The Go Authors for copyright purposes.
|
||||||
|
# The master list of authors is in the main Go distribution,
|
||||||
|
# visible at https://tip.golang.org/AUTHORS.
|
3
vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code was written by the Go contributors.
|
||||||
|
# The master list of contributors is in the main Go distribution,
|
||||||
|
# visible at https://tip.golang.org/CONTRIBUTORS.
|
27
vendor/golang.org/x/crypto/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/crypto/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2009 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.
|
22
vendor/golang.org/x/crypto/PATENTS
generated
vendored
Normal file
22
vendor/golang.org/x/crypto/PATENTS
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Go project.
|
||||||
|
|
||||||
|
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||||
|
patent license to make, have made, use, offer to sell, sell, import,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Go, where such license applies only to those patent
|
||||||
|
claims, both currently owned or controlled by Google and acquired in
|
||||||
|
the future, licensable by Google that are necessarily infringed by this
|
||||||
|
implementation of Go. This grant does not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of this
|
||||||
|
implementation. If you or your agent or exclusive licensee institute or
|
||||||
|
order or agree to the institution of patent litigation against any
|
||||||
|
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that this implementation of Go or any code incorporated within this
|
||||||
|
implementation of Go constitutes direct or contributory patent
|
||||||
|
infringement, or inducement of patent infringement, then any patent
|
||||||
|
rights granted to you under this License for this implementation of Go
|
||||||
|
shall terminate as of the date such litigation is filed.
|
122
vendor/golang.org/x/crypto/md4/md4.go
generated
vendored
Normal file
122
vendor/golang.org/x/crypto/md4/md4.go
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package md4 implements the MD4 hash algorithm as defined in RFC 1320.
|
||||||
|
//
|
||||||
|
// Deprecated: MD4 is cryptographically broken and should should only be used
|
||||||
|
// where compatibility with legacy systems, not security, is the goal. Instead,
|
||||||
|
// use a secure hash like SHA-256 (from crypto/sha256).
|
||||||
|
package md4 // import "golang.org/x/crypto/md4"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
crypto.RegisterHash(crypto.MD4, New)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The size of an MD4 checksum in bytes.
|
||||||
|
const Size = 16
|
||||||
|
|
||||||
|
// The blocksize of MD4 in bytes.
|
||||||
|
const BlockSize = 64
|
||||||
|
|
||||||
|
const (
|
||||||
|
_Chunk = 64
|
||||||
|
_Init0 = 0x67452301
|
||||||
|
_Init1 = 0xEFCDAB89
|
||||||
|
_Init2 = 0x98BADCFE
|
||||||
|
_Init3 = 0x10325476
|
||||||
|
)
|
||||||
|
|
||||||
|
// digest represents the partial evaluation of a checksum.
|
||||||
|
type digest struct {
|
||||||
|
s [4]uint32
|
||||||
|
x [_Chunk]byte
|
||||||
|
nx int
|
||||||
|
len uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *digest) Reset() {
|
||||||
|
d.s[0] = _Init0
|
||||||
|
d.s[1] = _Init1
|
||||||
|
d.s[2] = _Init2
|
||||||
|
d.s[3] = _Init3
|
||||||
|
d.nx = 0
|
||||||
|
d.len = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a new hash.Hash computing the MD4 checksum.
|
||||||
|
func New() hash.Hash {
|
||||||
|
d := new(digest)
|
||||||
|
d.Reset()
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *digest) Size() int { return Size }
|
||||||
|
|
||||||
|
func (d *digest) BlockSize() int { return BlockSize }
|
||||||
|
|
||||||
|
func (d *digest) Write(p []byte) (nn int, err error) {
|
||||||
|
nn = len(p)
|
||||||
|
d.len += uint64(nn)
|
||||||
|
if d.nx > 0 {
|
||||||
|
n := len(p)
|
||||||
|
if n > _Chunk-d.nx {
|
||||||
|
n = _Chunk - d.nx
|
||||||
|
}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
d.x[d.nx+i] = p[i]
|
||||||
|
}
|
||||||
|
d.nx += n
|
||||||
|
if d.nx == _Chunk {
|
||||||
|
_Block(d, d.x[0:])
|
||||||
|
d.nx = 0
|
||||||
|
}
|
||||||
|
p = p[n:]
|
||||||
|
}
|
||||||
|
n := _Block(d, p)
|
||||||
|
p = p[n:]
|
||||||
|
if len(p) > 0 {
|
||||||
|
d.nx = copy(d.x[:], p)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d0 *digest) Sum(in []byte) []byte {
|
||||||
|
// Make a copy of d0, so that caller can keep writing and summing.
|
||||||
|
d := new(digest)
|
||||||
|
*d = *d0
|
||||||
|
|
||||||
|
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
|
||||||
|
len := d.len
|
||||||
|
var tmp [64]byte
|
||||||
|
tmp[0] = 0x80
|
||||||
|
if len%64 < 56 {
|
||||||
|
d.Write(tmp[0 : 56-len%64])
|
||||||
|
} else {
|
||||||
|
d.Write(tmp[0 : 64+56-len%64])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length in bits.
|
||||||
|
len <<= 3
|
||||||
|
for i := uint(0); i < 8; i++ {
|
||||||
|
tmp[i] = byte(len >> (8 * i))
|
||||||
|
}
|
||||||
|
d.Write(tmp[0:8])
|
||||||
|
|
||||||
|
if d.nx != 0 {
|
||||||
|
panic("d.nx != 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range d.s {
|
||||||
|
in = append(in, byte(s>>0))
|
||||||
|
in = append(in, byte(s>>8))
|
||||||
|
in = append(in, byte(s>>16))
|
||||||
|
in = append(in, byte(s>>24))
|
||||||
|
}
|
||||||
|
return in
|
||||||
|
}
|
89
vendor/golang.org/x/crypto/md4/md4block.go
generated
vendored
Normal file
89
vendor/golang.org/x/crypto/md4/md4block.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// MD4 block step.
|
||||||
|
// In its own file so that a faster assembly or C version
|
||||||
|
// can be substituted easily.
|
||||||
|
|
||||||
|
package md4
|
||||||
|
|
||||||
|
var shift1 = []uint{3, 7, 11, 19}
|
||||||
|
var shift2 = []uint{3, 5, 9, 13}
|
||||||
|
var shift3 = []uint{3, 9, 11, 15}
|
||||||
|
|
||||||
|
var xIndex2 = []uint{0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}
|
||||||
|
var xIndex3 = []uint{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}
|
||||||
|
|
||||||
|
func _Block(dig *digest, p []byte) int {
|
||||||
|
a := dig.s[0]
|
||||||
|
b := dig.s[1]
|
||||||
|
c := dig.s[2]
|
||||||
|
d := dig.s[3]
|
||||||
|
n := 0
|
||||||
|
var X [16]uint32
|
||||||
|
for len(p) >= _Chunk {
|
||||||
|
aa, bb, cc, dd := a, b, c, d
|
||||||
|
|
||||||
|
j := 0
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
X[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
|
||||||
|
j += 4
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this needs to be made faster in the future,
|
||||||
|
// the usual trick is to unroll each of these
|
||||||
|
// loops by a factor of 4; that lets you replace
|
||||||
|
// the shift[] lookups with constants and,
|
||||||
|
// with suitable variable renaming in each
|
||||||
|
// unrolled body, delete the a, b, c, d = d, a, b, c
|
||||||
|
// (or you can let the optimizer do the renaming).
|
||||||
|
//
|
||||||
|
// The index variables are uint so that % by a power
|
||||||
|
// of two can be optimized easily by a compiler.
|
||||||
|
|
||||||
|
// Round 1.
|
||||||
|
for i := uint(0); i < 16; i++ {
|
||||||
|
x := i
|
||||||
|
s := shift1[i%4]
|
||||||
|
f := ((c ^ d) & b) ^ d
|
||||||
|
a += f + X[x]
|
||||||
|
a = a<<s | a>>(32-s)
|
||||||
|
a, b, c, d = d, a, b, c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round 2.
|
||||||
|
for i := uint(0); i < 16; i++ {
|
||||||
|
x := xIndex2[i]
|
||||||
|
s := shift2[i%4]
|
||||||
|
g := (b & c) | (b & d) | (c & d)
|
||||||
|
a += g + X[x] + 0x5a827999
|
||||||
|
a = a<<s | a>>(32-s)
|
||||||
|
a, b, c, d = d, a, b, c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round 3.
|
||||||
|
for i := uint(0); i < 16; i++ {
|
||||||
|
x := xIndex3[i]
|
||||||
|
s := shift3[i%4]
|
||||||
|
h := b ^ c ^ d
|
||||||
|
a += h + X[x] + 0x6ed9eba1
|
||||||
|
a = a<<s | a>>(32-s)
|
||||||
|
a, b, c, d = d, a, b, c
|
||||||
|
}
|
||||||
|
|
||||||
|
a += aa
|
||||||
|
b += bb
|
||||||
|
c += cc
|
||||||
|
d += dd
|
||||||
|
|
||||||
|
p = p[_Chunk:]
|
||||||
|
n += _Chunk
|
||||||
|
}
|
||||||
|
|
||||||
|
dig.s[0] = a
|
||||||
|
dig.s[1] = b
|
||||||
|
dig.s[2] = c
|
||||||
|
dig.s[3] = d
|
||||||
|
return n
|
||||||
|
}
|
30
vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go
generated
vendored
Normal file
30
vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package unsafeheader contains header declarations for the Go runtime's
|
||||||
|
// slice and string implementations.
|
||||||
|
//
|
||||||
|
// This package allows x/sys to use types equivalent to
|
||||||
|
// reflect.SliceHeader and reflect.StringHeader without introducing
|
||||||
|
// a dependency on the (relatively heavy) "reflect" package.
|
||||||
|
package unsafeheader
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Slice is the runtime representation of a slice.
|
||||||
|
// It cannot be used safely or portably and its representation may change in a later release.
|
||||||
|
type Slice struct {
|
||||||
|
Data unsafe.Pointer
|
||||||
|
Len int
|
||||||
|
Cap int
|
||||||
|
}
|
||||||
|
|
||||||
|
// String is the runtime representation of a string.
|
||||||
|
// It cannot be used safely or portably and its representation may change in a later release.
|
||||||
|
type String struct {
|
||||||
|
Data unsafe.Pointer
|
||||||
|
Len int
|
||||||
|
}
|
15
vendor/golang.org/x/sys/unix/README.md
generated
vendored
15
vendor/golang.org/x/sys/unix/README.md
generated
vendored
@ -89,7 +89,7 @@ constants.
|
|||||||
|
|
||||||
Adding new syscall numbers is mostly done by running the build on a sufficiently
|
Adding new syscall numbers is mostly done by running the build on a sufficiently
|
||||||
new installation of the target OS (or updating the source checkouts for the
|
new installation of the target OS (or updating the source checkouts for the
|
||||||
new build system). However, depending on the OS, you make need to update the
|
new build system). However, depending on the OS, you may need to update the
|
||||||
parsing in mksysnum.
|
parsing in mksysnum.
|
||||||
|
|
||||||
### mksyscall.go
|
### mksyscall.go
|
||||||
@ -149,10 +149,21 @@ To add a constant, add the header that includes it to the appropriate variable.
|
|||||||
Then, edit the regex (if necessary) to match the desired constant. Avoid making
|
Then, edit the regex (if necessary) to match the desired constant. Avoid making
|
||||||
the regex too broad to avoid matching unintended constants.
|
the regex too broad to avoid matching unintended constants.
|
||||||
|
|
||||||
|
### mkmerge.go
|
||||||
|
|
||||||
|
This program is used to extract duplicate const, func, and type declarations
|
||||||
|
from the generated architecture-specific files listed below, and merge these
|
||||||
|
into a common file for each OS.
|
||||||
|
|
||||||
|
The merge is performed in the following steps:
|
||||||
|
1. Construct the set of common code that is idential in all architecture-specific files.
|
||||||
|
2. Write this common code to the merged file.
|
||||||
|
3. Remove the common code from all architecture-specific files.
|
||||||
|
|
||||||
|
|
||||||
## Generated files
|
## Generated files
|
||||||
|
|
||||||
### `zerror_${GOOS}_${GOARCH}.go`
|
### `zerrors_${GOOS}_${GOARCH}.go`
|
||||||
|
|
||||||
A file containing all of the system's generated error numbers, error strings,
|
A file containing all of the system's generated error numbers, error strings,
|
||||||
signal numbers, and constants. Generated by `mkerrors.sh` (see above).
|
signal numbers, and constants. Generated by `mkerrors.sh` (see above).
|
||||||
|
42
vendor/golang.org/x/sys/unix/affinity_linux.go
generated
vendored
42
vendor/golang.org/x/sys/unix/affinity_linux.go
generated
vendored
@ -7,6 +7,7 @@
|
|||||||
package unix
|
package unix
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/bits"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -79,46 +80,7 @@ func (s *CPUSet) IsSet(cpu int) bool {
|
|||||||
func (s *CPUSet) Count() int {
|
func (s *CPUSet) Count() int {
|
||||||
c := 0
|
c := 0
|
||||||
for _, b := range s {
|
for _, b := range s {
|
||||||
c += onesCount64(uint64(b))
|
c += bits.OnesCount64(uint64(b))
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// onesCount64 is a copy of Go 1.9's math/bits.OnesCount64.
|
|
||||||
// Once this package can require Go 1.9, we can delete this
|
|
||||||
// and update the caller to use bits.OnesCount64.
|
|
||||||
func onesCount64(x uint64) int {
|
|
||||||
const m0 = 0x5555555555555555 // 01010101 ...
|
|
||||||
const m1 = 0x3333333333333333 // 00110011 ...
|
|
||||||
const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ...
|
|
||||||
const m3 = 0x00ff00ff00ff00ff // etc.
|
|
||||||
const m4 = 0x0000ffff0000ffff
|
|
||||||
|
|
||||||
// Implementation: Parallel summing of adjacent bits.
|
|
||||||
// See "Hacker's Delight", Chap. 5: Counting Bits.
|
|
||||||
// The following pattern shows the general approach:
|
|
||||||
//
|
|
||||||
// x = x>>1&(m0&m) + x&(m0&m)
|
|
||||||
// x = x>>2&(m1&m) + x&(m1&m)
|
|
||||||
// x = x>>4&(m2&m) + x&(m2&m)
|
|
||||||
// x = x>>8&(m3&m) + x&(m3&m)
|
|
||||||
// x = x>>16&(m4&m) + x&(m4&m)
|
|
||||||
// x = x>>32&(m5&m) + x&(m5&m)
|
|
||||||
// return int(x)
|
|
||||||
//
|
|
||||||
// Masking (& operations) can be left away when there's no
|
|
||||||
// danger that a field's sum will carry over into the next
|
|
||||||
// field: Since the result cannot be > 64, 8 bits is enough
|
|
||||||
// and we can ignore the masks for the shifts by 8 and up.
|
|
||||||
// Per "Hacker's Delight", the first line can be simplified
|
|
||||||
// more, but it saves at best one instruction, so we leave
|
|
||||||
// it alone for clarity.
|
|
||||||
const m = 1<<64 - 1
|
|
||||||
x = x>>1&(m0&m) + x&(m0&m)
|
|
||||||
x = x>>2&(m1&m) + x&(m1&m)
|
|
||||||
x = (x>>4 + x) & (m2 & m)
|
|
||||||
x += x >> 8
|
|
||||||
x += x >> 16
|
|
||||||
x += x >> 32
|
|
||||||
return int(x) & (1<<7 - 1)
|
|
||||||
}
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_darwin_386.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_darwin_386.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_darwin_arm.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_darwin_arm.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
// +build arm,darwin
|
// +build arm,darwin
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
// +build arm64,darwin
|
// +build arm64,darwin
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_freebsd_386.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_freebsd_386.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_linux_386.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_linux_386.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_linux_amd64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_linux_amd64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_linux_arm.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_linux_arm.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_linux_arm64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_linux_arm64.s
generated
vendored
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// +build linux
|
// +build linux
|
||||||
// +build arm64
|
// +build arm64
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
generated
vendored
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// +build linux
|
// +build linux
|
||||||
// +build mips64 mips64le
|
// +build mips64 mips64le
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
generated
vendored
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// +build linux
|
// +build linux
|
||||||
// +build mips mipsle
|
// +build mips mipsle
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
generated
vendored
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// +build linux
|
// +build linux
|
||||||
// +build ppc64 ppc64le
|
// +build ppc64 ppc64le
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
47
vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
generated
vendored
Normal file
47
vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build riscv64,gc
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for linux/riscv64.
|
||||||
|
//
|
||||||
|
// Where available, just jump to package syscall's implementation of
|
||||||
|
// these functions.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||||
|
CALL runtime·entersyscall(SB)
|
||||||
|
MOV a1+8(FP), A0
|
||||||
|
MOV a2+16(FP), A1
|
||||||
|
MOV a3+24(FP), A2
|
||||||
|
MOV trap+0(FP), A7 // syscall entry
|
||||||
|
ECALL
|
||||||
|
MOV A0, r1+32(FP) // r1
|
||||||
|
MOV A1, r2+40(FP) // r2
|
||||||
|
CALL runtime·exitsyscall(SB)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||||
|
MOV a1+8(FP), A0
|
||||||
|
MOV a2+16(FP), A1
|
||||||
|
MOV a3+24(FP), A2
|
||||||
|
MOV trap+0(FP), A7 // syscall entry
|
||||||
|
ECALL
|
||||||
|
MOV A0, r1+32(FP)
|
||||||
|
MOV A1, r2+40(FP)
|
||||||
|
RET
|
2
vendor/golang.org/x/sys/unix/asm_linux_s390x.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_linux_s390x.s
generated
vendored
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// +build s390x
|
// +build s390x
|
||||||
// +build linux
|
// +build linux
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_netbsd_386.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_netbsd_386.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_openbsd_386.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_openbsd_386.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/asm_openbsd_arm.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_openbsd_arm.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
29
vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gc
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for arm64, OpenBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gc
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for mips64, OpenBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
2
vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
generated
vendored
2
vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !gccgo
|
// +build gc
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
|
1
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
1
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
@ -23,6 +23,7 @@ const (
|
|||||||
HCI_CHANNEL_USER = 1
|
HCI_CHANNEL_USER = 1
|
||||||
HCI_CHANNEL_MONITOR = 2
|
HCI_CHANNEL_MONITOR = 2
|
||||||
HCI_CHANNEL_CONTROL = 3
|
HCI_CHANNEL_CONTROL = 3
|
||||||
|
HCI_CHANNEL_LOGGING = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
// Socketoption Level
|
// Socketoption Level
|
||||||
|
91
vendor/golang.org/x/sys/unix/dirent.go
generated
vendored
91
vendor/golang.org/x/sys/unix/dirent.go
generated
vendored
@ -2,16 +2,101 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris
|
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
import "syscall"
|
import "unsafe"
|
||||||
|
|
||||||
|
// readInt returns the size-bytes unsigned integer in native byte order at offset off.
|
||||||
|
func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
|
||||||
|
if len(b) < int(off+size) {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
if isBigEndian {
|
||||||
|
return readIntBE(b[off:], size), true
|
||||||
|
}
|
||||||
|
return readIntLE(b[off:], size), true
|
||||||
|
}
|
||||||
|
|
||||||
|
func readIntBE(b []byte, size uintptr) uint64 {
|
||||||
|
switch size {
|
||||||
|
case 1:
|
||||||
|
return uint64(b[0])
|
||||||
|
case 2:
|
||||||
|
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint64(b[1]) | uint64(b[0])<<8
|
||||||
|
case 4:
|
||||||
|
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
|
||||||
|
case 8:
|
||||||
|
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
|
||||||
|
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
|
||||||
|
default:
|
||||||
|
panic("syscall: readInt with unsupported size")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func readIntLE(b []byte, size uintptr) uint64 {
|
||||||
|
switch size {
|
||||||
|
case 1:
|
||||||
|
return uint64(b[0])
|
||||||
|
case 2:
|
||||||
|
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint64(b[0]) | uint64(b[1])<<8
|
||||||
|
case 4:
|
||||||
|
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
|
||||||
|
case 8:
|
||||||
|
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
||||||
|
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||||
|
default:
|
||||||
|
panic("syscall: readInt with unsupported size")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ParseDirent parses up to max directory entries in buf,
|
// ParseDirent parses up to max directory entries in buf,
|
||||||
// appending the names to names. It returns the number of
|
// appending the names to names. It returns the number of
|
||||||
// bytes consumed from buf, the number of entries added
|
// bytes consumed from buf, the number of entries added
|
||||||
// to names, and the new names slice.
|
// to names, and the new names slice.
|
||||||
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
|
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
|
||||||
return syscall.ParseDirent(buf, max, names)
|
origlen := len(buf)
|
||||||
|
count = 0
|
||||||
|
for max != 0 && len(buf) > 0 {
|
||||||
|
reclen, ok := direntReclen(buf)
|
||||||
|
if !ok || reclen > uint64(len(buf)) {
|
||||||
|
return origlen, count, names
|
||||||
|
}
|
||||||
|
rec := buf[:reclen]
|
||||||
|
buf = buf[reclen:]
|
||||||
|
ino, ok := direntIno(rec)
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if ino == 0 { // File absent in directory.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))
|
||||||
|
namlen, ok := direntNamlen(rec)
|
||||||
|
if !ok || namoff+namlen > uint64(len(rec)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
name := rec[namoff : namoff+namlen]
|
||||||
|
for i, c := range name {
|
||||||
|
if c == 0 {
|
||||||
|
name = name[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check for useless names before allocating a string.
|
||||||
|
if string(name) == "." || string(name) == ".." {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
max--
|
||||||
|
count++
|
||||||
|
names = append(names, string(name))
|
||||||
|
}
|
||||||
|
return origlen - len(buf), count, names
|
||||||
}
|
}
|
||||||
|
2
vendor/golang.org/x/sys/unix/endian_big.go
generated
vendored
2
vendor/golang.org/x/sys/unix/endian_big.go
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
//
|
//
|
||||||
// +build ppc64 s390x mips mips64
|
// +build armbe arm64be m68k mips mips64 mips64p32 ppc ppc64 s390 s390x shbe sparc sparc64
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
2
vendor/golang.org/x/sys/unix/endian_little.go
generated
vendored
2
vendor/golang.org/x/sys/unix/endian_little.go
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
//
|
//
|
||||||
// +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le
|
// +build 386 amd64 amd64p32 alpha arm arm64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
6
vendor/golang.org/x/sys/unix/errors_freebsd_386.go
generated
vendored
6
vendor/golang.org/x/sys/unix/errors_freebsd_386.go
generated
vendored
@ -8,6 +8,7 @@
|
|||||||
package unix
|
package unix
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
DLT_HHDLC = 0x79
|
||||||
IFF_SMART = 0x20
|
IFF_SMART = 0x20
|
||||||
IFT_1822 = 0x2
|
IFT_1822 = 0x2
|
||||||
IFT_A12MPPSWITCH = 0x82
|
IFT_A12MPPSWITCH = 0x82
|
||||||
@ -210,13 +211,18 @@ const (
|
|||||||
IFT_XETHER = 0x1a
|
IFT_XETHER = 0x1a
|
||||||
IPPROTO_MAXID = 0x34
|
IPPROTO_MAXID = 0x34
|
||||||
IPV6_FAITH = 0x1d
|
IPV6_FAITH = 0x1d
|
||||||
|
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||||
IP_FAITH = 0x16
|
IP_FAITH = 0x16
|
||||||
|
IP_MAX_SOURCE_FILTER = 0x400
|
||||||
|
IP_MIN_MEMBERSHIPS = 0x1f
|
||||||
MAP_NORESERVE = 0x40
|
MAP_NORESERVE = 0x40
|
||||||
MAP_RENAME = 0x20
|
MAP_RENAME = 0x20
|
||||||
NET_RT_MAXID = 0x6
|
NET_RT_MAXID = 0x6
|
||||||
RTF_PRCLONING = 0x10000
|
RTF_PRCLONING = 0x10000
|
||||||
RTM_OLDADD = 0x9
|
RTM_OLDADD = 0x9
|
||||||
RTM_OLDDEL = 0xa
|
RTM_OLDDEL = 0xa
|
||||||
|
RT_CACHING_CONTEXT = 0x1
|
||||||
|
RT_NORTREF = 0x2
|
||||||
SIOCADDRT = 0x8030720a
|
SIOCADDRT = 0x8030720a
|
||||||
SIOCALIFADDR = 0x8118691b
|
SIOCALIFADDR = 0x8118691b
|
||||||
SIOCDELRT = 0x8030720b
|
SIOCDELRT = 0x8030720b
|
||||||
|
6
vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go
generated
vendored
6
vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go
generated
vendored
@ -8,6 +8,7 @@
|
|||||||
package unix
|
package unix
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
DLT_HHDLC = 0x79
|
||||||
IFF_SMART = 0x20
|
IFF_SMART = 0x20
|
||||||
IFT_1822 = 0x2
|
IFT_1822 = 0x2
|
||||||
IFT_A12MPPSWITCH = 0x82
|
IFT_A12MPPSWITCH = 0x82
|
||||||
@ -210,13 +211,18 @@ const (
|
|||||||
IFT_XETHER = 0x1a
|
IFT_XETHER = 0x1a
|
||||||
IPPROTO_MAXID = 0x34
|
IPPROTO_MAXID = 0x34
|
||||||
IPV6_FAITH = 0x1d
|
IPV6_FAITH = 0x1d
|
||||||
|
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||||
IP_FAITH = 0x16
|
IP_FAITH = 0x16
|
||||||
|
IP_MAX_SOURCE_FILTER = 0x400
|
||||||
|
IP_MIN_MEMBERSHIPS = 0x1f
|
||||||
MAP_NORESERVE = 0x40
|
MAP_NORESERVE = 0x40
|
||||||
MAP_RENAME = 0x20
|
MAP_RENAME = 0x20
|
||||||
NET_RT_MAXID = 0x6
|
NET_RT_MAXID = 0x6
|
||||||
RTF_PRCLONING = 0x10000
|
RTF_PRCLONING = 0x10000
|
||||||
RTM_OLDADD = 0x9
|
RTM_OLDADD = 0x9
|
||||||
RTM_OLDDEL = 0xa
|
RTM_OLDDEL = 0xa
|
||||||
|
RT_CACHING_CONTEXT = 0x1
|
||||||
|
RT_NORTREF = 0x2
|
||||||
SIOCADDRT = 0x8040720a
|
SIOCADDRT = 0x8040720a
|
||||||
SIOCALIFADDR = 0x8118691b
|
SIOCALIFADDR = 0x8118691b
|
||||||
SIOCDELRT = 0x8040720b
|
SIOCDELRT = 0x8040720b
|
||||||
|
17
vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go
generated
vendored
Normal file
17
vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
||||||
|
// them here for backwards compatibility.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
const (
|
||||||
|
DLT_HHDLC = 0x79
|
||||||
|
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||||
|
IP_MAX_SOURCE_FILTER = 0x400
|
||||||
|
IP_MIN_MEMBERSHIPS = 0x1f
|
||||||
|
RT_CACHING_CONTEXT = 0x1
|
||||||
|
RT_NORTREF = 0x2
|
||||||
|
)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user