| 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 ldap
 
- import (
 
- 	"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
 
- 	}
 
- }
 
 
  |