From c1f0247586c98bbdfc42c4a8db3410d34dfbc500 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Sun, 26 Jan 2020 19:27:17 +0100 Subject: Externalize config --- main.go | 117 +++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 87 insertions(+), 30 deletions(-) (limited to 'main.go') diff --git a/main.go b/main.go index 6516724..8894f26 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,15 @@ package main -// @FIXME: Implement a real permission system: limit read/write scope/attributes, possibly based on group membership // @FIXME: Implement missing search filters (in applyFilter) // @FIXME: Add an initial prefix to the consul key value -// @FIXME: Add TLS connections import ( + "crypto/tls" "encoding/base64" "encoding/json" + "flag" "fmt" + "io/ioutil" "log" "math/rand" "os" @@ -21,9 +22,24 @@ import ( message "github.com/vjeantet/goldap/message" ) +type ConfigFile struct { + Suffix string `json:"suffix"` + BindAddress string `json:"bind_address"` + ConsulHost string `json:"consul_host"` + Acl []string `json:"acl"` + SSLCertFile string `json:"ssl_cert_file"` + SSLKeyFile string `json:"ssl_key_file"` + SSLServerName string `json:"ssl_server_name"` +} + type Config struct { - Suffix string - Acl ACL + Suffix string + BindAddress string + ConsulHost string + + Acl ACL + + TlsConfig *tls.Config } type Server struct { @@ -37,42 +53,77 @@ type State struct { type Entry map[string][]string -func main() { - //ldap logger - ldap.Logger = log.New(os.Stdout, "[server] ", log.LstdFlags) +var configFlag = flag.String("config", "./config.json", "Configuration file path") - // Connect to Consul - client, err := consul.NewClient(consul.DefaultConfig()) +func readConfig() Config { + config_file := ConfigFile{ + BindAddress: "0.0.0.0:389", + } + + bytes, err := ioutil.ReadFile(*configFlag) if err != nil { panic(err) } - kv := client.KV() - aclStr := []string{ - // Anybody (before binding) can bind to an entity under ou=users,dc=gobottin,dc=eu - "ANONYMOUS::bind:*,ou=users,dc=gobottin,dc=eu:", - // Anybody (before binding) can bind to the specific admin entity - "ANONYMOUS::bind:cn=admin,dc=gobottin,dc=eu:", - // Anybody who is logged in can read anything that is not a userpassword attribute - "*,dc=gobottin,dc=eu::read:*:* !userpassword", - // Anybody can read and modify anything from their own entry - "*::read modify:SELF:*", - // The admin can read, add, modify, delete anything - "cn=admin,dc=gobottin,dc=eu::read add modify delete:*:*", - // Members of the admin group can read, add, modify, delete anything - "*:cn=admin,ou=groups,dc=gobottin,dc=eu:read add modify delete:*:*", + err = json.Unmarshal(bytes, &config_file) + if err != nil { + panic(err) } - acl, err := ParseACL(aclStr) + + acl, err := ParseACL(config_file.Acl) if err != nil { panic(err) } - // TODO read config from somewhere - config := Config{ - Suffix: "dc=gobottin,dc=eu", - Acl: acl, + ret := Config{ + Suffix: config_file.Suffix, + BindAddress: config_file.BindAddress, + ConsulHost: config_file.ConsulHost, + Acl: acl, } + if config_file.SSLCertFile != "" && config_file.SSLKeyFile != "" && config_file.SSLServerName != "" { + cert_txt, err := ioutil.ReadFile(config_file.SSLCertFile) + if err != nil { + panic(err) + } + key_txt, err := ioutil.ReadFile(config_file.SSLKeyFile) + if err != nil { + panic(err) + } + cert, err := tls.X509KeyPair(cert_txt, key_txt) + if err != nil { + panic(err) + } + ret.TlsConfig = &tls.Config{ + MinVersion: tls.VersionSSL30, + MaxVersion: tls.VersionTLS12, + Certificates: []tls.Certificate{cert}, + ServerName: config_file.SSLServerName, + } + + } + + return ret +} + +func main() { + ldap.Logger = log.New(os.Stdout, "[server] ", log.LstdFlags) + + config := readConfig() + + // Connect to Consul + consul_config := consul.DefaultConfig() + if config.ConsulHost != "" { + consul_config.Address = config.ConsulHost + } + consul_client, err := consul.NewClient(consul_config) + if err != nil { + panic(err) + } + kv := consul_client.KV() + + // Create gobottin server gobottin := Server{config: config, kv: kv} err = gobottin.init() if err != nil { @@ -99,8 +150,14 @@ func main() { routes.Modify(gobottin.handleModify) ldapserver.Handle(routes) - // listen on 10389 - go ldapserver.ListenAndServe("127.0.0.1:10389") + if config.TlsConfig != nil { + secureConn := func(s *ldap.Server) { + s.Listener = tls.NewListener(s.Listener, config.TlsConfig) + } + go ldapserver.ListenAndServe(config.BindAddress, secureConn) + } else { + go ldapserver.ListenAndServe(config.BindAddress) + } // When CTRL+C, SIGINT and SIGTERM signal occurs // Then stop server gracefully -- cgit v1.2.3