| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 | // Copyright 2011 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package ldapimport (	"errors"	"fmt"	"github.com/gogits/gogs/modules/asn1-ber")const (	FilterAnd             = 0	FilterOr              = 1	FilterNot             = 2	FilterEqualityMatch   = 3	FilterSubstrings      = 4	FilterGreaterOrEqual  = 5	FilterLessOrEqual     = 6	FilterPresent         = 7	FilterApproxMatch     = 8	FilterExtensibleMatch = 9)var FilterMap = map[uint64]string{	FilterAnd:             "And",	FilterOr:              "Or",	FilterNot:             "Not",	FilterEqualityMatch:   "Equality Match",	FilterSubstrings:      "Substrings",	FilterGreaterOrEqual:  "Greater Or Equal",	FilterLessOrEqual:     "Less Or Equal",	FilterPresent:         "Present",	FilterApproxMatch:     "Approx Match",	FilterExtensibleMatch: "Extensible Match",}const (	FilterSubstringsInitial = 0	FilterSubstringsAny     = 1	FilterSubstringsFinal   = 2)var FilterSubstringsMap = map[uint64]string{	FilterSubstringsInitial: "Substrings Initial",	FilterSubstringsAny:     "Substrings Any",	FilterSubstringsFinal:   "Substrings Final",}func CompileFilter(filter string) (*ber.Packet, error) {	if len(filter) == 0 || filter[0] != '(' {		return nil, NewError(ErrorFilterCompile, errors.New("ldap: filter does not start with an '('"))	}	packet, pos, err := compileFilter(filter, 1)	if err != nil {		return nil, err	}	if pos != len(filter) {		return nil, NewError(ErrorFilterCompile, errors.New("ldap: finished compiling filter with extra at end: "+fmt.Sprint(filter[pos:])))	}	return packet, nil}func DecompileFilter(packet *ber.Packet) (ret string, err error) {	defer func() {		if r := recover(); r != nil {			err = NewError(ErrorFilterDecompile, errors.New("ldap: error decompiling filter"))		}	}()	ret = "("	err = nil	childStr := ""	switch packet.Tag {	case FilterAnd:		ret += "&"		for _, child := range packet.Children {			childStr, err = DecompileFilter(child)			if err != nil {				return			}			ret += childStr		}	case FilterOr:		ret += "|"		for _, child := range packet.Children {			childStr, err = DecompileFilter(child)			if err != nil {				return			}			ret += childStr		}	case FilterNot:		ret += "!"		childStr, err = DecompileFilter(packet.Children[0])		if err != nil {			return		}		ret += childStr	case FilterSubstrings:		ret += ber.DecodeString(packet.Children[0].Data.Bytes())		ret += "="		switch packet.Children[1].Children[0].Tag {		case FilterSubstringsInitial:			ret += ber.DecodeString(packet.Children[1].Children[0].Data.Bytes()) + "*"		case FilterSubstringsAny:			ret += "*" + ber.DecodeString(packet.Children[1].Children[0].Data.Bytes()) + "*"		case FilterSubstringsFinal:			ret += "*" + ber.DecodeString(packet.Children[1].Children[0].Data.Bytes())		}	case FilterEqualityMatch:		ret += ber.DecodeString(packet.Children[0].Data.Bytes())		ret += "="		ret += ber.DecodeString(packet.Children[1].Data.Bytes())	case FilterGreaterOrEqual:		ret += ber.DecodeString(packet.Children[0].Data.Bytes())		ret += ">="		ret += ber.DecodeString(packet.Children[1].Data.Bytes())	case FilterLessOrEqual:		ret += ber.DecodeString(packet.Children[0].Data.Bytes())		ret += "<="		ret += ber.DecodeString(packet.Children[1].Data.Bytes())	case FilterPresent:		ret += ber.DecodeString(packet.Children[0].Data.Bytes())		ret += "=*"	case FilterApproxMatch:		ret += ber.DecodeString(packet.Children[0].Data.Bytes())		ret += "~="		ret += ber.DecodeString(packet.Children[1].Data.Bytes())	}	ret += ")"	return}func compileFilterSet(filter string, pos int, parent *ber.Packet) (int, error) {	for pos < len(filter) && filter[pos] == '(' {		child, newPos, err := compileFilter(filter, pos+1)		if err != nil {			return pos, err		}		pos = newPos		parent.AppendChild(child)	}	if pos == len(filter) {		return pos, NewError(ErrorFilterCompile, errors.New("ldap: unexpected end of filter"))	}	return pos + 1, nil}func compileFilter(filter string, pos int) (*ber.Packet, int, error) {	var packet *ber.Packet	var err error	defer func() {		if r := recover(); r != nil {			err = NewError(ErrorFilterCompile, errors.New("ldap: error compiling filter"))		}	}()	newPos := pos	switch filter[pos] {	case '(':		packet, newPos, err = compileFilter(filter, pos+1)		newPos++		return packet, newPos, err	case '&':		packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterAnd, nil, FilterMap[FilterAnd])		newPos, err = compileFilterSet(filter, pos+1, packet)		return packet, newPos, err	case '|':		packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterOr, nil, FilterMap[FilterOr])		newPos, err = compileFilterSet(filter, pos+1, packet)		return packet, newPos, err	case '!':		packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterNot, nil, FilterMap[FilterNot])		var child *ber.Packet		child, newPos, err = compileFilter(filter, pos+1)		packet.AppendChild(child)		return packet, newPos, err	default:		attribute := ""		condition := ""		for newPos < len(filter) && filter[newPos] != ')' {			switch {			case packet != nil:				condition += fmt.Sprintf("%c", filter[newPos])			case filter[newPos] == '=':				packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterEqualityMatch, nil, FilterMap[FilterEqualityMatch])			case filter[newPos] == '>' && filter[newPos+1] == '=':				packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterGreaterOrEqual, nil, FilterMap[FilterGreaterOrEqual])				newPos++			case filter[newPos] == '<' && filter[newPos+1] == '=':				packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterLessOrEqual, nil, FilterMap[FilterLessOrEqual])				newPos++			case filter[newPos] == '~' && filter[newPos+1] == '=':				packet = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterApproxMatch, nil, FilterMap[FilterLessOrEqual])				newPos++			case packet == nil:				attribute += fmt.Sprintf("%c", filter[newPos])			}			newPos++		}		if newPos == len(filter) {			err = NewError(ErrorFilterCompile, errors.New("ldap: unexpected end of filter"))			return packet, newPos, err		}		if packet == nil {			err = NewError(ErrorFilterCompile, errors.New("ldap: error parsing filter"))			return packet, newPos, err		}		packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "Attribute"))		switch {		case packet.Tag == FilterEqualityMatch && condition == "*":			packet.Tag = FilterPresent			packet.Description = FilterMap[uint64(packet.Tag)]		case packet.Tag == FilterEqualityMatch && condition[0] == '*' && condition[len(condition)-1] == '*':			// Any			packet.Tag = FilterSubstrings			packet.Description = FilterMap[uint64(packet.Tag)]			seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings")			seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterSubstringsAny, condition[1:len(condition)-1], "Any Substring"))			packet.AppendChild(seq)		case packet.Tag == FilterEqualityMatch && condition[0] == '*':			// Final			packet.Tag = FilterSubstrings			packet.Description = FilterMap[uint64(packet.Tag)]			seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings")			seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterSubstringsFinal, condition[1:], "Final Substring"))			packet.AppendChild(seq)		case packet.Tag == FilterEqualityMatch && condition[len(condition)-1] == '*':			// Initial			packet.Tag = FilterSubstrings			packet.Description = FilterMap[uint64(packet.Tag)]			seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings")			seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, FilterSubstringsInitial, condition[:len(condition)-1], "Initial Substring"))			packet.AppendChild(seq)		default:			packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, condition, "Condition"))		}		newPos++		return packet, newPos, err	}}
 |