From 48e6e9a36c9194f0dc1e8dee46e0a02f4df73a14 Mon Sep 17 00:00:00 2001 From: Mihai Doarna Date: Fri, 5 Jul 2024 11:58:50 +0300 Subject: [PATCH] LDAP: Compute values when reloading LDAP settings (#90059) * compute values when reloading LDAP settings * remove grafana-cli/logger dependency * export defaultTimeout from ldap package * add server host to logs --- pkg/services/ldap/ldap.go | 4 +-- pkg/services/ldap/service/ldap.go | 28 +++++++++++++++++ pkg/services/ldap/service/ldap_test.go | 43 ++++++++++++++++++++------ pkg/services/ldap/settings.go | 22 ++++++------- pkg/services/ldap/settings_test.go | 4 +-- 5 files changed, 76 insertions(+), 25 deletions(-) diff --git a/pkg/services/ldap/ldap.go b/pkg/services/ldap/ldap.go index add301da595..ac63c00cf9a 100644 --- a/pkg/services/ldap/ldap.go +++ b/pkg/services/ldap/ldap.go @@ -117,8 +117,8 @@ func (server *Server) Dial() error { InsecureSkipVerify: server.Config.SkipVerifySSL, ServerName: host, RootCAs: certPool, - MinVersion: server.Config.minTLSVersion, - CipherSuites: server.Config.tlsCiphers, + MinVersion: server.Config.MinTLSVersionID, + CipherSuites: server.Config.TLSCipherIDs, } if len(clientCert.Certificate) > 0 { tlsCfg.Certificates = append(tlsCfg.Certificates, clientCert) diff --git a/pkg/services/ldap/service/ldap.go b/pkg/services/ldap/service/ldap.go index e67a291a025..0a72f93721b 100644 --- a/pkg/services/ldap/service/ldap.go +++ b/pkg/services/ldap/service/ldap.go @@ -99,6 +99,34 @@ func (s *LDAPImpl) Reload(ctx context.Context, settings models.SSOSettings) erro return err } + // calculate MinTLSVersionID and TLSCipherIDs from input text values + // also initialize Timeout and OrgID from group mappings with default values if they are not configured + for _, server := range ldapCfg.Servers { + if server.MinTLSVersion != "" { + server.MinTLSVersionID, err = util.TlsNameToVersion(server.MinTLSVersion) + if err != nil { + s.log.Error("failed to set min TLS version, ignoring", "err", err, "server", server.Host) + } + } + + if len(server.TLSCiphers) > 0 { + server.TLSCipherIDs, err = util.TlsCiphersToIDs(server.TLSCiphers) + if err != nil { + s.log.Error("unrecognized TLS Cipher(s), ignoring", "err", err, "server", server.Host) + } + } + + for _, groupMap := range server.Groups { + if groupMap.OrgId == 0 { + groupMap.OrgId = 1 + } + } + + if server.Timeout == 0 { + server.Timeout = ldap.DefaultTimeout + } + } + s.loadingMutex.Lock() defer s.loadingMutex.Unlock() diff --git a/pkg/services/ldap/service/ldap_test.go b/pkg/services/ldap/service/ldap_test.go index 2fe46701264..d58efaf49aa 100644 --- a/pkg/services/ldap/service/ldap_test.go +++ b/pkg/services/ldap/service/ldap_test.go @@ -2,6 +2,7 @@ package service import ( "context" + "crypto/tls" "sync" "testing" @@ -71,6 +72,12 @@ func TestReload(t *testing.T) { "servers": []any{ map[string]any{ "host": "127.0.0.1", + "group_mappings": []any{ + map[string]any{ + "group_dn": "cn=admin,ou=groups,dc=ldap,dc=goauthentik,dc=io", + "grafana_admin": true, + }, + }, }, }, }, @@ -80,7 +87,15 @@ func TestReload(t *testing.T) { expectedServersConfig: &ldap.ServersConfig{ Servers: []*ldap.ServerConfig{ { - Host: "127.0.0.1", + Host: "127.0.0.1", + Timeout: 10, + Groups: []*ldap.GroupToOrgRole{ + { + GroupDN: "cn=admin,ou=groups,dc=ldap,dc=goauthentik,dc=io", + OrgId: 1, + IsGrafanaAdmin: &isAdmin, + }, + }, }, }, }, @@ -122,6 +137,7 @@ func TestReload(t *testing.T) { "group_search_base_dns": []string{"ou=groups,dc=grafana,dc=org"}, "tls_ciphers": []string{ "TLS_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", }, "attributes": map[string]string{ "email": "mail", @@ -147,7 +163,7 @@ func TestReload(t *testing.T) { }, map[string]any{ "group_dn": "cn=viewer,ou=groups,dc=ldap,dc=goauthentik,dc=io", - "org_id": 1, + "org_id": 2, "org_role": "Viewer", }, }, @@ -160,14 +176,20 @@ func TestReload(t *testing.T) { expectedServersConfig: &ldap.ServersConfig{ Servers: []*ldap.ServerConfig{ { - Host: "127.0.0.1", - Port: 3389, - UseSSL: true, - StartTLS: true, - SkipVerifySSL: false, - MinTLSVersion: "TLS1.3", + Host: "127.0.0.1", + Port: 3389, + UseSSL: true, + StartTLS: true, + SkipVerifySSL: false, + MinTLSVersion: "TLS1.3", + MinTLSVersionID: tls.VersionTLS13, TLSCiphers: []string{ "TLS_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + }, + TLSCipherIDs: []uint16{ + tls.TLS_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, }, RootCACert: "/path/to/certificate.crt", RootCACertValue: []string{validCert}, @@ -204,7 +226,7 @@ func TestReload(t *testing.T) { }, { GroupDN: "cn=viewer,ou=groups,dc=ldap,dc=goauthentik,dc=io", - OrgId: 1, + OrgId: 2, OrgRole: "Viewer", }, }, @@ -271,7 +293,8 @@ func TestReload(t *testing.T) { expectedServersConfig: &ldap.ServersConfig{ Servers: []*ldap.ServerConfig{ { - Host: "127.0.0.1", + Host: "127.0.0.1", + Timeout: 10, }, }, }, diff --git a/pkg/services/ldap/settings.go b/pkg/services/ldap/settings.go index 5d30e53c138..5b0a5b30d55 100644 --- a/pkg/services/ldap/settings.go +++ b/pkg/services/ldap/settings.go @@ -14,7 +14,7 @@ import ( "github.com/grafana/grafana/pkg/util" ) -const defaultTimeout = 10 +const DefaultTimeout = 10 // Config holds parameters from the .ini config file type Config struct { @@ -36,13 +36,13 @@ type ServerConfig struct { Host string `toml:"host" json:"host"` Port int `toml:"port" json:"port,omitempty"` - UseSSL bool `toml:"use_ssl" json:"use_ssl,omitempty"` - StartTLS bool `toml:"start_tls" json:"start_tls,omitempty"` - SkipVerifySSL bool `toml:"ssl_skip_verify" json:"ssl_skip_verify,omitempty"` - MinTLSVersion string `toml:"min_tls_version" json:"min_tls_version,omitempty"` - minTLSVersion uint16 `toml:"-" json:"-"` - TLSCiphers []string `toml:"tls_ciphers" json:"tls_ciphers,omitempty"` - tlsCiphers []uint16 `toml:"-" json:"-"` + UseSSL bool `toml:"use_ssl" json:"use_ssl,omitempty"` + StartTLS bool `toml:"start_tls" json:"start_tls,omitempty"` + SkipVerifySSL bool `toml:"ssl_skip_verify" json:"ssl_skip_verify,omitempty"` + MinTLSVersion string `toml:"min_tls_version" json:"min_tls_version,omitempty"` + MinTLSVersionID uint16 `toml:"-" json:"-"` + TLSCiphers []string `toml:"tls_ciphers" json:"tls_ciphers,omitempty"` + TLSCipherIDs []uint16 `toml:"-" json:"-"` RootCACert string `toml:"root_ca_cert" json:"root_ca_cert,omitempty"` RootCACertValue []string `json:"root_ca_cert_value,omitempty"` @@ -184,14 +184,14 @@ func readConfig(configFile string) (*ServersConfig, error) { } if server.MinTLSVersion != "" { - server.minTLSVersion, err = util.TlsNameToVersion(server.MinTLSVersion) + server.MinTLSVersionID, err = util.TlsNameToVersion(server.MinTLSVersion) if err != nil { logger.Error("Failed to set min TLS version. Ignoring", "err", err) } } if len(server.TLSCiphers) > 0 { - server.tlsCiphers, err = util.TlsCiphersToIDs(server.TLSCiphers) + server.TLSCipherIDs, err = util.TlsCiphersToIDs(server.TLSCiphers) if err != nil { logger.Error("Unrecognized TLS Cipher(s). Ignoring", "err", err) } @@ -209,7 +209,7 @@ func readConfig(configFile string) (*ServersConfig, error) { // set default timeout if unspecified if server.Timeout == 0 { - server.Timeout = defaultTimeout + server.Timeout = DefaultTimeout } } diff --git a/pkg/services/ldap/settings_test.go b/pkg/services/ldap/settings_test.go index 2ca8c5025e4..6775b8e511a 100644 --- a/pkg/services/ldap/settings_test.go +++ b/pkg/services/ldap/settings_test.go @@ -13,9 +13,9 @@ func TestReadingLDAPSettings(t *testing.T) { assert.Nil(t, err, "No error when reading ldap config") assert.EqualValues(t, "127.0.0.1", config.Servers[0].Host) assert.EqualValues(t, "tls1.3", config.Servers[0].MinTLSVersion) - assert.EqualValues(t, uint16(tls.VersionTLS13), config.Servers[0].minTLSVersion) + assert.EqualValues(t, uint16(tls.VersionTLS13), config.Servers[0].MinTLSVersionID) assert.EqualValues(t, []string{"TLS_CHACHA20_POLY1305_SHA256", "TLS_AES_128_GCM_SHA256"}, config.Servers[0].TLSCiphers) - assert.ElementsMatch(t, []uint16{tls.TLS_CHACHA20_POLY1305_SHA256, tls.TLS_AES_128_GCM_SHA256}, config.Servers[0].tlsCiphers) + assert.ElementsMatch(t, []uint16{tls.TLS_CHACHA20_POLY1305_SHA256, tls.TLS_AES_128_GCM_SHA256}, config.Servers[0].TLSCipherIDs) } func TestReadingLDAPSettingsWithEnvVariable(t *testing.T) {