Compare commits

...

3 Commits

Author SHA1 Message Date
Chris F Ravenscroft bbb9f4a25e Merge branch 'master' into chore/rewire-ldap-packages 2023-12-10 15:22:10 -08:00
Alessandro Cabbia 01bdb7148e startTLS: ldap over TLS functionality (#364)
* feat: introduce tls parameters in config to allow startTLS

* feat: pass tls config for startTLS to ldap server

* build: update libs to use newer ldap

* feat: allow tls config for startTLS
2023-12-10 15:20:29 -08:00
Chris F Ravenscroft 0c0d742ea9 chore: reweure ldap packages 2023-12-10 15:13:23 -08:00
20 changed files with 168 additions and 41 deletions
+14
View File
@@ -1,6 +1,7 @@
package main
import (
"crypto/tls"
"fmt"
"net/http"
"os"
@@ -14,6 +15,7 @@ import (
docopt "github.com/docopt/docopt-go"
"github.com/fsnotify/fsnotify"
"github.com/glauth/glauth/v2/internal/monitoring"
_tls "github.com/glauth/glauth/v2/internal/tls"
"github.com/glauth/glauth/v2/internal/toml"
"github.com/glauth/glauth/v2/internal/version"
"github.com/glauth/glauth/v2/pkg/config"
@@ -131,10 +133,22 @@ func startService() {
startConfigWatcher()
var err error
var tlsConfig *tls.Config
if c := activeConfig.LDAP; c.Enabled && c.TLS {
// TODO check if tls params are string or bytes and change config accordingly
tlsConfig, err = _tls.MakeTLS([]byte(c.TLSCert), []byte(c.TLSKey))
if err != nil {
log.Warn().Err(err).Msg("unable to configure TLS, proceeding without....StartTLS won't be supported")
}
}
s, err := server.NewServer(
server.Logger(log),
server.Config(activeConfig),
server.Monitor(monitor),
server.TLSConfig(tlsConfig),
)
if err != nil {
+6 -9
View File
@@ -8,8 +8,8 @@ require (
github.com/arl/statsviz v0.6.0
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
github.com/fsnotify/fsnotify v1.6.0
github.com/glauth/ldap v0.0.0-20231210225823-b9bf4d1baf6e
github.com/jinzhu/copier v0.4.0
github.com/nmcclain/ldap v0.0.0-20210720162743-7f8d1e44eeba
github.com/pquerna/otp v1.4.0
github.com/prometheus/client_golang v1.17.0
github.com/prometheus/client_model v0.5.0
@@ -25,27 +25,24 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/boombuler/barcode v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/kr/text v0.1.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-sqlite3 v1.14.18 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/msteinert/pam v1.2.0 // indirect
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rickb777/date v1.20.5 // indirect
github.com/rickb777/plural v1.4.1 // indirect
github.com/smarty/assertions v1.15.0 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/tools v0.13.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
replace github.com/nmcclain/ldap => github.com/shipperizer/ldap v0.0.0-20231117095347-c1d6afe484ca
// replace github.com/nmcclain/ldap => ../../../ldap
+6 -17
View File
@@ -19,10 +19,10 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/glauth/ldap v0.0.0-20231210225823-b9bf4d1baf6e h1:ohe1O2DUo198delHsQvA8O+CgAPP8wv1SmSxLPlO9ao=
github.com/glauth/ldap v0.0.0-20231210225823-b9bf4d1baf6e/go.mod h1:EHMcFuVSIs0huelHOhaGtj9IKMB/Dmxo+jDheipjtYA=
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
@@ -43,23 +43,13 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI=
github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/msteinert/pam v1.2.0 h1:mYfjlvN2KYs2Pb9G6nb/1f/nPfAttT/Jee5Sq9r3bGE=
github.com/msteinert/pam v1.2.0/go.mod h1:d2n0DCUK8rGecChV3JzvmsDjOY4R7AYbsNxAT+ftQl0=
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484 h1:D9EvfGQvlkKaDr2CRKN++7HbSXbefUNDrPq60T+g24s=
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484/go.mod h1:O1EljZ+oHprtxDDPHiMWVo/5dBT6PlvWX5PSwj80aBA=
github.com/nmcclain/ldap v0.0.0-20210720162743-7f8d1e44eeba h1:DO8NFYdcRv1dnyAINJIBm6Bw2XibtLvQniNFGzf2W8E=
github.com/nmcclain/ldap v0.0.0-20210720162743-7f8d1e44eeba/go.mod h1:4S0XndRL8HNOaQBfdViJ2F/GPCgL524xlXRuXFH12/U=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -84,6 +74,8 @@ github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDN
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/shipperizer/ldap v0.0.0-20231117095347-c1d6afe484ca h1:KSpZYIDb2ei4d+AxsFmC9KJaTNlmSiONSl6hLd5Qmfg=
github.com/shipperizer/ldap v0.0.0-20231117095347-c1d6afe484ca/go.mod h1:/KinL0zHM54Sk4gMgvODL26YGG7u4SFBOAKNpJmsJvc=
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
@@ -105,8 +97,6 @@ golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -136,7 +126,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200529172331-a64b76657301/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200731060945-b5fad4ed8dd6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+1 -1
View File
@@ -1,6 +1,6 @@
package monitoring
import "github.com/nmcclain/ldap"
import "github.com/glauth/ldap"
type MonitorInterface interface {
SetResponseTimeMetric(map[string]string, float64) error
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"testing"
"time"
"github.com/nmcclain/ldap"
"github.com/glauth/ldap"
"github.com/rs/zerolog"
"go.uber.org/mock/gomock"
)
+81
View File
@@ -0,0 +1,81 @@
package tls
import (
tls "crypto/tls"
"crypto/x509"
"encoding/pem"
"github.com/rs/zerolog"
)
var (
log zerolog.Logger
)
// MakeTLS generates a tls.Config
func MakeTLS(clientCert, key []byte) (*tls.Config, error) {
if clientCert == nil && key == nil {
return new(tls.Config), nil
}
var err error
cert, err := tls.X509KeyPair(clientCert, key)
if err != nil {
return nil, err
}
log.Debug().Str("key", string(key))
log.Debug().Str("client.certificate", string(clientCert))
log.Debug().Interface("certificate", cert)
if err != nil {
return nil, err
}
// Get the SystemCertPool, continue with an empty pool on error
rootCAs, err := x509.SystemCertPool()
if rootCAs == nil {
rootCAs = x509.NewCertPool()
log.Warn().Err(err).Msg("Using empty cert-pool")
} else {
log.Info().Msg("Using system cert-pool")
}
for _, cert := range DecodePEM(clientCert).Certificate {
x509Cert, err := x509.ParseCertificate(cert)
if err != nil {
log.Error().Err(err).Msg("issue parsing cert PEM")
}
rootCAs.AddCert(x509Cert)
}
log.Debug().Interface("root.ca", rootCAs)
log.Debug().Interface("certificates", []tls.Certificate{cert})
return &tls.Config{
RootCAs: rootCAs,
MinVersion: tls.VersionTLS10,
MaxVersion: tls.VersionTLS13,
Certificates: []tls.Certificate{cert},
}, nil
}
// DecodePEM builds a PEM certificate object
func DecodePEM(certPEM []byte) tls.Certificate {
var cert tls.Certificate
var certDER *pem.Block
for {
certDER, certPEM = pem.Decode(certPEM)
if certDER == nil {
break
}
if certDER.Type == "CERTIFICATE" {
cert.Certificate = append(cert.Certificate, certDER.Bytes)
}
}
return cert
}
+19
View File
@@ -400,6 +400,25 @@ func validateConfig(cfg *config.Config) (*config.Config, error) {
if len(cfg.LDAP.Listen) == 0 {
return cfg, fmt.Errorf("no LDAP bind address was specified: please disable LDAP or use the 'listen' option")
}
if cfg.LDAP.TLS && cfg.LDAP.TLSCert == "" && cfg.LDAP.TLSCertPath != "" {
byteData, err := os.ReadFile(cfg.LDAP.TLSCertPath)
cfg.LDAP.TLSCert = string(byteData)
if err != nil {
return cfg, fmt.Errorf("unable to read TLS certificate file")
}
}
if cfg.LDAP.TLS && cfg.LDAP.TLSKey == "" && cfg.LDAP.TLSKeyPath != "" {
byteData, err := os.ReadFile(cfg.LDAP.TLSKeyPath)
cfg.LDAP.TLSKey = string(byteData)
if err != nil {
return cfg, fmt.Errorf("unable to read TLS key file")
}
}
}
//spew.Dump(cfg)
+6
View File
@@ -36,6 +36,12 @@ type Frontend struct {
type LDAP struct {
Enabled bool
Listen string
// StartTLS parameters
TLS bool
TLSCert string
TLSKey string
TLSCertPath string
TLSKeyPath string
}
type LDAPS struct {
Enabled bool
+1
View File
@@ -2,6 +2,7 @@ package frontend
import (
"context"
"github.com/rs/zerolog"
"github.com/glauth/glauth/v2/pkg/config"
+1 -1
View File
@@ -14,7 +14,7 @@ import (
"github.com/glauth/glauth/v2/internal/monitoring"
"github.com/glauth/glauth/v2/pkg/config"
"github.com/glauth/glauth/v2/pkg/stats"
"github.com/nmcclain/ldap"
"github.com/glauth/ldap"
)
type configHandler struct {
+1 -1
View File
@@ -2,7 +2,7 @@ package handler
import (
"github.com/glauth/glauth/v2/pkg/config"
"github.com/nmcclain/ldap"
"github.com/glauth/ldap"
)
type HelperMaker interface {
+1 -1
View File
@@ -19,7 +19,7 @@ import (
"github.com/glauth/glauth/v2/internal/monitoring"
"github.com/glauth/glauth/v2/pkg/config"
"github.com/glauth/glauth/v2/pkg/stats"
"github.com/nmcclain/ldap"
"github.com/glauth/ldap"
"github.com/pquerna/otp/totp"
)
+1 -1
View File
@@ -17,7 +17,7 @@ import (
"github.com/GeertJohan/yubigo"
"github.com/glauth/glauth/v2/pkg/config"
"github.com/glauth/glauth/v2/pkg/stats"
"github.com/nmcclain/ldap"
"github.com/glauth/ldap"
"github.com/pquerna/otp/totp"
"golang.org/x/crypto/bcrypt"
)
+1 -1
View File
@@ -18,7 +18,7 @@ import (
"github.com/glauth/glauth/v2/internal/monitoring"
"github.com/glauth/glauth/v2/pkg/config"
"github.com/glauth/glauth/v2/pkg/stats"
"github.com/nmcclain/ldap"
"github.com/glauth/ldap"
msgraph "github.com/yaegashi/msgraph.go/v1.0"
)
+2 -1
View File
@@ -5,7 +5,6 @@ package logging
import (
"fmt"
"github.com/rs/zerolog"
"io"
"log"
"log/syslog"
@@ -13,6 +12,8 @@ import (
"regexp"
"strings"
"time"
"github.com/rs/zerolog"
)
// We will use this package to wrap log messages coming from libraries who have no interest
+2 -1
View File
@@ -5,13 +5,14 @@ package logging
import (
"fmt"
"github.com/rs/zerolog"
"io"
"log"
"os"
"regexp"
"strings"
"time"
"github.com/rs/zerolog"
)
// We will use this package to wrap log messages coming from libraries who have no interest
+1 -1
View File
@@ -18,7 +18,7 @@ import (
"github.com/glauth/glauth/v2/pkg/config"
"github.com/glauth/glauth/v2/pkg/handler"
"github.com/glauth/glauth/v2/pkg/stats"
"github.com/nmcclain/ldap"
"github.com/glauth/ldap"
)
var configattributematcher = regexp.MustCompile(`(?i)\((?P<attribute>[a-zA-Z0-9]+)\s*=\s*(?P<value>.*)\)`)
+13 -4
View File
@@ -2,6 +2,7 @@ package server
import (
"context"
"crypto/tls"
"github.com/rs/zerolog"
@@ -14,10 +15,11 @@ type Option func(o *Options)
// Options defines the available options for this package.
type Options struct {
Logger zerolog.Logger
Config *config.Config
Monitor monitoring.MonitorInterface
Context context.Context
Logger zerolog.Logger
Config *config.Config
Monitor monitoring.MonitorInterface
TLSConfig *tls.Config
Context context.Context
}
// newOptions initializes the available default options.
@@ -52,6 +54,13 @@ func Context(val context.Context) Option {
}
}
// TLSConfig provides a function to set the TLS config option.
func TLSConfig(val *tls.Config) Option {
return func(o *Options) {
o.TLSConfig = val
}
}
// Monitor provides a function to set the monitor option.
func Monitor(val monitoring.MonitorInterface) Option {
return func(o *Options) {
+7 -1
View File
@@ -11,7 +11,7 @@ import (
"github.com/glauth/glauth/v2/internal/monitoring"
"github.com/glauth/glauth/v2/pkg/config"
"github.com/glauth/glauth/v2/pkg/handler"
"github.com/nmcclain/ldap"
"github.com/glauth/ldap"
)
type LdapSvc struct {
@@ -90,6 +90,12 @@ func NewServer(opts ...Option) (*LdapSvc, error) {
// configure the backends
s.l = ldap.NewServer()
s.l.EnforceLDAP = true
if tlsConfig := options.TLSConfig; tlsConfig != nil {
s.l.TLSConfig = tlsConfig
s.log.Info().Interface("tls.certificates", tlsConfig.Certificates).Msg("enabling LDAP over TLS")
}
for i, backend := range s.c.Backends {
var h handler.Handler
switch backend.Datastore {
+3
View File
@@ -21,6 +21,9 @@ debug = true
enabled = true
# run on a non privileged port
listen = "0.0.0.0:3893"
tls = false # enable StartTLS support
tlsCertPath = "glauth.crt"
tlsKeyPath = "glauth.key"
[ldaps]
# to enable ldaps generate a certificate, eg. with: