Skip to content

panic: Multiple panics in GetLDAPError #453

@TomSellers

Description

@TomSellers

GetLDAPError has been observed to panic when calling SimpleBind against certain targets.


panic: interface conversion: interface {} is nil, not string

[github.com/go-ldap/ldap/v3.GetLDAPError(0xc009b6ccb0)](http://github.com/go-ldap/ldap/v3.GetLDAPError(0xc009b6ccb0))
    /home/runner/go/pkg/mod/github.com/go-ldap/ldap/v3@v3.4.5/error.go:216 +0x368
[github.com/go-ldap/ldap/v3.(*Conn).SimpleBind](http://github.com/go-ldap/ldap/v3.(*Conn).SimpleBind)(0xc013ed47e0, 0xc004d16300?)
    /home/runner/go/pkg/mod/github.com/go-ldap/ldap/v3@v3.4.5/bind.go:90 +0x2b4
[github.com/go-ldap/ldap/v3.(*Conn).UnauthenticatedBind(...)](http://github.com/go-ldap/ldap/v3.(*Conn).UnauthenticatedBind(...))
    /home/runner/go/pkg/mod/github.com/go-ldap/ldap/v3@v3.4.5/bind.go:121

While I cannot provide the original packets that triggered this initially I have been able to reproduce this panic and one other using a modified version of the existing TestGetLDAPError test for GetLDAPError.


Reproducer for interface conversion: interface {} is nil, not string at error.go:216

package main

import (
	"fmt"

	ber "github.com/go-asn1-ber/asn1-ber"
	ldap "github.com/go-ldap/ldap/v3"
)

func main() {
	bindResponse := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ldap.ApplicationBindResponse, nil, "Bind Response")
	bindResponse.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(ldap.LDAPResultInvalidCredentials), "resultCode"))
	bindResponse.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "dc=example,dc=org", "matchedDN"))

	// Original message included the line below
	// bindResponse.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, diagnosticMessage, "diagnosticMessage"))
	bindResponse.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, nil, "diagnosticMessage"))

	packet := ber.NewSequence("LDAPMessage")
	packet.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(0), "messageID"))
	packet.AppendChild(bindResponse)

	fmt.Printf("packet: %+v\n", packet)
	_ = ldap.GetLDAPError(packet)
}

Results

go run main.go
packet: &{Identifier:{ClassType:0 TagType:32 Tag:16} Value:<nil> ByteValue:[] Data:adc=example,dc=org Children:[0x140000ee2a0 0x140000ee070] Description:LDAPMessage}
panic: interface conversion: interface {} is nil, not string

goroutine 1 [running]:
github.com/go-ldap/ldap/v3.GetLDAPError(0x140000ee230)
        /Users/tom.sellers/go/pkg/mod/github.com/go-ldap/ldap/v3@v3.4.5/error.go:216 +0x380
main.main()
        /Users/tom.sellers/Downloads/ldap-testing/main.go:24 +0x19c
exit status 2

Related code

ldap/error.go

Lines 213 to 217 in 3646355

return &Error{
ResultCode: resultCode,
MatchedDN: response.Children[1].Value.(string),
Err: fmt.Errorf("%s", response.Children[2].Value.(string)),
Packet: packet,


Reproducer for interface conversion: interface {} is string, not int64 at error.go:209

package main

import (
	ber "github.com/go-asn1-ber/asn1-ber"
	ldap "github.com/go-ldap/ldap/v3"
)

func main() {
	diagnosticMessage := "Detailed error message"
	bindResponse := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ldap.ApplicationBindResponse, nil, "Bind Response")

	bindResponse.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "dc=example,dc=org", "matchedDN"))
	bindResponse.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, diagnosticMessage, "diagnosticMessage"))

	// The following was originally the first call to bindResponse.AppendChild()
	bindResponse.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(ldap.LDAPResultInvalidCredentials), "resultCode"))

	packet := ber.NewSequence("LDAPMessage")
	packet.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(0), "messageID"))
	packet.AppendChild(bindResponse)
	_ = ldap.GetLDAPError(packet)
}

Results

go run main.go
panic: interface conversion: interface {} is string, not int64

goroutine 1 [running]:
github.com/go-ldap/ldap/v3.GetLDAPError(0x1400011c230)
        /Users/tom.sellers/go/pkg/mod/github.com/go-ldap/ldap/v3@v3.4.5/error.go:209 +0x3a0
main.main()
        /Users/tom.sellers/Downloads/ldap-testing/main.go:21 +0x158
exit status 2

Related code

ldap/error.go

Lines 208 to 209 in 3646355

if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 {
resultCode := uint16(response.Children[0].Value.(int64))

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions