From ca5952fe3484d6af9f21340a2e1147affcc06037 Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Thu, 23 Jun 2022 13:17:57 +0200 Subject: [PATCH] Improve LDAP CA cert check The check was still racy as it could return early if the cert file exists but was not fully written yet. --- ocis-pkg/ldap/ldap.go | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/ocis-pkg/ldap/ldap.go b/ocis-pkg/ldap/ldap.go index a03d58848..8eceaf3cb 100644 --- a/ocis-pkg/ldap/ldap.go +++ b/ocis-pkg/ldap/ldap.go @@ -1,24 +1,39 @@ package ldap import ( + "crypto/x509" "errors" + "io/ioutil" "os" "time" "github.com/owncloud/ocis/v2/ocis-pkg/log" ) -const _caTimeout = 5 +const ( + caCheckRetries = 3 + caCheckSleep = 2 +) func WaitForCA(log log.Logger, insecure bool, caCert string) error { if !insecure && caCert != "" { - if _, err := os.Stat(caCert); errors.Is(err, os.ErrNotExist) { - log.Warn().Str("LDAP CACert", caCert).Msgf("File does not exist. Waiting %d seconds for it to appear.", _caTimeout) - time.Sleep(_caTimeout * time.Second) - if _, err := os.Stat(caCert); errors.Is(err, os.ErrNotExist) { - log.Warn().Str("LDAP CACert", caCert).Msgf("File still does not exist after Timeout") + for i := 0; i < caCheckRetries; i++ { + if _, err := os.Stat(caCert); err != nil && !errors.Is(err, os.ErrNotExist) { return err } + // Check if this actually is a CA cert. We need to retry here as well + // as the file might exist already, but have no contents yet. + certs := x509.NewCertPool() + pemData, err := ioutil.ReadFile(caCert) + if err != nil { + log.Debug().Err(err).Str("LDAP CACert", caCert).Msg("Error reading CA") + } else if !certs.AppendCertsFromPEM(pemData) { + log.Debug().Str("LDAP CAcert", caCert).Msg("Failed to append CA to pool") + } else { + return nil + } + time.Sleep(caCheckSleep * time.Second) + log.Warn().Str("LDAP CACert", caCert).Msgf("CA cert file is not ready yet. Waiting %d seconds for it to appear.", caCheckSleep) } } return nil