internal/ldap: Handle bind

This commit is contained in:
Michael Aldridge 2020-08-22 20:49:54 -07:00
parent b3783dffb5
commit 83e78da739
9 changed files with 74 additions and 5 deletions

1
go.mod
View file

@ -4,6 +4,7 @@ go 1.15
require (
github.com/hashicorp/go-hclog v0.9.2
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3 // indirect
github.com/netauth/netauth v0.3.4
github.com/ps78674/goldap v0.0.0-20200721080011-cd2e7ee23841
github.com/ps78674/ldapserver v0.0.0-20200521101606-2395f680392c

2
go.sum
View file

@ -52,6 +52,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3 h1:wIONC+HMNRqmWBjuMxhatuSzHaljStc4gjDeKycxy0A=
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3/go.mod h1:37YR9jabpiIxsb8X9VCIx8qFOjTDIIrIHHODa8C4gz0=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=

View file

@ -0,0 +1,6 @@
package buildinfo
var (
// Version is the version this server.
Version = "dev"
)

View file

@ -22,7 +22,16 @@ func (s *server) handleBind(w ldap.ResponseWriter, m *ldap.Message) {
s.l.Debug("Bind from dn", "dn", r.Name())
if err := s.c.AuthEntity(ctx, entityIDFromDN(r.Name()), string(r.AuthenticationSimple())); err != nil {
entityID, err := s.entityIDFromDN(r.Name())
if err != nil {
res := ldap.NewBindResponse(ldap.LDAPResultInvalidDNSyntax)
res.SetDiagnosticMessage(err.Error())
s.l.Warn("Request with invalid DN", "dn", r.Name())
w.Write(res)
return
}
if err := s.c.AuthEntity(ctx, entityID, string(r.AuthenticationSimple())); err != nil {
res := ldap.NewBindResponse(ldap.LDAPResultInvalidCredentials)
res.SetDiagnosticMessage("invalid credentials")
w.Write(res)

View file

@ -3,6 +3,7 @@ package ldap
import (
"os"
"os/signal"
"strings"
"syscall"
"github.com/hashicorp/go-hclog"
@ -79,3 +80,17 @@ func (s *server) handleAbandon(w ldap.ResponseWriter, m *ldap.Message) {
requestToAbandon.Abandon()
}
}
func (s *server) SetDomain(domain string) {
nc := "dc=netauth,"
parts := strings.Split(domain, ".")
for i := range parts {
nc += "dc=" + parts[i] + ","
}
nc = strings.TrimSuffix(nc, ",")
s.nc = strings.Split(nc, ",")
for i := range s.nc {
s.nc[i] = strings.TrimSpace(s.nc[i])
}
}

View file

@ -2,17 +2,23 @@ package ldap
import (
"log"
"strings"
"github.com/ps78674/goldap/message"
ldap "github.com/ps78674/ldapserver"
"github.com/netauth/ldap/internal/buildinfo"
)
func (s *server) handleSearchDSE(w ldap.ResponseWriter, m *ldap.Message) {
nc := strings.Join(s.nc, ", ")
e := ldap.NewSearchResultEntry("")
e.AddAttribute("vendorName", "NetAuth")
e.AddAttribute("vendorVersion", "1.0")
e.AddAttribute("vendorVersion", message.AttributeValue(buildinfo.Version))
e.AddAttribute("objectClass", "top", "extensibleObject")
e.AddAttribute("supportedLDAPVersion", "3")
e.AddAttribute("namingContexts", "o=My Company, c=US")
e.AddAttribute("namingContexts", message.AttributeValue(nc))
w.Write(e)
res := ldap.NewSearchResultDoneResponse(ldap.LDAPResultSuccess)

View file

@ -16,4 +16,6 @@ type server struct {
c naClient
l hclog.Logger
nc []string
}

View file

@ -1,9 +1,34 @@
package ldap
import (
"errors"
"strings"
"github.com/ps78674/goldap/message"
)
func entityIDFromDN(message.LDAPDN) string {
return ""
// entityIDFromDN parses out an ID from a given DN. This only works
// for ID's that don't contain an escaped comma, but these aren't
// valid in NetAuth anyway, so this is taken as a known defect.
func (s *server) entityIDFromDN(dn message.LDAPDN) (string, error) {
parts := strings.Split(string(dn), ",")
for i := range parts {
parts[i] = strings.TrimSpace(parts[i])
}
if !strings.HasPrefix(parts[0], "uid=") {
return "", errors.New("entity DN must start with uid=")
}
if parts[1] != "cn=entities" {
return "", errors.New("entity DN is underneath cn=entities")
}
for i, p := range parts[2:] {
if p != s.nc[i] {
return "", errors.New("queries must be rooted at " + strings.Join(s.nc, ","))
}
}
return strings.TrimPrefix(parts[0], "uid="), nil
}

View file

@ -42,6 +42,9 @@ func main() {
}
ls := ldap.New(appLogger, nacl)
ls.SetDomain("netauth.org")
if err := ls.Serve("localhost:10389"); err != nil {
appLogger.Error("Error serving", "error", err)
return