Skip to content

Commit a926d97

Browse files
authored
Address panics in GetLDAPError (#455)
1 parent 3646355 commit a926d97

File tree

4 files changed

+72
-18
lines changed

4 files changed

+72
-18
lines changed

error.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,21 @@ func GetLDAPError(packet *ber.Packet) error {
206206
return &Error{ResultCode: ErrorUnexpectedResponse, Err: fmt.Errorf("Empty response in packet"), Packet: packet}
207207
}
208208
if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 {
209-
resultCode := uint16(response.Children[0].Value.(int64))
210-
if resultCode == 0 { // No error
211-
return nil
212-
}
213-
return &Error{
214-
ResultCode: resultCode,
215-
MatchedDN: response.Children[1].Value.(string),
216-
Err: fmt.Errorf("%s", response.Children[2].Value.(string)),
217-
Packet: packet,
209+
if ber.Type(response.Children[0].Tag) == ber.Type(ber.TagInteger) || ber.Type(response.Children[0].Tag) == ber.Type(ber.TagEnumerated) {
210+
resultCode := uint16(response.Children[0].Value.(int64))
211+
if resultCode == 0 { // No error
212+
return nil
213+
}
214+
215+
if ber.Type(response.Children[1].Tag) == ber.Type(ber.TagOctetString) &&
216+
ber.Type(response.Children[2].Tag) == ber.Type(ber.TagOctetString) {
217+
return &Error{
218+
ResultCode: resultCode,
219+
MatchedDN: response.Children[1].Value.(string),
220+
Err: fmt.Errorf("%s", response.Children[2].Value.(string)),
221+
Packet: packet,
222+
}
223+
}
218224
}
219225
}
220226
}

error_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,27 @@ func TestGetLDAPError(t *testing.T) {
8282
}
8383
}
8484

85+
// TestGetLDAPErrorInvalidResponse tests that responses with an unexpected ordering or combination of children
86+
// don't cause a panic.
87+
func TestGetLDAPErrorInvalidResponse(t *testing.T) {
88+
bindResponse := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindResponse, nil, "Bind Response")
89+
bindResponse.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "dc=example,dc=org", "matchedDN"))
90+
bindResponse.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(LDAPResultInvalidCredentials), "resultCode"))
91+
bindResponse.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(LDAPResultInvalidCredentials), "resultCode"))
92+
packet := ber.NewSequence("LDAPMessage")
93+
packet.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(0), "messageID"))
94+
packet.AppendChild(bindResponse)
95+
err := GetLDAPError(packet)
96+
if err == nil {
97+
t.Errorf("Did not get error response")
98+
}
99+
100+
ldapError := err.(*Error)
101+
if ldapError.ResultCode != ErrorNetwork {
102+
t.Errorf("Got incorrect error code in LDAP error; got %v, expected %v", ldapError.ResultCode, ErrorNetwork)
103+
}
104+
}
105+
85106
// TestGetLDAPErrorSuccess tests parsing of a result with no error (resultCode == 0).
86107
func TestGetLDAPErrorSuccess(t *testing.T) {
87108
bindResponse := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindResponse, nil, "Bind Response")

v3/error.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,21 @@ func GetLDAPError(packet *ber.Packet) error {
206206
return &Error{ResultCode: ErrorUnexpectedResponse, Err: fmt.Errorf("Empty response in packet"), Packet: packet}
207207
}
208208
if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 {
209-
resultCode := uint16(response.Children[0].Value.(int64))
210-
if resultCode == 0 { // No error
211-
return nil
212-
}
213-
return &Error{
214-
ResultCode: resultCode,
215-
MatchedDN: response.Children[1].Value.(string),
216-
Err: fmt.Errorf("%s", response.Children[2].Value.(string)),
217-
Packet: packet,
209+
if ber.Type(response.Children[0].Tag) == ber.Type(ber.TagInteger) || ber.Type(response.Children[0].Tag) == ber.Type(ber.TagEnumerated) {
210+
resultCode := uint16(response.Children[0].Value.(int64))
211+
if resultCode == 0 { // No error
212+
return nil
213+
}
214+
215+
if ber.Type(response.Children[1].Tag) == ber.Type(ber.TagOctetString) &&
216+
ber.Type(response.Children[2].Tag) == ber.Type(ber.TagOctetString) {
217+
return &Error{
218+
ResultCode: resultCode,
219+
MatchedDN: response.Children[1].Value.(string),
220+
Err: fmt.Errorf("%s", response.Children[2].Value.(string)),
221+
Packet: packet,
222+
}
223+
}
218224
}
219225
}
220226
}

v3/error_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,27 @@ func TestGetLDAPError(t *testing.T) {
8282
}
8383
}
8484

85+
// TestGetLDAPErrorInvalidResponse tests that responses with an unexpected ordering or combination of children
86+
// don't cause a panic.
87+
func TestGetLDAPErrorInvalidResponse(t *testing.T) {
88+
bindResponse := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindResponse, nil, "Bind Response")
89+
bindResponse.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "dc=example,dc=org", "matchedDN"))
90+
bindResponse.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(LDAPResultInvalidCredentials), "resultCode"))
91+
bindResponse.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(LDAPResultInvalidCredentials), "resultCode"))
92+
packet := ber.NewSequence("LDAPMessage")
93+
packet.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, int64(0), "messageID"))
94+
packet.AppendChild(bindResponse)
95+
err := GetLDAPError(packet)
96+
if err == nil {
97+
t.Errorf("Did not get error response")
98+
}
99+
100+
ldapError := err.(*Error)
101+
if ldapError.ResultCode != ErrorNetwork {
102+
t.Errorf("Got incorrect error code in LDAP error; got %v, expected %v", ldapError.ResultCode, ErrorNetwork)
103+
}
104+
}
105+
85106
// TestGetLDAPErrorSuccess tests parsing of a result with no error (resultCode == 0).
86107
func TestGetLDAPErrorSuccess(t *testing.T) {
87108
bindResponse := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindResponse, nil, "Bind Response")

0 commit comments

Comments
 (0)