From 701d1ab638b23c24877fc41824add66232446676 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Thu, 2 Feb 2017 09:32:00 -0500 Subject: Updating server dependancies (#5249) --- vendor/github.com/go-ldap/ldap/.travis.yml | 9 +- vendor/github.com/go-ldap/ldap/LICENSE | 43 ++++---- vendor/github.com/go-ldap/ldap/control.go | 12 +-- vendor/github.com/go-ldap/ldap/control_test.go | 39 +++++++ vendor/github.com/go-ldap/ldap/dn.go | 96 ++++++++++++++++- vendor/github.com/go-ldap/ldap/dn_test.go | 139 +++++++++++++++++++++++++ vendor/github.com/go-ldap/ldap/ldap.go | 55 +++++++--- 7 files changed, 344 insertions(+), 49 deletions(-) (limited to 'vendor/github.com/go-ldap') diff --git a/vendor/github.com/go-ldap/ldap/.travis.yml b/vendor/github.com/go-ldap/ldap/.travis.yml index 7e2f641e7..e32a2aa75 100644 --- a/vendor/github.com/go-ldap/ldap/.travis.yml +++ b/vendor/github.com/go-ldap/ldap/.travis.yml @@ -1,15 +1,20 @@ language: go env: global: - - VET_VERSIONS="1.5 1.6 tip" - - LINT_VERSIONS="1.5 1.6 tip" + - VET_VERSIONS="1.6 1.7 tip" + - LINT_VERSIONS="1.6 1.7 tip" go: - 1.2 - 1.3 - 1.4 - 1.5 - 1.6 + - 1.7 - tip +matrix: + fast_finish: true + allow_failures: + - go: tip go_import_path: gopkg.in/ldap.v2 install: - go get gopkg.in/asn1-ber.v1 diff --git a/vendor/github.com/go-ldap/ldap/LICENSE b/vendor/github.com/go-ldap/ldap/LICENSE index 744875676..6c0ed4b38 100644 --- a/vendor/github.com/go-ldap/ldap/LICENSE +++ b/vendor/github.com/go-ldap/ldap/LICENSE @@ -1,27 +1,22 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. +The MIT License (MIT) -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +Copyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com) +Portions copyright (c) 2015-2016 go-ldap Authors - * 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. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -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. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/go-ldap/ldap/control.go b/vendor/github.com/go-ldap/ldap/control.go index 5c62118d4..342f325ca 100644 --- a/vendor/github.com/go-ldap/ldap/control.go +++ b/vendor/github.com/go-ldap/ldap/control.go @@ -334,18 +334,18 @@ func DecodeControl(packet *ber.Packet) Control { for _, child := range sequence.Children { if child.Tag == 0 { //Warning - child := child.Children[0] - packet := ber.DecodePacket(child.Data.Bytes()) + warningPacket := child.Children[0] + packet := ber.DecodePacket(warningPacket.Data.Bytes()) val, ok := packet.Value.(int64) if ok { - if child.Tag == 0 { + if warningPacket.Tag == 0 { //timeBeforeExpiration c.Expire = val - child.Value = c.Expire - } else if child.Tag == 1 { + warningPacket.Value = c.Expire + } else if warningPacket.Tag == 1 { //graceAuthNsRemaining c.Grace = val - child.Value = c.Grace + warningPacket.Value = c.Grace } } } else if child.Tag == 1 { diff --git a/vendor/github.com/go-ldap/ldap/control_test.go b/vendor/github.com/go-ldap/ldap/control_test.go index 3fcdab0d7..11527463e 100644 --- a/vendor/github.com/go-ldap/ldap/control_test.go +++ b/vendor/github.com/go-ldap/ldap/control_test.go @@ -56,3 +56,42 @@ func runControlTest(t *testing.T, originalControl Control) { t.Errorf("%sgot different type decoding from encoded bytes: %T vs %T", header, fromBytes, originalControl) } } + +func TestDescribeControlManageDsaIT(t *testing.T) { + runAddControlDescriptions(t, NewControlManageDsaIT(false), "Control Type (Manage DSA IT)") + runAddControlDescriptions(t, NewControlManageDsaIT(true), "Control Type (Manage DSA IT)", "Criticality") +} + +func TestDescribeControlPaging(t *testing.T) { + runAddControlDescriptions(t, NewControlPaging(100), "Control Type (Paging)", "Control Value (Paging)") + runAddControlDescriptions(t, NewControlPaging(0), "Control Type (Paging)", "Control Value (Paging)") +} + +func TestDescribeControlString(t *testing.T) { + runAddControlDescriptions(t, NewControlString("x", true, "y"), "Control Type ()", "Criticality", "Control Value") + runAddControlDescriptions(t, NewControlString("x", true, ""), "Control Type ()", "Criticality", "Control Value") + runAddControlDescriptions(t, NewControlString("x", false, "y"), "Control Type ()", "Control Value") + runAddControlDescriptions(t, NewControlString("x", false, ""), "Control Type ()", "Control Value") +} + +func runAddControlDescriptions(t *testing.T, originalControl Control, childDescriptions ...string) { + header := "" + if callerpc, _, line, ok := runtime.Caller(1); ok { + if caller := runtime.FuncForPC(callerpc); caller != nil { + header = fmt.Sprintf("%s:%d: ", caller.Name(), line) + } + } + + encodedControls := encodeControls([]Control{originalControl}) + addControlDescriptions(encodedControls) + encodedPacket := encodedControls.Children[0] + if len(encodedPacket.Children) != len(childDescriptions) { + t.Errorf("%sinvalid number of children: %d != %d", header, len(encodedPacket.Children), len(childDescriptions)) + } + for i, desc := range childDescriptions { + if encodedPacket.Children[i].Description != desc { + t.Errorf("%sdescription not as expected: %s != %s", header, encodedPacket.Children[i].Description, desc) + } + } + +} diff --git a/vendor/github.com/go-ldap/ldap/dn.go b/vendor/github.com/go-ldap/ldap/dn.go index cc70c894c..a8ece3142 100644 --- a/vendor/github.com/go-ldap/ldap/dn.go +++ b/vendor/github.com/go-ldap/ldap/dn.go @@ -83,9 +83,19 @@ func ParseDN(str string) (*DN, error) { attribute := new(AttributeTypeAndValue) escaping := false + unescapedTrailingSpaces := 0 + stringFromBuffer := func() string { + s := buffer.String() + s = s[0 : len(s)-unescapedTrailingSpaces] + buffer.Reset() + unescapedTrailingSpaces = 0 + return s + } + for i := 0; i < len(str); i++ { char := str[i] if escaping { + unescapedTrailingSpaces = 0 escaping = false switch char { case ' ', '"', '#', '+', ',', ';', '<', '=', '>', '\\': @@ -107,10 +117,10 @@ func ParseDN(str string) (*DN, error) { buffer.WriteByte(dst[0]) i++ } else if char == '\\' { + unescapedTrailingSpaces = 0 escaping = true } else if char == '=' { - attribute.Type = buffer.String() - buffer.Reset() + 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 // and decode. @@ -133,7 +143,7 @@ func ParseDN(str string) (*DN, error) { } } else if char == ',' || char == '+' { // We're done with this RDN or value, push it - attribute.Value = buffer.String() + attribute.Value = stringFromBuffer() rdn.Attributes = append(rdn.Attributes, attribute) attribute = new(AttributeTypeAndValue) if char == ',' { @@ -141,8 +151,17 @@ func ParseDN(str string) (*DN, error) { rdn = new(RelativeDN) rdn.Attributes = make([]*AttributeTypeAndValue, 0) } - buffer.Reset() + } else if char == ' ' && buffer.Len() == 0 { + // ignore unescaped leading spaces + continue } else { + if char == ' ' { + // Track unescaped spaces in case they are trailing and we need to remove them + unescapedTrailingSpaces++ + } else { + // Reset if we see a non-space char + unescapedTrailingSpaces = 0 + } buffer.WriteByte(char) } } @@ -150,9 +169,76 @@ func ParseDN(str string) (*DN, error) { if len(attribute.Type) == 0 { return nil, errors.New("DN ended with incomplete type, value pair") } - attribute.Value = buffer.String() + attribute.Value = stringFromBuffer() rdn.Attributes = append(rdn.Attributes, attribute) dn.RDNs = append(dn.RDNs, rdn) } return dn, nil } + +// 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. +func (d *DN) Equal(other *DN) bool { + if len(d.RDNs) != len(other.RDNs) { + return false + } + for i := range d.RDNs { + if !d.RDNs[i].Equal(other.RDNs[i]) { + return false + } + } + return true +} + +// AncestorOf returns true if the other DN consists of at least one RDN followed by all the RDNs of the current DN. +// "ou=widgets,o=acme.com" is an ancestor of "ou=sprockets,ou=widgets,o=acme.com" +// "ou=widgets,o=acme.com" is not an ancestor of "ou=sprockets,ou=widgets,o=foo.com" +// "ou=widgets,o=acme.com" is not an ancestor of "ou=widgets,o=acme.com" +func (d *DN) AncestorOf(other *DN) bool { + if len(d.RDNs) >= len(other.RDNs) { + return false + } + // Take the last `len(d.RDNs)` RDNs from the other DN to compare against + otherRDNs := other.RDNs[len(other.RDNs)-len(d.RDNs):] + for i := range d.RDNs { + if !d.RDNs[i].Equal(otherRDNs[i]) { + return false + } + } + return true +} + +// Equal returns true if the RelativeDNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch). +// Relative distinguished names are the same if and only if they have the same number of AttributeTypeAndValues +// and each attribute of the first RDN is the same as the attribute of the second RDN with the same attribute type. +// The order of attributes is not significant. +// Case of attribute types is not significant. +func (r *RelativeDN) Equal(other *RelativeDN) bool { + if len(r.Attributes) != len(other.Attributes) { + return false + } + return r.hasAllAttributes(other.Attributes) && other.hasAllAttributes(r.Attributes) +} + +func (r *RelativeDN) hasAllAttributes(attrs []*AttributeTypeAndValue) bool { + for _, attr := range attrs { + found := false + for _, myattr := range r.Attributes { + if myattr.Equal(attr) { + found = true + break + } + } + if !found { + return false + } + } + return true +} + +// Equal returns true if the AttributeTypeAndValue is equivalent to the specified AttributeTypeAndValue +// Case of the attribute type is not significant +func (a *AttributeTypeAndValue) Equal(other *AttributeTypeAndValue) bool { + return strings.EqualFold(a.Type, other.Type) && a.Value == other.Value +} diff --git a/vendor/github.com/go-ldap/ldap/dn_test.go b/vendor/github.com/go-ldap/ldap/dn_test.go index 39817c427..5055cc15b 100644 --- a/vendor/github.com/go-ldap/ldap/dn_test.go +++ b/vendor/github.com/go-ldap/ldap/dn_test.go @@ -31,6 +31,22 @@ func TestSuccessfulDNParsing(t *testing.T) { &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "net"}}}}}, "CN=Lu\\C4\\8Di\\C4\\87": ldap.DN{[]*ldap.RelativeDN{ &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"CN", "Lučić"}}}}}, + " CN = Lu\\C4\\8Di\\C4\\87 ": ldap.DN{[]*ldap.RelativeDN{ + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"CN", "Lučić"}}}}}, + ` A = 1 , B = 2 `: ldap.DN{[]*ldap.RelativeDN{ + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"A", "1"}}}, + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"B", "2"}}}}}, + ` A = 1 + B = 2 `: ldap.DN{[]*ldap.RelativeDN{ + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{ + &ldap.AttributeTypeAndValue{"A", "1"}, + &ldap.AttributeTypeAndValue{"B", "2"}}}}}, + ` \ \ A\ \ = \ \ 1\ \ , \ \ B\ \ = \ \ 2\ \ `: ldap.DN{[]*ldap.RelativeDN{ + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{" A ", " 1 "}}}, + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{" B ", " 2 "}}}}}, + ` \ \ A\ \ = \ \ 1\ \ + \ \ B\ \ = \ \ 2\ \ `: ldap.DN{[]*ldap.RelativeDN{ + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{ + &ldap.AttributeTypeAndValue{" A ", " 1 "}, + &ldap.AttributeTypeAndValue{" B ", " 2 "}}}}}, } for test, answer := range testcases { @@ -41,6 +57,13 @@ func TestSuccessfulDNParsing(t *testing.T) { } if !reflect.DeepEqual(dn, &answer) { t.Errorf("Parsed DN %s is not equal to the expected structure", test) + t.Logf("Expected:") + for _, rdn := range answer.RDNs { + for _, attribs := range rdn.Attributes { + t.Logf("#%v\n", attribs) + } + } + t.Logf("Actual:") for _, rdn := range dn.RDNs { for _, attribs := range rdn.Attributes { t.Logf("#%v\n", attribs) @@ -68,3 +91,119 @@ func TestErrorDNParsing(t *testing.T) { } } } + +func TestDNEqual(t *testing.T) { + testcases := []struct { + A string + B string + Equal bool + }{ + // Exact match + {"", "", true}, + {"o=A", "o=A", true}, + {"o=A", "o=B", false}, + + {"o=A,o=B", "o=A,o=B", true}, + {"o=A,o=B", "o=A,o=C", false}, + + {"o=A+o=B", "o=A+o=B", true}, + {"o=A+o=B", "o=A+o=C", false}, + + // Case mismatch in type is ignored + {"o=A", "O=A", true}, + {"o=A,o=B", "o=A,O=B", true}, + {"o=A+o=B", "o=A+O=B", true}, + + // Case mismatch in value is significant + {"o=a", "O=A", false}, + {"o=a,o=B", "o=A,O=B", false}, + {"o=a+o=B", "o=A+O=B", false}, + + // Multi-valued RDN order mismatch is ignored + {"o=A+o=B", "O=B+o=A", true}, + // Number of RDN attributes is significant + {"o=A+o=B", "O=B+o=A+O=B", false}, + + // Missing values are significant + {"o=A+o=B", "O=B+o=A+O=C", false}, // missing values matter + {"o=A+o=B+o=C", "O=B+o=A", false}, // missing values matter + + // Whitespace tests + // Matching + { + "cn=John Doe, ou=People, dc=sun.com", + "cn=John Doe, ou=People, dc=sun.com", + true, + }, + // Difference in leading/trailing chars is ignored + { + "cn=John Doe, ou=People, dc=sun.com", + "cn=John Doe,ou=People,dc=sun.com", + true, + }, + // Difference in values is significant + { + "cn=John Doe, ou=People, dc=sun.com", + "cn=John Doe, ou=People, dc=sun.com", + false, + }, + } + + for i, tc := range testcases { + a, err := ldap.ParseDN(tc.A) + if err != nil { + t.Errorf("%d: %v", i, err) + continue + } + b, err := ldap.ParseDN(tc.B) + if err != nil { + t.Errorf("%d: %v", i, err) + continue + } + if expected, actual := tc.Equal, a.Equal(b); expected != actual { + t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual) + continue + } + if expected, actual := tc.Equal, b.Equal(a); expected != actual { + t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual) + continue + } + } +} + +func TestDNAncestor(t *testing.T) { + testcases := []struct { + A string + B string + Ancestor bool + }{ + // Exact match returns false + {"", "", false}, + {"o=A", "o=A", false}, + {"o=A,o=B", "o=A,o=B", false}, + {"o=A+o=B", "o=A+o=B", false}, + + // Mismatch + {"ou=C,ou=B,o=A", "ou=E,ou=D,ou=B,o=A", false}, + + // Descendant + {"ou=C,ou=B,o=A", "ou=E,ou=C,ou=B,o=A", true}, + } + + for i, tc := range testcases { + a, err := ldap.ParseDN(tc.A) + if err != nil { + t.Errorf("%d: %v", i, err) + continue + } + b, err := ldap.ParseDN(tc.B) + if err != nil { + t.Errorf("%d: %v", i, err) + continue + } + if expected, actual := tc.Ancestor, a.AncestorOf(b); expected != actual { + t.Errorf("%d: when comparing '%s' and '%s' expected %v, got %v", i, tc.A, tc.B, expected, actual) + continue + } + } +} diff --git a/vendor/github.com/go-ldap/ldap/ldap.go b/vendor/github.com/go-ldap/ldap/ldap.go index 90018be83..d27e639d0 100644 --- a/vendor/github.com/go-ldap/ldap/ldap.go +++ b/vendor/github.com/go-ldap/ldap/ldap.go @@ -153,16 +153,47 @@ func addLDAPDescriptions(packet *ber.Packet) (err error) { func addControlDescriptions(packet *ber.Packet) { packet.Description = "Controls" for _, child := range packet.Children { + var value *ber.Packet + controlType := "" child.Description = "Control" - child.Children[0].Description = "Control Type (" + ControlTypeMap[child.Children[0].Value.(string)] + ")" - value := child.Children[1] - if len(child.Children) == 3 { + switch len(child.Children) { + case 0: + // at least one child is required for control type + continue + + case 1: + // just type, no criticality or value + controlType = child.Children[0].Value.(string) + child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")" + + case 2: + controlType = child.Children[0].Value.(string) + child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")" + // Children[1] could be criticality or value (both are optional) + // duck-type on whether this is a boolean + if _, ok := child.Children[1].Value.(bool); ok { + child.Children[1].Description = "Criticality" + } else { + child.Children[1].Description = "Control Value" + value = child.Children[1] + } + + case 3: + // criticality and value present + controlType = child.Children[0].Value.(string) + child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")" child.Children[1].Description = "Criticality" + child.Children[2].Description = "Control Value" value = child.Children[2] - } - value.Description = "Control Value" - switch child.Children[0].Value.(string) { + default: + // more than 3 children is invalid + continue + } + if value == nil { + continue + } + switch controlType { case ControlTypePaging: value.Description += " (Paging)" if value.Value != nil { @@ -188,18 +219,18 @@ func addControlDescriptions(packet *ber.Packet) { for _, child := range sequence.Children { if child.Tag == 0 { //Warning - child := child.Children[0] - packet := ber.DecodePacket(child.Data.Bytes()) + warningPacket := child.Children[0] + packet := ber.DecodePacket(warningPacket.Data.Bytes()) val, ok := packet.Value.(int64) if ok { - if child.Tag == 0 { + if warningPacket.Tag == 0 { //timeBeforeExpiration value.Description += " (TimeBeforeExpiration)" - child.Value = val - } else if child.Tag == 1 { + warningPacket.Value = val + } else if warningPacket.Tag == 1 { //graceAuthNsRemaining value.Description += " (GraceAuthNsRemaining)" - child.Value = val + warningPacket.Value = val } } } else if child.Tag == 1 { -- cgit v1.2.3-1-g7c22