From 2508ce0ef75a6c63c61f2af94ee10b07c9722092 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Mon, 7 Jun 2021 15:00:52 +0200 Subject: [PATCH] use user system config to store tls artifacts --- glauth/pkg/flagset/flagset.go | 9 ++++++-- idp/pkg/crypto/gencert.go | 37 ++++++++++++++++++++++++++------- idp/pkg/flagset/flagset.go | 9 ++++++-- idp/pkg/server/http/server.go | 2 +- ocis/go.mod | 1 + ocis/go.sum | 2 ++ proxy/go.sum | 3 --- proxy/pkg/crypto/gencert.go | 37 ++++++++++++++++++++++++++------- proxy/pkg/flagset/flagset.go | 8 +++++-- proxy/pkg/server/http/server.go | 22 +++++++------------- 10 files changed, 90 insertions(+), 40 deletions(-) diff --git a/glauth/pkg/flagset/flagset.go b/glauth/pkg/flagset/flagset.go index ad767a0e7..0aa1a65d4 100644 --- a/glauth/pkg/flagset/flagset.go +++ b/glauth/pkg/flagset/flagset.go @@ -1,6 +1,10 @@ package flagset import ( + "path" + + "github.com/ProtonMail/go-appdir" + "github.com/micro/cli/v2" "github.com/owncloud/ocis/glauth/pkg/config" "github.com/owncloud/ocis/ocis-pkg/flags" @@ -45,6 +49,7 @@ func HealthWithConfig(cfg *config.Config) []cli.Flag { // ServerWithConfig applies cfg to the root flagset func ServerWithConfig(cfg *config.Config) []cli.Flag { + dirs := appdir.New("ldap") return []cli.Flag{ &cli.StringFlag{ Name: "log-file", @@ -158,14 +163,14 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { }, &cli.StringFlag{ Name: "ldaps-cert", - Value: flags.OverrideDefaultString(cfg.Ldaps.Cert, "./ldap.crt"), + Value: flags.OverrideDefaultString(cfg.Ldaps.Cert, path.Join(dirs.UserConfig(), "ldap.crt")), Usage: "path to ldaps certificate in PEM format", EnvVars: []string{"GLAUTH_LDAPS_CERT"}, Destination: &cfg.Ldaps.Cert, }, &cli.StringFlag{ Name: "ldaps-key", - Value: flags.OverrideDefaultString(cfg.Ldaps.Key, "./ldap.key"), + Value: flags.OverrideDefaultString(cfg.Ldaps.Key, path.Join(dirs.UserConfig(), "ldap.key")), Usage: "path to ldaps key in PEM format", EnvVars: []string{"GLAUTH_LDAPS_KEY"}, Destination: &cfg.Ldaps.Key, diff --git a/idp/pkg/crypto/gencert.go b/idp/pkg/crypto/gencert.go index a7627c150..3a287d5f7 100644 --- a/idp/pkg/crypto/gencert.go +++ b/idp/pkg/crypto/gencert.go @@ -10,6 +10,7 @@ import ( "math/big" "net" "os" + "path/filepath" "time" "github.com/owncloud/ocis/ocis-pkg/log" @@ -41,13 +42,20 @@ func pemBlockForKey(priv interface{}, l log.Logger) *pem.Block { } } -// GenCert generates TLS-Certificates -func GenCert(l log.Logger) error { +// GenCert generates TLS-Certificates and persists them to the filesystem. +func GenCert(certName string, keyName string, l log.Logger) error { var priv interface{} var err error - priv, err = rsa.GenerateKey(rand.Reader, 2048) + _, certErr := os.Stat(certName) + _, keyErr := os.Stat(keyName) + if certErr == nil || keyErr == nil { + l.Debug().Msg("IDP certificate or key already present, using these") + return nil + } + + priv, err = rsa.GenerateKey(rand.Reader, 2048) if err != nil { l.Fatal().Err(err).Msg("Failed to generate private key") } @@ -84,15 +92,20 @@ func GenCert(l log.Logger) error { } } - //template.IsCA = true - //template.KeyUsage |= x509.KeyUsageCertSign - derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) if err != nil { l.Fatal().Err(err).Msg("Failed to create certificate") } - certOut, err := os.Create("server.crt") + certPath := filepath.Dir(certName) + if _, err := os.Stat(certPath); os.IsNotExist(err) { + err = os.MkdirAll(certPath, 0700) + if err != nil { + l.Fatal().Err(err).Msg("Failed to create path " + certPath) + } + } + + certOut, err := os.Create(certName) if err != nil { l.Fatal().Err(err).Msg("Failed to open server.crt for writing") } @@ -106,7 +119,15 @@ func GenCert(l log.Logger) error { } l.Info().Msg("Written server.crt") - keyOut, err := os.OpenFile("server.key", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + keyPath := filepath.Dir(keyName) + if _, err := os.Stat(keyPath); os.IsNotExist(err) { + err = os.MkdirAll(keyPath, 0700) + if err != nil { + l.Fatal().Err(err).Msg("Failed to create path " + keyPath) + } + } + + keyOut, err := os.OpenFile(keyName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { l.Fatal().Err(err).Msg("Failed to open server.key for writing") } diff --git a/idp/pkg/flagset/flagset.go b/idp/pkg/flagset/flagset.go index c9205a7fc..851ae295c 100644 --- a/idp/pkg/flagset/flagset.go +++ b/idp/pkg/flagset/flagset.go @@ -1,6 +1,10 @@ package flagset import ( + "path" + + "github.com/ProtonMail/go-appdir" + "github.com/micro/cli/v2" "github.com/owncloud/ocis/idp/pkg/config" "github.com/owncloud/ocis/ocis-pkg/flags" @@ -45,6 +49,7 @@ func HealthWithConfig(cfg *config.Config) []cli.Flag { // ServerWithConfig applies cfg to the root flagset func ServerWithConfig(cfg *config.Config) []cli.Flag { + dirs := appdir.New("idp") return []cli.Flag{ &cli.StringFlag{ Name: "log-file", @@ -233,14 +238,14 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { }, &cli.StringFlag{ Name: "transport-tls-cert", - Value: flags.OverrideDefaultString(cfg.HTTP.TLSCert, ""), + Value: flags.OverrideDefaultString(cfg.HTTP.TLSCert, path.Join(dirs.UserConfig(), "server.crt")), Usage: "Certificate file for transport encryption", EnvVars: []string{"IDP_TRANSPORT_TLS_CERT"}, Destination: &cfg.HTTP.TLSCert, }, &cli.StringFlag{ Name: "transport-tls-key", - Value: flags.OverrideDefaultString(cfg.HTTP.TLSKey, ""), + Value: flags.OverrideDefaultString(cfg.HTTP.TLSKey, path.Join(dirs.UserConfig(), "server.key")), Usage: "Secret file for transport encryption", EnvVars: []string{"IDP_TRANSPORT_TLS_KEY"}, Destination: &cfg.HTTP.TLSKey, diff --git a/idp/pkg/server/http/server.go b/idp/pkg/server/http/server.go index 2bed18c36..279de2e49 100644 --- a/idp/pkg/server/http/server.go +++ b/idp/pkg/server/http/server.go @@ -24,7 +24,7 @@ func Server(opts ...Option) (http.Service, error) { if os.IsNotExist(certErr) || os.IsNotExist(keyErr) { options.Logger.Info().Msgf("Generating certs") - if err := crypto.GenCert(options.Logger); err != nil { + if err := crypto.GenCert(options.Config.HTTP.TLSCert, options.Config.HTTP.TLSKey, options.Logger); err != nil { options.Logger.Fatal().Err(err).Msg("Could not setup TLS") os.Exit(1) } diff --git a/ocis/go.mod b/ocis/go.mod index 72c2ca17f..1364bd30c 100644 --- a/ocis/go.mod +++ b/ocis/go.mod @@ -6,6 +6,7 @@ require ( contrib.go.opencensus.io/exporter/jaeger v0.2.1 contrib.go.opencensus.io/exporter/ocagent v0.7.0 contrib.go.opencensus.io/exporter/zipkin v0.1.2 + github.com/ProtonMail/go-appdir v1.1.0 // indirect github.com/asim/go-micro/plugins/logger/zerolog/v3 v3.0.0-20210217182006-0f0ace1a44a9 github.com/asim/go-micro/v3 v3.5.1-0.20210217182006-0f0ace1a44a9 github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d // indirect diff --git a/ocis/go.sum b/ocis/go.sum index a8403c313..6cf12811a 100644 --- a/ocis/go.sum +++ b/ocis/go.sum @@ -95,6 +95,8 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks= +github.com/ProtonMail/go-appdir v1.1.0 h1:9hdNDlU9kTqRKVNzmoqah8qqrj5QZyLByQdwQNlFWig= +github.com/ProtonMail/go-appdir v1.1.0/go.mod h1:3d8Y9F5mbEUjrYbcJ3rcDxcWbqbttF+011nVZmdRdzc= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= diff --git a/proxy/go.sum b/proxy/go.sum index 67d8dad06..a3ea9a762 100644 --- a/proxy/go.sum +++ b/proxy/go.sum @@ -304,7 +304,6 @@ github.com/cs3org/reva v1.6.1-0.20210329145723-ed244aac4ddc/go.mod h1:exwJqEJ8lV github.com/cs3org/reva v1.7.1-0.20210531093513-b74a2b156af6 h1:8KrCDk1GtDJUl0d1TqHEyH29yc8Wo+J6mMGYXDBh+uo= github.com/cs3org/reva v1.7.1-0.20210531093513-b74a2b156af6/go.mod h1:5hetpRcAS6Scj8FhGc6/kLf1phWdOLvI3RbHdJZ6sfo= github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAElF6hxnA= -github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -969,7 +968,6 @@ github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8 github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jmoiron/sqlx v0.0.0-20180614180643-0dae4fefe7c0/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= @@ -1588,7 +1586,6 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog= github.com/thejerf/suture/v4 v4.0.0 h1:GX3X+1Qaewtj9flL2wgoTBfLA5NcmrCY39TJRpPbUrI= github.com/thejerf/suture/v4 v4.0.0/go.mod h1:g0e8vwskm9tI0jRjxrnA6lSr0q6OfPdWJVX7G5bVWRs= diff --git a/proxy/pkg/crypto/gencert.go b/proxy/pkg/crypto/gencert.go index a7627c150..3af9169c7 100644 --- a/proxy/pkg/crypto/gencert.go +++ b/proxy/pkg/crypto/gencert.go @@ -10,6 +10,7 @@ import ( "math/big" "net" "os" + "path/filepath" "time" "github.com/owncloud/ocis/ocis-pkg/log" @@ -41,13 +42,20 @@ func pemBlockForKey(priv interface{}, l log.Logger) *pem.Block { } } -// GenCert generates TLS-Certificates -func GenCert(l log.Logger) error { +// GenCert generates TLS-Certificates and persists them to the filesystem. +func GenCert(certName string, keyName string, l log.Logger) error { var priv interface{} var err error - priv, err = rsa.GenerateKey(rand.Reader, 2048) + _, certErr := os.Stat(certName) + _, keyErr := os.Stat(keyName) + if certErr == nil || keyErr == nil { + l.Debug().Msg("Proxy certificate or key already present, using these") + return nil + } + + priv, err = rsa.GenerateKey(rand.Reader, 2048) if err != nil { l.Fatal().Err(err).Msg("Failed to generate private key") } @@ -84,15 +92,20 @@ func GenCert(l log.Logger) error { } } - //template.IsCA = true - //template.KeyUsage |= x509.KeyUsageCertSign - derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) if err != nil { l.Fatal().Err(err).Msg("Failed to create certificate") } - certOut, err := os.Create("server.crt") + certPath := filepath.Dir(certName) + if _, err := os.Stat(certPath); os.IsNotExist(err) { + err = os.MkdirAll(certPath, 0700) + if err != nil { + l.Fatal().Err(err).Msg("Failed to create path " + certPath) + } + } + + certOut, err := os.Create(certName) if err != nil { l.Fatal().Err(err).Msg("Failed to open server.crt for writing") } @@ -106,7 +119,15 @@ func GenCert(l log.Logger) error { } l.Info().Msg("Written server.crt") - keyOut, err := os.OpenFile("server.key", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + keyPath := filepath.Dir(keyName) + if _, err := os.Stat(keyPath); os.IsNotExist(err) { + err = os.MkdirAll(keyPath, 0700) + if err != nil { + l.Fatal().Err(err).Msg("Failed to create path " + keyPath) + } + } + + keyOut, err := os.OpenFile(keyName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { l.Fatal().Err(err).Msg("Failed to open server.key for writing") } diff --git a/proxy/pkg/flagset/flagset.go b/proxy/pkg/flagset/flagset.go index 292676ec8..077efe9aa 100644 --- a/proxy/pkg/flagset/flagset.go +++ b/proxy/pkg/flagset/flagset.go @@ -1,6 +1,9 @@ package flagset import ( + "path" + + "github.com/ProtonMail/go-appdir" "github.com/micro/cli/v2" "github.com/owncloud/ocis/ocis-pkg/flags" "github.com/owncloud/ocis/proxy/pkg/config" @@ -45,6 +48,7 @@ func HealthWithConfig(cfg *config.Config) []cli.Flag { // ServerWithConfig applies cfg to the root flagset func ServerWithConfig(cfg *config.Config) []cli.Flag { + dirs := appdir.New("proxy") return []cli.Flag{ &cli.StringFlag{ Name: "log-file", @@ -156,14 +160,14 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { }, &cli.StringFlag{ Name: "transport-tls-cert", - Value: flags.OverrideDefaultString(cfg.HTTP.TLSCert, ""), + Value: flags.OverrideDefaultString(cfg.HTTP.TLSCert, path.Join(dirs.UserConfig(), "server.crt")), Usage: "Certificate file for transport encryption", EnvVars: []string{"PROXY_TRANSPORT_TLS_CERT"}, Destination: &cfg.HTTP.TLSCert, }, &cli.StringFlag{ Name: "transport-tls-key", - Value: flags.OverrideDefaultString(cfg.HTTP.TLSKey, ""), + Value: flags.OverrideDefaultString(cfg.HTTP.TLSKey, path.Join(dirs.UserConfig(), "server.key")), Usage: "Secret file for transport encryption", EnvVars: []string{"PROXY_TRANSPORT_TLS_KEY"}, Destination: &cfg.HTTP.TLSKey, diff --git a/proxy/pkg/server/http/server.go b/proxy/pkg/server/http/server.go index 1849657d2..57985361d 100644 --- a/proxy/pkg/server/http/server.go +++ b/proxy/pkg/server/http/server.go @@ -17,25 +17,19 @@ func Server(opts ...Option) (svc.Service, error) { httpCfg := options.Config.HTTP var cer tls.Certificate - var certErr error var tlsConfig *tls.Config if options.Config.HTTP.TLS { - if httpCfg.TLSCert == "" || httpCfg.TLSKey == "" { - l.Warn().Msgf("No tls certificate provided, using a generated one") - _, certErr := os.Stat("./server.crt") - _, keyErr := os.Stat("./server.key") + l.Warn().Msgf("No tls certificate provided, using a generated one") + _, certErr := os.Stat(httpCfg.TLSCert) + _, keyErr := os.Stat(httpCfg.TLSKey) - if os.IsNotExist(certErr) || os.IsNotExist(keyErr) { - // GenCert has side effects as it writes 2 files to the binary running location - if err := crypto.GenCert(l); err != nil { - l.Fatal().Err(err).Msgf("Could not generate test-certificate") - os.Exit(1) - } + if os.IsNotExist(certErr) || os.IsNotExist(keyErr) { + // GenCert has side effects as it writes 2 files to the binary running location + if err := crypto.GenCert(httpCfg.TLSCert, httpCfg.TLSKey, l); err != nil { + l.Fatal().Err(err).Msgf("Could not generate test-certificate") + os.Exit(1) } - - httpCfg.TLSCert = "server.crt" - httpCfg.TLSKey = "server.key" } cer, certErr = tls.LoadX509KeyPair(httpCfg.TLSCert, httpCfg.TLSKey)