build(deps): bump github.com/go-ldap/ldap/v3 from 3.4.12 to 3.4.13
Bumps [github.com/go-ldap/ldap/v3](https://github.com/go-ldap/ldap) from 3.4.12 to 3.4.13. - [Release notes](https://github.com/go-ldap/ldap/releases) - [Commits](https://github.com/go-ldap/ldap/compare/v3.4.12...v3.4.13) --- updated-dependencies: - dependency-name: github.com/go-ldap/ldap/v3 dependency-version: 3.4.13 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
Ralf Haferkamp
parent
87a9660157
commit
9123e88f10
+11
-1
@@ -1,6 +1,7 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
@@ -880,7 +881,16 @@ func (c *ControlDirSync) Encode() *ber.Packet {
|
||||
|
||||
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"))
|
||||
|
||||
// Note: Active Directory expects a 4-byte unsigned integer for flags, but ASN.1 uses signed integers by default.
|
||||
// As a result, the BER encoder may encode flags as a 5-byte signed integer; we force 4-byte encoding here.
|
||||
flagsPacket := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, nil, "Flags")
|
||||
flagsPacket.Value = int64(c.Flags)
|
||||
flagsBytes := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(flagsBytes, uint32(c.Flags))
|
||||
flagsPacket.Data.Write(flagsBytes)
|
||||
seq.AppendChild(flagsPacket)
|
||||
|
||||
seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(c.MaxAttrCount), "MaxAttrCount"))
|
||||
seq.AppendChild(cookie)
|
||||
val.AppendChild(seq)
|
||||
|
||||
+7
@@ -210,6 +210,10 @@ func GetLDAPError(packet *ber.Packet) error {
|
||||
}
|
||||
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) {
|
||||
if response.Children[0].Value == nil {
|
||||
return &Error{ResultCode: ErrorNetwork, Err: fmt.Errorf("Invalid result code in packet"), Packet: packet}
|
||||
}
|
||||
|
||||
resultCode := uint16(response.Children[0].Value.(int64))
|
||||
if resultCode == 0 { // No error
|
||||
return nil
|
||||
@@ -217,6 +221,9 @@ func GetLDAPError(packet *ber.Packet) error {
|
||||
|
||||
if ber.Type(response.Children[1].Tag) == ber.Type(ber.TagOctetString) &&
|
||||
ber.Type(response.Children[2].Tag) == ber.Type(ber.TagOctetString) {
|
||||
if response.Children[1].Value == nil {
|
||||
return &Error{ResultCode: ErrorNetwork, Err: fmt.Errorf("Invalid matchedDN in packet"), Packet: packet}
|
||||
}
|
||||
return &Error{
|
||||
ResultCode: resultCode,
|
||||
MatchedDN: response.Children[1].Value.(string),
|
||||
|
||||
+12
-7
@@ -76,18 +76,27 @@ func (l *Conn) Extended(er *ExtendedRequest) (*ExtendedResponse, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(packet.Children[1].Children) < 4 {
|
||||
extResp := packet.Children[1]
|
||||
if len(extResp.Children) < 3 {
|
||||
return nil, fmt.Errorf(
|
||||
"ldap: malformed extended response: expected 4 children, got %d",
|
||||
"ldap: malformed extended response: expected at least 3 children, got %d",
|
||||
len(packet.Children),
|
||||
)
|
||||
}
|
||||
|
||||
response := &ExtendedResponse{
|
||||
Name: packet.Children[1].Children[3].Data.String(),
|
||||
Controls: make([]Control, 0),
|
||||
}
|
||||
|
||||
for _, child := range extResp.Children {
|
||||
switch child.Tag {
|
||||
case ber.TagEnumerated:
|
||||
response.Name = child.Data.String()
|
||||
case ber.TagEmbeddedPDV:
|
||||
response.Value = child
|
||||
}
|
||||
}
|
||||
|
||||
if len(packet.Children) == 3 {
|
||||
for _, child := range packet.Children[2].Children {
|
||||
decodedChild, decodeErr := DecodeControl(child)
|
||||
@@ -98,9 +107,5 @@ func (l *Conn) Extended(er *ExtendedRequest) (*ExtendedResponse, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if len(packet.Children[1].Children) == 5 {
|
||||
response.Value = packet.Children[1].Children[4]
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var ErrEmptyPostalAddress = errors.New("ldap: postal address cannot be empty")
|
||||
|
||||
// PostalAddress represents an RFC 4517 Postal Address
|
||||
// A postal address is a sequence of strings of one or more arbitrary UCS
|
||||
// characters, which form the lines of the address.
|
||||
type PostalAddress struct {
|
||||
lines []string
|
||||
}
|
||||
|
||||
// NewPostalAddress creates a new PostalAddress by copying non-empty lines from the provided slice of strings.
|
||||
func NewPostalAddress(lines []string) (*PostalAddress, error) {
|
||||
copiedLines := make([]string, 0, len(lines))
|
||||
for _, line := range lines {
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
copiedLines = append(copiedLines, line)
|
||||
}
|
||||
|
||||
if len(copiedLines) == 0 {
|
||||
return nil, ErrEmptyPostalAddress
|
||||
}
|
||||
|
||||
return &PostalAddress{lines: copiedLines}, nil
|
||||
}
|
||||
|
||||
// Lines returns a copy of the address lines as a slice of strings.
|
||||
func (p *PostalAddress) Lines() []string {
|
||||
copiedLines := make([]string, len(p.lines))
|
||||
copy(copiedLines, p.lines)
|
||||
return copiedLines
|
||||
}
|
||||
|
||||
// String returns the postal address as a single string, with lines joined by newline characters.
|
||||
func (p *PostalAddress) String() string {
|
||||
return strings.Join(p.lines, "\n")
|
||||
}
|
||||
|
||||
// Escape encodes special characters in the PostalAddress lines as per RFC 4517 and appends a `$` at the end of each line.
|
||||
func (p *PostalAddress) Escape() string {
|
||||
builder := &strings.Builder{}
|
||||
|
||||
for _, line := range p.lines {
|
||||
for _, char := range line {
|
||||
switch char {
|
||||
case '\\':
|
||||
builder.WriteString("\\5C")
|
||||
case '$':
|
||||
builder.WriteString("\\24")
|
||||
default:
|
||||
builder.WriteRune(char)
|
||||
}
|
||||
}
|
||||
|
||||
builder.WriteRune('$')
|
||||
}
|
||||
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// ParsePostalAddress parses an RFC 4517 escaped postal address string into a PostalAddress object or returns an error.
|
||||
func ParsePostalAddress(escaped string) (*PostalAddress, error) {
|
||||
lines := strings.Split(escaped, "$")
|
||||
parsedLines := make([]string, 0, len(lines))
|
||||
const totalEscapeLen = 3
|
||||
|
||||
for _, line := range lines {
|
||||
if line == "" {
|
||||
// Skip empty lines
|
||||
continue
|
||||
}
|
||||
|
||||
builder := &strings.Builder{}
|
||||
for i := 0; i < len(line); i++ {
|
||||
char := line[i]
|
||||
if char == '\\' && i+totalEscapeLen <= len(line) {
|
||||
escapeSeq := line[i+1 : i+totalEscapeLen]
|
||||
switch escapeSeq {
|
||||
case "5C", "5c":
|
||||
builder.WriteRune('\\')
|
||||
i += 2
|
||||
case "24":
|
||||
builder.WriteRune('$')
|
||||
i += 2
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid escape sequence: \\%s at position %d", escapeSeq, i)
|
||||
}
|
||||
} else if char == '\\' {
|
||||
return nil, fmt.Errorf("incomplete escape sequence at position %d", i)
|
||||
} else {
|
||||
builder.WriteByte(char)
|
||||
}
|
||||
}
|
||||
parsedLines = append(parsedLines, builder.String())
|
||||
}
|
||||
|
||||
if len(parsedLines) == 0 {
|
||||
return nil, ErrEmptyPostalAddress
|
||||
}
|
||||
|
||||
return &PostalAddress{lines: parsedLines}, nil
|
||||
}
|
||||
|
||||
// Equal compares the current PostalAddress with another PostalAddress and returns true if they are identical.
|
||||
func (p *PostalAddress) Equal(other *PostalAddress) bool {
|
||||
if p == other {
|
||||
return true
|
||||
}
|
||||
if p == nil || other == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(p.lines) != len(other.lines) {
|
||||
return false
|
||||
}
|
||||
for i := range p.lines {
|
||||
if p.lines[i] != other.lines[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
+1
-1
@@ -623,7 +623,7 @@ 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.
|
||||
// e.g. for size / time limited requests all are received 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 {
|
||||
|
||||
+4
-72
@@ -4,88 +4,20 @@ package ldap
|
||||
//
|
||||
// https://tools.ietf.org/html/rfc4532
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
ber "github.com/go-asn1-ber/asn1-ber"
|
||||
)
|
||||
|
||||
type whoAmIRequest bool
|
||||
|
||||
// WhoAmIResult is returned by the WhoAmI() call
|
||||
type WhoAmIResult struct {
|
||||
AuthzID string
|
||||
}
|
||||
|
||||
func (r whoAmIRequest) encode() (*ber.Packet, error) {
|
||||
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationExtendedRequest, nil, "Who Am I? Extended Operation")
|
||||
request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, ControlTypeWhoAmI, "Extended Request Name: Who Am I? OID"))
|
||||
return request, nil
|
||||
}
|
||||
|
||||
// WhoAmI returns the authzId the server thinks we are, you may pass controls
|
||||
// like a Proxied Authorization control
|
||||
func (l *Conn) WhoAmI(controls []Control) (*WhoAmIResult, error) {
|
||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
||||
req := whoAmIRequest(true)
|
||||
encodedWhoAmIRequest, err := req.encode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
packet.AppendChild(encodedWhoAmIRequest)
|
||||
|
||||
if len(controls) != 0 {
|
||||
packet.AppendChild(encodeControls(controls))
|
||||
}
|
||||
|
||||
l.Debug.PrintPacket(packet)
|
||||
|
||||
msgCtx, err := l.sendMessage(packet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
|
||||
result := &WhoAmIResult{}
|
||||
|
||||
l.Debug.Printf("%d: waiting for response", msgCtx.id)
|
||||
packetResponse, ok := <-msgCtx.responses
|
||||
if !ok {
|
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
|
||||
}
|
||||
packet, err = packetResponse.ReadPacket()
|
||||
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
|
||||
extendedRequest := NewExtendedRequest(ControlTypeWhoAmI, nil)
|
||||
extendedRequest.Controls = controls
|
||||
resp, err := l.Extended(extendedRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if packet == nil {
|
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve message"))
|
||||
}
|
||||
|
||||
if l.Debug {
|
||||
if err := addLDAPDescriptions(packet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ber.PrintPacket(packet)
|
||||
}
|
||||
|
||||
if packet.Children[1].Tag == ApplicationExtendedResponse {
|
||||
if err := GetLDAPError(packet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, NewError(ErrorUnexpectedResponse, fmt.Errorf("Unexpected Response: %d", packet.Children[1].Tag))
|
||||
}
|
||||
|
||||
extendedResponse := packet.Children[1]
|
||||
for _, child := range extendedResponse.Children {
|
||||
if child.Tag == 11 {
|
||||
result.AuthzID = ber.DecodeString(child.Data.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return &WhoAmIResult{AuthzID: resp.Value.Data.String()}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user