diff --git a/edition/community.go b/edition/community.go index 4a54f086..dd3dd8ac 100644 --- a/edition/community.go +++ b/edition/community.go @@ -41,8 +41,8 @@ func main() { rt.Product = domain.Product{} rt.Product.Major = "5" rt.Product.Minor = "11" - rt.Product.Patch = "2" - rt.Product.Revision = "1705427184" + rt.Product.Patch = "3" + rt.Product.Revision = "1708098744" rt.Product.Version = fmt.Sprintf("%s.%s.%s", rt.Product.Major, rt.Product.Minor, rt.Product.Patch) rt.Product.Edition = domain.CommunityEdition rt.Product.Title = "Community" diff --git a/go.mod b/go.mod index 026dda34..59db927a 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/documize/glick v0.0.0-20160503134043-a8ccbef88237 github.com/documize/html-diff v0.0.0-20160503140253-f61c192c7796 github.com/documize/slug v1.1.1 - github.com/go-ldap/ldap/v3 v3.4.6 + github.com/go-ldap/ldap/v3 v3.4.1 github.com/go-sql-driver/mysql v1.7.1 github.com/golang/glog v1.2.0 // indirect github.com/google/go-querystring v1.1.0 // indirect @@ -36,7 +36,7 @@ require ( ) require ( - github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect + github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/fatih/structs v1.1.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect @@ -44,7 +44,6 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect - github.com/google/uuid v1.3.1 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/trivago/tgo v1.0.7 // indirect ) diff --git a/go.sum b/go.sum index 64bd8653..e0d23480 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,11 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= -github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= -github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +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/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= -github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/andygrunwald/go-jira v1.16.0 h1:PU7C7Fkk5L96JvPc6vDVIrd99vdPnYudHu4ju2c2ikQ= github.com/andygrunwald/go-jira v1.16.0/go.mod h1:UQH4IBVxIYWbgagc0LF/k9FRs9xjIiQ8hIcC6HfLwFU= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= @@ -34,10 +32,11 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +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.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A= -github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc= +github.com/go-ldap/ldap/v3 v3.4.1 h1:fU/0xli6HY02ocbMuozHAYsaHLcnkLjvho2r5a34BUU= +github.com/go-ldap/ldap/v3 v3.4.1/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= @@ -59,8 +58,6 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= @@ -127,15 +124,16 @@ github.com/trivago/tgo v1.0.7 h1:uaWH/XIy9aWYWpjm2CU3RpcqZXmX2ysQ9/Go+d9gyrM= github.com/trivago/tgo v1.0.7/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -150,6 +148,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -159,21 +158,18 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/gui/package.json b/gui/package.json index e7e8f5ae..4cbfbdc7 100644 --- a/gui/package.json +++ b/gui/package.json @@ -1,6 +1,6 @@ { "name": "documize", - "version": "5.11.2", + "version": "5.11.3", "private": true, "description": "Documize Community", "repository": "", diff --git a/vendor/github.com/Azure/go-ntlmssp/SECURITY.md b/vendor/github.com/Azure/go-ntlmssp/SECURITY.md deleted file mode 100644 index e138ec5d..00000000 --- a/vendor/github.com/Azure/go-ntlmssp/SECURITY.md +++ /dev/null @@ -1,41 +0,0 @@ - - -## Security - -Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). - -If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. - -## Reporting Security Issues - -**Please do not report security vulnerabilities through public GitHub issues.** - -Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). - -If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). - -You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). - -Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - - * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - * Full paths of source file(s) related to the manifestation of the issue - * The location of the affected source code (tag/branch/commit or direct URL) - * Any special configuration required to reproduce the issue - * Step-by-step instructions to reproduce the issue - * Proof-of-concept or exploit code (if possible) - * Impact of the issue, including how an attacker might exploit the issue - -This information will help us triage your report more quickly. - -If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. - -## Preferred Languages - -We prefer all communications to be in English. - -## Policy - -Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). - - diff --git a/vendor/github.com/Azure/go-ntlmssp/authenticate_message.go b/vendor/github.com/Azure/go-ntlmssp/authenticate_message.go index ab183db6..c8930680 100644 --- a/vendor/github.com/Azure/go-ntlmssp/authenticate_message.go +++ b/vendor/github.com/Azure/go-ntlmssp/authenticate_message.go @@ -42,7 +42,7 @@ func (m authenicateMessage) MarshalBinary() ([]byte, error) { } target, user := toUnicode(m.TargetName), toUnicode(m.UserName) - workstation := toUnicode("") + workstation := toUnicode("go-ntlmssp") ptr := binary.Size(&authenticateMessageFields{}) f := authenticateMessageFields{ @@ -82,7 +82,7 @@ func (m authenicateMessage) MarshalBinary() ([]byte, error) { //ProcessChallenge crafts an AUTHENTICATE message in response to the CHALLENGE message //that was received from the server -func ProcessChallenge(challengeMessageData []byte, user, password string, domainNeeded bool) ([]byte, error) { +func ProcessChallenge(challengeMessageData []byte, user, password string) ([]byte, error) { if user == "" && password == "" { return nil, errors.New("Anonymous authentication not supported") } @@ -98,10 +98,6 @@ func ProcessChallenge(challengeMessageData []byte, user, password string, domain if cm.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATEKEYEXCH) { return nil, errors.New("Key exchange requested but not supported (NTLMSSP_NEGOTIATE_KEY_EXCH)") } - - if !domainNeeded { - cm.TargetName = "" - } am := authenicateMessage{ UserName: user, diff --git a/vendor/github.com/Azure/go-ntlmssp/authheader.go b/vendor/github.com/Azure/go-ntlmssp/authheader.go index c9d30d32..aac3f77d 100644 --- a/vendor/github.com/Azure/go-ntlmssp/authheader.go +++ b/vendor/github.com/Azure/go-ntlmssp/authheader.go @@ -5,55 +5,26 @@ import ( "strings" ) -type authheader []string +type authheader string func (h authheader) IsBasic() bool { - for _, s := range h { - if strings.HasPrefix(string(s), "Basic ") { - return true - } - } - return false -} - -func (h authheader) Basic() string { - for _, s := range h { - if strings.HasPrefix(string(s), "Basic ") { - return s - } - } - return "" + return strings.HasPrefix(string(h), "Basic ") } func (h authheader) IsNegotiate() bool { - for _, s := range h { - if strings.HasPrefix(string(s), "Negotiate") { - return true - } - } - return false + return strings.HasPrefix(string(h), "Negotiate") } func (h authheader) IsNTLM() bool { - for _, s := range h { - if strings.HasPrefix(string(s), "NTLM") { - return true - } - } - return false + return strings.HasPrefix(string(h), "NTLM") } func (h authheader) GetData() ([]byte, error) { - for _, s := range h { - if strings.HasPrefix(string(s), "NTLM") || strings.HasPrefix(string(s), "Negotiate") || strings.HasPrefix(string(s), "Basic ") { - p := strings.Split(string(s), " ") - if len(p) < 2 { - return nil, nil - } - return base64.StdEncoding.DecodeString(string(p[1])) - } + p := strings.Split(string(h), " ") + if len(p) < 2 { + return nil, nil } - return nil, nil + return base64.StdEncoding.DecodeString(string(p[1])) } func (h authheader) GetBasicCreds() (username, password string, err error) { diff --git a/vendor/github.com/Azure/go-ntlmssp/negotiator.go b/vendor/github.com/Azure/go-ntlmssp/negotiator.go index cce4955d..7705eae4 100644 --- a/vendor/github.com/Azure/go-ntlmssp/negotiator.go +++ b/vendor/github.com/Azure/go-ntlmssp/negotiator.go @@ -10,22 +10,15 @@ import ( ) // GetDomain : parse domain name from based on slashes in the input -// Need to check for upn as well -func GetDomain(user string) (string, string, bool) { +func GetDomain(user string) (string, string) { domain := "" - domainNeeded := false if strings.Contains(user, "\\") { ucomponents := strings.SplitN(user, "\\", 2) domain = ucomponents[0] user = ucomponents[1] - domainNeeded = true - } else if strings.Contains(user, "@") { - domainNeeded = false - } else { - domainNeeded = true } - return user, domain, domainNeeded + return user, domain } //Negotiator is a http.Roundtripper decorator that automatically @@ -41,11 +34,10 @@ func (l Negotiator) RoundTrip(req *http.Request) (res *http.Response, err error) rt = http.DefaultTransport } // If it is not basic auth, just round trip the request as usual - reqauth := authheader(req.Header.Values("Authorization")) + reqauth := authheader(req.Header.Get("Authorization")) if !reqauth.IsBasic() { return rt.RoundTrip(req) } - reqauthBasic := reqauth.Basic() // Save request body body := bytes.Buffer{} if req.Body != nil { @@ -67,10 +59,11 @@ func (l Negotiator) RoundTrip(req *http.Request) (res *http.Response, err error) if res.StatusCode != http.StatusUnauthorized { return res, err } - resauth := authheader(res.Header.Values("Www-Authenticate")) + + 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(reqauthBasic)) + req.Header.Set("Authorization", string(reqauth)) io.Copy(ioutil.Discard, res.Body) res.Body.Close() req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes())) @@ -82,7 +75,7 @@ func (l Negotiator) RoundTrip(req *http.Request) (res *http.Response, err error) if res.StatusCode != http.StatusUnauthorized { return res, err } - resauth = authheader(res.Header.Values("Www-Authenticate")) + resauth = authheader(res.Header.Get("Www-Authenticate")) } if resauth.IsNegotiate() || resauth.IsNTLM() { @@ -98,7 +91,7 @@ func (l Negotiator) RoundTrip(req *http.Request) (res *http.Response, err error) // get domain from username domain := "" - u, domain, domainNeeded := GetDomain(u) + u, domain = GetDomain(u) // send negotiate negotiateMessage, err := NewNegotiateMessage(domain, "") @@ -119,7 +112,7 @@ func (l Negotiator) RoundTrip(req *http.Request) (res *http.Response, err error) } // receive challenge? - resauth = authheader(res.Header.Values("Www-Authenticate")) + resauth = authheader(res.Header.Get("Www-Authenticate")) challengeMessage, err := resauth.GetData() if err != nil { return nil, err @@ -132,7 +125,7 @@ func (l Negotiator) RoundTrip(req *http.Request) (res *http.Response, err error) res.Body.Close() // send authenticate - authenticateMessage, err := ProcessChallenge(challengeMessage, u, p, domainNeeded) + authenticateMessage, err := ProcessChallenge(challengeMessage, u, p) if err != nil { return nil, err } diff --git a/vendor/github.com/go-ldap/ldap/v3/add.go b/vendor/github.com/go-ldap/ldap/v3/add.go index ab32b0b6..baecd787 100644 --- a/vendor/github.com/go-ldap/ldap/v3/add.go +++ b/vendor/github.com/go-ldap/ldap/v3/add.go @@ -1,7 +1,8 @@ package ldap import ( - "fmt" + "log" + ber "github.com/go-asn1-ber/asn1-ber" ) @@ -62,6 +63,7 @@ func NewAddRequest(dn string, controls []Control) *AddRequest { DN: dn, Controls: controls, } + } // Add performs the given AddRequest @@ -83,7 +85,7 @@ func (l *Conn) Add(addRequest *AddRequest) error { return err } } else { - return fmt.Errorf("ldap: unexpected response: %d", packet.Children[1].Tag) + log.Printf("Unexpected Response: %d", packet.Children[1].Tag) } return nil } diff --git a/vendor/github.com/go-ldap/ldap/v3/bind.go b/vendor/github.com/go-ldap/ldap/v3/bind.go index a37f8e2c..9bc57482 100644 --- a/vendor/github.com/go-ldap/ldap/v3/bind.go +++ b/vendor/github.com/go-ldap/ldap/v3/bind.go @@ -261,7 +261,7 @@ func parseParams(str string) (map[string]string, error) { var state int for i := 0; i <= len(str); i++ { switch state { - case 0: // reading key + case 0: //reading key if i == len(str) { return nil, fmt.Errorf("syntax error on %d", i) } @@ -270,7 +270,7 @@ func parseParams(str string) (map[string]string, error) { continue } state = 1 - case 1: // reading value + case 1: //reading value if i == len(str) { m[key] = value break @@ -289,7 +289,7 @@ func parseParams(str string) (map[string]string, error) { default: value += string(str[i]) } - case 2: // inside quotes + case 2: //inside quotes if i == len(str) { return nil, fmt.Errorf("syntax error on %d", i) } @@ -399,9 +399,6 @@ type NTLMBindRequest struct { Username string // Password is the credentials to bind with Password string - // AllowEmptyPassword sets whether the client allows binding with an empty password - // (normally used for unauthenticated bind). - AllowEmptyPassword bool // 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 @@ -445,22 +442,6 @@ func (l *Conn) NTLMBind(domain, username, password string) error { return err } -// NTLMUnauthenticatedBind performs an bind with an empty password. -// -// A username is required. The anonymous bind is not (yet) supported by the go-ntlmssp library (https://github.com/Azure/go-ntlmssp/blob/819c794454d067543bc61d29f61fef4b3c3df62c/authenticate_message.go#L87) -// -// See https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/b38c36ed-2804-4868-a9ff-8dd3182128e4 part 3.2.5.1.2 -func (l *Conn) NTLMUnauthenticatedBind(domain, username string) error { - req := &NTLMBindRequest{ - Domain: domain, - Username: username, - Password: "", - AllowEmptyPassword: true, - } - _, 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{ @@ -474,7 +455,7 @@ func (l *Conn) NTLMBindWithHash(domain, username, hash string) error { // NTLMChallengeBind performs the NTLMSSP bind operation defined in the given request func (l *Conn) NTLMChallengeBind(ntlmBindRequest *NTLMBindRequest) (*NTLMBindResult, error) { - if !ntlmBindRequest.AllowEmptyPassword && ntlmBindRequest.Password == "" && ntlmBindRequest.Hash == "" { + if ntlmBindRequest.Password == "" && ntlmBindRequest.Hash == "" { return nil, NewError(ErrorEmptyPassword, errors.New("ldap: empty password not allowed by the client")) } @@ -515,11 +496,10 @@ func (l *Conn) NTLMChallengeBind(ntlmBindRequest *NTLMBindRequest) (*NTLMBindRes var err error var responseMessage []byte // generate a response message to the challenge with the given Username/Password if password is provided - if ntlmBindRequest.Hash != "" { + 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 if ntlmBindRequest.Password != "" || ntlmBindRequest.AllowEmptyPassword { - _, _, domainNeeded := ntlmssp.GetDomain(ntlmBindRequest.Username) - responseMessage, err = ntlmssp.ProcessChallenge(ntlmsspChallenge, ntlmBindRequest.Username, ntlmBindRequest.Password, domainNeeded) } else { err = fmt.Errorf("need a password or hash to generate reply") } @@ -558,178 +538,3 @@ func (l *Conn) NTLMChallengeBind(ntlmBindRequest *NTLMBindRequest) (*NTLMBindRes err = GetLDAPError(packet) return result, err } - -// GSSAPIClient interface is used as the client-side implementation for the -// GSSAPI SASL mechanism. -// Interface inspired by GSSAPIClient from golang.org/x/crypto/ssh -type GSSAPIClient interface { - // InitSecContext initiates the establishment of a security context for - // GSS-API between the client and server. - // Initially the token parameter should be specified as nil. - // The routine may return a outputToken which should be transferred to - // the server, where the server will present it to AcceptSecContext. - // If no token need be sent, InitSecContext will indicate this by setting - // needContinue to false. To complete the context - // establishment, one or more reply tokens may be required from the server; - // if so, InitSecContext will return a needContinue which is true. - // In this case, InitSecContext should be called again when the - // reply token is received from the server, passing the reply token - // to InitSecContext via the token parameters. - // See RFC 4752 section 3.1. - InitSecContext(target string, token []byte) (outputToken []byte, needContinue bool, err error) - // NegotiateSaslAuth performs the last step of the Sasl handshake. - // It takes a token, which, when unwrapped, describes the servers supported - // security layers (first octet) and maximum receive buffer (remaining - // three octets). - // If the received token is unacceptable an error must be returned to abort - // the handshake. - // Outputs a signed token describing the client's selected security layer - // and receive buffer size and optionally an authorization identity. - // The returned token will be sent to the server and the handshake considered - // completed successfully and the server authenticated. - // See RFC 4752 section 3.1. - NegotiateSaslAuth(token []byte, authzid string) ([]byte, error) - // DeleteSecContext destroys any established secure context. - DeleteSecContext() error -} - -// GSSAPIBindRequest represents a GSSAPI SASL mechanism bind request. -// See rfc4752 and rfc4513 section 5.2.1.2. -type GSSAPIBindRequest struct { - // Service Principal Name user for the service ticket. Eg. "ldap/" - ServicePrincipalName string - // (Optional) Authorization entity - AuthZID string - // (Optional) Controls to send with the bind request - Controls []Control -} - -// GSSAPIBind performs the GSSAPI SASL bind using the provided GSSAPI client. -func (l *Conn) GSSAPIBind(client GSSAPIClient, servicePrincipal, authzid string) error { - return l.GSSAPIBindRequest(client, &GSSAPIBindRequest{ - ServicePrincipalName: servicePrincipal, - AuthZID: authzid, - }) -} - -// GSSAPIBindRequest performs the GSSAPI SASL bind using the provided GSSAPI client. -func (l *Conn) GSSAPIBindRequest(client GSSAPIClient, req *GSSAPIBindRequest) error { - //nolint:errcheck - defer client.DeleteSecContext() - - var err error - var reqToken []byte - var recvToken []byte - needInit := true - for { - if needInit { - // Establish secure context between client and server. - reqToken, needInit, err = client.InitSecContext(req.ServicePrincipalName, recvToken) - if err != nil { - return err - } - } else { - // Secure context is set up, perform the last step of SASL handshake. - reqToken, err = client.NegotiateSaslAuth(recvToken, req.AuthZID) - if err != nil { - return err - } - } - // Send Bind request containing the current token and extract the - // token sent by server. - recvToken, err = l.saslBindTokenExchange(req.Controls, reqToken) - if err != nil { - return err - } - - if !needInit && len(recvToken) == 0 { - break - } - } - - return nil -} - -func (l *Conn) saslBindTokenExchange(reqControls []Control, reqToken []byte) ([]byte, error) { - // Construct LDAP Bind request with GSSAPI SASL mechanism. - envelope := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") - envelope.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, "GSSAPI", "SASL Mech")) - if len(reqToken) > 0 { - auth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, string(reqToken), "Credentials")) - } - request.AppendChild(auth) - envelope.AppendChild(request) - if len(reqControls) > 0 { - envelope.AppendChild(encodeControls(reqControls)) - } - - msgCtx, err := l.sendMessage(envelope) - 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) - } - - // https://www.rfc-editor.org/rfc/rfc4511#section-4.1.1 - // packet is an envelope - // child 0 is message id - // child 1 is protocolOp - if len(packet.Children) != 2 { - return nil, fmt.Errorf("bad bind response") - } - - protocolOp := packet.Children[1] -RESP: - switch protocolOp.Description { - case "Bind Response": // Bind Response - // Bind Reponse is an LDAP Response (https://www.rfc-editor.org/rfc/rfc4511#section-4.1.9) - // with an additional optional serverSaslCreds string (https://www.rfc-editor.org/rfc/rfc4511#section-4.2.2) - // child 0 is resultCode - resultCode := protocolOp.Children[0] - if resultCode.Tag != ber.TagEnumerated { - break RESP - } - switch resultCode.Value.(int64) { - case 14: // Sasl bind in progress - if len(protocolOp.Children) < 3 { - break RESP - } - referral := protocolOp.Children[3] - switch referral.Description { - case "Referral": - if referral.ClassType != ber.ClassContext || referral.Tag != ber.TagObjectDescriptor { - break RESP - } - return ioutil.ReadAll(referral.Data) - } - // Optional: - //if len(protocolOp.Children) == 4 { - // serverSaslCreds := protocolOp.Children[4] - //} - case 0: // Success - Bind OK. - // SASL layer in effect (if any) (See https://www.rfc-editor.org/rfc/rfc4513#section-5.2.1.4) - // NOTE: SASL security layers are not supported currently. - return nil, nil - } - } - - return nil, GetLDAPError(packet) -} diff --git a/vendor/github.com/go-ldap/ldap/v3/client.go b/vendor/github.com/go-ldap/ldap/v3/client.go index ed96e840..1fa4ad5a 100644 --- a/vendor/github.com/go-ldap/ldap/v3/client.go +++ b/vendor/github.com/go-ldap/ldap/v3/client.go @@ -1,7 +1,6 @@ package ldap import ( - "context" "crypto/tls" "time" ) @@ -10,18 +9,14 @@ import ( type Client interface { Start() StartTLS(*tls.Config) error - Close() error - GetLastError() error + Close() IsClosing() bool SetTimeout(time.Duration) - TLSConnectionState() (tls.ConnectionState, bool) Bind(username, password string) error UnauthenticatedBind(username string) error SimpleBind(*SimpleBindRequest) (*SimpleBindResult, error) ExternalBind() error - NTLMUnauthenticatedBind(domain, username string) error - Unbind() error Add(*AddRequest) error Del(*DelRequest) error @@ -33,9 +28,5 @@ type Client interface { PasswordModify(*PasswordModifyRequest) (*PasswordModifyResult, error) Search(*SearchRequest) (*SearchResult, error) - SearchAsync(ctx context.Context, searchRequest *SearchRequest, bufferSize int) Response SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error) - DirSync(searchRequest *SearchRequest, flags, maxAttrCount int64, cookie []byte) (*SearchResult, error) - DirSyncAsync(ctx context.Context, searchRequest *SearchRequest, bufferSize int, flags, maxAttrCount int64, cookie []byte) Response - Syncrepl(ctx context.Context, searchRequest *SearchRequest, bufferSize int, mode ControlSyncRequestMode, cookie []byte, reloadHint bool) Response } diff --git a/vendor/github.com/go-ldap/ldap/v3/compare.go b/vendor/github.com/go-ldap/ldap/v3/compare.go index a1cd760b..cd43e4c5 100644 --- a/vendor/github.com/go-ldap/ldap/v3/compare.go +++ b/vendor/github.com/go-ldap/ldap/v3/compare.go @@ -34,8 +34,7 @@ func (l *Conn) Compare(dn, attribute, value string) (bool, error) { msgCtx, err := l.doRequest(&CompareRequest{ DN: dn, Attribute: attribute, - Value: value, - }) + Value: value}) if err != nil { return false, err } diff --git a/vendor/github.com/go-ldap/ldap/v3/conn.go b/vendor/github.com/go-ldap/ldap/v3/conn.go index 6d083621..ae5e19af 100644 --- a/vendor/github.com/go-ldap/ldap/v3/conn.go +++ b/vendor/github.com/go-ldap/ldap/v3/conn.go @@ -2,10 +2,10 @@ package ldap import ( "bufio" - "context" "crypto/tls" "errors" "fmt" + "log" "net" "net/url" "sync" @@ -61,21 +61,13 @@ type messageContext struct { // sendResponse should only be called within the processMessages() loop which // is also responsible for closing the responses channel. -func (msgCtx *messageContext) sendResponse(packet *PacketResponse, timeout time.Duration) { - timeoutCtx := context.Background() - if timeout > 0 { - var cancelFunc context.CancelFunc - timeoutCtx, cancelFunc = context.WithTimeout(context.Background(), timeout) - defer cancelFunc() - } +func (msgCtx *messageContext) sendResponse(packet *PacketResponse) { select { case msgCtx.responses <- packet: // Successfully sent packet to message handler. case <-msgCtx.done: // The request handler is done and will not receive more // packets. - case <-timeoutCtx.Done(): - // The timeout was reached before the packet was sent. } } @@ -96,7 +88,6 @@ const ( type Conn struct { // requestTimeout is loaded atomically // so we need to ensure 64-bit alignment on 32-bit platforms. - // https://github.com/go-ldap/ldap/pull/199 requestTimeout int64 conn net.Conn isTLS bool @@ -111,8 +102,6 @@ type Conn struct { wgClose sync.WaitGroup outstandingRequests uint messageMutex sync.Mutex - - err error } var _ Client = &Conn{} @@ -130,31 +119,30 @@ type DialOpt func(*DialContext) // DialWithDialer updates net.Dialer in DialContext. func DialWithDialer(d *net.Dialer) DialOpt { return func(dc *DialContext) { - dc.dialer = d + dc.d = d } } // DialWithTLSConfig updates tls.Config in DialContext. func DialWithTLSConfig(tc *tls.Config) DialOpt { return func(dc *DialContext) { - dc.tlsConfig = tc + dc.tc = tc } } // DialWithTLSDialer is a wrapper for DialWithTLSConfig with the option to // specify a net.Dialer to for example define a timeout or a custom resolver. -// @deprecated Use DialWithDialer and DialWithTLSConfig instead func DialWithTLSDialer(tlsConfig *tls.Config, dialer *net.Dialer) DialOpt { return func(dc *DialContext) { - dc.tlsConfig = tlsConfig - dc.dialer = dialer + dc.tc = tlsConfig + dc.d = dialer } } // DialContext contains necessary parameters to dial the given ldap URL. type DialContext struct { - dialer *net.Dialer - tlsConfig *tls.Config + d *net.Dialer + tc *tls.Config } func (dc *DialContext) dial(u *url.URL) (net.Conn, error) { @@ -162,7 +150,7 @@ func (dc *DialContext) dial(u *url.URL) (net.Conn, error) { if u.Path == "" || u.Path == "/" { u.Path = "/var/run/slapd/ldapi" } - return dc.dialer.Dial("unix", u.Path) + return dc.d.Dial("unix", u.Path) } host, port, err := net.SplitHostPort(u.Host) @@ -173,21 +161,16 @@ func (dc *DialContext) dial(u *url.URL) (net.Conn, error) { } switch u.Scheme { - case "cldap": - if port == "" { - port = DefaultLdapPort - } - return dc.dialer.Dial("udp", net.JoinHostPort(host, port)) case "ldap": if port == "" { port = DefaultLdapPort } - return dc.dialer.Dial("tcp", net.JoinHostPort(host, port)) + return dc.d.Dial("tcp", net.JoinHostPort(host, port)) case "ldaps": if port == "" { port = DefaultLdapsPort } - return tls.DialWithDialer(dc.dialer, "tcp", net.JoinHostPort(host, port), dc.tlsConfig) + return tls.DialWithDialer(dc.d, "tcp", net.JoinHostPort(host, port), dc.tc) } return nil, fmt.Errorf("Unknown scheme '%s'", u.Scheme) @@ -220,8 +203,7 @@ func DialTLS(network, addr string, config *tls.Config) (*Conn, error) { } // DialURL connects to the given ldap URL. -// The following schemas are supported: ldap://, ldaps://, ldapi://, -// and cldap:// (RFC1798, deprecated but used by Active Directory). +// The following schemas are supported: ldap://, ldaps://, ldapi://. // On success a new Conn for the connection is returned. func DialURL(addr string, opts ...DialOpt) (*Conn, error) { u, err := url.Parse(addr) @@ -233,8 +215,8 @@ func DialURL(addr string, opts ...DialOpt) (*Conn, error) { for _, opt := range opts { opt(&dc) } - if dc.dialer == nil { - dc.dialer = &net.Dialer{Timeout: DefaultTimeout} + if dc.d == nil { + dc.d = &net.Dialer{Timeout: DefaultTimeout} } c, err := dc.dial(u) @@ -249,7 +231,7 @@ func DialURL(addr string, opts ...DialOpt) (*Conn, error) { // NewConn returns a new Conn using conn for network I/O. func NewConn(conn net.Conn, isTLS bool) *Conn { - l := &Conn{ + return &Conn{ conn: conn, chanConfirm: make(chan struct{}), chanMessageID: make(chan int64), @@ -258,12 +240,11 @@ func NewConn(conn net.Conn, isTLS bool) *Conn { requestTimeout: 0, isTLS: isTLS, } - l.wgClose.Add(1) - return l } // Start initializes goroutines to read responses and process messages func (l *Conn) Start() { + l.wgClose.Add(1) go l.reader() go l.processMessages() } @@ -279,45 +260,31 @@ func (l *Conn) setClosing() bool { } // Close closes the connection. -func (l *Conn) Close() (err error) { +func (l *Conn) Close() { l.messageMutex.Lock() defer l.messageMutex.Unlock() if l.setClosing() { l.Debug.Printf("Sending quit message and waiting for confirmation") l.chanMessage <- &messagePacket{Op: MessageQuit} - - timeoutCtx := context.Background() - if l.getTimeout() > 0 { - var cancelFunc context.CancelFunc - timeoutCtx, cancelFunc = context.WithTimeout(timeoutCtx, time.Duration(l.getTimeout())) - defer cancelFunc() - } - select { - case <-l.chanConfirm: - // Confirmation was received. - case <-timeoutCtx.Done(): - // The timeout was reached before confirmation was received. - } - + <-l.chanConfirm close(l.chanMessage) l.Debug.Printf("Closing network connection") - err = l.conn.Close() + if err := l.conn.Close(); err != nil { + log.Println(err) + } + l.wgClose.Done() } l.wgClose.Wait() - - return err } // SetTimeout sets the time after a request is sent that a MessageTimeout triggers func (l *Conn) SetTimeout(timeout time.Duration) { - atomic.StoreInt64(&l.requestTimeout, int64(timeout)) -} - -func (l *Conn) getTimeout() int64 { - return atomic.LoadInt64(&l.requestTimeout) + if timeout > 0 { + atomic.StoreInt64(&l.requestTimeout, int64(timeout)) + } } // Returns the next available messageID @@ -328,14 +295,6 @@ func (l *Conn) nextMessageID() int64 { return 0 } -// GetLastError returns the last recorded error from goroutines like processMessages and reader. -// Only the last recorded error will be returned. -func (l *Conn) GetLastError() error { - l.messageMutex.Lock() - defer l.messageMutex.Unlock() - return l.err -} - // StartTLS sends the command to start a TLS session and then creates a new TLS Client func (l *Conn) StartTLS(config *tls.Config) error { if l.isTLS { @@ -484,13 +443,13 @@ func (l *Conn) sendProcessMessage(message *messagePacket) bool { func (l *Conn) processMessages() { defer func() { if err := recover(); err != nil { - l.err = fmt.Errorf("ldap: recovered panic in processMessages: %v", err) + log.Printf("ldap: recovered panic in processMessages: %v", err) } for messageID, msgCtx := range l.messageContexts { // If we are closing due to an error, inform anyone who // is waiting about the error. if l.IsClosing() && l.closeErr.Load() != nil { - msgCtx.sendResponse(&PacketResponse{Error: l.closeErr.Load().(error)}, time.Duration(l.getTimeout())) + msgCtx.sendResponse(&PacketResponse{Error: l.closeErr.Load().(error)}) } l.Debug.Printf("Closing channel for MessageID %d", messageID) close(msgCtx.responses) @@ -518,7 +477,7 @@ func (l *Conn) processMessages() { _, err := l.conn.Write(buf) if err != nil { l.Debug.Printf("Error Sending Message: %s", err.Error()) - message.Context.sendResponse(&PacketResponse{Error: fmt.Errorf("unable to send request: %s", err)}, time.Duration(l.getTimeout())) + message.Context.sendResponse(&PacketResponse{Error: fmt.Errorf("unable to send request: %s", err)}) close(message.Context.responses) break } @@ -528,35 +487,28 @@ func (l *Conn) processMessages() { l.messageContexts[message.MessageID] = message.Context // Add timeout if defined - requestTimeout := l.getTimeout() + requestTimeout := time.Duration(atomic.LoadInt64(&l.requestTimeout)) if requestTimeout > 0 { go func() { - timer := time.NewTimer(time.Duration(requestTimeout)) defer func() { if err := recover(); err != nil { - l.err = fmt.Errorf("ldap: recovered panic in RequestTimeout: %v", err) + log.Printf("ldap: recovered panic in RequestTimeout: %v", err) } - - timer.Stop() }() - - select { - case <-timer.C: - timeoutMessage := &messagePacket{ - Op: MessageTimeout, - MessageID: message.MessageID, - } - l.sendProcessMessage(timeoutMessage) - case <-message.Context.done: + time.Sleep(requestTimeout) + timeoutMessage := &messagePacket{ + Op: MessageTimeout, + MessageID: message.MessageID, } + l.sendProcessMessage(timeoutMessage) }() } case MessageResponse: l.Debug.Printf("Receiving message %d", message.MessageID) if msgCtx, ok := l.messageContexts[message.MessageID]; ok { - msgCtx.sendResponse(&PacketResponse{message.Packet, nil}, time.Duration(l.getTimeout())) + msgCtx.sendResponse(&PacketResponse{message.Packet, nil}) } else { - l.err = fmt.Errorf("ldap: received unexpected message %d, %v", message.MessageID, l.IsClosing()) + log.Printf("Received unexpected message %d, %v", message.MessageID, l.IsClosing()) l.Debug.PrintPacket(message.Packet) } case MessageTimeout: @@ -564,7 +516,7 @@ func (l *Conn) processMessages() { // All reads will return immediately if msgCtx, ok := l.messageContexts[message.MessageID]; ok { l.Debug.Printf("Receiving message timeout for %d", message.MessageID) - msgCtx.sendResponse(&PacketResponse{message.Packet, NewError(ErrorNetwork, errors.New("ldap: connection timed out"))}, time.Duration(l.getTimeout())) + msgCtx.sendResponse(&PacketResponse{message.Packet, NewError(ErrorNetwork, errors.New("ldap: connection timed out"))}) delete(l.messageContexts, message.MessageID) close(msgCtx.responses) } @@ -583,7 +535,7 @@ func (l *Conn) reader() { cleanstop := false defer func() { if err := recover(); err != nil { - l.err = fmt.Errorf("ldap: recovered panic in reader: %v", err) + log.Printf("ldap: recovered panic in reader: %v", err) } if !cleanstop { l.Close() diff --git a/vendor/github.com/go-ldap/ldap/v3/control.go b/vendor/github.com/go-ldap/ldap/v3/control.go index 60453deb..64fb002a 100644 --- a/vendor/github.com/go-ldap/ldap/v3/control.go +++ b/vendor/github.com/go-ldap/ldap/v3/control.go @@ -5,7 +5,6 @@ import ( "strconv" ber "github.com/go-asn1-ber/asn1-ber" - "github.com/google/uuid" ) const ( @@ -21,13 +20,6 @@ const ( ControlTypeManageDsaIT = "2.16.840.1.113730.3.4.2" // ControlTypeWhoAmI - https://tools.ietf.org/html/rfc4532 ControlTypeWhoAmI = "1.3.6.1.4.1.4203.1.11.3" - // ControlTypeSubtreeDelete - https://datatracker.ietf.org/doc/html/draft-armijo-ldap-treedelete-02 - ControlTypeSubtreeDelete = "1.2.840.113556.1.4.805" - - // ControlTypeServerSideSorting - https://www.ietf.org/rfc/rfc2891.txt - ControlTypeServerSideSorting = "1.2.840.113556.1.4.473" - // ControlTypeServerSideSorting - https://www.ietf.org/rfc/rfc2891.txt - ControlTypeServerSideSortingResult = "1.2.840.113556.1.4.474" // ControlTypeMicrosoftNotification - https://msdn.microsoft.com/en-us/library/aa366983(v=vs.85).aspx ControlTypeMicrosoftNotification = "1.2.840.113556.1.4.528" @@ -35,43 +27,16 @@ const ( ControlTypeMicrosoftShowDeleted = "1.2.840.113556.1.4.417" // ControlTypeMicrosoftServerLinkTTL - https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/f4f523a8-abc0-4b3a-a471-6b2fef135481?redirectedfrom=MSDN ControlTypeMicrosoftServerLinkTTL = "1.2.840.113556.1.4.2309" - // ControlTypeDirSync - Active Directory DirSync - https://msdn.microsoft.com/en-us/library/aa366978(v=vs.85).aspx - ControlTypeDirSync = "1.2.840.113556.1.4.841" - - // ControlTypeSyncRequest - https://www.ietf.org/rfc/rfc4533.txt - ControlTypeSyncRequest = "1.3.6.1.4.1.4203.1.9.1.1" - // ControlTypeSyncState - https://www.ietf.org/rfc/rfc4533.txt - ControlTypeSyncState = "1.3.6.1.4.1.4203.1.9.1.2" - // ControlTypeSyncDone - https://www.ietf.org/rfc/rfc4533.txt - ControlTypeSyncDone = "1.3.6.1.4.1.4203.1.9.1.3" - // ControlTypeSyncInfo - https://www.ietf.org/rfc/rfc4533.txt - ControlTypeSyncInfo = "1.3.6.1.4.1.4203.1.9.1.4" -) - -// Flags for DirSync control -const ( - DirSyncIncrementalValues int64 = 2147483648 - DirSyncPublicDataOnly int64 = 8192 - DirSyncAncestorsFirstOrder int64 = 2048 - DirSyncObjectSecurity int64 = 1 ) // ControlTypeMap maps controls to text descriptions var ControlTypeMap = map[string]string{ - ControlTypePaging: "Paging", - ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft", - ControlTypeManageDsaIT: "Manage DSA IT", - ControlTypeSubtreeDelete: "Subtree Delete Control", - ControlTypeMicrosoftNotification: "Change Notification - Microsoft", - ControlTypeMicrosoftShowDeleted: "Show Deleted Objects - Microsoft", - ControlTypeMicrosoftServerLinkTTL: "Return TTL-DNs for link values with associated expiry times - Microsoft", - ControlTypeServerSideSorting: "Server Side Sorting Request - LDAP Control Extension for Server Side Sorting of Search Results (RFC2891)", - ControlTypeServerSideSortingResult: "Server Side Sorting Results - LDAP Control Extension for Server Side Sorting of Search Results (RFC2891)", - ControlTypeDirSync: "DirSync", - ControlTypeSyncRequest: "Sync Request", - ControlTypeSyncState: "Sync State", - ControlTypeSyncDone: "Sync Done", - ControlTypeSyncInfo: "Sync Info", + ControlTypePaging: "Paging", + ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft", + ControlTypeManageDsaIT: "Manage DSA IT", + ControlTypeMicrosoftNotification: "Change Notification - Microsoft", + ControlTypeMicrosoftShowDeleted: "Show Deleted Objects - Microsoft", + ControlTypeMicrosoftServerLinkTTL: "Return TTL-DNs for link values with associated expiry times - Microsoft", } // Control defines an interface controls provide to encode and describe themselves @@ -264,7 +229,7 @@ func (c *ControlManageDsaIT) GetControlType() string { // Encode returns the ber packet representation func (c *ControlManageDsaIT) Encode() *ber.Packet { - // FIXME + //FIXME packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control") packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeManageDsaIT, "Control Type ("+ControlTypeMap[ControlTypeManageDsaIT]+")")) if c.Criticality { @@ -404,13 +369,7 @@ func DecodeControl(packet *ber.Packet) (Control, error) { case 2: packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")" - if packet.Children[0].Value != nil { - ControlType = packet.Children[0].Value.(string) - } else if packet.Children[0].Data != nil { - ControlType = packet.Children[0].Data.String() - } else { - return nil, fmt.Errorf("not found where to get the control type") - } + ControlType = packet.Children[0].Value.(string) // Children[1] could be criticality or value (both are optional) // duck-type on whether this is a boolean @@ -477,18 +436,18 @@ func DecodeControl(packet *ber.Packet) (Control, error) { for _, child := range sequence.Children { if child.Tag == 0 { - // Warning + //Warning warningPacket := child.Children[0] val, err := ber.ParseInt64(warningPacket.Data.Bytes()) if err != nil { return nil, fmt.Errorf("failed to decode data bytes: %s", err) } if warningPacket.Tag == 0 { - // timeBeforeExpiration + //timeBeforeExpiration c.Expire = val warningPacket.Value = c.Expire } else if warningPacket.Tag == 1 { - // graceAuthNsRemaining + //graceAuthNsRemaining c.Grace = val warningPacket.Value = c.Grace } @@ -526,36 +485,6 @@ func DecodeControl(packet *ber.Packet) (Control, error) { return NewControlMicrosoftShowDeleted(), nil case ControlTypeMicrosoftServerLinkTTL: return NewControlMicrosoftServerLinkTTL(), nil - case ControlTypeSubtreeDelete: - return NewControlSubtreeDelete(), nil - case ControlTypeServerSideSorting: - return NewControlServerSideSorting(value) - case ControlTypeServerSideSortingResult: - return NewControlServerSideSortingResult(value) - case ControlTypeDirSync: - value.Description += " (DirSync)" - return NewResponseControlDirSync(value) - case ControlTypeSyncState: - value.Description += " (Sync State)" - valueChildren, err := ber.DecodePacketErr(value.Data.Bytes()) - if err != nil { - return nil, fmt.Errorf("failed to decode data bytes: %s", err) - } - return NewControlSyncState(valueChildren) - case ControlTypeSyncDone: - value.Description += " (Sync Done)" - valueChildren, err := ber.DecodePacketErr(value.Data.Bytes()) - if err != nil { - return nil, fmt.Errorf("failed to decode data bytes: %s", err) - } - return NewControlSyncDone(valueChildren) - case ControlTypeSyncInfo: - value.Description += " (Sync Info)" - valueChildren, err := ber.DecodePacketErr(value.Data.Bytes()) - if err != nil { - return nil, fmt.Errorf("failed to decode data bytes: %s", err) - } - return NewControlSyncInfo(valueChildren) default: c := new(ControlString) c.ControlType = ControlType @@ -590,35 +519,6 @@ func NewControlBeheraPasswordPolicy() *ControlBeheraPasswordPolicy { } } -// ControlSubtreeDelete implements the subtree delete control described in -// https://datatracker.ietf.org/doc/html/draft-armijo-ldap-treedelete-02 -type ControlSubtreeDelete struct{} - -// GetControlType returns the OID -func (c *ControlSubtreeDelete) GetControlType() string { - return ControlTypeSubtreeDelete -} - -// NewControlSubtreeDelete returns a ControlSubtreeDelete control. -func NewControlSubtreeDelete() *ControlSubtreeDelete { - return &ControlSubtreeDelete{} -} - -// Encode returns the ber packet representation -func (c *ControlSubtreeDelete) Encode() *ber.Packet { - packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control") - packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeSubtreeDelete, "Control Type ("+ControlTypeMap[ControlTypeSubtreeDelete]+")")) - - return packet -} - -func (c *ControlSubtreeDelete) String() string { - return fmt.Sprintf( - "Control Type: %s (%q)", - ControlTypeMap[ControlTypeSubtreeDelete], - ControlTypeSubtreeDelete) -} - func encodeControls(controls []Control) *ber.Packet { packet := ber.Encode(ber.ClassContext, ber.TypeConstructed, 0, nil, "Controls") for _, control := range controls { @@ -626,669 +526,3 @@ func encodeControls(controls []Control) *ber.Packet { } return packet } - -// ControlDirSync implements the control described in https://msdn.microsoft.com/en-us/library/aa366978(v=vs.85).aspx -type ControlDirSync struct { - Criticality bool - Flags int64 - MaxAttrCount int64 - Cookie []byte -} - -// @deprecated Use NewRequestControlDirSync instead -func NewControlDirSync(flags int64, maxAttrCount int64, cookie []byte) *ControlDirSync { - return NewRequestControlDirSync(flags, maxAttrCount, cookie) -} - -// NewRequestControlDirSync returns a dir sync control -func NewRequestControlDirSync( - flags int64, maxAttrCount int64, cookie []byte, -) *ControlDirSync { - return &ControlDirSync{ - Criticality: true, - Flags: flags, - MaxAttrCount: maxAttrCount, - Cookie: cookie, - } -} - -// NewResponseControlDirSync returns a dir sync control -func NewResponseControlDirSync(value *ber.Packet) (*ControlDirSync, error) { - if value.Value != nil { - valueChildren, err := ber.DecodePacketErr(value.Data.Bytes()) - if err != nil { - return nil, fmt.Errorf("failed to decode data bytes: %s", err) - } - value.Data.Truncate(0) - value.Value = nil - value.AppendChild(valueChildren) - } - child := value.Children[0] - if len(child.Children) != 3 { // also on initial creation, Cookie is an empty string - return nil, fmt.Errorf("invalid number of children in dirSync control") - } - child.Description = "DirSync Control Value" - child.Children[0].Description = "Flags" - child.Children[1].Description = "MaxAttrCount" - child.Children[2].Description = "Cookie" - - cookie := child.Children[2].Data.Bytes() - child.Children[2].Value = cookie - return &ControlDirSync{ - Criticality: true, - Flags: child.Children[0].Value.(int64), - MaxAttrCount: child.Children[1].Value.(int64), - Cookie: cookie, - }, nil -} - -// GetControlType returns the OID -func (c *ControlDirSync) GetControlType() string { - return ControlTypeDirSync -} - -// String returns a human-readable description -func (c *ControlDirSync) String() string { - return fmt.Sprintf( - "ControlType: %s (%q) Criticality: %t ControlValue: Flags: %d MaxAttrCount: %d", - ControlTypeMap[ControlTypeDirSync], - ControlTypeDirSync, - c.Criticality, - c.Flags, - c.MaxAttrCount, - ) -} - -// Encode returns the ber packet representation -func (c *ControlDirSync) Encode() *ber.Packet { - cookie := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "Cookie") - if len(c.Cookie) != 0 { - cookie.Value = c.Cookie - cookie.Data.Write(c.Cookie) - } - - packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control") - packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeDirSync, "Control Type ("+ControlTypeMap[ControlTypeDirSync]+")")) - packet.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.Criticality, "Criticality")) // must be true always - - val := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value (DirSync)") - seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "DirSync Control Value") - seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(c.Flags), "Flags")) - seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(c.MaxAttrCount), "MaxAttrCount")) - seq.AppendChild(cookie) - val.AppendChild(seq) - - packet.AppendChild(val) - return packet -} - -// SetCookie stores the given cookie in the dirSync control -func (c *ControlDirSync) SetCookie(cookie []byte) { - c.Cookie = cookie -} - -// ControlServerSideSorting - -type SortKey struct { - Reverse bool - AttributeType string - MatchingRule string -} - -type ControlServerSideSorting struct { - SortKeys []*SortKey -} - -func (c *ControlServerSideSorting) GetControlType() string { - return ControlTypeServerSideSorting -} - -func NewControlServerSideSorting(value *ber.Packet) (*ControlServerSideSorting, error) { - sortKeys := []*SortKey{} - - val := value.Children[1].Children - - if len(val) != 1 { - return nil, fmt.Errorf("no sequence value in packet") - } - - sequences := val[0].Children - - for i, sequence := range sequences { - sortKey := &SortKey{} - - if len(sequence.Children) < 2 { - return nil, fmt.Errorf("attributeType or matchingRule is missing from sequence %d", i) - } - - sortKey.AttributeType = sequence.Children[0].Value.(string) - sortKey.MatchingRule = sequence.Children[1].Value.(string) - - if len(sequence.Children) == 3 { - sortKey.Reverse = sequence.Children[2].Value.(bool) - } - - sortKeys = append(sortKeys, sortKey) - } - - return &ControlServerSideSorting{SortKeys: sortKeys}, nil -} - -func NewControlServerSideSortingWithSortKeys(sortKeys []*SortKey) *ControlServerSideSorting { - return &ControlServerSideSorting{SortKeys: sortKeys} -} - -func (c *ControlServerSideSorting) Encode() *ber.Packet { - packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control") - control := ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.GetControlType(), "Control Type") - - value := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value") - seqs := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "SortKeyList") - - for _, f := range c.SortKeys { - seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "") - - seq.AppendChild( - ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, f.AttributeType, "attributeType"), - ) - seq.AppendChild( - ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, f.MatchingRule, "orderingRule"), - ) - if f.Reverse { - seq.AppendChild( - ber.NewBoolean(ber.ClassContext, ber.TypePrimitive, 1, f.Reverse, "reverseOrder"), - ) - } - - seqs.AppendChild(seq) - } - - value.AppendChild(seqs) - - packet.AppendChild(control) - packet.AppendChild(value) - - return packet -} - -func (c *ControlServerSideSorting) String() string { - return fmt.Sprintf( - "Control Type: %s (%q) Criticality:%t %+v", - "Server Side Sorting", - c.GetControlType(), - false, - c.SortKeys, - ) -} - -// ControlServerSideSortingResponse - -const ( - ControlServerSideSortingCodeSuccess ControlServerSideSortingCode = 0 - ControlServerSideSortingCodeOperationsError ControlServerSideSortingCode = 1 - ControlServerSideSortingCodeTimeLimitExceeded ControlServerSideSortingCode = 2 - ControlServerSideSortingCodeStrongAuthRequired ControlServerSideSortingCode = 8 - ControlServerSideSortingCodeAdminLimitExceeded ControlServerSideSortingCode = 11 - ControlServerSideSortingCodeNoSuchAttribute ControlServerSideSortingCode = 16 - ControlServerSideSortingCodeInappropriateMatching ControlServerSideSortingCode = 18 - ControlServerSideSortingCodeInsufficientAccessRights ControlServerSideSortingCode = 50 - ControlServerSideSortingCodeBusy ControlServerSideSortingCode = 51 - ControlServerSideSortingCodeUnwillingToPerform ControlServerSideSortingCode = 53 - ControlServerSideSortingCodeOther ControlServerSideSortingCode = 80 -) - -var ControlServerSideSortingCodes = []ControlServerSideSortingCode{ - ControlServerSideSortingCodeSuccess, - ControlServerSideSortingCodeOperationsError, - ControlServerSideSortingCodeTimeLimitExceeded, - ControlServerSideSortingCodeStrongAuthRequired, - ControlServerSideSortingCodeAdminLimitExceeded, - ControlServerSideSortingCodeNoSuchAttribute, - ControlServerSideSortingCodeInappropriateMatching, - ControlServerSideSortingCodeInsufficientAccessRights, - ControlServerSideSortingCodeBusy, - ControlServerSideSortingCodeUnwillingToPerform, - ControlServerSideSortingCodeOther, -} - -type ControlServerSideSortingCode int64 - -// Valid test the code contained in the control against the ControlServerSideSortingCodes slice and return an error if the code is unknown. -func (c ControlServerSideSortingCode) Valid() error { - for _, validRet := range ControlServerSideSortingCodes { - if c == validRet { - return nil - } - } - return fmt.Errorf("unknown return code : %d", c) -} - -func NewControlServerSideSortingResult(pkt *ber.Packet) (*ControlServerSideSortingResult, error) { - control := &ControlServerSideSortingResult{} - - if pkt == nil || len(pkt.Children) == 0 { - return nil, fmt.Errorf("bad packet") - } - - codeInt, err := ber.ParseInt64(pkt.Children[0].Data.Bytes()) - if err != nil { - return nil, err - } - - code := ControlServerSideSortingCode(codeInt) - if err := code.Valid(); err != nil { - return nil, err - } - - return control, nil -} - -type ControlServerSideSortingResult struct { - Criticality bool - - Result ControlServerSideSortingCode - - // Not populated for now. I can't get openldap to send me this value, so I think this is specific to other directory server - // AttributeType string -} - -func (control *ControlServerSideSortingResult) GetControlType() string { - return ControlTypeServerSideSortingResult -} - -func (c *ControlServerSideSortingResult) Encode() *ber.Packet { - packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "SortResult sequence") - sortResult := ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, int64(c.Result), "SortResult") - packet.AppendChild(sortResult) - - return packet -} - -func (c *ControlServerSideSortingResult) String() string { - return fmt.Sprintf( - "Control Type: %s (%q) Criticality:%t ResultCode:%+v", - "Server Side Sorting Result", - c.GetControlType(), - c.Criticality, - c.Result, - ) -} - -// Mode for ControlTypeSyncRequest -type ControlSyncRequestMode int64 - -const ( - SyncRequestModeRefreshOnly ControlSyncRequestMode = 1 - SyncRequestModeRefreshAndPersist ControlSyncRequestMode = 3 -) - -// ControlSyncRequest implements the Sync Request Control described in https://www.ietf.org/rfc/rfc4533.txt -type ControlSyncRequest struct { - Criticality bool - Mode ControlSyncRequestMode - Cookie []byte - ReloadHint bool -} - -func NewControlSyncRequest( - mode ControlSyncRequestMode, cookie []byte, reloadHint bool, -) *ControlSyncRequest { - return &ControlSyncRequest{ - Criticality: true, - Mode: mode, - Cookie: cookie, - ReloadHint: reloadHint, - } -} - -// GetControlType returns the OID -func (c *ControlSyncRequest) GetControlType() string { - return ControlTypeSyncRequest -} - -// Encode encodes the control -func (c *ControlSyncRequest) Encode() *ber.Packet { - _mode := int64(c.Mode) - mode := ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, _mode, "Mode") - var cookie *ber.Packet - if len(c.Cookie) > 0 { - cookie = ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Cookie") - cookie.Value = c.Cookie - cookie.Data.Write(c.Cookie) - } - reloadHint := ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.ReloadHint, "Reload Hint") - - packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control") - packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeSyncRequest, "Control Type ("+ControlTypeMap[ControlTypeSyncRequest]+")")) - packet.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.Criticality, "Criticality")) - - val := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value (Sync Request)") - seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Sync Request Value") - seq.AppendChild(mode) - if cookie != nil { - seq.AppendChild(cookie) - } - seq.AppendChild(reloadHint) - val.AppendChild(seq) - - packet.AppendChild(val) - return packet -} - -// String returns a human-readable description -func (c *ControlSyncRequest) String() string { - return fmt.Sprintf( - "Control Type: %s (%q) Criticality: %t Mode: %d Cookie: %s ReloadHint: %t", - ControlTypeMap[ControlTypeSyncRequest], - ControlTypeSyncRequest, - c.Criticality, - c.Mode, - string(c.Cookie), - c.ReloadHint, - ) -} - -// State for ControlSyncState -type ControlSyncStateState int64 - -const ( - SyncStatePresent ControlSyncStateState = 0 - SyncStateAdd ControlSyncStateState = 1 - SyncStateModify ControlSyncStateState = 2 - SyncStateDelete ControlSyncStateState = 3 -) - -// ControlSyncState implements the Sync State Control described in https://www.ietf.org/rfc/rfc4533.txt -type ControlSyncState struct { - Criticality bool - State ControlSyncStateState - EntryUUID uuid.UUID - Cookie []byte -} - -func NewControlSyncState(pkt *ber.Packet) (*ControlSyncState, error) { - var ( - state ControlSyncStateState - entryUUID uuid.UUID - cookie []byte - err error - ) - switch len(pkt.Children) { - case 0, 1: - return nil, fmt.Errorf("at least two children are required: %d", len(pkt.Children)) - case 2: - state = ControlSyncStateState(pkt.Children[0].Value.(int64)) - entryUUID, err = uuid.FromBytes(pkt.Children[1].ByteValue) - if err != nil { - return nil, fmt.Errorf("failed to decode uuid: %w", err) - } - case 3: - state = ControlSyncStateState(pkt.Children[0].Value.(int64)) - entryUUID, err = uuid.FromBytes(pkt.Children[1].ByteValue) - if err != nil { - return nil, fmt.Errorf("failed to decode uuid: %w", err) - } - cookie = pkt.Children[2].ByteValue - } - return &ControlSyncState{ - Criticality: false, - State: state, - EntryUUID: entryUUID, - Cookie: cookie, - }, nil -} - -// GetControlType returns the OID -func (c *ControlSyncState) GetControlType() string { - return ControlTypeSyncState -} - -// Encode encodes the control -func (c *ControlSyncState) Encode() *ber.Packet { - return nil -} - -// String returns a human-readable description -func (c *ControlSyncState) String() string { - return fmt.Sprintf( - "Control Type: %s (%q) Criticality: %t State: %d EntryUUID: %s Cookie: %s", - ControlTypeMap[ControlTypeSyncState], - ControlTypeSyncState, - c.Criticality, - c.State, - c.EntryUUID.String(), - string(c.Cookie), - ) -} - -// ControlSyncDone implements the Sync Done Control described in https://www.ietf.org/rfc/rfc4533.txt -type ControlSyncDone struct { - Criticality bool - Cookie []byte - RefreshDeletes bool -} - -func NewControlSyncDone(pkt *ber.Packet) (*ControlSyncDone, error) { - var ( - cookie []byte - refreshDeletes bool - ) - switch len(pkt.Children) { - case 0: - // have nothing to do - case 1: - cookie = pkt.Children[0].ByteValue - case 2: - cookie = pkt.Children[0].ByteValue - refreshDeletes = pkt.Children[1].Value.(bool) - } - return &ControlSyncDone{ - Criticality: false, - Cookie: cookie, - RefreshDeletes: refreshDeletes, - }, nil -} - -// GetControlType returns the OID -func (c *ControlSyncDone) GetControlType() string { - return ControlTypeSyncDone -} - -// Encode encodes the control -func (c *ControlSyncDone) Encode() *ber.Packet { - return nil -} - -// String returns a human-readable description -func (c *ControlSyncDone) String() string { - return fmt.Sprintf( - "Control Type: %s (%q) Criticality: %t Cookie: %s RefreshDeletes: %t", - ControlTypeMap[ControlTypeSyncDone], - ControlTypeSyncDone, - c.Criticality, - string(c.Cookie), - c.RefreshDeletes, - ) -} - -// Tag For ControlSyncInfo -type ControlSyncInfoValue uint64 - -const ( - SyncInfoNewcookie ControlSyncInfoValue = 0 - SyncInfoRefreshDelete ControlSyncInfoValue = 1 - SyncInfoRefreshPresent ControlSyncInfoValue = 2 - SyncInfoSyncIdSet ControlSyncInfoValue = 3 -) - -// ControlSyncInfoNewCookie implements a part of syncInfoValue described in https://www.ietf.org/rfc/rfc4533.txt -type ControlSyncInfoNewCookie struct { - Cookie []byte -} - -// String returns a human-readable description -func (c *ControlSyncInfoNewCookie) String() string { - return fmt.Sprintf( - "NewCookie[Cookie: %s]", - string(c.Cookie), - ) -} - -// ControlSyncInfoRefreshDelete implements a part of syncInfoValue described in https://www.ietf.org/rfc/rfc4533.txt -type ControlSyncInfoRefreshDelete struct { - Cookie []byte - RefreshDone bool -} - -// String returns a human-readable description -func (c *ControlSyncInfoRefreshDelete) String() string { - return fmt.Sprintf( - "RefreshDelete[Cookie: %s RefreshDone: %t]", - string(c.Cookie), - c.RefreshDone, - ) -} - -// ControlSyncInfoRefreshPresent implements a part of syncInfoValue described in https://www.ietf.org/rfc/rfc4533.txt -type ControlSyncInfoRefreshPresent struct { - Cookie []byte - RefreshDone bool -} - -// String returns a human-readable description -func (c *ControlSyncInfoRefreshPresent) String() string { - return fmt.Sprintf( - "RefreshPresent[Cookie: %s RefreshDone: %t]", - string(c.Cookie), - c.RefreshDone, - ) -} - -// ControlSyncInfoSyncIdSet implements a part of syncInfoValue described in https://www.ietf.org/rfc/rfc4533.txt -type ControlSyncInfoSyncIdSet struct { - Cookie []byte - RefreshDeletes bool - SyncUUIDs []uuid.UUID -} - -// String returns a human-readable description -func (c *ControlSyncInfoSyncIdSet) String() string { - return fmt.Sprintf( - "SyncIdSet[Cookie: %s RefreshDeletes: %t SyncUUIDs: %v]", - string(c.Cookie), - c.RefreshDeletes, - c.SyncUUIDs, - ) -} - -// ControlSyncInfo implements the Sync Info Control described in https://www.ietf.org/rfc/rfc4533.txt -type ControlSyncInfo struct { - Criticality bool - Value ControlSyncInfoValue - NewCookie *ControlSyncInfoNewCookie - RefreshDelete *ControlSyncInfoRefreshDelete - RefreshPresent *ControlSyncInfoRefreshPresent - SyncIdSet *ControlSyncInfoSyncIdSet -} - -func NewControlSyncInfo(pkt *ber.Packet) (*ControlSyncInfo, error) { - var ( - cookie []byte - refreshDone = true - refreshDeletes bool - syncUUIDs []uuid.UUID - ) - c := &ControlSyncInfo{Criticality: false} - switch ControlSyncInfoValue(pkt.Identifier.Tag) { - case SyncInfoNewcookie: - c.Value = SyncInfoNewcookie - c.NewCookie = &ControlSyncInfoNewCookie{ - Cookie: pkt.ByteValue, - } - case SyncInfoRefreshDelete: - c.Value = SyncInfoRefreshDelete - switch len(pkt.Children) { - case 0: - // have nothing to do - case 1: - cookie = pkt.Children[0].ByteValue - case 2: - cookie = pkt.Children[0].ByteValue - refreshDone = pkt.Children[1].Value.(bool) - } - c.RefreshDelete = &ControlSyncInfoRefreshDelete{ - Cookie: cookie, - RefreshDone: refreshDone, - } - case SyncInfoRefreshPresent: - c.Value = SyncInfoRefreshPresent - switch len(pkt.Children) { - case 0: - // have nothing to do - case 1: - cookie = pkt.Children[0].ByteValue - case 2: - cookie = pkt.Children[0].ByteValue - refreshDone = pkt.Children[1].Value.(bool) - } - c.RefreshPresent = &ControlSyncInfoRefreshPresent{ - Cookie: cookie, - RefreshDone: refreshDone, - } - case SyncInfoSyncIdSet: - c.Value = SyncInfoSyncIdSet - switch len(pkt.Children) { - case 0: - // have nothing to do - case 1: - cookie = pkt.Children[0].ByteValue - case 2: - cookie = pkt.Children[0].ByteValue - refreshDeletes = pkt.Children[1].Value.(bool) - case 3: - cookie = pkt.Children[0].ByteValue - refreshDeletes = pkt.Children[1].Value.(bool) - syncUUIDs = make([]uuid.UUID, 0, len(pkt.Children[2].Children)) - for _, child := range pkt.Children[2].Children { - u, err := uuid.FromBytes(child.ByteValue) - if err != nil { - return nil, fmt.Errorf("failed to decode uuid: %w", err) - } - syncUUIDs = append(syncUUIDs, u) - } - } - c.SyncIdSet = &ControlSyncInfoSyncIdSet{ - Cookie: cookie, - RefreshDeletes: refreshDeletes, - SyncUUIDs: syncUUIDs, - } - default: - return nil, fmt.Errorf("unknown sync info value: %d", pkt.Identifier.Tag) - } - return c, nil -} - -// GetControlType returns the OID -func (c *ControlSyncInfo) GetControlType() string { - return ControlTypeSyncInfo -} - -// Encode encodes the control -func (c *ControlSyncInfo) Encode() *ber.Packet { - return nil -} - -// String returns a human-readable description -func (c *ControlSyncInfo) String() string { - return fmt.Sprintf( - "Control Type: %s (%q) Criticality: %t Value: %d %s %s %s %s", - ControlTypeMap[ControlTypeSyncInfo], - ControlTypeSyncInfo, - c.Criticality, - c.Value, - c.NewCookie, - c.RefreshDelete, - c.RefreshPresent, - c.SyncIdSet, - ) -} diff --git a/vendor/github.com/go-ldap/ldap/v3/debug.go b/vendor/github.com/go-ldap/ldap/v3/debug.go index 6f89b4a0..d0a8fc15 100644 --- a/vendor/github.com/go-ldap/ldap/v3/debug.go +++ b/vendor/github.com/go-ldap/ldap/v3/debug.go @@ -1,11 +1,13 @@ package ldap import ( + "log" + ber "github.com/go-asn1-ber/asn1-ber" ) // debugging type -// - has a Printf method to write the debug output +// - has a Printf method to write the debug output type debugging bool // Enable controls debugging mode. @@ -16,13 +18,13 @@ func (debug *debugging) Enable(b bool) { // Printf writes debug output. func (debug debugging) Printf(format string, args ...interface{}) { if debug { - logger.Printf(format, args...) + log.Printf(format, args...) } } // PrintPacket dumps a packet. func (debug debugging) PrintPacket(packet *ber.Packet) { if debug { - ber.WritePacket(logger.Writer(), packet) + ber.WritePacket(log.Writer(), packet) } } diff --git a/vendor/github.com/go-ldap/ldap/v3/del.go b/vendor/github.com/go-ldap/ldap/v3/del.go index 62306951..6e987267 100644 --- a/vendor/github.com/go-ldap/ldap/v3/del.go +++ b/vendor/github.com/go-ldap/ldap/v3/del.go @@ -1,7 +1,8 @@ package ldap import ( - "fmt" + "log" + ber "github.com/go-asn1-ber/asn1-ber" ) @@ -52,8 +53,7 @@ func (l *Conn) Del(delRequest *DelRequest) error { return err } } else { - return fmt.Errorf("ldap: unexpected response: %d", packet.Children[1].Tag) + log.Printf("Unexpected Response: %d", packet.Children[1].Tag) } - return nil } diff --git a/vendor/github.com/go-ldap/ldap/v3/dn.go b/vendor/github.com/go-ldap/ldap/v3/dn.go index 6b485308..2b4cede9 100644 --- a/vendor/github.com/go-ldap/ldap/v3/dn.go +++ b/vendor/github.com/go-ldap/ldap/v3/dn.go @@ -5,7 +5,6 @@ import ( enchex "encoding/hex" "errors" "fmt" - "sort" "strings" ber "github.com/go-asn1-ber/asn1-ber" @@ -19,95 +18,16 @@ type AttributeTypeAndValue struct { Value string } -// String returns a normalized string representation of this attribute type and -// value pair which is the a lowercased join of the Type and Value with a "=". -func (a *AttributeTypeAndValue) String() string { - return strings.ToLower(a.Type) + "=" + a.encodeValue() -} - -func (a *AttributeTypeAndValue) encodeValue() string { - // Normalize the value first. - // value := strings.ToLower(a.Value) - value := a.Value - - encodedBuf := bytes.Buffer{} - - escapeChar := func(c byte) { - encodedBuf.WriteByte('\\') - encodedBuf.WriteByte(c) - } - - escapeHex := func(c byte) { - encodedBuf.WriteByte('\\') - encodedBuf.WriteString(enchex.EncodeToString([]byte{c})) - } - - for i := 0; i < len(value); i++ { - char := value[i] - if i == 0 && char == ' ' || char == '#' { - // Special case leading space or number sign. - escapeChar(char) - continue - } - if i == len(value)-1 && char == ' ' { - // Special case trailing space. - escapeChar(char) - continue - } - - switch char { - case '"', '+', ',', ';', '<', '>', '\\': - // Each of these special characters must be escaped. - escapeChar(char) - continue - } - - if char < ' ' || char > '~' { - // All special character escapes are handled first - // above. All bytes less than ASCII SPACE and all bytes - // greater than ASCII TILDE must be hex-escaped. - escapeHex(char) - continue - } - - // Any other character does not require escaping. - encodedBuf.WriteByte(char) - } - - return encodedBuf.String() -} - // RelativeDN represents a relativeDistinguishedName from https://tools.ietf.org/html/rfc4514 type RelativeDN struct { Attributes []*AttributeTypeAndValue } -// String returns a normalized string representation of this relative DN which -// is the a join of all attributes (sorted in increasing order) with a "+". -func (r *RelativeDN) String() string { - attrs := make([]string, len(r.Attributes)) - for i := range r.Attributes { - attrs[i] = r.Attributes[i].String() - } - sort.Strings(attrs) - return strings.Join(attrs, "+") -} - // DN represents a distinguishedName from https://tools.ietf.org/html/rfc4514 type DN struct { RDNs []*RelativeDN } -// String returns a normalized string representation of this DN which is the -// join of all relative DNs with a ",". -func (d *DN) String() string { - rdns := make([]string, len(d.RDNs)) - for i := range d.RDNs { - rdns[i] = d.RDNs[i].String() - } - return strings.Join(rdns, ",") -} - // ParseDN returns a distinguishedName or an error. // The function respects https://tools.ietf.org/html/rfc4514 func ParseDN(str string) (*DN, error) { @@ -156,7 +76,7 @@ func ParseDN(str string) (*DN, error) { case char == '\\': unescapedTrailingSpaces = 0 escaping = true - case char == '=' && attribute.Type == "": + case char == '=': attribute.Type = stringFromBuffer() // Special case: If the first character in the value is # the // following data is BER encoded so we can just fast forward @@ -164,7 +84,7 @@ func ParseDN(str string) (*DN, error) { if len(str) > i+1 && str[i+1] == '#' { i += 2 index := strings.IndexAny(str[i:], ",+") - var data string + data := str if index > 0 { data = str[i : i+index] } else { @@ -181,7 +101,7 @@ func ParseDN(str string) (*DN, error) { buffer.WriteString(packet.Data.String()) i += len(data) - 1 } - case char == ',' || char == '+' || char == ';': + case char == ',' || char == '+': // We're done with this RDN or value, push it if len(attribute.Type) == 0 { return nil, errors.New("incomplete type, value pair") @@ -189,7 +109,7 @@ func ParseDN(str string) (*DN, error) { attribute.Value = stringFromBuffer() rdn.Attributes = append(rdn.Attributes, attribute) attribute = new(AttributeTypeAndValue) - if char == ',' || char == ';' { + if char == ',' { dn.RDNs = append(dn.RDNs, rdn) rdn = new(RelativeDN) rdn.Attributes = make([]*AttributeTypeAndValue, 0) @@ -286,7 +206,7 @@ func (a *AttributeTypeAndValue) Equal(other *AttributeTypeAndValue) bool { return strings.EqualFold(a.Type, other.Type) && a.Value == other.Value } -// EqualFold returns true if the DNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch). +// Equal returns true if the DNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch). // Returns true if they have the same number of relative distinguished names // and corresponding relative distinguished names (by position) are the same. // Case of the attribute type and value is not significant @@ -318,7 +238,7 @@ func (d *DN) AncestorOfFold(other *DN) bool { return true } -// EqualFold returns true if the RelativeDNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch). +// Equal returns true if the RelativeDNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch). // Case of the attribute type is not significant func (r *RelativeDN) EqualFold(other *RelativeDN) bool { if len(r.Attributes) != len(other.Attributes) { diff --git a/vendor/github.com/go-ldap/ldap/v3/error.go b/vendor/github.com/go-ldap/ldap/v3/error.go index 3c2559ef..3cdb7b31 100644 --- a/vendor/github.com/go-ldap/ldap/v3/error.go +++ b/vendor/github.com/go-ldap/ldap/v3/error.go @@ -192,8 +192,6 @@ func (e *Error) Error() string { return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error()) } -func (e *Error) Unwrap() error { return e.Err } - // GetLDAPError creates an Error out of a BER packet representing a LDAPResult // The return is an error object. It can be casted to a Error structure. // This function returns nil if resultCode in the LDAPResult sequence is success(0). @@ -208,21 +206,15 @@ func GetLDAPError(packet *ber.Packet) error { 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 ber.Type(response.Children[0].Tag) == ber.Type(ber.TagInteger) || ber.Type(response.Children[0].Tag) == ber.Type(ber.TagEnumerated) { - resultCode := uint16(response.Children[0].Value.(int64)) - if resultCode == 0 { // No error - return nil - } - - if ber.Type(response.Children[1].Tag) == ber.Type(ber.TagOctetString) && - ber.Type(response.Children[2].Tag) == ber.Type(ber.TagOctetString) { - return &Error{ - ResultCode: resultCode, - MatchedDN: response.Children[1].Value.(string), - Err: fmt.Errorf("%s", response.Children[2].Value.(string)), - Packet: packet, - } - } + resultCode := uint16(response.Children[0].Value.(int64)) + if resultCode == 0 { // No error + return nil + } + return &Error{ + ResultCode: resultCode, + MatchedDN: response.Children[1].Value.(string), + Err: fmt.Errorf("%s", response.Children[2].Value.(string)), + Packet: packet, } } } diff --git a/vendor/github.com/go-ldap/ldap/v3/filter.go b/vendor/github.com/go-ldap/ldap/v3/filter.go index db76210c..73505e79 100644 --- a/vendor/github.com/go-ldap/ldap/v3/filter.go +++ b/vendor/github.com/go-ldap/ldap/v3/filter.go @@ -396,7 +396,7 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) { case packet.Tag == FilterEqualityMatch && bytes.Equal(condition.Bytes(), _SymbolAny): packet = ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterPresent, attribute.String(), FilterMap[FilterPresent]) - case packet.Tag == FilterEqualityMatch && bytes.Contains(condition.Bytes(), _SymbolAny): + case packet.Tag == FilterEqualityMatch && bytes.Index(condition.Bytes(), _SymbolAny) > -1: packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute.String(), "Attribute")) packet.Tag = FilterSubstrings packet.Description = FilterMap[uint64(packet.Tag)] @@ -438,6 +438,7 @@ func compileFilter(filter string, pos int) (*ber.Packet, int, error) { // Convert from "ABC\xx\xx\xx" form to literal bytes for transport func decodeEscapedSymbols(src []byte) (string, error) { + var ( buffer bytes.Buffer offset int diff --git a/vendor/github.com/go-ldap/ldap/v3/ldap.go b/vendor/github.com/go-ldap/ldap/v3/ldap.go index 90837a77..7ae6dfe2 100644 --- a/vendor/github.com/go-ldap/ldap/v3/ldap.go +++ b/vendor/github.com/go-ldap/ldap/v3/ldap.go @@ -3,9 +3,7 @@ package ldap import ( "fmt" "io/ioutil" - "log" "os" - "strings" ber "github.com/go-asn1-ber/asn1-ber" ) @@ -32,7 +30,6 @@ const ( ApplicationSearchResultReference = 19 ApplicationExtendedRequest = 23 ApplicationExtendedResponse = 24 - ApplicationIntermediateResponse = 25 ) // ApplicationMap contains human readable descriptions of LDAP Application Codes @@ -57,7 +54,6 @@ var ApplicationMap = map[uint8]string{ ApplicationSearchResultReference: "Search Result Reference", ApplicationExtendedRequest: "Extended Request", ApplicationExtendedResponse: "Extended Response", - ApplicationIntermediateResponse: "Intermediate Response", } // Ldap Behera Password Policy Draft 10 (https://tools.ietf.org/html/draft-behera-ldap-password-policy-10) @@ -86,13 +82,6 @@ var BeheraPasswordPolicyErrorMap = map[int8]string{ BeheraPasswordInHistory: "New password is in list of old passwords", } -var logger = log.New(os.Stderr, "", log.LstdFlags) - -// Logger allows clients to override the default logger -func Logger(l *log.Logger) { - logger = l -} - // Adds descriptions to an LDAP Response packet for debugging func addLDAPDescriptions(packet *ber.Packet) (err error) { defer func() { @@ -232,18 +221,18 @@ func addControlDescriptions(packet *ber.Packet) error { sequence := value.Children[0] for _, child := range sequence.Children { if child.Tag == 0 { - // Warning + //Warning warningPacket := child.Children[0] val, err := ber.ParseInt64(warningPacket.Data.Bytes()) if err != nil { return fmt.Errorf("failed to decode data bytes: %s", err) } if warningPacket.Tag == 0 { - // timeBeforeExpiration + //timeBeforeExpiration value.Description += " (TimeBeforeExpiration)" warningPacket.Value = val } else if warningPacket.Tag == 1 { - // graceAuthNsRemaining + //graceAuthNsRemaining value.Description += " (GraceAuthNsRemaining)" warningPacket.Value = val } @@ -348,43 +337,3 @@ func EscapeFilter(filter string) string { } return string(buf) } - -// EscapeDN escapes distinguished names as described in RFC4514. Characters in the -// set `"+,;<>\` are escaped by prepending a backslash, which is also done for trailing -// spaces or a leading `#`. Null bytes are replaced with `\00`. -func EscapeDN(dn string) string { - if dn == "" { - return "" - } - - builder := strings.Builder{} - - for i, r := range dn { - // Escape leading and trailing spaces - if (i == 0 || i == len(dn)-1) && r == ' ' { - builder.WriteRune('\\') - builder.WriteRune(r) - continue - } - - // Escape leading '#' - if i == 0 && r == '#' { - builder.WriteRune('\\') - builder.WriteRune(r) - continue - } - - // Escape characters as defined in RFC4514 - switch r { - case '"', '+', ',', ';', '<', '>', '\\': - builder.WriteRune('\\') - builder.WriteRune(r) - case '\x00': // Null byte may not be escaped by a leading backslash - builder.WriteString("\\00") - default: - builder.WriteRune(r) - } - } - - return builder.String() -} diff --git a/vendor/github.com/go-ldap/ldap/v3/moddn.go b/vendor/github.com/go-ldap/ldap/v3/moddn.go index 84a6488e..71cdcd0b 100644 --- a/vendor/github.com/go-ldap/ldap/v3/moddn.go +++ b/vendor/github.com/go-ldap/ldap/v3/moddn.go @@ -1,7 +1,8 @@ package ldap import ( - "fmt" + "log" + ber "github.com/go-asn1-ber/asn1-ber" ) @@ -24,9 +25,7 @@ type ModifyDNRequest struct { // RDN of the given DN. // // A call like -// -// mdnReq := NewModifyDNRequest("uid=someone,dc=example,dc=org", "uid=newname", true, "") -// +// mdnReq := NewModifyDNRequest("uid=someone,dc=example,dc=org", "uid=newname", true, "") // will setup the request to just rename uid=someone,dc=example,dc=org to // uid=newname,dc=example,dc=org. func NewModifyDNRequest(dn string, rdn string, delOld bool, newSup string) *ModifyDNRequest { @@ -95,8 +94,7 @@ func (l *Conn) ModifyDN(m *ModifyDNRequest) error { return err } } else { - return fmt.Errorf("ldap: unexpected response: %d", packet.Children[1].Tag) + log.Printf("Unexpected Response: %d", packet.Children[1].Tag) } - return nil } diff --git a/vendor/github.com/go-ldap/ldap/v3/modify.go b/vendor/github.com/go-ldap/ldap/v3/modify.go index 0e501360..1821413d 100644 --- a/vendor/github.com/go-ldap/ldap/v3/modify.go +++ b/vendor/github.com/go-ldap/ldap/v3/modify.go @@ -2,7 +2,7 @@ package ldap import ( "errors" - "fmt" + "log" ber "github.com/go-asn1-ber/asn1-ber" ) @@ -127,9 +127,8 @@ func (l *Conn) Modify(modifyRequest *ModifyRequest) error { return err } } else { - return fmt.Errorf("ldap: unexpected response: %d", packet.Children[1].Tag) + log.Printf("Unexpected Response: %d", packet.Children[1].Tag) } - return nil } @@ -137,8 +136,6 @@ func (l *Conn) Modify(modifyRequest *ModifyRequest) error { type ModifyResult struct { // Controls are the returned controls Controls []Control - // Referral is the returned referral - Referral string } // ModifyWithResult performs the ModifyRequest and returns the result @@ -161,10 +158,9 @@ func (l *Conn) ModifyWithResult(modifyRequest *ModifyRequest) (*ModifyResult, er switch packet.Children[1].Tag { case ApplicationModifyResponse: - if err = GetLDAPError(packet); err != nil { - result.Referral = getReferral(err, packet) - - return result, err + err := GetLDAPError(packet) + if err != nil { + return nil, err } if len(packet.Children) == 3 { for _, child := range packet.Children[2].Children { diff --git a/vendor/github.com/go-ldap/ldap/v3/passwdmodify.go b/vendor/github.com/go-ldap/ldap/v3/passwdmodify.go index 72a2351a..62a11084 100644 --- a/vendor/github.com/go-ldap/ldap/v3/passwdmodify.go +++ b/vendor/github.com/go-ldap/ldap/v3/passwdmodify.go @@ -70,6 +70,7 @@ func (req *PasswordModifyRequest) appendTo(envelope *ber.Packet) error { // newPassword is the desired user's password. If empty the server can return // an error or generate a new password that will be available in the // PasswordModifyResult.GeneratedPassword +// func NewPasswordModifyRequest(userIdentity string, oldPassword string, newPassword string) *PasswordModifyRequest { return &PasswordModifyRequest{ UserIdentity: userIdentity, @@ -94,9 +95,15 @@ func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*Pa result := &PasswordModifyResult{} if packet.Children[1].Tag == ApplicationExtendedResponse { - if err = GetLDAPError(packet); err != nil { - result.Referral = getReferral(err, packet) - + err := GetLDAPError(packet) + if err != nil { + if IsErrorWithCode(err, LDAPResultReferral) { + for _, child := range packet.Children[1].Children { + if child.Tag == 3 { + result.Referral = child.Children[0].Value.(string) + } + } + } return result, err } } else { @@ -105,10 +112,10 @@ func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*Pa extendedResponse := packet.Children[1] for _, child := range extendedResponse.Children { - if child.Tag == ber.TagEmbeddedPDV { + if child.Tag == 11 { passwordModifyResponseValue := ber.DecodePacket(child.Data.Bytes()) if len(passwordModifyResponseValue.Children) == 1 { - if passwordModifyResponseValue.Children[0].Tag == ber.TagEOC { + if passwordModifyResponseValue.Children[0].Tag == 0 { result.GeneratedPassword = ber.DecodeString(passwordModifyResponseValue.Children[0].Data.Bytes()) } } diff --git a/vendor/github.com/go-ldap/ldap/v3/request.go b/vendor/github.com/go-ldap/ldap/v3/request.go index b64f232d..4ea31e90 100644 --- a/vendor/github.com/go-ldap/ldap/v3/request.go +++ b/vendor/github.com/go-ldap/ldap/v3/request.go @@ -9,8 +9,7 @@ import ( var ( errRespChanClosed = errors.New("ldap: response channel closed") errCouldNotRetMsg = errors.New("ldap: could not retrieve message") - // ErrNilConnection is returned if doRequest is called with a nil connection. - ErrNilConnection = errors.New("ldap: conn is nil, expected net.Conn") + ErrNilConnection = errors.New("ldap: conn is nil, expected net.Conn") ) type request interface { @@ -70,41 +69,3 @@ func (l *Conn) readPacket(msgCtx *messageContext) (*ber.Packet, error) { } return packet, nil } - -func getReferral(err error, packet *ber.Packet) (referral string) { - if !IsErrorWithCode(err, LDAPResultReferral) { - return "" - } - - if len(packet.Children) < 2 { - return "" - } - - // The packet Tag itself (of child 2) is generally a ber.TagObjectDescriptor with referrals however OpenLDAP - // seemingly returns a ber.Tag.GeneralizedTime. Every currently tested LDAP server which returns referrals returns - // an ASN.1 BER packet with the Type of ber.TypeConstructed and Class of ber.ClassApplication however. Thus this - // check expressly checks these fields instead. - // - // Related Issues: - // - https://github.com/authelia/authelia/issues/4199 (downstream) - if len(packet.Children[1].Children) == 0 || (packet.Children[1].TagType != ber.TypeConstructed || packet.Children[1].ClassType != ber.ClassApplication) { - return "" - } - - var ok bool - - for _, child := range packet.Children[1].Children { - // The referral URI itself should be contained within a child which has a Tag of ber.BitString or - // ber.TagPrintableString, and the Type of ber.TypeConstructed and the Class of ClassContext. As soon as any of - // these conditions is not true we can skip this child. - if (child.Tag != ber.TagBitString && child.Tag != ber.TagPrintableString) || child.TagType != ber.TypeConstructed || child.ClassType != ber.ClassContext { - continue - } - - if referral, ok = child.Children[0].Value.(string); ok { - return referral - } - } - - return "" -} diff --git a/vendor/github.com/go-ldap/ldap/v3/response.go b/vendor/github.com/go-ldap/ldap/v3/response.go deleted file mode 100644 index 1abe02a3..00000000 --- a/vendor/github.com/go-ldap/ldap/v3/response.go +++ /dev/null @@ -1,207 +0,0 @@ -package ldap - -import ( - "context" - "errors" - "fmt" - - ber "github.com/go-asn1-ber/asn1-ber" -) - -// Response defines an interface to get data from an LDAP server -type Response interface { - Entry() *Entry - Referral() string - Controls() []Control - Err() error - Next() bool -} - -type searchResponse struct { - conn *Conn - ch chan *SearchSingleResult - - entry *Entry - referral string - controls []Control - err error -} - -// Entry returns an entry from the given search request -func (r *searchResponse) Entry() *Entry { - return r.entry -} - -// Referral returns a referral from the given search request -func (r *searchResponse) Referral() string { - return r.referral -} - -// Controls returns controls from the given search request -func (r *searchResponse) Controls() []Control { - return r.controls -} - -// Err returns an error when the given search request was failed -func (r *searchResponse) Err() error { - return r.err -} - -// Next returns whether next data exist or not -func (r *searchResponse) Next() bool { - res, ok := <-r.ch - if !ok { - return false - } - if res == nil { - return false - } - r.err = res.Error - if r.err != nil { - return false - } - r.entry = res.Entry - r.referral = res.Referral - r.controls = res.Controls - return true -} - -func (r *searchResponse) start(ctx context.Context, searchRequest *SearchRequest) { - go func() { - defer func() { - close(r.ch) - if err := recover(); err != nil { - r.conn.err = fmt.Errorf("ldap: recovered panic in searchResponse: %v", err) - } - }() - - if r.conn.IsClosing() { - return - } - - packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") - packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, r.conn.nextMessageID(), "MessageID")) - // encode search request - err := searchRequest.appendTo(packet) - if err != nil { - r.ch <- &SearchSingleResult{Error: err} - return - } - r.conn.Debug.PrintPacket(packet) - - msgCtx, err := r.conn.sendMessage(packet) - if err != nil { - r.ch <- &SearchSingleResult{Error: err} - return - } - defer r.conn.finishMessage(msgCtx) - - foundSearchSingleResultDone := false - for !foundSearchSingleResultDone { - select { - case <-ctx.Done(): - r.conn.Debug.Printf("%d: %s", msgCtx.id, ctx.Err().Error()) - return - default: - r.conn.Debug.Printf("%d: waiting for response", msgCtx.id) - packetResponse, ok := <-msgCtx.responses - if !ok { - err := NewError(ErrorNetwork, errors.New("ldap: response channel closed")) - r.ch <- &SearchSingleResult{Error: err} - return - } - packet, err = packetResponse.ReadPacket() - r.conn.Debug.Printf("%d: got response %p", msgCtx.id, packet) - if err != nil { - r.ch <- &SearchSingleResult{Error: err} - return - } - - if r.conn.Debug { - if err := addLDAPDescriptions(packet); err != nil { - r.ch <- &SearchSingleResult{Error: err} - return - } - ber.PrintPacket(packet) - } - - switch packet.Children[1].Tag { - case ApplicationSearchResultEntry: - result := &SearchSingleResult{ - Entry: &Entry{ - DN: packet.Children[1].Children[0].Value.(string), - Attributes: unpackAttributes(packet.Children[1].Children[1].Children), - }, - } - if len(packet.Children) != 3 { - r.ch <- result - continue - } - decoded, err := DecodeControl(packet.Children[2].Children[0]) - if err != nil { - werr := fmt.Errorf("failed to decode search result entry: %w", err) - result.Error = werr - r.ch <- result - return - } - result.Controls = append(result.Controls, decoded) - r.ch <- result - - case ApplicationSearchResultDone: - if err := GetLDAPError(packet); err != nil { - r.ch <- &SearchSingleResult{Error: err} - return - } - if len(packet.Children) == 3 { - result := &SearchSingleResult{} - for _, child := range packet.Children[2].Children { - decodedChild, err := DecodeControl(child) - if err != nil { - werr := fmt.Errorf("failed to decode child control: %w", err) - r.ch <- &SearchSingleResult{Error: werr} - return - } - result.Controls = append(result.Controls, decodedChild) - } - r.ch <- result - } - foundSearchSingleResultDone = true - - case ApplicationSearchResultReference: - ref := packet.Children[1].Children[0].Value.(string) - r.ch <- &SearchSingleResult{Referral: ref} - - case ApplicationIntermediateResponse: - decoded, err := DecodeControl(packet.Children[1]) - if err != nil { - werr := fmt.Errorf("failed to decode intermediate response: %w", err) - r.ch <- &SearchSingleResult{Error: werr} - return - } - result := &SearchSingleResult{} - result.Controls = append(result.Controls, decoded) - r.ch <- result - - default: - err := fmt.Errorf("unknown tag: %d", packet.Children[1].Tag) - r.ch <- &SearchSingleResult{Error: err} - return - } - } - } - r.conn.Debug.Printf("%d: returning", msgCtx.id) - }() -} - -func newSearchResponse(conn *Conn, bufferSize int) *searchResponse { - var ch chan *SearchSingleResult - if bufferSize > 0 { - ch = make(chan *SearchSingleResult, bufferSize) - } else { - ch = make(chan *SearchSingleResult) - } - return &searchResponse{ - conn: conn, - ch: ch, - } -} diff --git a/vendor/github.com/go-ldap/ldap/v3/search.go b/vendor/github.com/go-ldap/ldap/v3/search.go index 4eb10762..915e4203 100644 --- a/vendor/github.com/go-ldap/ldap/v3/search.go +++ b/vendor/github.com/go-ldap/ldap/v3/search.go @@ -1,14 +1,10 @@ package ldap import ( - "context" "errors" "fmt" - "reflect" "sort" - "strconv" "strings" - "time" ber "github.com/go-asn1-ber/asn1-ber" ) @@ -165,155 +161,6 @@ func (e *Entry) PrettyPrint(indent int) { } } -// Describe the tag to use for struct field tags -const decoderTagName = "ldap" - -// readTag will read the reflect.StructField value for -// the key defined in decoderTagName. If omitempty is -// specified, the field may not be filled. -func readTag(f reflect.StructField) (string, bool) { - val, ok := f.Tag.Lookup(decoderTagName) - if !ok { - return f.Name, false - } - opts := strings.Split(val, ",") - omit := false - if len(opts) == 2 { - omit = opts[1] == "omitempty" - } - return opts[0], omit -} - -// Unmarshal parses the Entry in the value pointed to by i -// -// Currently, this methods only supports struct fields of type -// string, []string, int, int64, []byte, *DN, []*DN or time.Time. Other field types -// will not be regarded. If the field type is a string or int but multiple -// attribute values are returned, the first value will be used to fill the field. -// -// Example: -// -// type UserEntry struct { -// // Fields with the tag key `dn` are automatically filled with the -// // objects distinguishedName. This can be used multiple times. -// DN string `ldap:"dn"` -// -// // This field will be filled with the attribute value for -// // userPrincipalName. An attribute can be read into a struct field -// // multiple times. Missing attributes will not result in an error. -// UserPrincipalName string `ldap:"userPrincipalName"` -// -// // memberOf may have multiple values. If you don't -// // know the amount of attribute values at runtime, use a string array. -// MemberOf []string `ldap:"memberOf"` -// -// // ID is an integer value, it will fail unmarshaling when the given -// // attribute value cannot be parsed into an integer. -// ID int `ldap:"id"` -// -// // LongID is similar to ID but uses an int64 instead. -// LongID int64 `ldap:"longId"` -// -// // Data is similar to MemberOf a slice containing all attribute -// // values. -// Data []byte `ldap:"data"` -// -// // Time is parsed with the generalizedTime spec into a time.Time -// Created time.Time `ldap:"createdTimestamp"` -// -// // *DN is parsed with the ParseDN -// Owner *ldap.DN `ldap:"owner"` -// -// // []*DN is parsed with the ParseDN -// Children []*ldap.DN `ldap:"children"` -// -// // This won't work, as the field is not of type string. For this -// // to work, you'll have to temporarily store the result in string -// // (or string array) and convert it to the desired type afterwards. -// UserAccountControl uint32 `ldap:"userPrincipalName"` -// } -// user := UserEntry{} -// -// if err := result.Unmarshal(&user); err != nil { -// // ... -// } -func (e *Entry) Unmarshal(i interface{}) (err error) { - // Make sure it's a ptr - if vo := reflect.ValueOf(i).Kind(); vo != reflect.Ptr { - return fmt.Errorf("ldap: cannot use %s, expected pointer to a struct", vo) - } - - sv, st := reflect.ValueOf(i).Elem(), reflect.TypeOf(i).Elem() - // Make sure it's pointing to a struct - if sv.Kind() != reflect.Struct { - return fmt.Errorf("ldap: expected pointer to a struct, got %s", sv.Kind()) - } - - for n := 0; n < st.NumField(); n++ { - // Holds struct field value and type - fv, ft := sv.Field(n), st.Field(n) - - // skip unexported fields - if ft.PkgPath != "" { - continue - } - - // omitempty can be safely discarded, as it's not needed when unmarshalling - fieldTag, _ := readTag(ft) - - // Fill the field with the distinguishedName if the tag key is `dn` - if fieldTag == "dn" { - fv.SetString(e.DN) - continue - } - - values := e.GetAttributeValues(fieldTag) - if len(values) == 0 { - continue - } - - switch fv.Interface().(type) { - case []string: - for _, item := range values { - fv.Set(reflect.Append(fv, reflect.ValueOf(item))) - } - case string: - fv.SetString(values[0]) - case []byte: - fv.SetBytes([]byte(values[0])) - case int, int64: - intVal, err := strconv.ParseInt(values[0], 10, 64) - if err != nil { - return fmt.Errorf("ldap: could not parse value '%s' into int field", values[0]) - } - fv.SetInt(intVal) - case time.Time: - t, err := ber.ParseGeneralizedTime([]byte(values[0])) - if err != nil { - return fmt.Errorf("ldap: could not parse value '%s' into time.Time field", values[0]) - } - fv.Set(reflect.ValueOf(t)) - case *DN: - dn, err := ParseDN(values[0]) - if err != nil { - return fmt.Errorf("ldap: could not parse value '%s' into *ldap.DN field", values[0]) - } - fv.Set(reflect.ValueOf(dn)) - case []*DN: - for _, item := range values { - dn, err := ParseDN(item) - if err != nil { - return fmt.Errorf("ldap: could not parse value '%s' into *ldap.DN field", item) - } - fv.Set(reflect.Append(fv, reflect.ValueOf(dn))) - } - default: - return fmt.Errorf("ldap: expected field to be of type string, []string, int, int64, []byte, *DN, []*DN or time.Time, got %v", ft.Type) - } - } - return -} - // NewEntryAttribute returns a new EntryAttribute with the desired key-value pair func NewEntryAttribute(name string, values []string) *EntryAttribute { var bytes [][]byte @@ -371,35 +218,6 @@ func (s *SearchResult) PrettyPrint(indent int) { } } -// appendTo appends all entries of `s` to `r` -func (s *SearchResult) appendTo(r *SearchResult) { - r.Entries = append(r.Entries, s.Entries...) - r.Referrals = append(r.Referrals, s.Referrals...) - r.Controls = append(r.Controls, s.Controls...) -} - -// SearchSingleResult holds the server's single entry response to a search request -type SearchSingleResult struct { - // Entry is the returned entry - Entry *Entry - // Referral is the returned referral - Referral string - // Controls are the returned controls - Controls []Control - // Error is set when the search request was failed - Error error -} - -// Print outputs a human-readable description -func (s *SearchSingleResult) Print() { - s.Entry.Print() -} - -// PrettyPrint outputs a human-readable description with indenting -func (s *SearchSingleResult) PrettyPrint(indent int) { - s.Entry.PrettyPrint(indent) -} - // SearchRequest represents a search request to send to the server type SearchRequest struct { BaseDN string @@ -467,11 +285,10 @@ func NewSearchRequest( // SearchWithPaging accepts a search request and desired page size in order to execute LDAP queries to fulfill the // search request. All paged LDAP query responses will be buffered and the final result will be returned atomically. // The following four cases are possible given the arguments: -// - given SearchRequest missing a control of type ControlTypePaging: we will add one with the desired paging size -// - given SearchRequest contains a control of type ControlTypePaging that isn't actually a ControlPaging: fail without issuing any queries -// - given SearchRequest contains a control of type ControlTypePaging with pagingSize equal to the size requested: no change to the search request -// - given SearchRequest contains a control of type ControlTypePaging with pagingSize not equal to the size requested: fail without issuing any queries -// +// - given SearchRequest missing a control of type ControlTypePaging: we will add one with the desired paging size +// - given SearchRequest contains a control of type ControlTypePaging that isn't actually a ControlPaging: fail without issuing any queries +// - given SearchRequest contains a control of type ControlTypePaging with pagingSize equal to the size requested: no change to the search request +// - given SearchRequest contains a control of type ControlTypePaging with pagingSize not equal to the size requested: fail without issuing any queries // A requested pagingSize of 0 is interpreted as no limit by LDAP servers. func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error) { var pagingControl *ControlPaging @@ -494,19 +311,23 @@ func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) searchResult := new(SearchResult) for { result, err := l.Search(searchRequest) - if result != nil { - result.appendTo(searchResult) - } else { - if err == nil { - // We have to do this beautifulness in case something absolutely strange happens, which - // should only occur in case there is no packet, but also no error. - return searchResult, NewError(ErrorNetwork, errors.New("ldap: packet not received")) - } - } + l.Debug.Printf("Looking for Paging Control...") if err != nil { - // If an error occurred, all results that have been received so far will be returned return searchResult, err } + if result == nil { + return searchResult, NewError(ErrorNetwork, errors.New("ldap: packet not received")) + } + + for _, entry := range result.Entries { + searchResult.Entries = append(searchResult.Entries, entry) + } + for _, referral := range result.Referrals { + searchResult.Referrals = append(searchResult.Referrals, referral) + } + for _, control := range result.Controls { + searchResult.Controls = append(searchResult.Controls, control) + } l.Debug.Printf("Looking for Paging Control...") pagingResult := FindControl(result.Controls, ControlTypePaging) @@ -528,9 +349,7 @@ func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) if pagingControl != nil { l.Debug.Printf("Abandoning Paging...") pagingControl.PagingSize = 0 - if _, err := l.Search(searchRequest); err != nil { - return searchResult, err - } + l.Search(searchRequest) } return searchResult, nil @@ -547,8 +366,7 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) { result := &SearchResult{ Entries: make([]*Entry, 0), Referrals: make([]string, 0), - Controls: make([]Control, 0), - } + Controls: make([]Control, 0)} for { packet, err := l.readPacket(msgCtx) @@ -584,32 +402,6 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) { } } -// SearchAsync performs a search request and returns all search results asynchronously. -// This means you get all results until an error happens (or the search successfully finished), -// e.g. for size / time limited requests all are recieved until the limit is reached. -// To stop the search, call cancel function of the context. -func (l *Conn) SearchAsync( - ctx context.Context, searchRequest *SearchRequest, bufferSize int) Response { - r := newSearchResponse(l, bufferSize) - r.start(ctx, searchRequest) - return r -} - -// Syncrepl is a short name for LDAP Sync Replication engine that works on the -// consumer-side. This can perform a persistent search and returns an entry -// when the entry is updated on the server side. -// To stop the search, call cancel function of the context. -func (l *Conn) Syncrepl( - ctx context.Context, searchRequest *SearchRequest, bufferSize int, - mode ControlSyncRequestMode, cookie []byte, reloadHint bool, -) Response { - control := NewControlSyncRequest(mode, cookie, reloadHint) - searchRequest.Controls = append(searchRequest.Controls, control) - r := newSearchResponse(l, bufferSize) - r.start(ctx, searchRequest) - return r -} - // unpackAttributes will extract all given LDAP attributes and it's values // from the ber.Packet func unpackAttributes(children []*ber.Packet) []*EntryAttribute { @@ -633,58 +425,3 @@ func unpackAttributes(children []*ber.Packet) []*EntryAttribute { return entries } - -// DirSync does a Search with dirSync Control. -func (l *Conn) DirSync( - searchRequest *SearchRequest, flags int64, maxAttrCount int64, cookie []byte, -) (*SearchResult, error) { - control := FindControl(searchRequest.Controls, ControlTypeDirSync) - if control == nil { - c := NewRequestControlDirSync(flags, maxAttrCount, cookie) - searchRequest.Controls = append(searchRequest.Controls, c) - } else { - c := control.(*ControlDirSync) - if c.Flags != flags { - return nil, fmt.Errorf("flags given in search request (%d) conflicts with flags given in search call (%d)", c.Flags, flags) - } - if c.MaxAttrCount != maxAttrCount { - return nil, fmt.Errorf("MaxAttrCnt given in search request (%d) conflicts with maxAttrCount given in search call (%d)", c.MaxAttrCount, maxAttrCount) - } - } - searchResult, err := l.Search(searchRequest) - l.Debug.Printf("Looking for result...") - if err != nil { - return nil, err - } - if searchResult == nil { - return nil, NewError(ErrorNetwork, errors.New("ldap: packet not received")) - } - - l.Debug.Printf("Looking for DirSync Control...") - resultControl := FindControl(searchResult.Controls, ControlTypeDirSync) - if resultControl == nil { - l.Debug.Printf("Could not find dirSyncControl control. Breaking...") - return searchResult, nil - } - - cookie = resultControl.(*ControlDirSync).Cookie - if len(cookie) == 0 { - l.Debug.Printf("Could not find cookie. Breaking...") - return searchResult, nil - } - - return searchResult, nil -} - -// DirSyncDirSyncAsync performs a search request and returns all search results -// asynchronously. This is efficient when the server returns lots of entries. -func (l *Conn) DirSyncAsync( - ctx context.Context, searchRequest *SearchRequest, bufferSize int, - flags, maxAttrCount int64, cookie []byte, -) Response { - control := NewRequestControlDirSync(flags, maxAttrCount, cookie) - searchRequest.Controls = append(searchRequest.Controls, control) - r := newSearchResponse(l, bufferSize) - r.start(ctx, searchRequest) - return r -} diff --git a/vendor/github.com/go-ldap/ldap/v3/unbind.go b/vendor/github.com/go-ldap/ldap/v3/unbind.go index 10cf75c6..6c411cd1 100644 --- a/vendor/github.com/go-ldap/ldap/v3/unbind.go +++ b/vendor/github.com/go-ldap/ldap/v3/unbind.go @@ -6,7 +6,6 @@ import ( ber "github.com/go-asn1-ber/asn1-ber" ) -// ErrConnUnbound is returned when Unbind is called on an already closing connection. var ErrConnUnbound = NewError(ErrorNetwork, errors.New("ldap: connection is closed")) type unbindRequest struct{} diff --git a/vendor/github.com/google/uuid/CHANGELOG.md b/vendor/github.com/google/uuid/CHANGELOG.md deleted file mode 100644 index 2bd78667..00000000 --- a/vendor/github.com/google/uuid/CHANGELOG.md +++ /dev/null @@ -1,10 +0,0 @@ -# Changelog - -## [1.3.1](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) (2023-08-18) - - -### Bug Fixes - -* Use .EqualFold() to parse urn prefixed UUIDs ([#118](https://github.com/google/uuid/issues/118)) ([574e687](https://github.com/google/uuid/commit/574e6874943741fb99d41764c705173ada5293f0)) - -## Changelog diff --git a/vendor/github.com/google/uuid/CONTRIBUTING.md b/vendor/github.com/google/uuid/CONTRIBUTING.md deleted file mode 100644 index 55668887..00000000 --- a/vendor/github.com/google/uuid/CONTRIBUTING.md +++ /dev/null @@ -1,26 +0,0 @@ -# How to contribute - -We definitely welcome patches and contribution to this project! - -### Tips - -Commits must be formatted according to the [Conventional Commits Specification](https://www.conventionalcommits.org). - -Always try to include a test case! If it is not possible or not necessary, -please explain why in the pull request description. - -### Releasing - -Commits that would precipitate a SemVer change, as desrcibed in the Conventional -Commits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action) -to create a release candidate pull request. Once submitted, `release-please` -will create a release. - -For tips on how to work with `release-please`, see its documentation. - -### Legal requirements - -In order to protect both you and ourselves, you will need to sign the -[Contributor License Agreement](https://cla.developers.google.com/clas). - -You may have already signed it for other Google projects. diff --git a/vendor/github.com/google/uuid/CONTRIBUTORS b/vendor/github.com/google/uuid/CONTRIBUTORS deleted file mode 100644 index b4bb97f6..00000000 --- a/vendor/github.com/google/uuid/CONTRIBUTORS +++ /dev/null @@ -1,9 +0,0 @@ -Paul Borman -bmatsuo -shawnps -theory -jboverfelt -dsymonds -cd1 -wallclockbuilder -dansouza diff --git a/vendor/github.com/google/uuid/LICENSE b/vendor/github.com/google/uuid/LICENSE deleted file mode 100644 index 5dc68268..00000000 --- a/vendor/github.com/google/uuid/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009,2014 Google Inc. 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. diff --git a/vendor/github.com/google/uuid/README.md b/vendor/github.com/google/uuid/README.md deleted file mode 100644 index 3e9a6188..00000000 --- a/vendor/github.com/google/uuid/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# uuid -The uuid package generates and inspects UUIDs based on -[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) -and DCE 1.1: Authentication and Security Services. - -This package is based on the github.com/pborman/uuid package (previously named -code.google.com/p/go-uuid). It differs from these earlier packages in that -a UUID is a 16 byte array rather than a byte slice. One loss due to this -change is the ability to represent an invalid UUID (vs a NIL UUID). - -###### Install -```sh -go get github.com/google/uuid -``` - -###### Documentation -[![Go Reference](https://pkg.go.dev/badge/github.com/google/uuid.svg)](https://pkg.go.dev/github.com/google/uuid) - -Full `go doc` style documentation for the package can be viewed online without -installing this package by using the GoDoc site here: -http://pkg.go.dev/github.com/google/uuid diff --git a/vendor/github.com/google/uuid/dce.go b/vendor/github.com/google/uuid/dce.go deleted file mode 100644 index fa820b9d..00000000 --- a/vendor/github.com/google/uuid/dce.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "encoding/binary" - "fmt" - "os" -) - -// A Domain represents a Version 2 domain -type Domain byte - -// Domain constants for DCE Security (Version 2) UUIDs. -const ( - Person = Domain(0) - Group = Domain(1) - Org = Domain(2) -) - -// NewDCESecurity returns a DCE Security (Version 2) UUID. -// -// The domain should be one of Person, Group or Org. -// On a POSIX system the id should be the users UID for the Person -// domain and the users GID for the Group. The meaning of id for -// the domain Org or on non-POSIX systems is site defined. -// -// For a given domain/id pair the same token may be returned for up to -// 7 minutes and 10 seconds. -func NewDCESecurity(domain Domain, id uint32) (UUID, error) { - uuid, err := NewUUID() - if err == nil { - uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2 - uuid[9] = byte(domain) - binary.BigEndian.PutUint32(uuid[0:], id) - } - return uuid, err -} - -// NewDCEPerson returns a DCE Security (Version 2) UUID in the person -// domain with the id returned by os.Getuid. -// -// NewDCESecurity(Person, uint32(os.Getuid())) -func NewDCEPerson() (UUID, error) { - return NewDCESecurity(Person, uint32(os.Getuid())) -} - -// NewDCEGroup returns a DCE Security (Version 2) UUID in the group -// domain with the id returned by os.Getgid. -// -// NewDCESecurity(Group, uint32(os.Getgid())) -func NewDCEGroup() (UUID, error) { - return NewDCESecurity(Group, uint32(os.Getgid())) -} - -// Domain returns the domain for a Version 2 UUID. Domains are only defined -// for Version 2 UUIDs. -func (uuid UUID) Domain() Domain { - return Domain(uuid[9]) -} - -// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2 -// UUIDs. -func (uuid UUID) ID() uint32 { - return binary.BigEndian.Uint32(uuid[0:4]) -} - -func (d Domain) String() string { - switch d { - case Person: - return "Person" - case Group: - return "Group" - case Org: - return "Org" - } - return fmt.Sprintf("Domain%d", int(d)) -} diff --git a/vendor/github.com/google/uuid/doc.go b/vendor/github.com/google/uuid/doc.go deleted file mode 100644 index 5b8a4b9a..00000000 --- a/vendor/github.com/google/uuid/doc.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package uuid generates and inspects UUIDs. -// -// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security -// Services. -// -// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to -// maps or compared directly. -package uuid diff --git a/vendor/github.com/google/uuid/hash.go b/vendor/github.com/google/uuid/hash.go deleted file mode 100644 index b404f4be..00000000 --- a/vendor/github.com/google/uuid/hash.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "crypto/md5" - "crypto/sha1" - "hash" -) - -// Well known namespace IDs and UUIDs -var ( - NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) - NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) - NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) - NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) - Nil UUID // empty UUID, all zeros -) - -// NewHash returns a new UUID derived from the hash of space concatenated with -// data generated by h. The hash should be at least 16 byte in length. The -// first 16 bytes of the hash are used to form the UUID. The version of the -// UUID will be the lower 4 bits of version. NewHash is used to implement -// NewMD5 and NewSHA1. -func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { - h.Reset() - h.Write(space[:]) //nolint:errcheck - h.Write(data) //nolint:errcheck - s := h.Sum(nil) - var uuid UUID - copy(uuid[:], s) - uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) - uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant - return uuid -} - -// NewMD5 returns a new MD5 (Version 3) UUID based on the -// supplied name space and data. It is the same as calling: -// -// NewHash(md5.New(), space, data, 3) -func NewMD5(space UUID, data []byte) UUID { - return NewHash(md5.New(), space, data, 3) -} - -// NewSHA1 returns a new SHA1 (Version 5) UUID based on the -// supplied name space and data. It is the same as calling: -// -// NewHash(sha1.New(), space, data, 5) -func NewSHA1(space UUID, data []byte) UUID { - return NewHash(sha1.New(), space, data, 5) -} diff --git a/vendor/github.com/google/uuid/marshal.go b/vendor/github.com/google/uuid/marshal.go deleted file mode 100644 index 14bd3407..00000000 --- a/vendor/github.com/google/uuid/marshal.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import "fmt" - -// MarshalText implements encoding.TextMarshaler. -func (uuid UUID) MarshalText() ([]byte, error) { - var js [36]byte - encodeHex(js[:], uuid) - return js[:], nil -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (uuid *UUID) UnmarshalText(data []byte) error { - id, err := ParseBytes(data) - if err != nil { - return err - } - *uuid = id - return nil -} - -// MarshalBinary implements encoding.BinaryMarshaler. -func (uuid UUID) MarshalBinary() ([]byte, error) { - return uuid[:], nil -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler. -func (uuid *UUID) UnmarshalBinary(data []byte) error { - if len(data) != 16 { - return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) - } - copy(uuid[:], data) - return nil -} diff --git a/vendor/github.com/google/uuid/node.go b/vendor/github.com/google/uuid/node.go deleted file mode 100644 index d651a2b0..00000000 --- a/vendor/github.com/google/uuid/node.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "sync" -) - -var ( - nodeMu sync.Mutex - ifname string // name of interface being used - nodeID [6]byte // hardware for version 1 UUIDs - zeroID [6]byte // nodeID with only 0's -) - -// NodeInterface returns the name of the interface from which the NodeID was -// derived. The interface "user" is returned if the NodeID was set by -// SetNodeID. -func NodeInterface() string { - defer nodeMu.Unlock() - nodeMu.Lock() - return ifname -} - -// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. -// If name is "" then the first usable interface found will be used or a random -// Node ID will be generated. If a named interface cannot be found then false -// is returned. -// -// SetNodeInterface never fails when name is "". -func SetNodeInterface(name string) bool { - defer nodeMu.Unlock() - nodeMu.Lock() - return setNodeInterface(name) -} - -func setNodeInterface(name string) bool { - iname, addr := getHardwareInterface(name) // null implementation for js - if iname != "" && addr != nil { - ifname = iname - copy(nodeID[:], addr) - return true - } - - // We found no interfaces with a valid hardware address. If name - // does not specify a specific interface generate a random Node ID - // (section 4.1.6) - if name == "" { - ifname = "random" - randomBits(nodeID[:]) - return true - } - return false -} - -// NodeID returns a slice of a copy of the current Node ID, setting the Node ID -// if not already set. -func NodeID() []byte { - defer nodeMu.Unlock() - nodeMu.Lock() - if nodeID == zeroID { - setNodeInterface("") - } - nid := nodeID - return nid[:] -} - -// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes -// of id are used. If id is less than 6 bytes then false is returned and the -// Node ID is not set. -func SetNodeID(id []byte) bool { - if len(id) < 6 { - return false - } - defer nodeMu.Unlock() - nodeMu.Lock() - copy(nodeID[:], id) - ifname = "user" - return true -} - -// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is -// not valid. The NodeID is only well defined for version 1 and 2 UUIDs. -func (uuid UUID) NodeID() []byte { - var node [6]byte - copy(node[:], uuid[10:]) - return node[:] -} diff --git a/vendor/github.com/google/uuid/node_js.go b/vendor/github.com/google/uuid/node_js.go deleted file mode 100644 index b2a0bc87..00000000 --- a/vendor/github.com/google/uuid/node_js.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2017 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build js - -package uuid - -// getHardwareInterface returns nil values for the JS version of the code. -// This removes the "net" dependency, because it is not used in the browser. -// Using the "net" library inflates the size of the transpiled JS code by 673k bytes. -func getHardwareInterface(name string) (string, []byte) { return "", nil } diff --git a/vendor/github.com/google/uuid/node_net.go b/vendor/github.com/google/uuid/node_net.go deleted file mode 100644 index 0cbbcddb..00000000 --- a/vendor/github.com/google/uuid/node_net.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2017 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !js - -package uuid - -import "net" - -var interfaces []net.Interface // cached list of interfaces - -// getHardwareInterface returns the name and hardware address of interface name. -// If name is "" then the name and hardware address of one of the system's -// interfaces is returned. If no interfaces are found (name does not exist or -// there are no interfaces) then "", nil is returned. -// -// Only addresses of at least 6 bytes are returned. -func getHardwareInterface(name string) (string, []byte) { - if interfaces == nil { - var err error - interfaces, err = net.Interfaces() - if err != nil { - return "", nil - } - } - for _, ifs := range interfaces { - if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { - return ifs.Name, ifs.HardwareAddr - } - } - return "", nil -} diff --git a/vendor/github.com/google/uuid/null.go b/vendor/github.com/google/uuid/null.go deleted file mode 100644 index d7fcbf28..00000000 --- a/vendor/github.com/google/uuid/null.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2021 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "bytes" - "database/sql/driver" - "encoding/json" - "fmt" -) - -var jsonNull = []byte("null") - -// NullUUID represents a UUID that may be null. -// NullUUID implements the SQL driver.Scanner interface so -// it can be used as a scan destination: -// -// var u uuid.NullUUID -// err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&u) -// ... -// if u.Valid { -// // use u.UUID -// } else { -// // NULL value -// } -// -type NullUUID struct { - UUID UUID - Valid bool // Valid is true if UUID is not NULL -} - -// Scan implements the SQL driver.Scanner interface. -func (nu *NullUUID) Scan(value interface{}) error { - if value == nil { - nu.UUID, nu.Valid = Nil, false - return nil - } - - err := nu.UUID.Scan(value) - if err != nil { - nu.Valid = false - return err - } - - nu.Valid = true - return nil -} - -// Value implements the driver Valuer interface. -func (nu NullUUID) Value() (driver.Value, error) { - if !nu.Valid { - return nil, nil - } - // Delegate to UUID Value function - return nu.UUID.Value() -} - -// MarshalBinary implements encoding.BinaryMarshaler. -func (nu NullUUID) MarshalBinary() ([]byte, error) { - if nu.Valid { - return nu.UUID[:], nil - } - - return []byte(nil), nil -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler. -func (nu *NullUUID) UnmarshalBinary(data []byte) error { - if len(data) != 16 { - return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) - } - copy(nu.UUID[:], data) - nu.Valid = true - return nil -} - -// MarshalText implements encoding.TextMarshaler. -func (nu NullUUID) MarshalText() ([]byte, error) { - if nu.Valid { - return nu.UUID.MarshalText() - } - - return jsonNull, nil -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (nu *NullUUID) UnmarshalText(data []byte) error { - id, err := ParseBytes(data) - if err != nil { - nu.Valid = false - return err - } - nu.UUID = id - nu.Valid = true - return nil -} - -// MarshalJSON implements json.Marshaler. -func (nu NullUUID) MarshalJSON() ([]byte, error) { - if nu.Valid { - return json.Marshal(nu.UUID) - } - - return jsonNull, nil -} - -// UnmarshalJSON implements json.Unmarshaler. -func (nu *NullUUID) UnmarshalJSON(data []byte) error { - if bytes.Equal(data, jsonNull) { - *nu = NullUUID{} - return nil // valid null UUID - } - err := json.Unmarshal(data, &nu.UUID) - nu.Valid = err == nil - return err -} diff --git a/vendor/github.com/google/uuid/sql.go b/vendor/github.com/google/uuid/sql.go deleted file mode 100644 index 2e02ec06..00000000 --- a/vendor/github.com/google/uuid/sql.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "database/sql/driver" - "fmt" -) - -// Scan implements sql.Scanner so UUIDs can be read from databases transparently. -// Currently, database types that map to string and []byte are supported. Please -// consult database-specific driver documentation for matching types. -func (uuid *UUID) Scan(src interface{}) error { - switch src := src.(type) { - case nil: - return nil - - case string: - // if an empty UUID comes from a table, we return a null UUID - if src == "" { - return nil - } - - // see Parse for required string format - u, err := Parse(src) - if err != nil { - return fmt.Errorf("Scan: %v", err) - } - - *uuid = u - - case []byte: - // if an empty UUID comes from a table, we return a null UUID - if len(src) == 0 { - return nil - } - - // assumes a simple slice of bytes if 16 bytes - // otherwise attempts to parse - if len(src) != 16 { - return uuid.Scan(string(src)) - } - copy((*uuid)[:], src) - - default: - return fmt.Errorf("Scan: unable to scan type %T into UUID", src) - } - - return nil -} - -// Value implements sql.Valuer so that UUIDs can be written to databases -// transparently. Currently, UUIDs map to strings. Please consult -// database-specific driver documentation for matching types. -func (uuid UUID) Value() (driver.Value, error) { - return uuid.String(), nil -} diff --git a/vendor/github.com/google/uuid/time.go b/vendor/github.com/google/uuid/time.go deleted file mode 100644 index e6ef06cd..00000000 --- a/vendor/github.com/google/uuid/time.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "encoding/binary" - "sync" - "time" -) - -// A Time represents a time as the number of 100's of nanoseconds since 15 Oct -// 1582. -type Time int64 - -const ( - lillian = 2299160 // Julian day of 15 Oct 1582 - unix = 2440587 // Julian day of 1 Jan 1970 - epoch = unix - lillian // Days between epochs - g1582 = epoch * 86400 // seconds between epochs - g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs -) - -var ( - timeMu sync.Mutex - lasttime uint64 // last time we returned - clockSeq uint16 // clock sequence for this run - - timeNow = time.Now // for testing -) - -// UnixTime converts t the number of seconds and nanoseconds using the Unix -// epoch of 1 Jan 1970. -func (t Time) UnixTime() (sec, nsec int64) { - sec = int64(t - g1582ns100) - nsec = (sec % 10000000) * 100 - sec /= 10000000 - return sec, nsec -} - -// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and -// clock sequence as well as adjusting the clock sequence as needed. An error -// is returned if the current time cannot be determined. -func GetTime() (Time, uint16, error) { - defer timeMu.Unlock() - timeMu.Lock() - return getTime() -} - -func getTime() (Time, uint16, error) { - t := timeNow() - - // If we don't have a clock sequence already, set one. - if clockSeq == 0 { - setClockSequence(-1) - } - now := uint64(t.UnixNano()/100) + g1582ns100 - - // If time has gone backwards with this clock sequence then we - // increment the clock sequence - if now <= lasttime { - clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000 - } - lasttime = now - return Time(now), clockSeq, nil -} - -// ClockSequence returns the current clock sequence, generating one if not -// already set. The clock sequence is only used for Version 1 UUIDs. -// -// The uuid package does not use global static storage for the clock sequence or -// the last time a UUID was generated. Unless SetClockSequence is used, a new -// random clock sequence is generated the first time a clock sequence is -// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) -func ClockSequence() int { - defer timeMu.Unlock() - timeMu.Lock() - return clockSequence() -} - -func clockSequence() int { - if clockSeq == 0 { - setClockSequence(-1) - } - return int(clockSeq & 0x3fff) -} - -// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to -// -1 causes a new sequence to be generated. -func SetClockSequence(seq int) { - defer timeMu.Unlock() - timeMu.Lock() - setClockSequence(seq) -} - -func setClockSequence(seq int) { - if seq == -1 { - var b [2]byte - randomBits(b[:]) // clock sequence - seq = int(b[0])<<8 | int(b[1]) - } - oldSeq := clockSeq - clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant - if oldSeq != clockSeq { - lasttime = 0 - } -} - -// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in -// uuid. The time is only defined for version 1 and 2 UUIDs. -func (uuid UUID) Time() Time { - time := int64(binary.BigEndian.Uint32(uuid[0:4])) - time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 - time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 - return Time(time) -} - -// ClockSequence returns the clock sequence encoded in uuid. -// The clock sequence is only well defined for version 1 and 2 UUIDs. -func (uuid UUID) ClockSequence() int { - return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff -} diff --git a/vendor/github.com/google/uuid/util.go b/vendor/github.com/google/uuid/util.go deleted file mode 100644 index 5ea6c737..00000000 --- a/vendor/github.com/google/uuid/util.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "io" -) - -// randomBits completely fills slice b with random data. -func randomBits(b []byte) { - if _, err := io.ReadFull(rander, b); err != nil { - panic(err.Error()) // rand should never fail - } -} - -// xvalues returns the value of a byte as a hexadecimal digit or 255. -var xvalues = [256]byte{ - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -} - -// xtob converts hex characters x1 and x2 into a byte. -func xtob(x1, x2 byte) (byte, bool) { - b1 := xvalues[x1] - b2 := xvalues[x2] - return (b1 << 4) | b2, b1 != 255 && b2 != 255 -} diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go deleted file mode 100644 index a56138cc..00000000 --- a/vendor/github.com/google/uuid/uuid.go +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright 2018 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "bytes" - "crypto/rand" - "encoding/hex" - "errors" - "fmt" - "io" - "strings" - "sync" -) - -// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC -// 4122. -type UUID [16]byte - -// A Version represents a UUID's version. -type Version byte - -// A Variant represents a UUID's variant. -type Variant byte - -// Constants returned by Variant. -const ( - Invalid = Variant(iota) // Invalid UUID - RFC4122 // The variant specified in RFC4122 - Reserved // Reserved, NCS backward compatibility. - Microsoft // Reserved, Microsoft Corporation backward compatibility. - Future // Reserved for future definition. -) - -const randPoolSize = 16 * 16 - -var ( - rander = rand.Reader // random function - poolEnabled = false - poolMu sync.Mutex - poolPos = randPoolSize // protected with poolMu - pool [randPoolSize]byte // protected with poolMu -) - -type invalidLengthError struct{ len int } - -func (err invalidLengthError) Error() string { - return fmt.Sprintf("invalid UUID length: %d", err.len) -} - -// IsInvalidLengthError is matcher function for custom error invalidLengthError -func IsInvalidLengthError(err error) bool { - _, ok := err.(invalidLengthError) - return ok -} - -// Parse decodes s into a UUID or returns an error. Both the standard UUID -// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the -// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex -// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. -func Parse(s string) (UUID, error) { - var uuid UUID - switch len(s) { - // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - case 36: - - // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - case 36 + 9: - if !strings.EqualFold(s[:9], "urn:uuid:") { - return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) - } - s = s[9:] - - // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} - case 36 + 2: - s = s[1:] - - // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - case 32: - var ok bool - for i := range uuid { - uuid[i], ok = xtob(s[i*2], s[i*2+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - } - return uuid, nil - default: - return uuid, invalidLengthError{len(s)} - } - // s is now at least 36 bytes long - // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { - return uuid, errors.New("invalid UUID format") - } - for i, x := range [16]int{ - 0, 2, 4, 6, - 9, 11, - 14, 16, - 19, 21, - 24, 26, 28, 30, 32, 34, - } { - v, ok := xtob(s[x], s[x+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - uuid[i] = v - } - return uuid, nil -} - -// ParseBytes is like Parse, except it parses a byte slice instead of a string. -func ParseBytes(b []byte) (UUID, error) { - var uuid UUID - switch len(b) { - case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if !bytes.EqualFold(b[:9], []byte("urn:uuid:")) { - return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) - } - b = b[9:] - case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} - b = b[1:] - case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - var ok bool - for i := 0; i < 32; i += 2 { - uuid[i/2], ok = xtob(b[i], b[i+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - } - return uuid, nil - default: - return uuid, invalidLengthError{len(b)} - } - // s is now at least 36 bytes long - // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' { - return uuid, errors.New("invalid UUID format") - } - for i, x := range [16]int{ - 0, 2, 4, 6, - 9, 11, - 14, 16, - 19, 21, - 24, 26, 28, 30, 32, 34, - } { - v, ok := xtob(b[x], b[x+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - uuid[i] = v - } - return uuid, nil -} - -// MustParse is like Parse but panics if the string cannot be parsed. -// It simplifies safe initialization of global variables holding compiled UUIDs. -func MustParse(s string) UUID { - uuid, err := Parse(s) - if err != nil { - panic(`uuid: Parse(` + s + `): ` + err.Error()) - } - return uuid -} - -// FromBytes creates a new UUID from a byte slice. Returns an error if the slice -// does not have a length of 16. The bytes are copied from the slice. -func FromBytes(b []byte) (uuid UUID, err error) { - err = uuid.UnmarshalBinary(b) - return uuid, err -} - -// Must returns uuid if err is nil and panics otherwise. -func Must(uuid UUID, err error) UUID { - if err != nil { - panic(err) - } - return uuid -} - -// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -// , or "" if uuid is invalid. -func (uuid UUID) String() string { - var buf [36]byte - encodeHex(buf[:], uuid) - return string(buf[:]) -} - -// URN returns the RFC 2141 URN form of uuid, -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. -func (uuid UUID) URN() string { - var buf [36 + 9]byte - copy(buf[:], "urn:uuid:") - encodeHex(buf[9:], uuid) - return string(buf[:]) -} - -func encodeHex(dst []byte, uuid UUID) { - hex.Encode(dst, uuid[:4]) - dst[8] = '-' - hex.Encode(dst[9:13], uuid[4:6]) - dst[13] = '-' - hex.Encode(dst[14:18], uuid[6:8]) - dst[18] = '-' - hex.Encode(dst[19:23], uuid[8:10]) - dst[23] = '-' - hex.Encode(dst[24:], uuid[10:]) -} - -// Variant returns the variant encoded in uuid. -func (uuid UUID) Variant() Variant { - switch { - case (uuid[8] & 0xc0) == 0x80: - return RFC4122 - case (uuid[8] & 0xe0) == 0xc0: - return Microsoft - case (uuid[8] & 0xe0) == 0xe0: - return Future - default: - return Reserved - } -} - -// Version returns the version of uuid. -func (uuid UUID) Version() Version { - return Version(uuid[6] >> 4) -} - -func (v Version) String() string { - if v > 15 { - return fmt.Sprintf("BAD_VERSION_%d", v) - } - return fmt.Sprintf("VERSION_%d", v) -} - -func (v Variant) String() string { - switch v { - case RFC4122: - return "RFC4122" - case Reserved: - return "Reserved" - case Microsoft: - return "Microsoft" - case Future: - return "Future" - case Invalid: - return "Invalid" - } - return fmt.Sprintf("BadVariant%d", int(v)) -} - -// SetRand sets the random number generator to r, which implements io.Reader. -// If r.Read returns an error when the package requests random data then -// a panic will be issued. -// -// Calling SetRand with nil sets the random number generator to the default -// generator. -func SetRand(r io.Reader) { - if r == nil { - rander = rand.Reader - return - } - rander = r -} - -// EnableRandPool enables internal randomness pool used for Random -// (Version 4) UUID generation. The pool contains random bytes read from -// the random number generator on demand in batches. Enabling the pool -// may improve the UUID generation throughput significantly. -// -// Since the pool is stored on the Go heap, this feature may be a bad fit -// for security sensitive applications. -// -// Both EnableRandPool and DisableRandPool are not thread-safe and should -// only be called when there is no possibility that New or any other -// UUID Version 4 generation function will be called concurrently. -func EnableRandPool() { - poolEnabled = true -} - -// DisableRandPool disables the randomness pool if it was previously -// enabled with EnableRandPool. -// -// Both EnableRandPool and DisableRandPool are not thread-safe and should -// only be called when there is no possibility that New or any other -// UUID Version 4 generation function will be called concurrently. -func DisableRandPool() { - poolEnabled = false - defer poolMu.Unlock() - poolMu.Lock() - poolPos = randPoolSize -} diff --git a/vendor/github.com/google/uuid/version1.go b/vendor/github.com/google/uuid/version1.go deleted file mode 100644 index 46310962..00000000 --- a/vendor/github.com/google/uuid/version1.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "encoding/binary" -) - -// NewUUID returns a Version 1 UUID based on the current NodeID and clock -// sequence, and the current time. If the NodeID has not been set by SetNodeID -// or SetNodeInterface then it will be set automatically. If the NodeID cannot -// be set NewUUID returns nil. If clock sequence has not been set by -// SetClockSequence then it will be set automatically. If GetTime fails to -// return the current NewUUID returns nil and an error. -// -// In most cases, New should be used. -func NewUUID() (UUID, error) { - var uuid UUID - now, seq, err := GetTime() - if err != nil { - return uuid, err - } - - timeLow := uint32(now & 0xffffffff) - timeMid := uint16((now >> 32) & 0xffff) - timeHi := uint16((now >> 48) & 0x0fff) - timeHi |= 0x1000 // Version 1 - - binary.BigEndian.PutUint32(uuid[0:], timeLow) - binary.BigEndian.PutUint16(uuid[4:], timeMid) - binary.BigEndian.PutUint16(uuid[6:], timeHi) - binary.BigEndian.PutUint16(uuid[8:], seq) - - nodeMu.Lock() - if nodeID == zeroID { - setNodeInterface("") - } - copy(uuid[10:], nodeID[:]) - nodeMu.Unlock() - - return uuid, nil -} diff --git a/vendor/github.com/google/uuid/version4.go b/vendor/github.com/google/uuid/version4.go deleted file mode 100644 index 7697802e..00000000 --- a/vendor/github.com/google/uuid/version4.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import "io" - -// New creates a new random UUID or panics. New is equivalent to -// the expression -// -// uuid.Must(uuid.NewRandom()) -func New() UUID { - return Must(NewRandom()) -} - -// NewString creates a new random UUID and returns it as a string or panics. -// NewString is equivalent to the expression -// -// uuid.New().String() -func NewString() string { - return Must(NewRandom()).String() -} - -// NewRandom returns a Random (Version 4) UUID. -// -// The strength of the UUIDs is based on the strength of the crypto/rand -// package. -// -// Uses the randomness pool if it was enabled with EnableRandPool. -// -// A note about uniqueness derived from the UUID Wikipedia entry: -// -// Randomly generated UUIDs have 122 random bits. One's annual risk of being -// hit by a meteorite is estimated to be one chance in 17 billion, that -// means the probability is about 0.00000000006 (6 × 10−11), -// equivalent to the odds of creating a few tens of trillions of UUIDs in a -// year and having one duplicate. -func NewRandom() (UUID, error) { - if !poolEnabled { - return NewRandomFromReader(rander) - } - return newRandomFromPool() -} - -// NewRandomFromReader returns a UUID based on bytes read from a given io.Reader. -func NewRandomFromReader(r io.Reader) (UUID, error) { - var uuid UUID - _, err := io.ReadFull(r, uuid[:]) - if err != nil { - return Nil, err - } - uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 - uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 - return uuid, nil -} - -func newRandomFromPool() (UUID, error) { - var uuid UUID - poolMu.Lock() - if poolPos == randPoolSize { - _, err := io.ReadFull(rander, pool[:]) - if err != nil { - poolMu.Unlock() - return Nil, err - } - poolPos = 0 - } - copy(uuid[:], pool[poolPos:(poolPos+16)]) - poolPos += 16 - poolMu.Unlock() - - uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 - uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 - return uuid, nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 17bdd394..29e9836f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 +# github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c ## explicit github.com/Azure/go-ntlmssp # github.com/BurntSushi/toml v1.3.2 @@ -39,8 +39,8 @@ github.com/felixge/httpsnoop # github.com/go-asn1-ber/asn1-ber v1.5.5 ## explicit; go 1.13 github.com/go-asn1-ber/asn1-ber -# github.com/go-ldap/ldap/v3 v3.4.6 -## explicit; go 1.14 +# github.com/go-ldap/ldap/v3 v3.4.1 +## explicit; go 1.13 github.com/go-ldap/ldap/v3 # github.com/go-sql-driver/mysql v1.7.1 ## explicit; go 1.13 @@ -62,9 +62,6 @@ github.com/golang/glog/internal/stackdump # github.com/google/go-querystring v1.1.0 ## explicit; go 1.10 github.com/google/go-querystring/query -# github.com/google/uuid v1.3.1 -## explicit -github.com/google/uuid # github.com/gorilla/css v1.0.1 ## explicit; go 1.20 github.com/gorilla/css/scanner