mirror of
https://github.com/netauth/ldap.git
synced 2026-11-03 11:43:44 -06:00
124 lines
3.9 KiB
Go
124 lines
3.9 KiB
Go
package ldap
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
ldap "github.com/ps78674/ldapserver"
|
|
|
|
pb "github.com/netauth/protocol"
|
|
)
|
|
|
|
var _ naClient = (*fakeClient)(nil)
|
|
|
|
type fakeClient struct {
|
|
authErr error
|
|
authCalls []string
|
|
}
|
|
|
|
func (f *fakeClient) AuthEntity(ctx context.Context, id, password string) error {
|
|
f.authCalls = append(f.authCalls, id)
|
|
return f.authErr
|
|
}
|
|
func (f *fakeClient) EntitySearch(context.Context, string) ([]*pb.Entity, error) { return nil, nil }
|
|
func (f *fakeClient) EntityGroups(context.Context, string) ([]*pb.Group, error) { return nil, nil }
|
|
func (f *fakeClient) GroupSearch(context.Context, string) ([]*pb.Group, error) { return nil, nil }
|
|
func (f *fakeClient) GroupMembers(context.Context, string) ([]*pb.Entity, error) { return nil, nil }
|
|
|
|
func TestAnonBindSingleResponse(t *testing.T) {
|
|
c := &fakeClient{}
|
|
s := &server{l: testLogger(), c: c}
|
|
s.nc = []string{"dc=netauth", "dc=example", "dc=com"}
|
|
s.allowAnon = true
|
|
|
|
w := &recordingWriter{}
|
|
s.handleBind(w, mustDecode(t, berBindRequest("", "")))
|
|
|
|
if len(w.responses) != 1 {
|
|
t.Fatalf("got %d responses for an anonymous bind, want exactly 1", len(w.responses))
|
|
}
|
|
if code := resultCode(t, w.responses[0]); code != ldap.LDAPResultSuccess {
|
|
t.Errorf("result code is %d, want %d", code, ldap.LDAPResultSuccess)
|
|
}
|
|
if len(c.authCalls) != 0 {
|
|
t.Errorf("an anonymous bind reached NetAuth with %v", c.authCalls)
|
|
}
|
|
}
|
|
|
|
func TestAnonBindDisabled(t *testing.T) {
|
|
s := &server{l: testLogger(), c: &fakeClient{}}
|
|
s.nc = []string{"dc=netauth", "dc=example", "dc=com"}
|
|
|
|
w := &recordingWriter{}
|
|
s.handleBind(w, mustDecode(t, berBindRequest("", "")))
|
|
|
|
if len(w.responses) != 1 {
|
|
t.Fatalf("got %d responses, want exactly 1", len(w.responses))
|
|
}
|
|
if code := resultCode(t, w.responses[0]); code != ldap.LDAPResultInvalidDNSyntax {
|
|
t.Errorf("result code is %d, want %d", code, ldap.LDAPResultInvalidDNSyntax)
|
|
}
|
|
}
|
|
|
|
func TestBindValidCredentials(t *testing.T) {
|
|
c := &fakeClient{}
|
|
s := &server{l: testLogger(), c: c}
|
|
s.nc = []string{"dc=netauth", "dc=example", "dc=com"}
|
|
|
|
w := &recordingWriter{}
|
|
s.handleBind(w, mustDecode(t,
|
|
berBindRequest("uid=jsmith,ou=entities,dc=netauth,dc=example,dc=com", "hunter2")))
|
|
|
|
if len(w.responses) != 1 {
|
|
t.Fatalf("got %d responses, want exactly 1", len(w.responses))
|
|
}
|
|
if code := resultCode(t, w.responses[0]); code != ldap.LDAPResultSuccess {
|
|
t.Errorf("result code is %d, want %d", code, ldap.LDAPResultSuccess)
|
|
}
|
|
if len(c.authCalls) != 1 || c.authCalls[0] != "jsmith" {
|
|
t.Errorf("NetAuth authenticated %v, want [jsmith]", c.authCalls)
|
|
}
|
|
}
|
|
|
|
func TestBindInvalidCredentials(t *testing.T) {
|
|
c := &fakeClient{authErr: errors.New("invalid password")}
|
|
s := &server{l: testLogger(), c: c}
|
|
s.nc = []string{"dc=netauth", "dc=example", "dc=com"}
|
|
|
|
w := &recordingWriter{}
|
|
s.handleBind(w, mustDecode(t,
|
|
berBindRequest("uid=jsmith,ou=entities,dc=netauth,dc=example,dc=com", "wrong")))
|
|
|
|
if len(w.responses) != 1 {
|
|
t.Fatalf("got %d responses, want exactly 1", len(w.responses))
|
|
}
|
|
if code := resultCode(t, w.responses[0]); code != ldap.LDAPResultInvalidCredentials {
|
|
t.Errorf("result code is %d, want %d", code, ldap.LDAPResultInvalidCredentials)
|
|
}
|
|
}
|
|
|
|
func TestBindUnsupportedMechanism(t *testing.T) {
|
|
s := &server{l: testLogger(), c: &fakeClient{}}
|
|
s.nc = []string{"dc=netauth", "dc=example", "dc=com"}
|
|
|
|
// A bind request carrying SASL credentials rather than a simple
|
|
// password must be refused outright.
|
|
sasl := berElement(0x60,
|
|
berInteger(3),
|
|
berOctetString("uid=jsmith,ou=entities,dc=netauth,dc=example,dc=com"),
|
|
berElement(0xa3, berOctetString("GSSAPI")),
|
|
)
|
|
msg := berElement(0x30, berInteger(1), sasl)
|
|
|
|
w := &recordingWriter{}
|
|
s.handleBind(w, mustDecode(t, msg))
|
|
|
|
if len(w.responses) != 1 {
|
|
t.Fatalf("got %d responses, want exactly 1", len(w.responses))
|
|
}
|
|
if code := resultCode(t, w.responses[0]); code != ldap.LDAPResultUnwillingToPerform {
|
|
t.Errorf("result code is %d, want %d", code, ldap.LDAPResultUnwillingToPerform)
|
|
}
|
|
}
|