Generate certificates if they don't exist
This commit is contained in:
@@ -103,7 +103,7 @@ func ActionClientUpload(c *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s uploaded with id %s. Available at %s\n", arg, resp.Id, resp.FileUrl)
|
||||
fmt.Printf("%s uploaded with id %s. Available at:\n%s\n", arg, resp.Id, resp.FileUrl)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package actions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"gitea.benny.dog/torjus/ezshare/certs"
|
||||
"gitea.benny.dog/torjus/ezshare/config"
|
||||
@@ -25,10 +26,20 @@ func getConfig(c *cli.Context) (*config.Config, error) {
|
||||
cfgPath := c.String("config")
|
||||
return config.FromFile(cfgPath)
|
||||
}
|
||||
if val, ok := os.LookupEnv("EZSHARE_CONFIG"); ok {
|
||||
return config.FromFile(val)
|
||||
}
|
||||
cfg, err := config.FromDefaultLocations()
|
||||
if err == nil {
|
||||
verbosePrint(c, fmt.Sprintf("Config loaded from %s", cfg.Location()))
|
||||
}
|
||||
if cfg == nil {
|
||||
cfg = config.FromDefault()
|
||||
}
|
||||
cfg.UpdateFromEnv()
|
||||
if cfg.Client.Valid() == nil || cfg.Server.Valid() == nil {
|
||||
return cfg, nil
|
||||
}
|
||||
return cfg, err
|
||||
}
|
||||
|
||||
|
165
actions/serve.go
165
actions/serve.go
@@ -4,11 +4,15 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.benny.dog/torjus/ezshare/certs"
|
||||
@@ -37,21 +41,9 @@ func ActionServe(c *cli.Context) error {
|
||||
binsLogger := logger.Named("BINS")
|
||||
|
||||
// Read certificates
|
||||
srvCertBytes, err := cfg.Server.GRPC.Certs.GetCertBytes()
|
||||
certificates, err := getCerts(c, serverLogger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srvKeyBytes, err := cfg.Server.GRPC.Certs.GetKeyBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
caCertBytes, err := cfg.Server.GRPC.CACerts.GetCertBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
caKeyBytes, err := cfg.Server.GRPC.CACerts.GetKeyBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
return cli.Exit(fmt.Sprintf("Error getting certificates: %s", err), 1)
|
||||
}
|
||||
|
||||
// Setup file store
|
||||
@@ -74,7 +66,7 @@ func ActionServe(c *cli.Context) error {
|
||||
}
|
||||
|
||||
// Setup cert-service
|
||||
certSvc, err := certs.NewCertService(dataStore, caCertBytes, caKeyBytes)
|
||||
certSvc, err := certs.NewCertService(dataStore, certificates.caCert, certificates.caCertKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error initializing certificate service: %w", err)
|
||||
}
|
||||
@@ -122,13 +114,13 @@ func ActionServe(c *cli.Context) error {
|
||||
serverLogger.Errorw("Unable to setup GRPC listener.", "error", err)
|
||||
rootCancel()
|
||||
}
|
||||
srvCert, err := tls.X509KeyPair(srvCertBytes, srvKeyBytes)
|
||||
srvCert, err := tls.X509KeyPair(certificates.serverCert, certificates.serverKey)
|
||||
if err != nil {
|
||||
serverLogger.Errorw("Unable to load server certs.", "error", err)
|
||||
rootCancel()
|
||||
}
|
||||
certPool := x509.NewCertPool()
|
||||
if !certPool.AppendCertsFromPEM(caCertBytes) {
|
||||
if !certPool.AppendCertsFromPEM(certificates.caCert) {
|
||||
serverLogger.Errorw("Unable to load CA certs.")
|
||||
rootCancel()
|
||||
}
|
||||
@@ -176,7 +168,7 @@ func ActionServe(c *cli.Context) error {
|
||||
if c.IsSet("http-addr") {
|
||||
httpAddr = c.String("http-addr")
|
||||
}
|
||||
httpServer := server.NewHTTPSever(s, dataStore, srvCertBytes, cfg.Server.GRPCEndpoint)
|
||||
httpServer := server.NewHTTPSever(s, dataStore, certificates.serverCert, cfg.Server.GRPCEndpoint)
|
||||
httpServer.Logger = httpLogger
|
||||
httpServer.Addr = httpAddr
|
||||
|
||||
@@ -235,3 +227,140 @@ func initializeUsers(us store.UserStore, logger *zap.SugaredLogger) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type certBytes struct {
|
||||
caCert []byte
|
||||
caCertKey []byte
|
||||
serverCert []byte
|
||||
serverKey []byte
|
||||
}
|
||||
|
||||
func getCerts(c *cli.Context, logger *zap.SugaredLogger) (*certBytes, error) {
|
||||
cfg, err := getConfig(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cb := &certBytes{}
|
||||
|
||||
caCertBytes, caCertErr := cfg.Server.GRPC.CACerts.GetCertBytes()
|
||||
caKeyBytes, caKeyErr := cfg.Server.GRPC.CACerts.GetKeyBytes()
|
||||
if caCertErr != nil || caKeyErr != nil {
|
||||
if errors.Is(caCertErr, fs.ErrNotExist) && errors.Is(caKeyErr, fs.ErrNotExist) {
|
||||
// Neither cert or key found, generate
|
||||
logger.Warn("Certificates not found. Generating.")
|
||||
priv, pub, err := certs.GenCACert()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cb.caCert = pub
|
||||
cb.caCertKey = priv
|
||||
|
||||
// Since we remade ca certs, any existing server certs are useless
|
||||
parsedUrl, err := url.Parse(cfg.Server.Hostname)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse hostname: %w", err)
|
||||
}
|
||||
host := parsedUrl.Host
|
||||
if strings.Contains(host, ":") {
|
||||
host, _, err = net.SplitHostPort(host)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse hostname: %w", err)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to generate certs due to unknown hostname")
|
||||
}
|
||||
priv, pub, err = certs.GenCert(host, cb.caCert, cb.caCertKey, []string{host})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating server cert: %s", err)
|
||||
}
|
||||
pub, err = certs.ToPEM(pub, "CERTIFICATE")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error encoding server cert: %s", err)
|
||||
}
|
||||
priv, err = certs.ToPEM(priv, "EC PRIVATE KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error encoding server cert: %s", err)
|
||||
}
|
||||
cb.serverCert = pub
|
||||
cb.serverKey = priv
|
||||
cb.caCert, err = certs.ToPEM(cb.caCert, "CERTIFICATE")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error encoding server cert: %s", err)
|
||||
}
|
||||
cb.caCertKey, err = certs.ToPEM(cb.caCertKey, "EC PRIVATE KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error encoding server cert: %s", err)
|
||||
}
|
||||
|
||||
// Write them to files
|
||||
if cfg.Server.GRPC.CACerts.CertificatePath != "" {
|
||||
f, err := os.Create(cfg.Server.GRPC.CACerts.CertificatePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error writing certificate: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := f.Write(cb.caCert); err != nil {
|
||||
return nil, fmt.Errorf("error writing certificate: %w", err)
|
||||
}
|
||||
logger.Infow("Wrote CACert.", "path", cfg.Server.GRPC.CACerts.CertificatePath)
|
||||
}
|
||||
if cfg.Server.GRPC.CACerts.CertificateKeyPath != "" {
|
||||
f, err := os.Create(cfg.Server.GRPC.CACerts.CertificateKeyPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error writing certificate: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := f.Write(cb.caCertKey); err != nil {
|
||||
return nil, fmt.Errorf("error writing certificate: %w", err)
|
||||
}
|
||||
logger.Infow("Wrote CACert key.", "path", cfg.Server.GRPC.CACerts.CertificateKeyPath)
|
||||
}
|
||||
if cfg.Server.GRPC.Certs.CertificateKeyPath != "" {
|
||||
f, err := os.Create(cfg.Server.GRPC.Certs.CertificateKeyPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error writing certificate: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := f.Write(cb.serverKey); err != nil {
|
||||
return nil, fmt.Errorf("error writing certificate: %w", err)
|
||||
}
|
||||
logger.Infow("Wrote server cert key.", "path", cfg.Server.GRPC.Certs.CertificateKeyPath)
|
||||
}
|
||||
if cfg.Server.GRPC.Certs.CertificatePath != "" {
|
||||
f, err := os.Create(cfg.Server.GRPC.Certs.CertificatePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error writing certificate: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := f.Write(cb.serverCert); err != nil {
|
||||
return nil, fmt.Errorf("error writing certificate: %w", err)
|
||||
}
|
||||
logger.Infow("Wrote server cert key.", "path", cfg.Server.GRPC.Certs.CertificatePath)
|
||||
}
|
||||
|
||||
return cb, nil
|
||||
} else {
|
||||
if caCertErr != nil {
|
||||
return nil, caCertErr
|
||||
}
|
||||
return nil, caKeyErr
|
||||
}
|
||||
}
|
||||
|
||||
srvCertBytes, err := cfg.Server.GRPC.Certs.GetCertBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
srvKeyBytes, err := cfg.Server.GRPC.Certs.GetKeyBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &certBytes{
|
||||
caCert: caCertBytes,
|
||||
caCertKey: caKeyBytes,
|
||||
serverCert: srvCertBytes,
|
||||
serverKey: srvKeyBytes}, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user