From 46d643de04aaf02bc9a83d7b21091e2200fe731f Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Tue, 22 Sep 2020 16:39:06 +0200 Subject: [PATCH] Add basic and bypass auth methods --- auth/auth.go | 28 +++++++++++++++++++-------- auth/basic/basic.go | 44 +++++++++++++++++++++++++++++++++++++++++++ auth/bypass/bypass.go | 21 +++++++++++++++++++++ auth/ldap/ldap.go | 11 ++++------- ghostream.yml.example | 28 +++++++++++++++++++++++++++ go.mod | 3 +++ go.sum | 3 +++ main.go | 2 +- 8 files changed, 124 insertions(+), 16 deletions(-) create mode 100644 auth/basic/basic.go create mode 100644 auth/bypass/bypass.go create mode 100644 ghostream.yml.example diff --git a/auth/auth.go b/auth/auth.go index 9503ce3..2fe2311 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -2,13 +2,18 @@ package auth import ( "errors" + "log" + "strings" + "gitlab.crans.org/nounous/ghostream/auth/basic" + "gitlab.crans.org/nounous/ghostream/auth/bypass" "gitlab.crans.org/nounous/ghostream/auth/ldap" ) // Options holds package configuration type Options struct { Backend string + Basic basic.Options LDAP ldap.Options } @@ -23,16 +28,23 @@ func New(cfg *Options) (Backend, error) { var backend Backend var err error - if cfg.Backend == "LDAP" { - backend, err = ldap.NewLDAP(&cfg.LDAP) - if err != nil { - return nil, err - } - } else { + switch strings.ToLower(cfg.Backend) { + case "basic": + backend, err = basic.New(&cfg.Basic) + case "bypass": + backend, err = bypass.New() + case "ldap": + backend, err = ldap.New(&cfg.LDAP) + default: // Package is misconfigured - return nil, errors.New("Authentification backend not found") + backend, err = nil, errors.New("Authentification backend not found") } - // Init and return backend + if err != nil { + // Backend init failed + return nil, err + } + + log.Printf("%s backend successfully initialized", cfg.Backend) return backend, nil } diff --git a/auth/basic/basic.go b/auth/basic/basic.go new file mode 100644 index 0000000..5bf4623 --- /dev/null +++ b/auth/basic/basic.go @@ -0,0 +1,44 @@ +package basic + +import ( + "errors" + + "golang.org/x/crypto/bcrypt" +) + +// To generate bcrypt hashed password from Python, +// python3 -c 'import bcrypt; print(bcrypt.hashpw(b"PASSWORD", bcrypt.gensalt(rounds=15)).decode("ascii"))' + +// Options holds package configuration +type Options struct { + // Username: hashedPassword + Credentials map[string]string +} + +// Basic authentification backend +type Basic struct { + Cfg *Options +} + +// Login hashs password and compare +// Returns (true, nil) if success +func (a Basic) Login(username string, password string) (bool, error) { + hash, ok := a.Cfg.Credentials[username] + if !ok { + return false, errors.New("User not found in credentials") + } + err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) + + // Login succeeded if no error + return err == nil, err +} + +// Close has no connection to close +func (a Basic) Close() { +} + +// New instanciates a new Basic authentification backend +func New(cfg *Options) (Basic, error) { + backend := Basic{Cfg: cfg} + return backend, nil +} diff --git a/auth/bypass/bypass.go b/auth/bypass/bypass.go new file mode 100644 index 0000000..5abcd25 --- /dev/null +++ b/auth/bypass/bypass.go @@ -0,0 +1,21 @@ +package bypass + +// ByPass authentification backend +// By pass password check, open your streaming server to everyone! +type ByPass struct { +} + +// Login always return success +func (a ByPass) Login(username string, password string) (bool, error) { + return true, nil +} + +// Close has no connection to close +func (a ByPass) Close() { +} + +// New instanciates a new Basic authentification backend +func New() (ByPass, error) { + backend := ByPass{} + return backend, nil +} diff --git a/auth/ldap/ldap.go b/auth/ldap/ldap.go index 0dba25f..657bb10 100644 --- a/auth/ldap/ldap.go +++ b/auth/ldap/ldap.go @@ -22,12 +22,9 @@ func (a LDAP) Login(username string, password string) (bool, error) { // Try to bind as user bindDn := "cn=" + username + "," + a.Cfg.UserDn err := a.Conn.Bind(bindDn, password) - if err != nil { - return false, err - } - // Login succeeded - return true, nil + // Login succeeded if no error + return err == nil, err } // Close LDAP connection @@ -35,8 +32,8 @@ func (a LDAP) Close() { a.Conn.Close() } -// NewLDAP instanciate a new LDAP connection -func NewLDAP(cfg *Options) (LDAP, error) { +// New instanciates a new LDAP connection +func New(cfg *Options) (LDAP, error) { backend := LDAP{Cfg: cfg} // Connect to LDAP server diff --git a/ghostream.yml.example b/ghostream.yml.example new file mode 100644 index 0000000..280bb3a --- /dev/null +++ b/ghostream.yml.example @@ -0,0 +1,28 @@ +# Example configuration + +# Authentification +auth: + backend: basic + basic: + credentials: + # Demo user with password "demo" + demo: $2b$15$LRnG3eIHFlYIguTxZOLH7eHwbQC/vqjnLq6nDFiHSUDKIU.f5/1H6 + + # Example to bypass login, dangerous! + #backend: bypass + + # Example of LDAP server login + #backend: ldap + #ldap: + # uri: ldap://127.0.0.1:389 + # userdn: cn=users,dc=example,dc=com + +# Prometheus monitoring endpoint +monitoring: + listenaddress: 127.0.0.1:2112 + +# Customize web server +web: + name: Demo + Hostname: localhost + Favicon: https://www.crans.org/images/favicon.ico diff --git a/go.mod b/go.mod index e34a5a9..a66f83f 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,11 @@ module gitlab.crans.org/nounous/ghostream go 1.13 require ( + github.com/go-ldap/ldap v3.0.3+incompatible github.com/go-ldap/ldap/v3 v3.2.3 github.com/prometheus/client_golang v1.7.1 github.com/spf13/viper v1.7.1 + golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 + gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect honnef.co/go/tools v0.0.1-2019.2.3 ) diff --git a/go.sum b/go.sum index 9de5e74..17bc385 100644 --- a/go.sum +++ b/go.sum @@ -55,6 +55,7 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-ldap/ldap v3.0.3+incompatible h1:HTeSZO8hWMS1Rgb2Ziku6b8a7qRIZZMHjsvuZyatzwk= +github.com/go-ldap/ldap v3.0.3+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= github.com/go-ldap/ldap/v3 v3.2.3 h1:FBt+5w3q/vPVPb4eYMQSn+pOiz4zewPamYhlGMmc7yM= github.com/go-ldap/ldap/v3 v3.2.3/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -339,6 +340,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/main.go b/main.go index 1c5e666..713af45 100644 --- a/main.go +++ b/main.go @@ -39,7 +39,7 @@ func loadConfiguration() { } // Define configuration default values - viper.SetDefault("Auth.Backend", "LDAP") + viper.SetDefault("Auth.Backend", "Basic") viper.SetDefault("Auth.LDAP.URI", "ldap://127.0.0.1:389") viper.SetDefault("Auth.LDAP.UserDn", "cn=users,dc=example,dc=com") viper.SetDefault("Monitoring.ListenAddress", ":2112")